pack scripts into s9pk

This commit is contained in:
Keagan McClelland
2022-05-06 15:23:15 -06:00
parent 2d44852ec4
commit 2890798342
5 changed files with 56 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ pub struct S9pkPacker<
RIcon: Read, RIcon: Read,
RDockerImages: Read, RDockerImages: Read,
RAssets: Read, RAssets: Read,
RScripts: Read,
> { > {
writer: W, writer: W,
manifest: &'a Manifest, manifest: &'a Manifest,
@@ -28,6 +29,7 @@ pub struct S9pkPacker<
icon: RIcon, icon: RIcon,
docker_images: RDockerImages, docker_images: RDockerImages,
assets: RAssets, assets: RAssets,
scripts: RScripts,
} }
impl< impl<
'a, 'a,
@@ -37,7 +39,8 @@ impl<
RIcon: Read, RIcon: Read,
RDockerImages: Read, RDockerImages: Read,
RAssets: Read, RAssets: Read,
> S9pkPacker<'a, W, RLicense, RInstructions, RIcon, RDockerImages, RAssets> RScripts: Read,
> S9pkPacker<'a, W, RLicense, RInstructions, RIcon, RDockerImages, RAssets, RScripts>
{ {
/// BLOCKING /// BLOCKING
#[instrument(skip(self))] #[instrument(skip(self))]
@@ -114,6 +117,15 @@ impl<
length: new_pos - position, length: new_pos - position,
}; };
position = new_pos; position = new_pos;
// scripts
std::io::copy(&mut self.scripts, &mut writer)
.with_ctx(|_| (crate::ErrorKind::Filesystem, "Copying Scripts"))?;
let new_pos = writer.inner_mut().stream_position()?;
header.table_of_contents.scripts = FileSection {
position,
length: new_pos - position,
};
position = new_pos;
// header // header
let (hash, _) = writer.finish(); let (hash, _) = writer.finish();

View File

@@ -38,7 +38,7 @@ impl Header {
reader.read_exact(&mut magic).await?; reader.read_exact(&mut magic).await?;
if magic != MAGIC { if magic != MAGIC {
return Err(Error::new( return Err(Error::new(
eyre!("Incorrect Magic"), eyre!("Incorrect Magic: {:?}", magic),
crate::ErrorKind::ParseS9pk, crate::ErrorKind::ParseS9pk,
)); ));
} }
@@ -46,7 +46,7 @@ impl Header {
reader.read_exact(&mut version).await?; reader.read_exact(&mut version).await?;
if version[0] != VERSION { if version[0] != VERSION {
return Err(Error::new( return Err(Error::new(
eyre!("Unknown Version"), eyre!("Unknown Version: {}", version[0]),
crate::ErrorKind::ParseS9pk, crate::ErrorKind::ParseS9pk,
)); ));
} }
@@ -75,6 +75,7 @@ pub struct TableOfContents {
pub icon: FileSection, pub icon: FileSection,
pub docker_images: FileSection, pub docker_images: FileSection,
pub assets: FileSection, pub assets: FileSection,
pub scripts: FileSection,
} }
impl TableOfContents { impl TableOfContents {
pub fn serialize<W: Write>(&self, mut writer: W) -> std::io::Result<()> { pub fn serialize<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
@@ -93,6 +94,7 @@ impl TableOfContents {
self.docker_images self.docker_images
.serialize_entry("docker_images", &mut writer)?; .serialize_entry("docker_images", &mut writer)?;
self.assets.serialize_entry("assets", &mut writer)?; self.assets.serialize_entry("assets", &mut writer)?;
self.scripts.serialize_entry("scripts", &mut writer)?;
Ok(()) Ok(())
} }
pub async fn deserialize<R: AsyncRead + Unpin>(mut reader: R) -> std::io::Result<Self> { pub async fn deserialize<R: AsyncRead + Unpin>(mut reader: R) -> std::io::Result<Self> {
@@ -131,6 +133,7 @@ impl TableOfContents {
icon: from_table(&table, "icon")?, icon: from_table(&table, "icon")?,
docker_images: from_table(&table, "docker_images")?, docker_images: from_table(&table, "docker_images")?,
assets: from_table(&table, "assets")?, assets: from_table(&table, "assets")?,
scripts: from_table(&table, "scripts")?,
}) })
} }
} }

