-
Notifications
You must be signed in to change notification settings - Fork 41
/
docker.go
53 lines (46 loc) · 1.4 KB
/
docker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package utils
import (
"context"
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
"github.com/google/go-containerregistry/pkg/name"
)
func ImageExistsNatively(ctx context.Context, dc *client.Client, image string) (bool, string, error) {
image = strings.TrimPrefix(image, "docker.io/library/")
image = strings.TrimPrefix(image, "index.docker.io/library/")
is, err := dc.ImageList(ctx, types.ImageListOptions{
Filters: filters.NewArgs(filters.KeyValuePair{
Key: "reference",
Value: image,
}),
})
if err != nil {
return false, "", err
}
if len(is) == 0 {
return false, "", nil
}
ref, err := name.ParseReference(image)
if err != nil {
return false, "", err
}
// A local build which has never been pushed to a registry has no digest
// See https://github.com/moby/moby/issues/16482#issuecomment-149285106
// A remote build pulled to local will look like a local build (as it is returned by ImageList)
// but will have a digest
// This distinguishes between these two cases
var digest string
for _, refStrWithDigest := range is[0].RepoDigests {
refWithDigest, err := name.ParseReference(refStrWithDigest)
if err != nil {
return false, "", err
}
if ref.Context().RepositoryStr() == refWithDigest.Context().RepositoryStr() {
digest = refWithDigest.Identifier()
break
}
}
return true, digest, nil
}