Skip to content

Commit 8afbe78

Browse files
authored
Merge pull request #40 from Vanilla-OS/digest
feat: return manifest digest
2 parents bb81f94 + 5f375a0 commit 8afbe78

File tree

3 files changed

+44
-43
lines changed

3 files changed

+44
-43
lines changed

client.go

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,14 @@ import (
2828
"github.com/containers/image/v5/transports/alltransports"
2929
"github.com/containers/image/v5/types"
3030
cstorage "github.com/containers/storage"
31+
digest "github.com/opencontainers/go-digest"
3132
)
3233

3334
/* NewPrometheus creates a new Prometheus instance, note that currently
3435
* Prometheus only works with custom stores, so you need to pass the
3536
* root graphDriverName to create a new one.
3637
*/
3738
func NewPrometheus(root, graphDriverName string, maxParallelDownloads uint) (*Prometheus, error) {
38-
var err error
39-
4039
root = filepath.Clean(root)
4140
if _, err := os.Stat(root); os.IsNotExist(err) {
4241
err = os.MkdirAll(root, 0755)
@@ -72,7 +71,7 @@ func NewPrometheus(root, graphDriverName string, maxParallelDownloads uint) (*Pr
7271
// error if any. Note that the 'docker://' prefix is automatically added
7372
// to the imageName to make it compatible with the alltransports.ParseImageName
7473
// method.
75-
func (p *Prometheus) PullImage(imageName, dstName string) (*OciManifest, error) {
74+
func (p *Prometheus) PullImage(imageName, dstName string) (*OciManifest, digest.Digest, error) {
7675
progressCh := make(chan types.ProgressProperties)
7776
manifestCh := make(chan OciManifest)
7877
errorCh := make(chan error)
@@ -81,9 +80,9 @@ func (p *Prometheus) PullImage(imageName, dstName string) (*OciManifest, error)
8180
defer close(manifestCh)
8281
defer close(errorCh)
8382

84-
manifest, err := p.PullManifestOnly(imageName)
83+
manifest, manifestDigest, err := p.PullManifestOnly(imageName)
8584
if err != nil {
86-
return nil, fmt.Errorf("failed to pull manifest %w", err)
85+
return nil, "", fmt.Errorf("failed to pull manifest %w", err)
8786
}
8887

8988
// +1 to account for manifest
@@ -92,7 +91,7 @@ func (p *Prometheus) PullImage(imageName, dstName string) (*OciManifest, error)
9291

9392
err = p.pullImage(imageName, dstName, progressCh, manifestCh, errorCh)
9493
if err != nil {
95-
return nil, err
94+
return nil, "", err
9695
}
9796
for {
9897
select {
@@ -109,9 +108,9 @@ func (p *Prometheus) PullImage(imageName, dstName string) (*OciManifest, error)
109108
fmt.Printf("[%v/%v] %s: %v%%\n", layersDone, layersAll, digestShort, int(percentDone))
110109
}
111110
case manifest := <-manifestCh:
112-
return &manifest, nil
111+
return &manifest, manifestDigest, nil
113112
case err := <-errorCh:
114-
return nil, err
113+
return nil, "", err
115114
}
116115
}
117116
}
@@ -181,28 +180,21 @@ func (p *Prometheus) pullImage(imageName, dstName string, progressCh chan types.
181180
return
182181
}
183182

184-
// here we remove the 'sha256:' prefix from the digest, so we don't have
185-
// to deal with it later
186-
manifest.Config.Digest = manifest.Config.Digest[7:]
187-
for i := range manifest.Layers {
188-
manifest.Layers[i].Digest = manifest.Layers[i].Digest[7:]
189-
}
190-
191183
manifestCh <- manifest
192184
}()
193185

194186
return nil
195187
}
196188

197-
/* GetImageByDigest returns an image from the Prometheus store by its digest. */
198-
func (p *Prometheus) GetImageByDigest(digest string) (cstorage.Image, error) {
189+
/* GetImageById returns an image from the Prometheus store by its ID. */
190+
func (p *Prometheus) GetImageById(id string) (cstorage.Image, error) {
199191
images, err := p.Store.Images()
200192
if err != nil {
201193
return cstorage.Image{}, err
202194
}
203195

204196
for _, img := range images {
205-
if img.ID == digest {
197+
if img.ID == id {
206198
return img, nil
207199
}
208200
}
@@ -211,16 +203,15 @@ func (p *Prometheus) GetImageByDigest(digest string) (cstorage.Image, error) {
211203
return cstorage.Image{}, err
212204
}
213205

214-
/* DoesImageExist checks if an image exists in the Prometheus store by its
215-
* digest. It returns a boolean indicating if the image exists and an error
216-
* if any. */
217-
func (p *Prometheus) DoesImageExist(digest string) (bool, error) {
218-
image, err := p.GetImageByDigest(digest)
206+
/* DoesImageExist checks if an image exists in the Prometheus store by its ID.
207+
* It returns a boolean indicating if the image exists and an error if any. */
208+
func (p *Prometheus) DoesImageExist(id string) (bool, error) {
209+
image, err := p.GetImageById(id)
219210
if err != nil {
220211
return false, err
221212
}
222213

223-
if image.ID == digest {
214+
if image.ID == id {
224215
return true, nil
225216
}
226217

@@ -265,57 +256,60 @@ func (p *Prometheus) BuildContainerFile(dockerfilePath string, imageName string)
265256
return cstorage.Image{}, err
266257
}
267258

268-
image, err := p.GetImageByDigest(id)
259+
image, err := p.GetImageById(id)
269260
if err != nil {
270261
return cstorage.Image{}, err
271262
}
272263

273264
return image, nil
274265
}
275266

276-
func (p *Prometheus) PullManifestOnly(imageName string) (manifest.Manifest, error) {
267+
func (p *Prometheus) PullManifestOnly(imageName string) (manifest.Manifest, digest.Digest, error) {
277268
systemCtx := &types.SystemContext{}
278269
ctx := context.Background()
279270

280-
var outputManifest manifest.Manifest
281-
282271
srcRef, err := alltransports.ParseImageName(fmt.Sprintf("docker://%s", imageName))
283272
if err != nil {
284-
return outputManifest, fmt.Errorf("failed to parse image name: %w", err)
273+
return nil, "", fmt.Errorf("failed to parse image name: %w", err)
285274
}
286275

287276
source, err := srcRef.NewImageSource(ctx, systemCtx)
288277
if err != nil {
289-
return outputManifest, fmt.Errorf("failed to create image source: %w", err)
278+
return nil, "", fmt.Errorf("failed to create image source: %w", err)
290279
}
291280
defer source.Close()
292281

293282
manRaw, manMime, err := source.GetManifest(ctx, nil)
294283
if err != nil {
295-
return outputManifest, fmt.Errorf("failed to fetch manifest: %w", err)
284+
return nil, "", fmt.Errorf("failed to fetch manifest: %w", err)
296285
}
297286

298-
if manMime == manifest.DockerV2ListMediaType || manMime == "application/vnd.oci.image.index.v1+json" {
287+
if manifest.MIMETypeIsMultiImage(manMime) {
299288
list, err := manifest.ListFromBlob(manRaw, manMime)
300289
if err != nil {
301-
return outputManifest, fmt.Errorf("failed to parse manifest list: %w", err)
290+
return nil, "", fmt.Errorf("failed to parse manifest list: %w", err)
302291
}
303292

304293
instanceDigest, err := list.ChooseInstance(systemCtx)
305294
if err != nil {
306-
return outputManifest, fmt.Errorf("failed to select platform instance: %w", err)
295+
return nil, "", fmt.Errorf("failed to select platform instance: %w", err)
307296
}
308297

309298
manRaw, manMime, err = source.GetManifest(ctx, &instanceDigest)
310299
if err != nil {
311-
return outputManifest, fmt.Errorf("failed to fetch platform manifest: %w", err)
300+
return nil, "", fmt.Errorf("failed to fetch platform manifest: %w", err)
312301
}
313302
}
314303

315-
outputManifest, err = manifest.FromBlob(manRaw, manMime)
304+
outputManifest, err := manifest.FromBlob(manRaw, manMime)
305+
if err != nil {
306+
return nil, "", fmt.Errorf("failed to parse platform specific manifest: %w", err)
307+
}
308+
309+
manifestDigest, err := manifest.Digest(manRaw)
316310
if err != nil {
317-
return outputManifest, fmt.Errorf("failed to parse platform specific manifest: %w", err)
311+
return nil, "", fmt.Errorf("failed to fetch digest of manifest: %w", err)
318312
}
319313

320-
return outputManifest, nil
314+
return outputManifest, manifestDigest, nil
321315
}

structs.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ package prometheus
1111
and Albius.
1212
*/
1313

14-
import cstorage "github.com/containers/storage"
14+
import (
15+
cstorage "github.com/containers/storage"
16+
digest "github.com/opencontainers/go-digest"
17+
)
1518

1619
type Prometheus struct {
1720
Store cstorage.Store
@@ -26,9 +29,9 @@ type OciManifest struct {
2629
}
2730

2831
type OciManifestConfig struct {
29-
MediaType string `json:"mediaType"`
30-
Size int `json:"size"`
31-
Digest string `json:"digest"`
32+
MediaType string `json:"mediaType"`
33+
Size int `json:"size"`
34+
Digest digest.Digest `json:"digest"`
3235
}
3336

3437
type PrometheusConfig struct {

tests/pull_image_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestMain(m *testing.M) {
3232
}
3333

3434
func TestPullImage(t *testing.T) {
35-
image, err := pmt.PullImage("docker.io/library/alpine:latest", "my-alpine")
35+
image, digest, err := pmt.PullImage("docker.io/library/alpine:latest", "my-alpine")
3636
if err != nil {
3737
t.Fatalf("error pulling image: %v", err)
3838
}
@@ -41,6 +41,10 @@ func TestPullImage(t *testing.T) {
4141
t.Fatal("image is nil")
4242
}
4343

44+
if digest == "" {
45+
t.Fatal("image digest is empty")
46+
}
47+
4448
if image.Config.Digest == "" {
4549
t.Fatal("image config digest is empty")
4650
}

0 commit comments

Comments
 (0)