9c88801a12
Back in the before time, the best practices surrounding usage of Context weren't quite worked out. We defined our own type to make usage easier. As this packaged was used elsewhere, it make it more and more challenging to integrate with the forked `Context` type. Now that it is available in the standard library, we can just use that one directly. To make usage more consistent, we now use `dcontext` when referring to the distribution context package. Signed-off-by: Stephen J Day <stephen.day@docker.com>
99 lines
2.7 KiB
Go
99 lines
2.7 KiB
Go
package schema1
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/docker/distribution"
|
|
"github.com/docker/distribution/manifest"
|
|
"github.com/docker/distribution/reference"
|
|
"github.com/docker/libtrust"
|
|
"github.com/opencontainers/go-digest"
|
|
)
|
|
|
|
// referenceManifestBuilder is a type for constructing manifests from schema1
|
|
// dependencies.
|
|
type referenceManifestBuilder struct {
|
|
Manifest
|
|
pk libtrust.PrivateKey
|
|
}
|
|
|
|
// NewReferenceManifestBuilder is used to build new manifests for the current
|
|
// schema version using schema1 dependencies.
|
|
func NewReferenceManifestBuilder(pk libtrust.PrivateKey, ref reference.Named, architecture string) distribution.ManifestBuilder {
|
|
tag := ""
|
|
if tagged, isTagged := ref.(reference.Tagged); isTagged {
|
|
tag = tagged.Tag()
|
|
}
|
|
|
|
return &referenceManifestBuilder{
|
|
Manifest: Manifest{
|
|
Versioned: manifest.Versioned{
|
|
SchemaVersion: 1,
|
|
},
|
|
Name: ref.Name(),
|
|
Tag: tag,
|
|
Architecture: architecture,
|
|
},
|
|
pk: pk,
|
|
}
|
|
}
|
|
|
|
func (mb *referenceManifestBuilder) Build(ctx context.Context) (distribution.Manifest, error) {
|
|
m := mb.Manifest
|
|
if len(m.FSLayers) == 0 {
|
|
return nil, errors.New("cannot build manifest with zero layers or history")
|
|
}
|
|
|
|
m.FSLayers = make([]FSLayer, len(mb.Manifest.FSLayers))
|
|
m.History = make([]History, len(mb.Manifest.History))
|
|
copy(m.FSLayers, mb.Manifest.FSLayers)
|
|
copy(m.History, mb.Manifest.History)
|
|
|
|
return Sign(&m, mb.pk)
|
|
}
|
|
|
|
// AppendReference adds a reference to the current ManifestBuilder
|
|
func (mb *referenceManifestBuilder) AppendReference(d distribution.Describable) error {
|
|
r, ok := d.(Reference)
|
|
if !ok {
|
|
return fmt.Errorf("Unable to add non-reference type to v1 builder")
|
|
}
|
|
|
|
// Entries need to be prepended
|
|
mb.Manifest.FSLayers = append([]FSLayer{{BlobSum: r.Digest}}, mb.Manifest.FSLayers...)
|
|
mb.Manifest.History = append([]History{r.History}, mb.Manifest.History...)
|
|
return nil
|
|
|
|
}
|
|
|
|
// References returns the current references added to this builder
|
|
func (mb *referenceManifestBuilder) References() []distribution.Descriptor {
|
|
refs := make([]distribution.Descriptor, len(mb.Manifest.FSLayers))
|
|
for i := range mb.Manifest.FSLayers {
|
|
layerDigest := mb.Manifest.FSLayers[i].BlobSum
|
|
history := mb.Manifest.History[i]
|
|
ref := Reference{layerDigest, 0, history}
|
|
refs[i] = ref.Descriptor()
|
|
}
|
|
return refs
|
|
}
|
|
|
|
// Reference describes a manifest v2, schema version 1 dependency.
|
|
// An FSLayer associated with a history entry.
|
|
type Reference struct {
|
|
Digest digest.Digest
|
|
Size int64 // if we know it, set it for the descriptor.
|
|
History History
|
|
}
|
|
|
|
// Descriptor describes a reference
|
|
func (r Reference) Descriptor() distribution.Descriptor {
|
|
return distribution.Descriptor{
|
|
MediaType: MediaTypeManifestLayer,
|
|
Digest: r.Digest,
|
|
Size: r.Size,
|
|
}
|
|
}
|