Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/ide-service/pkg/ocitool/resolve.go
2506 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package oci_tool
6
7
import (
8
"context"
9
"encoding/json"
10
"fmt"
11
"io/ioutil"
12
"time"
13
14
"github.com/containerd/containerd/remotes"
15
"github.com/distribution/reference"
16
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
17
)
18
19
func Resolve(ctx context.Context, res remotes.Resolver, ref string) (string, error) {
20
newCtx, cancel := context.WithTimeout(ctx, time.Second*30)
21
defer cancel()
22
23
name, desc, err := res.Resolve(newCtx, ref)
24
if err != nil {
25
return "", err
26
}
27
28
pref, err := reference.ParseNamed(name)
29
if err != nil {
30
return "", err
31
}
32
cref, err := reference.WithDigest(pref, desc.Digest)
33
if err != nil {
34
return "", err
35
}
36
return cref.String(), nil
37
}
38
39
func interactiveFetchManifestOrIndex(ctx context.Context, res remotes.Resolver, ref string) (name string, result *ociv1.Manifest, err error) {
40
resolved, desc, err := res.Resolve(ctx, ref)
41
if err != nil {
42
return "", nil, fmt.Errorf("cannot resolve %v: %w", ref, err)
43
}
44
45
fetcher, err := res.Fetcher(ctx, resolved)
46
if err != nil {
47
return "", nil, err
48
}
49
50
in, err := fetcher.Fetch(ctx, desc)
51
if err != nil {
52
return "", nil, err
53
}
54
defer in.Close()
55
buf, err := ioutil.ReadAll(in)
56
if err != nil {
57
return "", nil, err
58
}
59
60
var mf ociv1.Manifest
61
err = json.Unmarshal(buf, &mf)
62
if err != nil {
63
return "", nil, fmt.Errorf("cannot unmarshal manifest: %w", err)
64
}
65
66
if mf.Config.Size != 0 {
67
return resolved, &mf, nil
68
}
69
return "", nil, nil
70
}
71
72
func ResolveIDEVersion(ctx context.Context, res remotes.Resolver, ref string) (string, error) {
73
newCtx, cancel := context.WithTimeout(ctx, time.Second*30)
74
defer cancel()
75
76
name, mf, err := interactiveFetchManifestOrIndex(newCtx, res, ref)
77
if err != nil {
78
return "", err
79
}
80
81
fetcher, err := res.Fetcher(ctx, name)
82
if err != nil {
83
return "", err
84
}
85
86
cfgin, err := fetcher.Fetch(ctx, mf.Config)
87
if err != nil {
88
return "", err
89
}
90
defer cfgin.Close()
91
92
var tmp ManifestJSON
93
94
err = json.NewDecoder(cfgin).Decode(&tmp)
95
if err != nil {
96
return "", nil
97
}
98
return tmp.Config.Labels.Version, nil
99
}
100
101
type ManifestJSON struct {
102
Config struct {
103
Labels struct {
104
Version string `json:"io.gitpod.ide.version"`
105
} `json:"Labels"`
106
} `json:"config"`
107
}
108
109