/// Make sure that a given package is on disk, downloading it if it is not
/// already locally available. Unlike [ensure_package_on_disk], this function
/// does not statically know the type of the package artifact on disk, so it
/// does not return the downloaded artifact.
Make sure that a given package is on disk, downloading it if it is not
already locally available. Unlike [ensure_package_on_disk], this function
does not statically know the type of the package artifact on disk, so it
does not return the downloaded artifact.
Make sure that a given package is on disk downloading it if it is not already locally available . Unlike [ ensure_package_on_disk ] this function does not statically know the type of the package artifact on disk so it does not return the downloaded artifact .
pub async fn ensure_package_on_disk_ignoring_artifacts<D>(
    log: Logger,
    dl: D,
    pkg: &packages::generic::Package,
) -> Result<()>
where
    D: PackageDownloader,
{
    let dest = pkg.path();
    if dest.exists() {
        return Ok(());
    }
    let map_install_err = |error: anyhow::Error| Error::Install {
        error,
        package: pkg.clone(),
    };
    std::fs::create_dir_all(dest.parent().unwrap())
        .with_context(|| format!("while creating parent directory for {}", dest.display()))
        .map_err(|error| Error::Install {
            error,
            package: pkg.clone(),
        })?;
    let mut stream = dl.open_bytes_stream(log.clone(), pkg).await?;
    match pkg.format {
        Format::Sendstream => {
            debug!(log, "receiving {:?} into {}", pkg, dest.display());
            let sendstream = Sendstream::<Zstd, _>::new(stream);
            let mut subvol = sendstream
                .receive_into(&dest)
                .await
                .map_err(anyhow::Error::msg)
                .map_err(map_install_err)?;
            // set the subvolume to readwrite so that we can write xattrs on it
            subvol
                .set_readonly(false)
                .context("while setting subvolume rw")
                .map_err(map_install_err)?;
        }
        Format::File => {
            let mut tmp_dest = NamedTempFile::new_in(dest.parent().unwrap())
                .with_context(|| {
                    format!(
                        "while creating temporary file in {}",
                        dest.parent().unwrap().display()
                    )
                })
                .map_err(map_install_err)?;
            debug!(
                log,
                "downloading {:?} to {}",
                pkg,
                tmp_dest.path().display()
            );
            while let Some(item) = stream.next().await {
                tmp_dest
                    .write_all(
                        &item
                            .context("while reading chunk from downloader")
                            .map_err(|error| Error::Download {
                                error,
                                package: pkg.clone(),
                            })?,
                    )
                    .with_context(|| {
                        format!("while writing chunk to {}", tmp_dest.path().display())
                    })
                    .map_err(map_install_err)?;
            }
            let tmp_dest_path = tmp_dest.path().to_path_buf();
            tmp_dest
                .persist(&dest)
                .with_context(|| {
                    format!(
                        "while moving {} -> {}",
                        tmp_dest_path.display(),
                        dest.display()
                    )
                })
                .map_err(map_install_err)?;
        }
    };
    xattr::set(
        &dest,
        "user.metalos.package",
        &fbthrift::simplejson_protocol::serialize(&pkg),
    )
    .with_context(|| {
        format!(
            "while writing user.metalos.package xattr on {}",
            dest.display()
        )
    })
    .map_err(map_install_err)?;
    match pkg.format {
        Format::Sendstream => {
            Subvolume::get(&dest)
                .context("while getting subvol")
                .map_err(map_install_err)?
                .set_readonly(true)
                .context("while setting subvol ro")
                .map_err(map_install_err)?;
        }
        Format::File => {
            let perm = Permissions::from_mode(0o444);
            tokio::fs::set_permissions(&dest, perm)
                .await
                .with_context(|| format!("while setting {} readonly", dest.display()))
                .map_err(map_install_err)?;
        }
    }
    Ok(())
}
pub async fn ensure_package_on_disk_ignoring_artifacts < D > ( log : Logger , dl : D , pkg : & packages :: generic :: Package , ) -> Result < ( ) > where D : PackageDownloader , { let dest = pkg . path ( ) ; if dest . exists ( ) { return Ok ( ( ) ) ; } let map_install_err = | error : anyhow :: Error | Error :: Install { error , package : pkg . clone ( ) , } ; std :: fs :: create_dir_all ( dest . parent ( ) . unwrap ( ) ) . with_context ( | | format ! ( " " dest display ( ) ) ) . map_err ( | error | Error :: Install { error , package : pkg . clone ( ) , } ) ? ; let mut stream = dl . open_bytes_stream ( log . clone ( ) , pkg ) . await ? ; match pkg . format { Format :: Sendstream => { debug ! ( log " " pkg dest display ( ) ) ; let sendstream = Sendstream :: < Zstd , _ > :: new ( stream ) ; let mut subvol = sendstream . receive_into ( & dest ) . await . map_err ( anyhow :: Error :: msg ) . map_err ( map_install_err ) ? ; // set the subvolume to readwrite so that we can write xattrs on it subvol . set_readonly ( false ) . context ( " " ) . map_err ( map_install_err ) ? ; } Format :: File => { let mut tmp_dest = NamedTempFile :: new_in ( dest . parent ( ) . unwrap ( ) ) . with_context ( | | { format ! ( " " dest parent ( ) unwrap ( ) display ( ) ) } ) . map_err ( map_install_err ) ? ; debug ! ( log " " pkg tmp_dest path ( ) display ( ) ) ; while let Some ( item ) = stream . next ( ) . await { tmp_dest . write_all ( & item . context ( " " ) . map_err ( | error | Error :: Download { error , package : pkg . clone ( ) , } ) ? , ) . with_context ( | | { format ! ( " " tmp_dest path ( ) display ( ) ) } ) . map_err ( map_install_err ) ? ; } let tmp_dest_path = tmp_dest . path ( ) . to_path_buf ( ) ; tmp_dest . persist ( & dest ) . with_context ( | | { format ! ( " " tmp_dest_path display ( ) dest display ( ) ) } ) . map_err ( map_install_err ) ? ; } } ; xattr :: set ( & dest , " " , & fbthrift :: simplejson_protocol :: serialize ( & pkg ) , ) . with_context ( | | { format ! ( " " dest display ( ) ) } ) . map_err ( map_install_err ) ? ; match pkg . format { Format :: Sendstream => { Subvolume :: get ( & dest ) . context ( " " ) . map_err ( map_install_err ) ? . set_readonly ( true ) . context ( " " ) . map_err ( map_install_err ) ? ; } Format :: File => { let perm = Permissions :: from_mode ( 0o444 ) ; tokio :: fs :: set_permissions ( & dest , perm ) . await . with_context ( | | format ! ( " " dest display ( ) ) ) . map_err ( map_install_err ) ? ; } } Ok ( ( ) ) }
Make sure that a given package is on disk, downloading it if it is not
already locally available.
Make sure that a given package is on disk downloading it if it is not already locally available .
log
Logger
dl
D
pkg
&packages::generic::Package