Path: blob/main/components/ide-service/pkg/ocitool/resolve.go
2506 views
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package oci_tool56import (7"context"8"encoding/json"9"fmt"10"io/ioutil"11"time"1213"github.com/containerd/containerd/remotes"14"github.com/distribution/reference"15ociv1 "github.com/opencontainers/image-spec/specs-go/v1"16)1718func Resolve(ctx context.Context, res remotes.Resolver, ref string) (string, error) {19newCtx, cancel := context.WithTimeout(ctx, time.Second*30)20defer cancel()2122name, desc, err := res.Resolve(newCtx, ref)23if err != nil {24return "", err25}2627pref, err := reference.ParseNamed(name)28if err != nil {29return "", err30}31cref, err := reference.WithDigest(pref, desc.Digest)32if err != nil {33return "", err34}35return cref.String(), nil36}3738func interactiveFetchManifestOrIndex(ctx context.Context, res remotes.Resolver, ref string) (name string, result *ociv1.Manifest, err error) {39resolved, desc, err := res.Resolve(ctx, ref)40if err != nil {41return "", nil, fmt.Errorf("cannot resolve %v: %w", ref, err)42}4344fetcher, err := res.Fetcher(ctx, resolved)45if err != nil {46return "", nil, err47}4849in, err := fetcher.Fetch(ctx, desc)50if err != nil {51return "", nil, err52}53defer in.Close()54buf, err := ioutil.ReadAll(in)55if err != nil {56return "", nil, err57}5859var mf ociv1.Manifest60err = json.Unmarshal(buf, &mf)61if err != nil {62return "", nil, fmt.Errorf("cannot unmarshal manifest: %w", err)63}6465if mf.Config.Size != 0 {66return resolved, &mf, nil67}68return "", nil, nil69}7071func ResolveIDEVersion(ctx context.Context, res remotes.Resolver, ref string) (string, error) {72newCtx, cancel := context.WithTimeout(ctx, time.Second*30)73defer cancel()7475name, mf, err := interactiveFetchManifestOrIndex(newCtx, res, ref)76if err != nil {77return "", err78}7980fetcher, err := res.Fetcher(ctx, name)81if err != nil {82return "", err83}8485cfgin, err := fetcher.Fetch(ctx, mf.Config)86if err != nil {87return "", err88}89defer cfgin.Close()9091var tmp ManifestJSON9293err = json.NewDecoder(cfgin).Decode(&tmp)94if err != nil {95return "", nil96}97return tmp.Config.Labels.Version, nil98}99100type ManifestJSON struct {101Config struct {102Labels struct {103Version string `json:"io.gitpod.ide.version"`104} `json:"Labels"`105} `json:"config"`106}107108109