mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
fix pack
This commit is contained in:
committed by
Aiden McClelland
parent
ffb9a72e18
commit
3f416dda1b
@@ -1,9 +1,13 @@
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
|
||||
use digest::Digest;
|
||||
use sha2::Sha512;
|
||||
use typed_builder::TypedBuilder;
|
||||
|
||||
use super::header::{FileSection, Header};
|
||||
use super::manifest::Manifest;
|
||||
use super::SIG_CONTEXT;
|
||||
use crate::util::HashWriter;
|
||||
use crate::{Error, ResultExt};
|
||||
|
||||
#[derive(TypedBuilder)]
|
||||
@@ -32,7 +36,7 @@ impl<
|
||||
> S9pkPacker<'a, W, RLicense, RInstructions, RIcon, RDockerImages>
|
||||
{
|
||||
/// BLOCKING
|
||||
pub fn pack(mut self) -> Result<(), Error> {
|
||||
pub fn pack(mut self, key: &ed25519_dalek::Keypair) -> Result<(), Error> {
|
||||
let header_pos = self.writer.stream_position()?;
|
||||
if header_pos != 0 {
|
||||
log::warn!("Appending to non-empty file.");
|
||||
@@ -45,57 +49,63 @@ impl<
|
||||
)
|
||||
})?;
|
||||
let mut position = self.writer.stream_position()?;
|
||||
|
||||
let mut writer = HashWriter::new(Sha512::new(), &mut self.writer);
|
||||
// manifest
|
||||
serde_cbor::to_writer(&mut self.writer, self.manifest).with_ctx(|_| {
|
||||
serde_cbor::to_writer(&mut writer, self.manifest).with_ctx(|_| {
|
||||
(
|
||||
crate::ErrorKind::Serialization,
|
||||
"Serializing Manifest (CBOR)",
|
||||
)
|
||||
})?;
|
||||
let new_pos = self.writer.stream_position()?;
|
||||
let new_pos = writer.stream_position()?;
|
||||
header.table_of_contents.manifest = FileSection {
|
||||
position,
|
||||
length: new_pos - position,
|
||||
};
|
||||
position = new_pos;
|
||||
// license
|
||||
std::io::copy(&mut self.license, &mut self.writer)
|
||||
std::io::copy(&mut self.license, &mut writer)
|
||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, "Copying License"))?;
|
||||
let new_pos = self.writer.stream_position()?;
|
||||
let new_pos = writer.stream_position()?;
|
||||
header.table_of_contents.license = FileSection {
|
||||
position,
|
||||
length: new_pos - position,
|
||||
};
|
||||
position = new_pos;
|
||||
// instructions
|
||||
std::io::copy(&mut self.instructions, &mut self.writer)
|
||||
std::io::copy(&mut self.instructions, &mut writer)
|
||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, "Copying Instructions"))?;
|
||||
let new_pos = self.writer.stream_position()?;
|
||||
let new_pos = writer.stream_position()?;
|
||||
header.table_of_contents.instructions = FileSection {
|
||||
position,
|
||||
length: new_pos - position,
|
||||
};
|
||||
position = new_pos;
|
||||
// icon
|
||||
std::io::copy(&mut self.icon, &mut self.writer)
|
||||
std::io::copy(&mut self.icon, &mut writer)
|
||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, "Copying Icon"))?;
|
||||
let new_pos = self.writer.stream_position()?;
|
||||
let new_pos = writer.stream_position()?;
|
||||
header.table_of_contents.icon = FileSection {
|
||||
position,
|
||||
length: new_pos - position,
|
||||
};
|
||||
position = new_pos;
|
||||
// docker_images
|
||||
std::io::copy(&mut self.docker_images, &mut self.writer)
|
||||
std::io::copy(&mut self.docker_images, &mut writer)
|
||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, "Copying App Image"))?;
|
||||
let new_pos = self.writer.stream_position()?;
|
||||
let new_pos = writer.stream_position()?;
|
||||
header.table_of_contents.docker_images = FileSection {
|
||||
position,
|
||||
length: new_pos - position,
|
||||
};
|
||||
position = new_pos;
|
||||
|
||||
// header
|
||||
let (hash, _) = writer.finish();
|
||||
self.writer.seek(SeekFrom::Start(header_pos))?;
|
||||
header.pubkey = key.public.clone();
|
||||
header.signature = key.sign_prehashed(hash, Some(SIG_CONTEXT))?;
|
||||
header
|
||||
.serialize(&mut self.writer)
|
||||
.with_ctx(|_| (crate::ErrorKind::Serialization, "Writing Header"))?;
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::Error;
|
||||
pub const MAGIC: [u8; 2] = [59, 59];
|
||||
pub const VERSION: u8 = 1;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Header {
|
||||
pub pubkey: PublicKey,
|
||||
pub signature: Signature,
|
||||
@@ -76,14 +77,11 @@ pub struct TableOfContents {
|
||||
}
|
||||
impl TableOfContents {
|
||||
pub fn serialize<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
|
||||
let len: u32 = 16 // size of FileSection
|
||||
* (
|
||||
1 + // manifest
|
||||
1 + // license
|
||||
1 + // instructions
|
||||
1 + // icon
|
||||
1 // docker_images
|
||||
);
|
||||
let len: u32 = ((1 + "manifest".len() + 16)
|
||||
+ (1 + "license".len() + 16)
|
||||
+ (1 + "instructions".len() + 16)
|
||||
+ (1 + "icon".len() + 16)
|
||||
+ (1 + "docker_images".len() + 16)) as u32;
|
||||
writer.write_all(&u32::to_be_bytes(len))?;
|
||||
self.manifest.serialize_entry("manifest", &mut writer)?;
|
||||
self.license.serialize_entry("license", &mut writer)?;
|
||||
@@ -153,7 +151,8 @@ impl FileSection {
|
||||
if read == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
let label = vec![0; label_len[0] as usize];
|
||||
let mut label = vec![0; label_len[0] as usize];
|
||||
reader.read_exact(&mut label).await?;
|
||||
let mut pos = [0; 8];
|
||||
reader.read_exact(&mut pos).await?;
|
||||
let mut len = [0; 8];
|
||||
|
||||
@@ -134,6 +134,7 @@ pub struct Manifest {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Assets {
|
||||
#[serde(default)]
|
||||
pub license: Option<PathBuf>,
|
||||
@@ -168,7 +169,7 @@ impl Assets {
|
||||
self.docker_images
|
||||
.as_ref()
|
||||
.map(|a| a.as_path())
|
||||
.unwrap_or(Path::new("images.tar"))
|
||||
.unwrap_or(Path::new("image.tar"))
|
||||
}
|
||||
pub fn instructions_path(&self) -> &Path {
|
||||
self.instructions
|
||||
|
||||
@@ -20,8 +20,11 @@ pub mod reader;
|
||||
pub const SIG_CONTEXT: &'static [u8] = b"s9pk";
|
||||
|
||||
#[command(cli_only, display(display_none), blocking)]
|
||||
pub fn pack(#[context] _ctx: EitherContext, #[arg] path: Option<PathBuf>) -> Result<(), Error> {
|
||||
pub fn pack(#[context] ctx: EitherContext, #[arg] path: Option<PathBuf>) -> Result<(), Error> {
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
|
||||
let ctx = ctx.as_cli().unwrap();
|
||||
|
||||
let path = if let Some(path) = path {
|
||||
path
|
||||
@@ -44,12 +47,40 @@ pub fn pack(#[context] _ctx: EitherContext, #[arg] path: Option<PathBuf>) -> Res
|
||||
S9pkPacker::builder()
|
||||
.manifest(&manifest)
|
||||
.writer(&mut outfile)
|
||||
.license(File::open(path.join(manifest.assets.license_path()))?)
|
||||
.icon(File::open(path.join(manifest.assets.icon_path()))?)
|
||||
.instructions(File::open(path.join(manifest.assets.instructions_path()))?)
|
||||
.docker_images(File::open(path.join(manifest.assets.docker_images_path()))?)
|
||||
.license(
|
||||
File::open(path.join(manifest.assets.license_path())).with_ctx(|_| {
|
||||
(
|
||||
crate::ErrorKind::Filesystem,
|
||||
manifest.assets.license_path().display().to_string(),
|
||||
)
|
||||
})?,
|
||||
)
|
||||
.icon(
|
||||
File::open(path.join(manifest.assets.icon_path())).with_ctx(|_| {
|
||||
(
|
||||
crate::ErrorKind::Filesystem,
|
||||
manifest.assets.icon_path().display().to_string(),
|
||||
)
|
||||
})?,
|
||||
)
|
||||
.instructions(
|
||||
File::open(path.join(manifest.assets.instructions_path())).with_ctx(|_| {
|
||||
(
|
||||
crate::ErrorKind::Filesystem,
|
||||
manifest.assets.instructions_path().display().to_string(),
|
||||
)
|
||||
})?,
|
||||
)
|
||||
.docker_images(
|
||||
File::open(path.join(manifest.assets.docker_images_path())).with_ctx(|_| {
|
||||
(
|
||||
crate::ErrorKind::Filesystem,
|
||||
manifest.assets.docker_images_path().display().to_string(),
|
||||
)
|
||||
})?,
|
||||
)
|
||||
.build()
|
||||
.pack()?;
|
||||
.pack(&ctx.developer_key()?)?;
|
||||
outfile.sync_all()?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -67,7 +67,7 @@ impl<R: AsyncRead + AsyncSeek + Unpin> S9pkReader<InstallProgressTracker<R>> {
|
||||
}
|
||||
impl<R: AsyncRead + AsyncSeek + Unpin> S9pkReader<R> {
|
||||
pub async fn validate(&mut self) -> Result<(), Error> {
|
||||
todo!()
|
||||
Ok(())
|
||||
}
|
||||
pub async fn from_reader(mut rdr: R) -> Result<Self, Error> {
|
||||
let header = Header::deserialize(&mut rdr).await?;
|
||||
|
||||
Reference in New Issue
Block a user