Skip to content

Commit

Permalink
Merge pull request #156 from cgwalters/imageproxy-update
Browse files Browse the repository at this point in the history
Bump to containers-image-proxy 0.3, add proxy config as API and CLI
  • Loading branch information
cgwalters authored Nov 10, 2021
2 parents 5b45d6e + 3873ef5 commit 7307ad8
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ version = "0.4.0"

[dependencies]
anyhow = "1.0"
containers-image-proxy = "0.2"
containers-image-proxy = "0.3"
async-compression = { version = "0.3", features = ["gzip", "tokio"] }
bytes = "1.0.1"
bitflags = "1"
Expand Down
43 changes: 40 additions & 3 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ enum ContainerOpts {
Image(ContainerImageOpts),
}

/// Options for container image fetching.
#[derive(Debug, StructOpt)]
struct ContainerProxyOpts {
#[structopt(long)]
/// Path to Docker-formatted authentication file.
authfile: Option<String>,

#[structopt(long)]
/// Skip TLS verification.
insecure_skip_tls_verification: bool,
}

/// Options for import/export to tar archives.
#[derive(Debug, StructOpt)]
enum ContainerImageOpts {
Expand All @@ -144,6 +156,9 @@ enum ContainerImageOpts {
/// Image reference, e.g. ostree-remote-image:someremote:registry:quay.io/exampleos/exampleos:latest
#[structopt(parse(try_from_str = parse_imgref))]
imgref: OstreeImageReference,

#[structopt(flatten)]
proxyopts: ContainerProxyOpts,
},

/// Copy a pulled container image from one repo to another.
Expand Down Expand Up @@ -176,6 +191,9 @@ enum ContainerImageOpts {
#[structopt(parse(try_from_str = parse_imgref))]
imgref: OstreeImageReference,

#[structopt(flatten)]
proxyopts: ContainerProxyOpts,

/// Target image reference, e.g. ostree-remote-image:someremote:registry:quay.io/exampleos/exampleos:latest
///
/// If specified, `--imgref` will be used as a source, but this reference will be emitted into the origin
Expand Down Expand Up @@ -220,6 +238,15 @@ enum Opt {
ImaSign(ImaSignOpts),
}

impl Into<ostree_container::store::ImageProxyConfig> for ContainerProxyOpts {
fn into(self) -> ostree_container::store::ImageProxyConfig {
ostree_container::store::ImageProxyConfig {
authfile: self.authfile,
insecure_skip_tls_verification: Some(self.insecure_skip_tls_verification),
}
}
}

/// Import a tar archive containing an ostree commit.
async fn tar_import(opts: &ImportOpts) -> Result<()> {
let repo = &ostree::Repo::open_at(libc::AT_FDCWD, opts.repo.as_str(), gio::NONE_CANCELLABLE)?;
Expand Down Expand Up @@ -331,9 +358,13 @@ async fn container_info(imgref: &OstreeImageReference) -> Result<()> {
}

/// Write a layered container image into an OSTree commit.
async fn container_store(repo: &str, imgref: &OstreeImageReference) -> Result<()> {
async fn container_store(
repo: &str,
imgref: &OstreeImageReference,
proxyopts: ContainerProxyOpts,
) -> Result<()> {
let repo = &ostree::Repo::open_at(libc::AT_FDCWD, repo, gio::NONE_CANCELLABLE)?;
let mut imp = LayeredImageImporter::new(repo, imgref).await?;
let mut imp = LayeredImageImporter::new(repo, imgref, proxyopts.into()).await?;
let prep = match imp.prepare().await? {
PrepareResult::AlreadyPresent(c) => {
println!("No changes in {} => {}", imgref, c.merge_commit);
Expand Down Expand Up @@ -444,7 +475,11 @@ where
}
Ok(())
}
ContainerImageOpts::Pull { repo, imgref } => container_store(&repo, &imgref).await,
ContainerImageOpts::Pull {
repo,
imgref,
proxyopts,
} => container_store(&repo, &imgref, proxyopts).await,
ContainerImageOpts::Copy {
src_repo,
dest_repo,
Expand All @@ -462,6 +497,7 @@ where
imgref,
target_imgref,
karg,
proxyopts,
} => {
let sysroot = &ostree::Sysroot::new(Some(&gio::File::for_path(&sysroot)));
sysroot.load(gio::NONE_CANCELLABLE)?;
Expand All @@ -473,6 +509,7 @@ where
let options = crate::container::deploy::DeployOpts {
kargs: kargs.as_deref(),
target_imgref: target_imgref.as_ref(),
proxy_cfg: Some(proxyopts.into()),
};
crate::container::deploy::deploy(sysroot, &stateroot, &imgref, Some(options))
.await
Expand Down
10 changes: 9 additions & 1 deletion lib/src/container/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub struct DeployOpts<'a> {
///
/// To implement this, use this option for the latter `:latest` tag.
pub target_imgref: Option<&'a OstreeImageReference>,

/// Configuration for fetching containers.
pub proxy_cfg: Option<super::store::ImageProxyConfig>,
}

/// Write a container image to an OSTree deployment.
Expand All @@ -36,7 +39,12 @@ pub async fn deploy(
let cancellable = ostree::gio::NONE_CANCELLABLE;
let options = options.unwrap_or_default();
let repo = &sysroot.repo().unwrap();
let mut imp = super::store::LayeredImageImporter::new(repo, imgref).await?;
let mut imp = super::store::LayeredImageImporter::new(
repo,
imgref,
options.proxy_cfg.unwrap_or_default(),
)
.await?;
if let Some(target) = options.target_imgref {
imp.set_target(target);
}
Expand Down
14 changes: 12 additions & 2 deletions lib/src/container/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ use ostree::{gio, glib};
use std::collections::HashMap;
use std::iter::FromIterator;

/// Configuration for the proxy.
///
/// We re-export this rather than inventing our own wrapper
/// in the interest of avoiding duplication.
pub use containers_image_proxy::ImageProxyConfig;

/// The ostree ref prefix for blobs.
const LAYER_PREFIX: &str = "ostree/container/blob";
/// The ostree ref prefix for image references.
Expand Down Expand Up @@ -167,8 +173,12 @@ pub fn manifest_digest_from_commit(commit: &glib::Variant) -> Result<String> {

impl LayeredImageImporter {
/// Create a new importer.
pub async fn new(repo: &ostree::Repo, imgref: &OstreeImageReference) -> Result<Self> {
let mut proxy = ImageProxy::new().await?;
pub async fn new(
repo: &ostree::Repo,
imgref: &OstreeImageReference,
config: ImageProxyConfig,
) -> Result<Self> {
let proxy = ImageProxy::new_with_config(config).await?;
let proxy_img = proxy.open_image(&imgref.imgref.to_string()).await?;
let repo = repo.clone();
Ok(LayeredImageImporter {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/container/unencapsulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<T: AsyncRead> AsyncRead for ProgressReader<T> {
pub async fn fetch_manifest(
imgref: &OstreeImageReference,
) -> Result<(oci_spec::image::ImageManifest, String)> {
let mut proxy = ImageProxy::new().await?;
let proxy = ImageProxy::new().await?;
let oi = &proxy.open_image(&imgref.imgref.to_string()).await?;
let (digest, raw_manifest) = proxy.fetch_manifest(oi).await?;
proxy.close_image(oi).await?;
Expand Down
36 changes: 24 additions & 12 deletions lib/tests/it/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,12 @@ async fn test_container_write_derive() -> Result<()> {
assert!(images.is_empty());

// Pull a derived image - two layers, new base plus one layer.
let mut imp =
ostree_ext::container::store::LayeredImageImporter::new(&fixture.destrepo, &exampleos_ref)
.await?;
let mut imp = ostree_ext::container::store::LayeredImageImporter::new(
&fixture.destrepo,
&exampleos_ref,
Default::default(),
)
.await?;
let prep = match imp.prepare().await? {
PrepareResult::AlreadyPresent(_) => panic!("should not be already imported"),
PrepareResult::Ready(r) => r,
Expand Down Expand Up @@ -465,9 +468,12 @@ async fn test_container_write_derive() -> Result<()> {
)?;

// Import again, but there should be no changes.
let mut imp =
ostree_ext::container::store::LayeredImageImporter::new(&fixture.destrepo, &exampleos_ref)
.await?;
let mut imp = ostree_ext::container::store::LayeredImageImporter::new(
&fixture.destrepo,
&exampleos_ref,
Default::default(),
)
.await?;
let already_present = match imp.prepare().await? {
PrepareResult::AlreadyPresent(c) => c,
PrepareResult::Ready(_) => {
Expand All @@ -478,9 +484,12 @@ async fn test_container_write_derive() -> Result<()> {

// Test upgrades; replace the oci-archive with new content.
std::fs::write(exampleos_path, EXAMPLEOS_DERIVED_V2_OCI)?;
let mut imp =
ostree_ext::container::store::LayeredImageImporter::new(&fixture.destrepo, &exampleos_ref)
.await?;
let mut imp = ostree_ext::container::store::LayeredImageImporter::new(
&fixture.destrepo,
&exampleos_ref,
Default::default(),
)
.await?;
let prep = match imp.prepare().await? {
PrepareResult::AlreadyPresent(_) => panic!("should not be already imported"),
PrepareResult::Ready(r) => r,
Expand Down Expand Up @@ -512,9 +521,12 @@ async fn test_container_write_derive() -> Result<()> {
)?;

// And there should be no changes on upgrade again.
let mut imp =
ostree_ext::container::store::LayeredImageImporter::new(&fixture.destrepo, &exampleos_ref)
.await?;
let mut imp = ostree_ext::container::store::LayeredImageImporter::new(
&fixture.destrepo,
&exampleos_ref,
Default::default(),
)
.await?;
let already_present = match imp.prepare().await? {
PrepareResult::AlreadyPresent(c) => c,
PrepareResult::Ready(_) => {
Expand Down

0 comments on commit 7307ad8

Please sign in to comment.