mirror of https://github.com/harness/drone.git
136 lines
4.3 KiB
Go
136 lines
4.3 KiB
Go
// Source: https://gitlab.com/gitlab-org/container-registry
|
|
|
|
// Copyright 2019 Gitlab Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package docker
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/harness/gitness/registry/app/manifest"
|
|
"github.com/harness/gitness/registry/app/manifest/manifestlist"
|
|
"github.com/harness/gitness/registry/app/manifest/ocischema"
|
|
"github.com/harness/gitness/registry/app/manifest/schema2"
|
|
|
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
|
)
|
|
|
|
const (
|
|
// MediaTypeManifest specifies the mediaType for the current version. Note
|
|
// that for schema version 1, the the media is optionally "application/json".
|
|
MediaTypeManifest = "application/vnd.docker.distribution.manifest.v1+json"
|
|
// MediaTypeSignedManifest specifies the mediatype for current SignedManifest version.
|
|
MediaTypeSignedManifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
|
|
)
|
|
|
|
// MediaTypeBuildxCacheConfig is the mediatype associated with buildx
|
|
// cache config blobs. This should be unique to buildx.
|
|
var MediaTypeBuildxCacheConfig = "application/vnd.buildkit.cacheconfig.v0"
|
|
|
|
// SplitReferences contains two lists of manifest list references broken down
|
|
// into either blobs or manifests. The result of appending these two lists
|
|
// together should include all of the descriptors returned by
|
|
// ManifestList.References with no duplicates, additions, or omissions.
|
|
type SplitReferences struct {
|
|
Manifests []manifest.Descriptor
|
|
Blobs []manifest.Descriptor
|
|
}
|
|
|
|
// References returns the references of the DeserializedManifestList split into
|
|
// manifests and layers based on the mediatype of the standard list of
|
|
// descriptors. Only known manifest mediatypes will be sorted into the manifests
|
|
// array while everything else will be sorted into blobs. Helm chart manifests
|
|
// do not include a mediatype at the time of this commit, but they are unlikely
|
|
// to be included within a manifest list.
|
|
func References(ml *manifestlist.DeserializedManifestList) SplitReferences {
|
|
var (
|
|
manifests = make([]manifest.Descriptor, 0)
|
|
blobs = make([]manifest.Descriptor, 0)
|
|
)
|
|
|
|
for _, r := range ml.References() {
|
|
switch r.MediaType {
|
|
case schema2.MediaTypeManifest,
|
|
manifestlist.MediaTypeManifestList,
|
|
v1.MediaTypeImageManifest,
|
|
MediaTypeSignedManifest,
|
|
MediaTypeManifest:
|
|
|
|
manifests = append(manifests, r)
|
|
default:
|
|
blobs = append(blobs, r)
|
|
}
|
|
}
|
|
|
|
return SplitReferences{Manifests: manifests, Blobs: blobs}
|
|
}
|
|
|
|
// LikelyBuildxCache returns true if the manifest list is likely a buildx cache
|
|
// manifest based on the unique buildx config mediatype.
|
|
func LikelyBuildxCache(ml *manifestlist.DeserializedManifestList) bool {
|
|
blobs := References(ml).Blobs
|
|
|
|
for _, desc := range blobs {
|
|
if desc.MediaType == MediaTypeBuildxCacheConfig {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// ContainsBlobs returns true if the manifest list contains any blobs.
|
|
func ContainsBlobs(ml *manifestlist.DeserializedManifestList) bool {
|
|
return len(References(ml).Blobs) > 0
|
|
}
|
|
|
|
func OCIManifestFromBuildkitIndex(ml *manifestlist.DeserializedManifestList) (*ocischema.DeserializedManifest, error) {
|
|
refs := References(ml)
|
|
if len(refs.Manifests) > 0 {
|
|
return nil, errors.New("buildkit index has unexpected manifest references")
|
|
}
|
|
|
|
// set "config" and "layer" references apart.
|
|
var cfg *manifest.Descriptor
|
|
var layers []manifest.Descriptor
|
|
for _, ref := range refs.Blobs {
|
|
refCopy := ref
|
|
if refCopy.MediaType == MediaTypeBuildxCacheConfig {
|
|
cfg = &refCopy
|
|
} else {
|
|
layers = append(layers, refCopy)
|
|
}
|
|
}
|
|
|
|
// make sure they were found.
|
|
if cfg == nil {
|
|
return nil, errors.New("buildkit index has no config reference")
|
|
}
|
|
|
|
m, err := ocischema.FromStruct(
|
|
ocischema.Manifest{
|
|
Versioned: ocischema.SchemaVersion,
|
|
Config: *cfg,
|
|
Layers: layers,
|
|
},
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("building manifest from buildkit index: %w", err)
|
|
}
|
|
|
|
return m, nil
|
|
}
|