*: switch from godep to glide
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
0d7b500cee
commit
4bc8701fc0
673 changed files with 57012 additions and 46916 deletions
206
vendor/github.com/containers/image/oci/layout/oci_dest.go
generated
vendored
Normal file
206
vendor/github.com/containers/image/oci/layout/oci_dest.go
generated
vendored
Normal file
|
@ -0,0 +1,206 @@
|
|||
package layout
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/containers/image/types"
|
||||
imgspec "github.com/opencontainers/image-spec/specs-go"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
type ociImageDestination struct {
|
||||
ref ociReference
|
||||
}
|
||||
|
||||
// newImageDestination returns an ImageDestination for writing to an existing directory.
|
||||
func newImageDestination(ref ociReference) types.ImageDestination {
|
||||
return &ociImageDestination{ref: ref}
|
||||
}
|
||||
|
||||
// Reference returns the reference used to set up this destination. Note that this should directly correspond to user's intent,
|
||||
// e.g. it should use the public hostname instead of the result of resolving CNAMEs or following redirects.
|
||||
func (d *ociImageDestination) Reference() types.ImageReference {
|
||||
return d.ref
|
||||
}
|
||||
|
||||
// Close removes resources associated with an initialized ImageDestination, if any.
|
||||
func (d *ociImageDestination) Close() {
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) SupportedManifestMIMETypes() []string {
|
||||
return []string{
|
||||
imgspecv1.MediaTypeImageManifest,
|
||||
manifest.DockerV2Schema2MediaType,
|
||||
}
|
||||
}
|
||||
|
||||
// SupportsSignatures returns an error (to be displayed to the user) if the destination certainly can't store signatures.
|
||||
// Note: It is still possible for PutSignatures to fail if SupportsSignatures returns nil.
|
||||
func (d *ociImageDestination) SupportsSignatures() error {
|
||||
return fmt.Errorf("Pushing signatures for OCI images is not supported")
|
||||
}
|
||||
|
||||
// PutBlob writes contents of stream and returns its computed digest and size.
|
||||
// A digest can be optionally provided if known, the specific image destination can decide to play with it or not.
|
||||
// The length of stream is expected to be expectedSize; if expectedSize == -1, it is not known.
|
||||
// WARNING: The contents of stream are being verified on the fly. Until stream.Read() returns io.EOF, the contents of the data SHOULD NOT be available
|
||||
// to any other readers for download using the supplied digest.
|
||||
// If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far.
|
||||
func (d *ociImageDestination) PutBlob(stream io.Reader, _ string, expectedSize int64) (string, int64, error) {
|
||||
if err := ensureDirectoryExists(d.ref.dir); err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
blobFile, err := ioutil.TempFile(d.ref.dir, "oci-put-blob")
|
||||
if err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
succeeded := false
|
||||
defer func() {
|
||||
blobFile.Close()
|
||||
if !succeeded {
|
||||
os.Remove(blobFile.Name())
|
||||
}
|
||||
}()
|
||||
|
||||
h := sha256.New()
|
||||
tee := io.TeeReader(stream, h)
|
||||
|
||||
size, err := io.Copy(blobFile, tee)
|
||||
if err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
computedDigest := "sha256:" + hex.EncodeToString(h.Sum(nil))
|
||||
if expectedSize != -1 && size != expectedSize {
|
||||
return "", -1, fmt.Errorf("Size mismatch when copying %s, expected %d, got %d", computedDigest, expectedSize, size)
|
||||
}
|
||||
if err := blobFile.Sync(); err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
if err := blobFile.Chmod(0644); err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
|
||||
blobPath, err := d.ref.blobPath(computedDigest)
|
||||
if err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
if err := ensureParentDirectoryExists(blobPath); err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
if err := os.Rename(blobFile.Name(), blobPath); err != nil {
|
||||
return "", -1, err
|
||||
}
|
||||
succeeded = true
|
||||
return computedDigest, size, nil
|
||||
}
|
||||
|
||||
func createManifest(m []byte) ([]byte, string, error) {
|
||||
om := imgspecv1.Manifest{}
|
||||
mt := manifest.GuessMIMEType(m)
|
||||
switch mt {
|
||||
case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType:
|
||||
// There a simple reason about not yet implementing this.
|
||||
// OCI image-spec assure about backward compatibility with docker v2s2 but not v2s1
|
||||
// generating a v2s2 is a migration docker does when upgrading to 1.10.3
|
||||
// and I don't think we should bother about this now (I don't want to have migration code here in skopeo)
|
||||
return nil, "", errors.New("can't create an OCI manifest from Docker V2 schema 1 manifest")
|
||||
case manifest.DockerV2Schema2MediaType:
|
||||
if err := json.Unmarshal(m, &om); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
om.MediaType = imgspecv1.MediaTypeImageManifest
|
||||
for i := range om.Layers {
|
||||
om.Layers[i].MediaType = imgspecv1.MediaTypeImageLayer
|
||||
}
|
||||
om.Config.MediaType = imgspecv1.MediaTypeImageConfig
|
||||
b, err := json.Marshal(om)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return b, om.MediaType, nil
|
||||
case manifest.DockerV2ListMediaType:
|
||||
return nil, "", errors.New("can't create an OCI manifest from Docker V2 schema 2 manifest list")
|
||||
case imgspecv1.MediaTypeImageManifestList:
|
||||
return nil, "", errors.New("can't create an OCI manifest from OCI manifest list")
|
||||
case imgspecv1.MediaTypeImageManifest:
|
||||
return m, mt, nil
|
||||
}
|
||||
return nil, "", fmt.Errorf("unrecognized manifest media type %q", mt)
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) PutManifest(m []byte) error {
|
||||
// TODO(mitr, runcom): this breaks signatures entirely since at this point we're creating a new manifest
|
||||
// and signatures don't apply anymore. Will fix.
|
||||
ociMan, mt, err := createManifest(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
digest, err := manifest.Digest(ociMan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
desc := imgspec.Descriptor{}
|
||||
desc.Digest = digest
|
||||
// TODO(runcom): beaware and add support for OCI manifest list
|
||||
desc.MediaType = mt
|
||||
desc.Size = int64(len(ociMan))
|
||||
data, err := json.Marshal(desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blobPath, err := d.ref.blobPath(digest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ioutil.WriteFile(blobPath, ociMan, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(runcom): ugly here?
|
||||
if err := ioutil.WriteFile(d.ref.ociLayoutPath(), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
descriptorPath := d.ref.descriptorPath(d.ref.tag)
|
||||
if err := ensureParentDirectoryExists(descriptorPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(descriptorPath, data, 0644)
|
||||
}
|
||||
|
||||
func ensureDirectoryExists(path string) error {
|
||||
if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureParentDirectoryExists ensures the parent of the supplied path exists.
|
||||
func ensureParentDirectoryExists(path string) error {
|
||||
return ensureDirectoryExists(filepath.Dir(path))
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) PutSignatures(signatures [][]byte) error {
|
||||
if len(signatures) != 0 {
|
||||
return fmt.Errorf("Pushing signatures for OCI images is not supported")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Commit marks the process of storing the image as successful and asks for the image to be persisted.
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *ociImageDestination) Commit() error {
|
||||
return nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package oci
|
||||
package layout
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/docker/docker/reference"
|
||||
)
|
||||
|
||||
// Transport is an ImageTransport for Docker references.
|
||||
// Transport is an ImageTransport for OCI directories.
|
||||
var Transport = ociTransport{}
|
||||
|
||||
type ociTransport struct{}
|
||||
|
@ -58,6 +58,10 @@ func (t ociTransport) ValidatePolicyConfigurationScope(scope string) error {
|
|||
if scope == "/" {
|
||||
return errors.New(`Invalid scope "/": Use the generic default scope ""`)
|
||||
}
|
||||
cleaned := filepath.Clean(dir)
|
||||
if cleaned != dir {
|
||||
return fmt.Errorf(`Invalid scope %s: Uses non-canonical path format, perhaps try with path %s`, scope, cleaned)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -161,28 +165,42 @@ func (ref ociReference) PolicyConfigurationNamespaces() []string {
|
|||
}
|
||||
|
||||
// NewImage returns a types.Image for this reference.
|
||||
func (ref ociReference) NewImage(certPath string, tlsVerify bool) (types.Image, error) {
|
||||
// The caller must call .Close() on the returned Image.
|
||||
func (ref ociReference) NewImage(ctx *types.SystemContext) (types.Image, error) {
|
||||
return nil, errors.New("Full Image support not implemented for oci: image names")
|
||||
}
|
||||
|
||||
// NewImageSource returns a types.ImageSource for this reference.
|
||||
func (ref ociReference) NewImageSource(certPath string, tlsVerify bool) (types.ImageSource, error) {
|
||||
// NewImageSource returns a types.ImageSource for this reference,
|
||||
// asking the backend to use a manifest from requestedManifestMIMETypes if possible.
|
||||
// nil requestedManifestMIMETypes means manifest.DefaultRequestedManifestMIMETypes.
|
||||
// The caller must call .Close() on the returned ImageSource.
|
||||
func (ref ociReference) NewImageSource(ctx *types.SystemContext, requestedManifestMIMETypes []string) (types.ImageSource, error) {
|
||||
return nil, errors.New("Reading images not implemented for oci: image names")
|
||||
}
|
||||
|
||||
// NewImageDestination returns a types.ImageDestination for this reference.
|
||||
func (ref ociReference) NewImageDestination(certPath string, tlsVerify bool) (types.ImageDestination, error) {
|
||||
// The caller must call .Close() on the returned ImageDestination.
|
||||
func (ref ociReference) NewImageDestination(ctx *types.SystemContext) (types.ImageDestination, error) {
|
||||
return newImageDestination(ref), nil
|
||||
}
|
||||
|
||||
// DeleteImage deletes the named image from the registry, if supported.
|
||||
func (ref ociReference) DeleteImage(ctx *types.SystemContext) error {
|
||||
return fmt.Errorf("Deleting images not implemented for oci: images")
|
||||
}
|
||||
|
||||
// ociLayoutPathPath returns a path for the oci-layout within a directory using OCI conventions.
|
||||
func (ref ociReference) ociLayoutPath() string {
|
||||
return filepath.Join(ref.dir, "oci-layout")
|
||||
}
|
||||
|
||||
// blobPath returns a path for a blob within a directory using OCI image-layout conventions.
|
||||
func (ref ociReference) blobPath(digest string) string {
|
||||
return filepath.Join(ref.dir, "blobs", strings.Replace(digest, ":", "-", -1))
|
||||
func (ref ociReference) blobPath(digest string) (string, error) {
|
||||
pts := strings.SplitN(digest, ":", 2)
|
||||
if len(pts) != 2 {
|
||||
return "", fmt.Errorf("unexpected digest reference %s", digest)
|
||||
}
|
||||
return filepath.Join(ref.dir, "blobs", pts[0], pts[1]), nil
|
||||
}
|
||||
|
||||
// descriptorPath returns a path for the manifest within a directory using OCI conventions.
|
155
vendor/github.com/containers/image/oci/oci_dest.go
generated
vendored
155
vendor/github.com/containers/image/oci/oci_dest.go
generated
vendored
|
@ -1,155 +0,0 @@
|
|||
package oci
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/containers/image/types"
|
||||
)
|
||||
|
||||
type ociManifest struct {
|
||||
SchemaVersion int `json:"schemaVersion"`
|
||||
MediaType string `json:"mediaType"`
|
||||
Config descriptor `json:"config"`
|
||||
Layers []descriptor `json:"layers"`
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
}
|
||||
|
||||
type descriptor struct {
|
||||
Digest string `json:"digest"`
|
||||
MediaType string `json:"mediaType"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type ociImageDestination struct {
|
||||
ref ociReference
|
||||
}
|
||||
|
||||
// newImageDestination returns an ImageDestination for writing to an existing directory.
|
||||
func newImageDestination(ref ociReference) types.ImageDestination {
|
||||
return &ociImageDestination{ref: ref}
|
||||
}
|
||||
|
||||
// Reference returns the reference used to set up this destination. Note that this should directly correspond to user's intent,
|
||||
// e.g. it should use the public hostname instead of the result of resolving CNAMEs or following redirects.
|
||||
func (d *ociImageDestination) Reference() types.ImageReference {
|
||||
return d.ref
|
||||
}
|
||||
|
||||
func createManifest(m []byte) ([]byte, string, error) {
|
||||
om := ociManifest{}
|
||||
mt := manifest.GuessMIMEType(m)
|
||||
switch mt {
|
||||
case manifest.DockerV2Schema1MIMEType:
|
||||
// There a simple reason about not yet implementing this.
|
||||
// OCI image-spec assure about backward compatibility with docker v2s2 but not v2s1
|
||||
// generating a v2s2 is a migration docker does when upgrading to 1.10.3
|
||||
// and I don't think we should bother about this now (I don't want to have migration code here in skopeo)
|
||||
return nil, "", fmt.Errorf("can't create OCI manifest from Docker V2 schema 1 manifest")
|
||||
case manifest.DockerV2Schema2MIMEType:
|
||||
if err := json.Unmarshal(m, &om); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
om.MediaType = manifest.OCIV1ImageManifestMIMEType
|
||||
for i := range om.Layers {
|
||||
om.Layers[i].MediaType = manifest.OCIV1ImageSerializationMIMEType
|
||||
}
|
||||
om.Config.MediaType = manifest.OCIV1ImageSerializationConfigMIMEType
|
||||
b, err := json.Marshal(om)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return b, om.MediaType, nil
|
||||
case manifest.DockerV2ListMIMEType:
|
||||
return nil, "", fmt.Errorf("can't create OCI manifest from Docker V2 schema 2 manifest list")
|
||||
case manifest.OCIV1ImageManifestListMIMEType:
|
||||
return nil, "", fmt.Errorf("can't create OCI manifest from OCI manifest list")
|
||||
case manifest.OCIV1ImageManifestMIMEType:
|
||||
return m, om.MediaType, nil
|
||||
}
|
||||
return nil, "", fmt.Errorf("Unrecognized manifest media type")
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) PutManifest(m []byte) error {
|
||||
// TODO(mitr, runcom): this breaks signatures entirely since at this point we're creating a new manifest
|
||||
// and signatures don't apply anymore. Will fix.
|
||||
ociMan, mt, err := createManifest(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
digest, err := manifest.Digest(ociMan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
desc := descriptor{}
|
||||
desc.Digest = digest
|
||||
// TODO(runcom): beaware and add support for OCI manifest list
|
||||
desc.MediaType = mt
|
||||
desc.Size = int64(len(ociMan))
|
||||
data, err := json.Marshal(desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(d.ref.blobPath(digest), ociMan, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(runcom): ugly here?
|
||||
if err := ioutil.WriteFile(d.ref.ociLayoutPath(), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
descriptorPath := d.ref.descriptorPath(d.ref.tag)
|
||||
if err := ensureParentDirectoryExists(descriptorPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(descriptorPath, data, 0644)
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) PutBlob(digest string, stream io.Reader) error {
|
||||
blobPath := d.ref.blobPath(digest)
|
||||
if err := ensureParentDirectoryExists(blobPath); err != nil {
|
||||
return err
|
||||
}
|
||||
blob, err := os.Create(blobPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer blob.Close()
|
||||
if _, err := io.Copy(blob, stream); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := blob.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureParentDirectoryExists ensures the parent of the supplied path exists.
|
||||
func ensureParentDirectoryExists(path string) error {
|
||||
parent := filepath.Dir(path)
|
||||
if _, err := os.Stat(parent); err != nil && os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(parent, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) SupportedManifestMIMETypes() []string {
|
||||
return []string{
|
||||
manifest.OCIV1ImageManifestMIMEType,
|
||||
manifest.DockerV2Schema2MIMEType,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *ociImageDestination) PutSignatures(signatures [][]byte) error {
|
||||
if len(signatures) != 0 {
|
||||
return fmt.Errorf("Pushing signatures for OCI images is not supported")
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue