Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ on:
jobs:
build:
runs-on: ubuntu-latest
strategy:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why this was removed? We had this on here so other tests could still run on the OS it didn't fail on

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. strategy only applies to matrix jobs. From the docs

jobs.<job_id>.strategy.fail-fast applies to the entire matrix.

fail-fast: false
steps:
- uses: actions/[email protected]
- uses: engineerd/[email protected]
Expand Down
10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ version = "0.14.0"
[badges]
maintenance = { status = "actively-developed" }

[[example]]
name = "blocking-get-manifest"
path = "examples/blocking-get-manifest/main.rs"
required-features = ["blocking"]

[features]
default = ["native-tls", "test-registry"]
default = ["native-tls"]
native-tls = ["reqwest/native-tls"]
rustls-tls = ["reqwest/rustls-tls"]
rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots"]
trust-dns = ["reqwest/trust-dns"]
blocking = ["reqwest/blocking"]
# This features is used by tests that use docker to create a registry
test-registry = []

Expand Down Expand Up @@ -70,6 +76,6 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tempfile = "3.3"
# This should stay pinned here until testcontainers makes sure all of its deps using rustls are
# using the ring feature. Otherwise this fails to compile on Windows
testcontainers = "0.23"
testcontainers = { version = "0.23", features = ["blocking"] }
tokio = { version = "1.21", features = ["macros", "fs", "rt-multi-thread"] }
tokio-util = { version = "0.7.4", features = ["compat"] }
100 changes: 100 additions & 0 deletions examples/blocking-get-manifest/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use oci_client::{blocking::Client, secrets::RegistryAuth, Reference};

use clap::Parser;
use docker_credential::{CredentialRetrievalError, DockerCredential};
use tracing::{debug, warn};
use tracing_subscriber::prelude::*;
use tracing_subscriber::{fmt, EnvFilter};

/// Pull a WebAssembly module from a OCI container registry
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
pub(crate) struct Cli {
/// Enable verbose mode
#[clap(short, long)]
pub verbose: bool,

/// Perform anonymous operation, by default the tool tries to reuse the docker credentials read
/// from the default docker file
#[clap(short, long)]
pub anonymous: bool,

/// Pull image from registry using HTTP instead of HTTPS
#[clap(short, long)]
pub insecure: bool,

/// Enable json output
#[clap(long)]
pub json: bool,

/// Name of the image to pull
image: String,
}

fn build_auth(reference: &Reference, cli: &Cli) -> RegistryAuth {
let server = reference
.resolve_registry()
.strip_suffix('/')
.unwrap_or_else(|| reference.resolve_registry());

if cli.anonymous {
return RegistryAuth::Anonymous;
}

match docker_credential::get_credential(server) {
Err(CredentialRetrievalError::ConfigNotFound) => RegistryAuth::Anonymous,
Err(CredentialRetrievalError::NoCredentialConfigured) => RegistryAuth::Anonymous,
Err(e) => panic!("Error handling docker configuration file: {}", e),
Ok(DockerCredential::UsernamePassword(username, password)) => {
debug!("Found docker credentials");
RegistryAuth::Basic(username, password)
}
Ok(DockerCredential::IdentityToken(_)) => {
warn!("Cannot use contents of docker config, identity token not supported. Using anonymous auth");
RegistryAuth::Anonymous
}
}
}

fn build_client_config(cli: &Cli) -> oci_client::blocking::ClientConfig {
let protocol = if cli.insecure {
oci_client::blocking::ClientProtocol::Http
} else {
oci_client::blocking::ClientProtocol::Https
};

oci_client::blocking::ClientConfig {
protocol,
..Default::default()
}
}

pub fn main() {
let cli = Cli::parse();

// setup logging
let level_filter = if cli.verbose { "debug" } else { "info" };
let filter_layer = EnvFilter::new(level_filter);
tracing_subscriber::registry()
.with(filter_layer)
.with(fmt::layer().with_writer(std::io::stderr))
.init();

let reference: Reference = cli.image.parse().expect("Not a valid image reference");
let auth = build_auth(&reference, &cli);

let client_config = build_client_config(&cli);
let mut client = Client::new(client_config);

let (manifest, _) = client
.pull_manifest(&reference, &auth)
.expect("Cannot pull manifest");

if cli.json {
serde_json::to_writer_pretty(std::io::stdout(), &manifest)
.expect("Cannot serialize manifest to JSON");
println!();
} else {
println!("{}", manifest);
}
}
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ build +FLAGS='':
test:
cargo fmt --all -- --check
cargo clippy --workspace
cargo test --workspace --lib --tests
cargo test --workspace --lib --tests --all-features
cargo test --doc --all
Loading
Loading