@@ -2,6 +2,8 @@ package utils
22
33import (
44 "bufio"
5+ "encoding/base64"
6+ "encoding/json"
57 "fmt"
68 "io"
79 "net"
@@ -10,6 +12,7 @@ import (
1012 "path/filepath"
1113 "strings"
1214
15+ "github.com/docker/cli/cli/config"
1316 "github.com/docker/distribution/context"
1417 "github.com/docker/docker/api/types"
1518 "github.com/docker/docker/api/types/container"
@@ -20,6 +23,7 @@ import (
2023 "github.com/docker/go-connections/nat"
2124 "github.com/google/go-containerregistry/pkg/name"
2225 "github.com/lf-edge/eden/pkg/defaults"
26+
2327 log "github.com/sirupsen/logrus"
2428)
2529
@@ -201,6 +205,37 @@ func GetDockerNetworks() ([]*net.IPNet, error) {
201205 return results , nil
202206}
203207
208+ func extractRegistry (image string ) string {
209+ if strings .Contains (image , "/" ) {
210+ parts := strings .Split (image , "/" )
211+ if strings .Contains (parts [0 ], "." ) || strings .Contains (parts [0 ], ":" ) || parts [0 ] == "localhost" {
212+ return parts [0 ]
213+ }
214+ }
215+ return "https://index.docker.io/v1/"
216+ }
217+
218+ func getEncodedAuth (image string ) (string , error ) {
219+ registry := extractRegistry (image )
220+
221+ cfg , err := config .Load ("" )
222+ if err != nil {
223+ return "" , fmt .Errorf ("failed to load docker config: %w" , err )
224+ }
225+
226+ authConfig , err := cfg .GetAuthConfig (registry )
227+ if err != nil {
228+ return "" , fmt .Errorf ("failed to get auth config for registry %s: %w" , registry , err )
229+ }
230+
231+ encodedJSON , err := json .Marshal (authConfig )
232+ if err != nil {
233+ return "" , fmt .Errorf ("failed to marshal auth config: %w" , err )
234+ }
235+
236+ return base64 .StdEncoding .EncodeToString (encodedJSON ), nil
237+ }
238+
204239// PullImage from docker
205240func PullImage (image string ) error {
206241 ctx := context .Background ()
@@ -209,13 +244,24 @@ func PullImage(image string) error {
209244 return fmt .Errorf ("client.NewClientWithOpts: %w" , err )
210245 }
211246 _ , _ , err = cli .ImageInspectWithRaw (ctx , image )
212- if err == nil { // local image is ok
213- return nil
247+ if err == nil {
248+ return nil // Image already present
214249 }
215- resp , err := cli .ImagePull (ctx , image , types.ImagePullOptions {})
250+
251+ authStr , err := getEncodedAuth (image )
252+ if err != nil {
253+ log .Warnf ("Falling back to anonymous pull: %v" , err )
254+ authStr = ""
255+ }
256+
257+ resp , err := cli .ImagePull (ctx , image , types.ImagePullOptions {
258+ RegistryAuth : authStr ,
259+ })
216260 if err != nil {
217261 return fmt .Errorf ("imagePull: %w" , err )
218262 }
263+ defer resp .Close ()
264+
219265 if err = writeToLog (resp ); err != nil {
220266 return fmt .Errorf ("imagePull LOG: %w" , err )
221267 }
0 commit comments