@@ -559,21 +559,16 @@ impl Client {
559
559
username : impl AsRef < str > ,
560
560
password : impl AsRef < str > ,
561
561
) -> 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) ;
568
563
569
564
// First, validate the credentials. If a user accidentally enters a wrong credential set, this
570
565
// can catch the issue early rather than getting an error at the first operation that needs
571
566
// 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 ?;
573
568
574
569
// Save an encoded representation of the credential set in the local configuration file.
575
570
let mut auth = AuthConfig :: load_default ( ) . await ?;
576
- auth. insert ( server , username, password) ?;
571
+ auth. insert ( registry , username, password) ?;
577
572
auth. save_default ( ) . await
578
573
}
579
574
@@ -672,6 +667,20 @@ fn digest_from_url(manifest_url: &str) -> Option<String> {
672
667
}
673
668
}
674
669
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
+
675
684
#[ cfg( test) ]
676
685
mod test {
677
686
use super :: * ;
@@ -686,6 +695,34 @@ mod test {
686
695
) ;
687
696
}
688
697
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
+
689
726
#[ tokio:: test]
690
727
async fn can_assemble_layers ( ) {
691
728
use spin_locked_app:: locked:: LockedComponent ;
0 commit comments