mirror of
https://github.com/imjasonh/krust
synced 2026-07-18 06:56:13 +00:00
feat: Implement registry authentication support
This implements authentication for container registries, porting functionality from go-containerregistry's authn package to Rust. Key features: - AuthConfig struct for various auth types (basic, bearer, anonymous) - Authenticator trait for pluggable auth providers - DefaultKeychain that reads Docker config files from standard locations - Support for credential helpers (docker-credential-*) - Integration with oci-distribution for registry operations The implementation checks for credentials in this order: 1. DOCKER_CONFIG environment variable 2. REGISTRY_AUTH_FILE environment variable 3. XDG_RUNTIME_DIR/containers/auth.json 4. HOME/.docker/config.json Credential helpers are supported if configured in the Docker config. This enables krust to: - Pull private base images - Push to authenticated registries - Support various auth methods (basic, token, oauth2) Closes #2 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
5acbc21b3f
commit
b6b0c71d0c
8 changed files with 898 additions and 12 deletions
|
|
@ -10,14 +10,12 @@ mod tests;
|
|||
|
||||
pub struct RegistryClient {
|
||||
client: Client,
|
||||
#[allow(dead_code)]
|
||||
auth: RegistryAuth,
|
||||
}
|
||||
|
||||
impl RegistryClient {
|
||||
pub fn new(auth: RegistryAuth) -> Result<Self> {
|
||||
pub fn new() -> Result<Self> {
|
||||
let client = Client::new(oci_distribution::client::ClientConfig::default());
|
||||
Ok(Self { client, auth })
|
||||
Ok(Self { client })
|
||||
}
|
||||
|
||||
pub async fn push_image(
|
||||
|
|
@ -25,6 +23,7 @@ impl RegistryClient {
|
|||
image_ref: &str,
|
||||
config_data: Vec<u8>,
|
||||
layers: Vec<(Vec<u8>, String)>,
|
||||
auth: &RegistryAuth,
|
||||
) -> Result<(String, usize)> {
|
||||
let reference: Reference = image_ref
|
||||
.parse()
|
||||
|
|
@ -32,6 +31,12 @@ impl RegistryClient {
|
|||
|
||||
info!("Pushing image to {}", reference);
|
||||
|
||||
// Authenticate with the registry
|
||||
self.client
|
||||
.auth(&reference, auth, oci_distribution::RegistryOperation::Push)
|
||||
.await
|
||||
.context("Failed to authenticate with registry")?;
|
||||
|
||||
// Push config blob
|
||||
let config_digest = format!("sha256:{}", sha256::digest(&config_data));
|
||||
debug!("Pushing config blob: {}", config_digest);
|
||||
|
|
@ -110,10 +115,17 @@ impl RegistryClient {
|
|||
&mut self,
|
||||
image_ref: &str,
|
||||
manifest_descriptors: Vec<crate::manifest::ManifestDescriptor>,
|
||||
auth: &RegistryAuth,
|
||||
) -> Result<String> {
|
||||
let reference = Reference::from_str(image_ref)
|
||||
.context(format!("Failed to parse image reference: {}", image_ref))?;
|
||||
|
||||
// Authenticate with the registry
|
||||
self.client
|
||||
.auth(&reference, auth, oci_distribution::RegistryOperation::Push)
|
||||
.await
|
||||
.context("Failed to authenticate with registry")?;
|
||||
|
||||
// Create the image index
|
||||
let index = crate::manifest::ImageIndex::new(manifest_descriptors);
|
||||
|
||||
|
|
@ -180,7 +192,11 @@ impl RegistryClient {
|
|||
}
|
||||
|
||||
/// Fetch the manifest for an image and extract available platforms
|
||||
pub async fn get_image_platforms(&mut self, image_ref: &str) -> Result<Vec<String>> {
|
||||
pub async fn get_image_platforms(
|
||||
&mut self,
|
||||
image_ref: &str,
|
||||
auth: &RegistryAuth,
|
||||
) -> Result<Vec<String>> {
|
||||
let reference: Reference = image_ref
|
||||
.parse()
|
||||
.context("Failed to parse image reference")?;
|
||||
|
|
@ -190,7 +206,7 @@ impl RegistryClient {
|
|||
// Pull the manifest
|
||||
let (manifest, _) = self
|
||||
.client
|
||||
.pull_manifest(&reference, &self.auth)
|
||||
.pull_manifest(&reference, auth)
|
||||
.await
|
||||
.context("Failed to pull manifest")?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue