Skip to content

Commit e078f8d

Browse files
authored
Merge pull request #2513 from vdice/feat/login-registry-from-input
feat(oci/client.rs): add registry_from_input helper
2 parents 5c14552 + 72f4343 commit e078f8d

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

crates/oci/src/client.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -559,21 +559,16 @@ impl Client {
559559
username: impl AsRef<str>,
560560
password: impl AsRef<str>,
561561
) -> Result<()> {
562-
// We want to allow a user to login to both https://ghcr.io and ghcr.io.
563-
let server = server.as_ref();
564-
let server = match server.parse::<Url>() {
565-
Ok(url) => url.host_str().unwrap_or(server).to_string(),
566-
Err(_) => server.to_string(),
567-
};
562+
let registry = registry_from_input(server);
568563

569564
// First, validate the credentials. If a user accidentally enters a wrong credential set, this
570565
// can catch the issue early rather than getting an error at the first operation that needs
571566
// to use the credentials (first time they do a push/pull/up).
572-
Self::validate_credentials(&server, &username, &password).await?;
567+
Self::validate_credentials(&registry, &username, &password).await?;
573568

574569
// Save an encoded representation of the credential set in the local configuration file.
575570
let mut auth = AuthConfig::load_default().await?;
576-
auth.insert(server, username, password)?;
571+
auth.insert(registry, username, password)?;
577572
auth.save_default().await
578573
}
579574

@@ -672,6 +667,20 @@ fn digest_from_url(manifest_url: &str) -> Option<String> {
672667
}
673668
}
674669

670+
fn registry_from_input(server: impl AsRef<str>) -> String {
671+
// We want to allow a user to login to both https://ghcr.io and ghcr.io.
672+
let server = server.as_ref();
673+
let server = match server.parse::<Url>() {
674+
Ok(url) => url.host_str().unwrap_or(server).to_string(),
675+
Err(_) => server.to_string(),
676+
};
677+
// DockerHub is commonly referenced as 'docker.io' but needs to be 'index.docker.io'
678+
match server.as_str() {
679+
"docker.io" => "index.docker.io".to_string(),
680+
_ => server,
681+
}
682+
}
683+
675684
#[cfg(test)]
676685
mod test {
677686
use super::*;
@@ -686,6 +695,34 @@ mod test {
686695
);
687696
}
688697

698+
#[test]
699+
fn can_derive_registry_from_input() {
700+
#[derive(Clone)]
701+
struct TestCase {
702+
input: &'static str,
703+
want: &'static str,
704+
}
705+
let tests: Vec<TestCase> = [
706+
TestCase {
707+
input: "docker.io",
708+
want: "index.docker.io",
709+
},
710+
TestCase {
711+
input: "index.docker.io",
712+
want: "index.docker.io",
713+
},
714+
TestCase {
715+
input: "https://ghcr.io",
716+
want: "ghcr.io",
717+
},
718+
]
719+
.to_vec();
720+
721+
for tc in tests {
722+
assert_eq!(tc.want, registry_from_input(tc.input));
723+
}
724+
}
725+
689726
#[tokio::test]
690727
async fn can_assemble_layers() {
691728
use spin_locked_app::locked::LockedComponent;

0 commit comments

Comments
 (0)