podman

Форк
0
116 строк · 3.1 Кб
1
package ocipull
2

3
import (
4
	"context"
5
	"encoding/json"
6
	"errors"
7
	"fmt"
8

9
	"github.com/containers/image/v5/manifest"
10
	"github.com/containers/image/v5/oci/layout"
11
	"github.com/containers/image/v5/types"
12
	"github.com/opencontainers/go-digest"
13
	specV1 "github.com/opencontainers/image-spec/specs-go/v1"
14
	"github.com/sirupsen/logrus"
15
)
16

17
func GetLocalBlob(ctx context.Context, path string) (*types.BlobInfo, error) {
18
	ociRef, err := layout.ParseReference(path)
19
	if err != nil {
20
		return nil, err
21
	}
22
	img, err := ociRef.NewImage(ctx, &types.SystemContext{})
23
	if err != nil {
24
		return nil, err
25
	}
26

27
	b, _, err := img.Manifest(ctx)
28
	if err != nil {
29
		return nil, err
30
	}
31

32
	localManifest := specV1.Manifest{}
33
	if err := json.Unmarshal(b, &localManifest); err != nil {
34
		return nil, err
35
	}
36
	blobs := img.LayerInfos()
37
	if err != nil {
38
		return nil, err
39
	}
40
	if len(blobs) != 1 {
41
		return nil, errors.New("invalid disk image")
42
	}
43
	fmt.Println(blobs[0].Digest.Hex())
44
	return &blobs[0], nil
45
}
46

47
func GetDiskArtifactReference(ctx context.Context, imgSrc types.ImageSource, opts *DiskArtifactOpts) (digest.Digest, error) {
48
	rawMannyFest, mannyType, err := imgSrc.GetManifest(ctx, nil)
49
	if err != nil {
50
		return "", err
51
	}
52

53
	if !manifest.MIMETypeIsMultiImage(mannyType) { // if not true
54
		return "", fmt.Errorf("wrong manifest type for disk artifact: %s", mannyType)
55
	}
56

57
	mannyFestList, err := manifest.ListFromBlob(rawMannyFest, mannyType)
58
	if err != nil {
59
		return "", fmt.Errorf("failed to parse manifest list from blob: %q", err)
60
	}
61

62
	var (
63
		artifactDigest digest.Digest
64
	)
65
	for _, d := range mannyFestList.Instances() {
66
		bar, err := mannyFestList.Instance(d)
67
		if err != nil {
68
			return "", err
69
		}
70
		val, ok := bar.ReadOnly.Annotations["disktype"]
71
		if !ok { // quick exit, no type match
72
			continue
73
		}
74
		// wrong arch
75
		if bar.ReadOnly.Platform.Architecture != opts.arch {
76
			continue
77
		}
78
		// wrong os
79
		if bar.ReadOnly.Platform.OS != opts.os {
80
			continue
81
		}
82
		// wrong disktype
83
		if val != opts.diskType {
84
			continue
85
		}
86

87
		// ok, we have a match
88
		artifactDigest = d
89
		logrus.Debugf("found image in digest: %q", artifactDigest.String())
90
		break
91
	}
92
	if artifactDigest == "" {
93
		return "", fmt.Errorf("no valid disk artifact found")
94
	}
95
	v1RawMannyfest, _, err := imgSrc.GetManifest(ctx, &artifactDigest)
96
	if err != nil {
97
		return "", err
98
	}
99
	v1MannyFest := specV1.Manifest{}
100
	if err := json.Unmarshal(v1RawMannyfest, &v1MannyFest); err != nil {
101
		return "", err
102
	}
103
	if layerLen := len(v1MannyFest.Layers); layerLen > 1 {
104
		return "", fmt.Errorf("podman-machine images should only have 1 layer: %d found", layerLen)
105
	}
106

107
	// podman-machine-images should have a original file name
108
	// stored in the annotations under org.opencontainers.image.title
109
	// i.e. fedora-coreos-39.20240128.2.2-qemu.x86_64.qcow2.xz
110
	originalFileName, ok := v1MannyFest.Layers[0].Annotations["org.opencontainers.image.title"]
111
	if !ok {
112
		return "", fmt.Errorf("unable to determine original artifact name: missing required annotation 'org.opencontainers.image.title'")
113
	}
114
	logrus.Debugf("original artifact file name: %s", originalFileName)
115
	return artifactDigest, err
116
}
117

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.