hashes.go
1 package main 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "io" 8 "log" 9 "net/http" 10 11 "github.com/docker/docker/client" 12 ) 13 14 func getCurrentHash(ctx context.Context, cli *client.Client, imageName string) (string, string, string) { 15 image, _, err := cli.ImageInspectWithRaw(ctx, imageName) 16 if err != nil { 17 log.Printf("Error inspecting image %s: %v", imageName, err) 18 return "", "", "" 19 } 20 // TODO: loop over repodigests if more than one and compare with latestHash 21 return image.RepoDigests[0], image.Architecture, image.Created 22 } 23 24 func getLatestHash(namespace, repository, tag, arch string) (string, error) { 25 url := fmt.Sprintf("https://hub.docker.com/v2/namespaces/%s/repositories/%s/tags/%s", namespace, repository, tag) 26 resp, err := http.Get(url) 27 if err != nil { 28 return "", err 29 } 30 defer resp.Body.Close() 31 32 log.Printf("checking on dockerhub: %s", url) 33 34 if resp.StatusCode != http.StatusOK { 35 return "", fmt.Errorf("failed to fetch data: %s", resp.Status) 36 } 37 38 body, err := io.ReadAll(resp.Body) 39 if err != nil { 40 return "", err 41 } 42 43 var repo Repository 44 err = json.Unmarshal(body, &repo) 45 if err != nil { 46 return "", err 47 } 48 49 if repo.Digest == "" { 50 for _, image := range repo.Images { 51 if image.Architecture == arch { 52 return image.Digest, nil 53 } 54 } 55 } 56 57 return repo.Digest, nil 58 59 // return "", fmt.Errorf("no images found for architecture: %s", architecture) 60 } 61 62 func pingDockerhub(namespace, repository, tag string) (int, error) { 63 url := fmt.Sprintf("https://hub.docker.com/v2/namespaces/%s/repositories/%s/tags/%s", namespace, repository, tag) 64 resp, err := http.Get(url) 65 if err != nil { 66 return 0, err 67 } 68 defer resp.Body.Close() 69 70 if resp.StatusCode == http.StatusNotFound { 71 return resp.StatusCode, nil 72 } 73 74 return 0, nil 75 }