use super::{remote_transport::RemoteTransport, LocalArtifact, LocalManifest};
use oci_spec::image::Descriptor;
impl LocalArtifact<'_> {
pub fn push(&self) -> crate::Result<()> {
let manifest = self.get_manifest()?.clone();
let blob_descriptors = collect_blob_descriptors(&manifest);
let transport = RemoteTransport::new(self.image_name())?;
transport.auth(self.image_name())?;
for descriptor in &blob_descriptors {
let digest = descriptor.digest().to_string();
let bytes = self.get_blob_by_descriptor(descriptor)?;
tracing::debug!(
size = bytes.len(),
"Pushing blob {digest} of {}",
self.image_name()
);
transport.push_blob(self.image_name(), &digest, bytes)?;
}
let manifest_bytes = self.read_blob_by_digest(self.manifest_digest())?;
let content_type = manifest.media_type();
tracing::info!(
"Publishing manifest {} ({}, {} bytes) to {}",
self.manifest_digest(),
content_type,
manifest_bytes.len(),
self.image_name(),
);
transport.push_manifest_bytes(self.image_name(), manifest_bytes, content_type)?;
Ok(())
}
}
fn collect_blob_descriptors(manifest: &LocalManifest) -> Vec<Descriptor> {
let layers = manifest.layers();
let mut out = Vec::with_capacity(1 + layers.len());
out.push(manifest.config());
out.extend(layers);
out
}