-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprobe.go
74 lines (65 loc) · 1.98 KB
/
probe.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package main
import (
"bytes"
"fmt"
log "github.com/sirupsen/logrus"
"io"
"net/http"
"os/exec"
"strings"
)
// imageExistsInAnotherRegistry checks if an image exists in a registry other than dockerhub.
// It does work for dockerhub as well, but we reach the rate limit very quickly.
// It uses the docker command to check if the image exists in the registry which makes it slow.
// ToDo: Implement this function without using an external command
func imageExistsInAnotherRegistry(image string) (bool, error) {
cmd := exec.Command("docker", "manifest", "inspect", image)
var buf bytes.Buffer
cmd.Stderr = &buf
err := cmd.Run()
if err != nil {
return false, fmt.Errorf("error running docker manifest inspect %s: %v, %s", image, err, buf.String())
}
return true, nil
}
func imageExistsInDockerhub(image string) (bool, error) {
if !strings.Contains(image, ":") {
image = fmt.Sprintf("%s:latest", image)
}
if strings.HasPrefix(image, "docker.io/") {
image = strings.Replace(image, "docker.io/", "", 1)
}
imageAndTag := strings.Split(image, ":")
if !strings.Contains(image, "/") {
imageAndTag[0] = fmt.Sprintf("library/%s", imageAndTag[0])
}
resp, err := http.Get(fmt.Sprintf("https://hub.docker.com/v2/repositories/%s/tags/%s/", imageAndTag[0], imageAndTag[1]))
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Error(err)
}
}(resp.Body)
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, nil
}
b, _ := io.ReadAll(resp.Body)
return string(b) != "\"Resource not found\"" && string(b) != "Tag not found", nil
}
func imageExistsInRegistry(image string) (bool, error) {
registry := getRegistryFromImageName(image)
if registry == "docker.io" {
return imageExistsInDockerhub(image)
}
return imageExistsInAnotherRegistry(image)
}
func getRegistryFromImageName(image string) string {
parts := strings.Split(image, "/")
if len(parts) > 1 && strings.Contains(parts[0], ".") {
return parts[0]
}
return "docker.io"
}