1package docker
2
3import (
4 "context"
5 "fmt"
6 "io"
7 "os"
8
9 "github.com/docker/docker/api/types"
10)
11
12func ListContainerImages() ([]types.ImageSummary, error) {
13 // Check if the Docker client has been initialized
14 CheckIfInitialized()
15
16 // List images using the Docker client
17 images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{})
18 if err != nil {
19 return nil, err
20 }
21
22 return images, nil
23}
24
25// DeleteContainerImage deletes an image from the Docker engine
26func DeleteContainerImage(imageID string) error {
27 _, err := dockerCli.ImageRemove(context.Background(), imageID, types.ImageRemoveOptions{})
28 if err != nil {
29 return err
30 }
31
32 return nil
33}
34
35func GetImageID(imageName string) (string, error) {
36
37 images, err := dockerCli.ImageList(context.Background(), types.ImageListOptions{})
38 if err != nil {
39 return "", fmt.Errorf("failed to list images: %w", err)
40 }
41
42 // Search for the image we just loaded
43 var imageID string
44 for _, image := range images {
45 for _, tag := range image.RepoTags {
46 if tag == imageName {
47 imageID = image.ID
48 }
49 }
50 }
51
52 if imageID == "" {
53 return "", fmt.Errorf("image not found")
54 }
55
56 return imageID, nil
57}
58
59// ImportImageToEngine imports an image to the Docker engine
60func ImportImageToEngine(imageFilePath string) error {
61 // Open the image file
62 imageFile, err := os.Open(imageFilePath)
63 if err != nil {
64 return fmt.Errorf("failed to open image file: %w", err)
65 }
66 defer imageFile.Close()
67
68 // Import the image using the Docker client
69 importedImage, err := dockerCli.ImageLoad(context.Background(), imageFile, false)
70 if err != nil {
71 return fmt.Errorf("failed to import image: %w", err)
72 }
73 defer importedImage.Body.Close()
74
75 return nil
76}
77
78// ExportImageFromEngine exports an image from the Docker engine and returns it as an io.Reader
79func ExportImageFromEngine(imageID string) (io.ReadCloser, error) {
80 // Check if the Docker client has been initialized
81
82 // Get the image information using the Docker client
83 imageInfo, err := GetImageInfo(imageID)
84 if err != nil {
85 return nil, err
86 }
87
88 if len(imageInfo.RepoTags) == 0 {
89 return nil, fmt.Errorf("image has no tag")
90 }
91
92 // Export the image using the Docker client
93 imageReader, err := dockerCli.ImageSave(context.Background(), []string{imageInfo.RepoTags[0]})
94 if err != nil {
95 return nil, fmt.Errorf("failed to export image: %w", err)
96 }
97
98 return imageReader, nil
99}
100
101// From an ID, get the all the information about the image
102func GetImageInfo(imageID string) (*types.ImageInspect, error) {
103 // Get the image information using the Docker client
104 imageInfo, _, err := dockerCli.ImageInspectWithRaw(context.Background(), imageID)
105 if err != nil {
106 return nil, err
107 }
108
109 return &imageInfo, nil
110}
111
112// GetImageSize returns the size of an image
113func GetImageSize(imageID string) (int64, error) {
114 // Get the image information using the Docker client
115 imageInfo, err := GetImageInfo(imageID)
116 if err != nil {
117 return 0, err
118 }
119
120 return imageInfo.Size, nil
121}
122
123// GetImageTag returns the tag of an image
124func GetImageTag(imageID string) (string, error) {
125 // Get the image information using the Docker client
126 imageInfo, err := GetImageInfo(imageID)
127 if err != nil {
128 return "", err
129 }
130
131 return imageInfo.RepoTags[0], nil
132}
133
134// GetImageName returns the name of an image
135func GetImageName(imageID string) (string, error) {
136 // Get the image information using the Docker client
137 imageInfo, err := GetImageInfo(imageID)
138 if err != nil {
139 return "", err
140 }
141
142 return imageInfo.RepoDigests[0], nil
143}
144
145// WhoAmI attempts to identify the Docker image digest of the container running this code.
146func WhoAmI() (string, error) {
147 gordonImage := "ghcr.io/bnema/gordon:latest"
148
149 // Get the image information using the Docker client
150 imageInfo, _, err := dockerCli.ImageInspectWithRaw(context.Background(), gordonImage)
151 if err != nil {
152 return "", err
153 }
154
155 return imageInfo.ID, nil
156}
157
158func GetImageSizeFromReader(imageID string) (int64, error) {
159 // Export the image using the Docker client
160 imageReader, err := dockerCli.ImageSave(context.Background(), []string{imageID})
161 if err != nil {
162 return 0, fmt.Errorf("failed to export image: %w", err)
163 }
164
165 // Read the entire stream to get the actual size
166 actualSize := int64(0)
167 buf := make([]byte, 1024) // A buffer for reading the stream
168 for {
169 n, err := imageReader.Read(buf)
170 actualSize += int64(n)
171 if err != nil {
172 if err == io.EOF {
173 break // End of file is reached
174 }
175 return 0, fmt.Errorf("failed to read image: %w", err)
176 }
177 }
178
179 return actualSize, nil
180}