@@ -23,8 +23,8 @@ type Client struct {
2323 logInfo func (format string , args ... interface {})
2424}
2525
26- // NewClient returns a Docker client configured with the given information logger.
27- func NewClient (logInfo func (format string , args ... interface {})) (Client , error ) {
26+ // New returns a Docker client configured with the given information logger.
27+ func New (logInfo func (format string , args ... interface {})) (Client , error ) {
2828 retry .DefaultDelay = 5 * time .Second
2929 retry .DefaultAttempts = 2
3030
@@ -41,11 +41,11 @@ func NewClient(logInfo func(format string, args ...interface{})) (Client, error)
4141 return client , nil
4242}
4343
44- // PushImageAndWait pushes an image and waits for it to finish pushing.
44+ // PushAndWait pushes an image and waits for it to finish pushing.
4545// If an error occurs when pushing an image, the push will be attempted again before failing.
46- func (c Client ) PushImageAndWait (ctx context.Context , image string , auth string ) error {
46+ func (c Client ) PushAndWait (ctx context.Context , image string , auth string ) error {
4747 push := func () error {
48- if err := c .tryPushImageAndWait (ctx , image , auth ); err != nil {
48+ if err := c .tryPushAndWait (ctx , image , auth ); err != nil {
4949 return fmt .Errorf ("try push image: %w" , err )
5050 }
5151
@@ -63,11 +63,11 @@ func (c Client) PushImageAndWait(ctx context.Context, image string, auth string)
6363 return nil
6464}
6565
66- // PullImageAndWait pulls an image and waits for it to finish pulling.
66+ // PullAndWait pulls an image and waits for it to finish pulling.
6767// If an error occurs when pulling an image, the pull will be attempted again before failing.
68- func (c Client ) PullImageAndWait (ctx context.Context , image string , auth string ) error {
68+ func (c Client ) PullAndWait (ctx context.Context , image string , auth string ) error {
6969 pull := func () error {
70- if err := c .tryPullImageAndWait (ctx , image , auth ); err != nil {
70+ if err := c .tryPullAndWait (ctx , image , auth ); err != nil {
7171 return fmt .Errorf ("try pull image: %w" , err )
7272 }
7373
@@ -170,35 +170,42 @@ func (c Client) Tag(ctx context.Context, sourceImage string, targetImage string)
170170
171171// ImageExistsAtRemote returns true if the image exists at the remote registry.
172172func (c Client ) ImageExistsAtRemote (ctx context.Context , image string ) (bool , error ) {
173- if hasLatestTag (image ) {
174- return false , nil
175- }
176-
177173 reference , err := name .ParseReference (image , name .WeakValidation )
178174 if err != nil {
179175 return false , fmt .Errorf ("parse ref: %w" , err )
180176 }
181177
182178 if _ , err := remote .Get (reference , remote .WithAuthFromKeychain (authn .DefaultKeychain )); err != nil {
183179
184- // If the error is a transport error, check that the error code is of type MANIFEST_UNKNOWN.
185- // This is the expected error if an image does not exist.
180+ // If the error is a transport error, check that the error code is of type
181+ // MANIFEST_UNKNOWN or NOT_FOUND. These errors are expected if an image does
182+ // not exist in the registry.
186183 if t , exists := err .(* transport.Error ); exists {
187184 for _ , diagnostic := range t .Errors {
188185 if strings .EqualFold ("MANIFEST_UNKNOWN" , string (diagnostic .Code )) {
189186 return false , nil
190187 }
188+
191189 if strings .EqualFold ("NOT_FOUND" , string (diagnostic .Code )) {
192190 return false , nil
193191 }
194192 }
195193 }
196194
197- // If the error is not a transport error, some other error occured
198- // that is unrelated to checking if an image exists and it should be returned.
199195 return false , fmt .Errorf ("get image: %w" , err )
200196 }
201197
198+ // Always return false if the image has the latest tag as this method
199+ // is used to determine if the image should be pushed or not. The latest
200+ // tag is assumed to always need to be pushed, but a better approach
201+ // would be to compare digests.
202+ //
203+ // This check must also be performed after the Get request to the remote
204+ // registry to ensure that the client has appropriate access to pull the image.
205+ if hasLatestTag (image ) {
206+ return false , nil
207+ }
208+
202209 return true , nil
203210}
204211
@@ -245,7 +252,7 @@ func (c Client) waitForScannerComplete(clientScanner *bufio.Scanner, image strin
245252 return nil
246253}
247254
248- func (c Client ) tryPullImageAndWait (ctx context.Context , image string , auth string ) error {
255+ func (c Client ) tryPullAndWait (ctx context.Context , image string , auth string ) error {
249256 opts := types.ImagePullOptions {
250257 RegistryAuth : auth ,
251258 }
@@ -266,7 +273,7 @@ func (c Client) tryPullImageAndWait(ctx context.Context, image string, auth stri
266273 return nil
267274}
268275
269- func (c Client ) tryPushImageAndWait (ctx context.Context , image string , auth string ) error {
276+ func (c Client ) tryPushAndWait (ctx context.Context , image string , auth string ) error {
270277 opts := types.ImagePushOptions {
271278 RegistryAuth : auth ,
272279 }
0 commit comments