View File

@@ -166,6 +166,8 @@ pub struct Assets {
pub docker_images: Option<PathBuf>, pub docker_images: Option<PathBuf>,
#[serde(default)] #[serde(default)]
pub assets: Option<PathBuf>, pub assets: Option<PathBuf>,
#[serde(default)]
pub scripts: Option<PathBuf>,
} }
impl Assets { impl Assets {
pub fn license_path(&self) -> &Path { pub fn license_path(&self) -> &Path {
@@ -205,6 +207,12 @@ impl Assets {
.map(|a| a.as_path()) .map(|a| a.as_path())
.unwrap_or(Path::new("assets")) .unwrap_or(Path::new("assets"))
} }
pub fn scripts_path(&self) -> &Path {
self.scripts
.as_ref()
.map(|a| a.as_path())
.unwrap_or(Path::new("scripts"))
}
} }
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]

View File

@@ -105,6 +105,23 @@ pub fn pack(#[context] ctx: SdkContext, #[arg] path: Option<PathBuf>) -> Result<
std::io::Cursor::new(assets.into_inner()?) std::io::Cursor::new(assets.into_inner()?)
}) })
.scripts({
let mut scripts = tar::Builder::new(Vec::new());
for (script_volume, _) in manifest
.volumes
.iter()
.filter(|(_, v)| matches!(v, &&Volume::Scripts {}))
{
scripts.append_dir_all(
script_volume,
path.join(manifest.assets.scripts_path())
.join(script_volume),
)?;
}
std::io::Cursor::new(scripts.into_inner()?)
})
.build() .build()
.pack(&ctx.developer_key()?)?; .pack(&ctx.developer_key()?)?;
outfile.sync_all()?; outfile.sync_all()?;

View File

@@ -162,6 +162,15 @@ pub fn asset_dir<P: AsRef<Path>>(datadir: P, pkg_id: &PackageId, version: &Versi
.join(version.as_str()) .join(version.as_str())
} }
pub fn script_dir<P: AsRef<Path>>(datadir: P, pkg_id: &PackageId, version: &Version) -> PathBuf {
datadir
.as_ref()
.join(PKG_VOLUME_DIR)
.join(pkg_id)
.join("scripts")
.join(version.as_str())
}
pub fn backup_dir(pkg_id: &PackageId) -> PathBuf { pub fn backup_dir(pkg_id: &PackageId) -> PathBuf {
Path::new(BACKUP_DIR).join(pkg_id).join("data") Path::new(BACKUP_DIR).join(pkg_id).join("data")
} }
@@ -178,6 +187,8 @@ pub enum Volume {
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
Assets {}, Assets {},
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
Scripts {},
#[serde(rename_all = "kebab-case")]
Pointer { Pointer {
package_id: PackageId, package_id: PackageId,
volume_id: VolumeId, volume_id: VolumeId,
@@ -228,6 +239,7 @@ impl Volume {
match self { match self {
Volume::Data { .. } => data_dir(&ctx.datadir, pkg_id, volume_id), Volume::Data { .. } => data_dir(&ctx.datadir, pkg_id, volume_id),
Volume::Assets {} => asset_dir(&ctx.datadir, pkg_id, version).join(volume_id), Volume::Assets {} => asset_dir(&ctx.datadir, pkg_id, version).join(volume_id),
Volume::Scripts {} => script_dir(&ctx.datadir, pkg_id, version).join(volume_id),
Volume::Pointer { Volume::Pointer {
package_id, package_id,
volume_id, volume_id,
@@ -260,6 +272,7 @@ impl Volume {
match self { match self {
Volume::Data { readonly } => *readonly, Volume::Data { readonly } => *readonly,
Volume::Assets {} => true, Volume::Assets {} => true,
Volume::Scripts {} => true,
Volume::Pointer { readonly, .. } => *readonly, Volume::Pointer { readonly, .. } => *readonly,
Volume::Certificate { .. } => true, Volume::Certificate { .. } => true,
Volume::Backup { readonly } => *readonly, Volume::Backup { readonly } => *readonly,