Merge pull request #180 from mtrmac/api-changes

Vendor in API changes from https://github.com/containers/image/pull/64
This commit is contained in:
Miloslav Trmač 2016-08-31 22:04:20 +02:00 committed by GitHub
commit d24cdcbcf3
18 changed files with 185 additions and 136 deletions

View File

@ -91,11 +91,11 @@ func copyHandler(context *cli.Context) error {
return fmt.Errorf("Error initializing %s: %v", context.Args()[1], err)
}
rawSource, err := parseImageSource(context, context.Args()[0])
rawSource, err := parseImageSource(context, context.Args()[0], dest.SupportedManifestMIMETypes())
if err != nil {
return fmt.Errorf("Error initializing %s: %v", context.Args()[0], err)
}
src := image.FromSource(rawSource, dest.SupportedManifestMIMETypes())
src := image.FromSource(rawSource)
signBy := context.String("sign-by")

View File

@ -2,7 +2,9 @@ package main
import (
"errors"
"fmt"
"github.com/containers/image/transports"
"github.com/urfave/cli"
)
@ -11,12 +13,12 @@ func deleteHandler(context *cli.Context) error {
return errors.New("Usage: delete imageReference")
}
image, err := parseImageSource(context, context.Args()[0])
ref, err := transports.ParseImageName(context.Args()[0])
if err != nil {
return err
return fmt.Errorf("Invalid source name %s: %v", context.Args()[0], err)
}
if err := image.Delete(); err != nil {
if err := ref.DeleteImage(contextFromGlobalOptions(context)); err != nil {
return err
}
return nil

View File

@ -16,16 +16,16 @@ var layersCmd = cli.Command{
Usage: "Get layers of IMAGE-NAME",
ArgsUsage: "IMAGE-NAME",
Action: func(c *cli.Context) error {
rawSource, err := parseImageSource(c, c.Args()[0])
if err != nil {
return err
}
src := image.FromSource(rawSource, []string{
rawSource, err := parseImageSource(c, c.Args()[0], []string{
// TODO: skopeo layers only support these now
// eventually we'll remove this command altogether...
manifest.DockerV2Schema1SignedMIMEType,
manifest.DockerV2Schema1MIMEType,
})
if err != nil {
return err
}
src := image.FromSource(rawSource)
blobDigests := c.Args().Tail()
if len(blobDigests) == 0 {
b, err := src.BlobDigests()
@ -42,7 +42,7 @@ var layersCmd = cli.Command{
if err != nil {
return err
}
dest, err := tmpDirRef.NewImageDestination("", true)
dest, err := tmpDirRef.NewImageDestination(nil)
if err != nil {
return err
}

View File

@ -6,42 +6,41 @@ import (
"github.com/urfave/cli"
)
// contextFromGlobalOptions returns a types.SystemContext depending on c.
func contextFromGlobalOptions(c *cli.Context) *types.SystemContext {
certPath := c.GlobalString("cert-path")
tlsVerify := c.GlobalBool("tls-verify") // FIXME!! defaults to false
return &types.SystemContext{
DockerCertPath: certPath,
DockerInsecureSkipTLSVerify: !tlsVerify,
}
}
// ParseImage converts image URL-like string to an initialized handler for that image.
func parseImage(c *cli.Context) (types.Image, error) {
var (
imgName = c.Args().First()
certPath = c.GlobalString("cert-path")
tlsVerify = c.GlobalBool("tls-verify")
)
imgName := c.Args().First()
ref, err := transports.ParseImageName(imgName)
if err != nil {
return nil, err
}
return ref.NewImage(certPath, tlsVerify)
return ref.NewImage(contextFromGlobalOptions(c))
}
// parseImageSource converts image URL-like string to an ImageSource.
func parseImageSource(c *cli.Context, name string) (types.ImageSource, error) {
var (
certPath = c.GlobalString("cert-path")
tlsVerify = c.GlobalBool("tls-verify") // FIXME!! defaults to false?
)
// requestedManifestMIMETypes is as in types.ImageReference.NewImageSource.
func parseImageSource(c *cli.Context, name string, requestedManifestMIMETypes []string) (types.ImageSource, error) {
ref, err := transports.ParseImageName(name)
if err != nil {
return nil, err
}
return ref.NewImageSource(certPath, tlsVerify)
return ref.NewImageSource(contextFromGlobalOptions(c), requestedManifestMIMETypes)
}
// parseImageDestination converts image URL-like string to an ImageDestination.
func parseImageDestination(c *cli.Context, name string) (types.ImageDestination, error) {
var (
certPath = c.GlobalString("cert-path")
tlsVerify = c.GlobalBool("tls-verify") // FIXME!! defaults to false?
)
ref, err := transports.ParseImageName(name)
if err != nil {
return nil, err
}
return ref.NewImageDestination(certPath, tlsVerify)
return ref.NewImageDestination(contextFromGlobalOptions(c))
}

View File

@ -1,7 +1,6 @@
package directory
import (
"fmt"
"io"
"io/ioutil"
"os"
@ -25,7 +24,7 @@ func (s *dirImageSource) Reference() types.ImageReference {
}
// it's up to the caller to determine the MIME type of the returned manifest's bytes
func (s *dirImageSource) GetManifest(_ []string) ([]byte, string, error) {
func (s *dirImageSource) GetManifest() ([]byte, string, error) {
m, err := ioutil.ReadFile(s.ref.manifestPath())
if err != nil {
return nil, "", err
@ -59,7 +58,3 @@ func (s *dirImageSource) GetSignatures() ([][]byte, error) {
}
return signatures, nil
}
func (s *dirImageSource) Delete() error {
return fmt.Errorf("directory#dirImageSource.Delete() not implmented")
}

View File

@ -128,21 +128,28 @@ func (ref dirReference) PolicyConfigurationNamespaces() []string {
}
// NewImage returns a types.Image for this reference.
func (ref dirReference) NewImage(certPath string, tlsVerify bool) (types.Image, error) {
func (ref dirReference) NewImage(ctx *types.SystemContext) (types.Image, error) {
src := newImageSource(ref)
return image.FromSource(src, nil), nil
return image.FromSource(src), nil
}
// NewImageSource returns a types.ImageSource for this reference.
func (ref dirReference) 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.
func (ref dirReference) NewImageSource(ctx *types.SystemContext, requestedManifestMIMETypes []string) (types.ImageSource, error) {
return newImageSource(ref), nil
}
// NewImageDestination returns a types.ImageDestination for this reference.
func (ref dirReference) NewImageDestination(certPath string, tlsVerify bool) (types.ImageDestination, error) {
func (ref dirReference) NewImageDestination(ctx *types.SystemContext) (types.ImageDestination, error) {
return newImageDestination(ref), nil
}
// DeleteImage deletes the named image from the registry, if supported.
func (ref dirReference) DeleteImage(ctx *types.SystemContext) error {
return fmt.Errorf("Deleting images not implemented for dir: images")
}
// manifestPath returns a path for the manifest within a directory using our conventions.
func (ref dirReference) manifestPath() string {
return filepath.Join(ref.path, "manifest.json")

View File

@ -14,6 +14,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/containers/image/types"
"github.com/docker/docker/pkg/homedir"
)
@ -44,7 +45,7 @@ type dockerClient struct {
}
// newDockerClient returns a new dockerClient instance for refHostname (a host a specified in the Docker image reference, not canonicalized to dockerRegistry)
func newDockerClient(refHostname, certPath string, tlsVerify bool) (*dockerClient, error) {
func newDockerClient(ctx *types.SystemContext, refHostname string) (*dockerClient, error) {
var registry string
if refHostname == dockerHostname {
registry = dockerRegistry
@ -56,17 +57,17 @@ func newDockerClient(refHostname, certPath string, tlsVerify bool) (*dockerClien
return nil, err
}
var tr *http.Transport
if certPath != "" || !tlsVerify {
if ctx != nil && (ctx.DockerCertPath != "" || ctx.DockerInsecureSkipTLSVerify) {
tlsc := &tls.Config{}
if certPath != "" {
cert, err := tls.LoadX509KeyPair(filepath.Join(certPath, "cert.pem"), filepath.Join(certPath, "key.pem"))
if ctx.DockerCertPath != "" {
cert, err := tls.LoadX509KeyPair(filepath.Join(ctx.DockerCertPath, "cert.pem"), filepath.Join(ctx.DockerCertPath, "key.pem"))
if err != nil {
return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
}
tlsc.Certificates = append(tlsc.Certificates, cert)
}
tlsc.InsecureSkipVerify = !tlsVerify
tlsc.InsecureSkipVerify = ctx.DockerInsecureSkipTLSVerify
tr = &http.Transport{
TLSClientConfig: tlsc,
}

View File

@ -18,12 +18,12 @@ type Image struct {
// newImage returns a new Image interface type after setting up
// a client to the registry hosting the given image.
func newImage(ref dockerReference, certPath string, tlsVerify bool) (types.Image, error) {
s, err := newImageSource(ref, certPath, tlsVerify)
func newImage(ctx *types.SystemContext, ref dockerReference) (types.Image, error) {
s, err := newImageSource(ctx, ref, nil)
if err != nil {
return nil, err
}
return &Image{Image: image.FromSource(s, nil), src: s}, nil
return &Image{Image: image.FromSource(s), src: s}, nil
}
// SourceRefFullName returns a fully expanded name for the repository this image is in.

View File

@ -17,9 +17,9 @@ type dockerImageDestination struct {
c *dockerClient
}
// newImageDestination creates a new ImageDestination for the specified image reference and connection specification.
func newImageDestination(ref dockerReference, certPath string, tlsVerify bool) (types.ImageDestination, error) {
c, err := newDockerClient(ref.ref.Hostname(), certPath, tlsVerify)
// newImageDestination creates a new ImageDestination for the specified image reference.
func newImageDestination(ctx *types.SystemContext, ref dockerReference) (types.ImageDestination, error) {
c, err := newDockerClient(ctx, ref.ref.Hostname())
if err != nil {
return nil, err
}

View File

@ -23,19 +23,26 @@ func (e errFetchManifest) Error() string {
}
type dockerImageSource struct {
ref dockerReference
c *dockerClient
ref dockerReference
requestedManifestMIMETypes []string
c *dockerClient
}
// newImageSource creates a new ImageSource for the specified image reference and connection specification.
func newImageSource(ref dockerReference, certPath string, tlsVerify bool) (*dockerImageSource, error) {
c, err := newDockerClient(ref.ref.Hostname(), certPath, tlsVerify)
// newImageSource creates a new ImageSource for the specified image reference,
// asking the backend to use a manifest from requestedManifestMIMETypes if possible
// nil requestedManifestMIMETypes means manifest.DefaultRequestedManifestMIMETypes.
func newImageSource(ctx *types.SystemContext, ref dockerReference, requestedManifestMIMETypes []string) (*dockerImageSource, error) {
c, err := newDockerClient(ctx, ref.ref.Hostname())
if err != nil {
return nil, err
}
if requestedManifestMIMETypes == nil {
requestedManifestMIMETypes = manifest.DefaultRequestedManifestMIMETypes
}
return &dockerImageSource{
ref: ref,
c: c,
requestedManifestMIMETypes: requestedManifestMIMETypes,
c: c,
}, nil
}
@ -58,7 +65,7 @@ func simplifyContentType(contentType string) string {
return mimeType
}
func (s *dockerImageSource) GetManifest(mimetypes []string) ([]byte, string, error) {
func (s *dockerImageSource) GetManifest() ([]byte, string, error) {
reference, err := s.ref.tagOrDigest()
if err != nil {
return nil, "", err
@ -67,7 +74,7 @@ func (s *dockerImageSource) GetManifest(mimetypes []string) ([]byte, string, err
// TODO(runcom) set manifest version header! schema1 for now - then schema2 etc etc and v1
// TODO(runcom) NO, switch on the resulter manifest like Docker is doing
headers := make(map[string][]string)
headers["Accept"] = mimetypes
headers["Accept"] = s.requestedManifestMIMETypes
res, err := s.c.makeRequest("GET", url, headers, nil)
if err != nil {
return nil, "", err
@ -106,42 +113,46 @@ func (s *dockerImageSource) GetSignatures() ([][]byte, error) {
return [][]byte{}, nil
}
func (s *dockerImageSource) Delete() error {
var body []byte
// deleteImage deletes the named image from the registry, if supported.
func deleteImage(ctx *types.SystemContext, ref dockerReference) error {
c, err := newDockerClient(ctx, ref.ref.Hostname())
if err != nil {
return err
}
// When retrieving the digest from a registry >= 2.3 use the following header:
// "Accept": "application/vnd.docker.distribution.manifest.v2+json"
headers := make(map[string][]string)
headers["Accept"] = []string{manifest.DockerV2Schema2MIMEType}
reference, err := s.ref.tagOrDigest()
reference, err := ref.tagOrDigest()
if err != nil {
return err
}
getURL := fmt.Sprintf(manifestURL, s.ref.ref.RemoteName(), reference)
get, err := s.c.makeRequest("GET", getURL, headers, nil)
getURL := fmt.Sprintf(manifestURL, ref.ref.RemoteName(), reference)
get, err := c.makeRequest("GET", getURL, headers, nil)
if err != nil {
return err
}
defer get.Body.Close()
body, err = ioutil.ReadAll(get.Body)
body, err := ioutil.ReadAll(get.Body)
if err != nil {
return err
}
switch get.StatusCode {
case http.StatusOK:
case http.StatusNotFound:
return fmt.Errorf("Unable to delete %v. Image may not exist or is not stored with a v2 Schema in a v2 registry.", s.ref.ref)
return fmt.Errorf("Unable to delete %v. Image may not exist or is not stored with a v2 Schema in a v2 registry.", ref.ref)
default:
return fmt.Errorf("Failed to delete %v: %v (%v)", s.ref.ref, body, get.Status)
return fmt.Errorf("Failed to delete %v: %s (%v)", ref.ref, string(body), get.Status)
}
digest := get.Header.Get("Docker-Content-Digest")
deleteURL := fmt.Sprintf(manifestURL, s.ref.ref.RemoteName(), digest)
deleteURL := fmt.Sprintf(manifestURL, ref.ref.RemoteName(), digest)
// When retrieving the digest from a registry >= 2.3 use the following header:
// "Accept": "application/vnd.docker.distribution.manifest.v2+json"
delete, err := s.c.makeRequest("DELETE", deleteURL, headers, nil)
delete, err := c.makeRequest("DELETE", deleteURL, headers, nil)
if err != nil {
return err
}
@ -152,7 +163,7 @@ func (s *dockerImageSource) Delete() error {
return err
}
if delete.StatusCode != http.StatusAccepted {
return fmt.Errorf("Failed to delete %v: %v (%v)", deleteURL, body, delete.Status)
return fmt.Errorf("Failed to delete %v: %s (%v)", deleteURL, string(body), delete.Status)
}
return nil

View File

@ -116,18 +116,25 @@ func (ref dockerReference) PolicyConfigurationNamespaces() []string {
}
// NewImage returns a types.Image for this reference.
func (ref dockerReference) NewImage(certPath string, tlsVerify bool) (types.Image, error) {
return newImage(ref, certPath, tlsVerify)
func (ref dockerReference) NewImage(ctx *types.SystemContext) (types.Image, error) {
return newImage(ctx, ref)
}
// NewImageSource returns a types.ImageSource for this reference.
func (ref dockerReference) NewImageSource(certPath string, tlsVerify bool) (types.ImageSource, error) {
return newImageSource(ref, certPath, tlsVerify)
// NewImageSource returns a types.ImageSource for this reference,
// asking the backend to use a manifest from requestedManifestMIMETypes if possible
// nil requestedManifestMIMETypes means manifest.DefaultRequestedManifestMIMETypes.
func (ref dockerReference) NewImageSource(ctx *types.SystemContext, requestedManifestMIMETypes []string) (types.ImageSource, error) {
return newImageSource(ctx, ref, requestedManifestMIMETypes)
}
// NewImageDestination returns a types.ImageDestination for this reference.
func (ref dockerReference) NewImageDestination(certPath string, tlsVerify bool) (types.ImageDestination, error) {
return newImageDestination(ref, certPath, tlsVerify)
func (ref dockerReference) NewImageDestination(ctx *types.SystemContext) (types.ImageDestination, error) {
return newImageDestination(ctx, ref)
}
// DeleteImage deletes the named image from the registry, if supported.
func (ref dockerReference) DeleteImage(ctx *types.SystemContext) error {
return deleteImage(ctx, ref)
}
// tagOrDigest returns a tag or digest from the reference.

View File

@ -33,21 +33,12 @@ type genericImage struct {
// this field is valid only if cachedManifest is not nil
cachedManifestMIMEType string
// private cache for Signatures(); nil if not yet known.
cachedSignatures [][]byte
requestedManifestMIMETypes []string
cachedSignatures [][]byte
}
// FromSource returns a types.Image implementation for source.
func FromSource(src types.ImageSource, requestedManifestMIMETypes []string) types.Image {
if len(requestedManifestMIMETypes) == 0 {
requestedManifestMIMETypes = []string{
manifest.OCIV1ImageManifestMIMEType,
manifest.DockerV2Schema2MIMEType,
manifest.DockerV2Schema1SignedMIMEType,
manifest.DockerV2Schema1MIMEType,
}
}
return &genericImage{src: src, requestedManifestMIMETypes: requestedManifestMIMETypes}
func FromSource(src types.ImageSource) types.Image {
return &genericImage{src: src}
}
// Reference returns the reference used to set up this source, _as specified by the user_
@ -60,7 +51,7 @@ func (i *genericImage) Reference() types.ImageReference {
// NOTE: It is essential for signature verification that Manifest returns the manifest from which BlobDigests is computed.
func (i *genericImage) Manifest() ([]byte, string, error) {
if i.cachedManifest == nil {
m, mt, err := i.src.GetManifest(i.requestedManifestMIMETypes)
m, mt, err := i.src.GetManifest()
if err != nil {
return nil, "", err
}
@ -299,15 +290,6 @@ func (i *genericImage) BlobDigests() ([]string, error) {
return uniqueBlobDigests(m), nil
}
func (i *genericImage) getLayer(dest types.ImageDestination, digest string) error {
stream, _, err := i.src.GetBlob(digest)
if err != nil {
return err
}
defer stream.Close()
return dest.PutBlob(digest, stream)
}
// fixManifestLayers, after validating the supplied manifest
// (to use correctly-formatted IDs, and to not have non-consecutive ID collisions in manifest.History),
// modifies manifest to only have one entry for each layer ID in manifest.History (deleting the older duplicates,

View File

@ -33,6 +33,15 @@ const (
OCIV1ImageSerializationConfigMIMEType = "application/vnd.oci.image.serialization.config.v1+json"
)
// DefaultRequestedManifestMIMETypes is a list of MIME types a types.ImageSource
// should request from the backend unless directed otherwise.
var DefaultRequestedManifestMIMETypes = []string{
OCIV1ImageManifestMIMEType,
DockerV2Schema2MIMEType,
DockerV2Schema1SignedMIMEType,
DockerV2Schema1MIMEType,
}
// GuessMIMEType guesses MIME type of a manifest and returns it _if it is recognized_, or "" if unknown or unrecognized.
// FIXME? We should, in general, prefer out-of-band MIME type instead of blindly parsing the manifest,
// but we may not have such metadata available (e.g. when the manifest is a local file).

View File

@ -165,20 +165,27 @@ func (ref ociReference) PolicyConfigurationNamespaces() []string {
}
// NewImage returns a types.Image for this reference.
func (ref ociReference) NewImage(certPath string, tlsVerify bool) (types.Image, error) {
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.
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) {
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")

View File

@ -54,6 +54,9 @@ func newOpenshiftClient(ref openshiftReference) (*openshiftClient, error) {
if *baseURL != *ref.baseURL {
return nil, fmt.Errorf("Unexpected baseURL mismatch: default %#v, reference %#v", *baseURL, *ref.baseURL)
}
if httpClient == nil {
httpClient = http.DefaultClient
}
httpClient.Timeout = 1 * time.Minute
return &openshiftClient{
@ -168,24 +171,26 @@ func (c *openshiftClient) dockerRegistryHostPart() string {
type openshiftImageSource struct {
client *openshiftClient
// Values specific to this image
certPath string // Only for parseDockerImageSource
tlsVerify bool // Only for parseDockerImageSource
ctx *types.SystemContext
requestedManifestMIMETypes []string
// State
docker types.ImageSource // The Docker Registry endpoint, or nil if not resolved yet
imageStreamImageName string // Resolved image identifier, or "" if not known yet
}
// newImageSource creates a new ImageSource for the specified reference and connection specification.
func newImageSource(ref openshiftReference, certPath string, tlsVerify bool) (types.ImageSource, error) {
// newImageSource creates a new ImageSource for the specified reference,
// asking the backend to use a manifest from requestedManifestMIMETypes if possible
// nil requestedManifestMIMETypes means manifest.DefaultRequestedManifestMIMETypes.
func newImageSource(ctx *types.SystemContext, ref openshiftReference, requestedManifestMIMETypes []string) (types.ImageSource, error) {
client, err := newOpenshiftClient(ref)
if err != nil {
return nil, err
}
return &openshiftImageSource{
client: client,
certPath: certPath,
tlsVerify: tlsVerify,
client: client,
ctx: ctx,
requestedManifestMIMETypes: requestedManifestMIMETypes,
}, nil
}
@ -195,11 +200,11 @@ func (s *openshiftImageSource) Reference() types.ImageReference {
return s.client.ref
}
func (s *openshiftImageSource) GetManifest(mimetypes []string) ([]byte, string, error) {
func (s *openshiftImageSource) GetManifest() ([]byte, string, error) {
if err := s.ensureImageIsResolved(); err != nil {
return nil, "", err
}
return s.docker.GetManifest(mimetypes)
return s.docker.GetManifest()
}
func (s *openshiftImageSource) GetBlob(digest string) (io.ReadCloser, int64, error) {
@ -267,7 +272,7 @@ func (s *openshiftImageSource) ensureImageIsResolved() error {
if err != nil {
return err
}
d, err := dockerRef.NewImageSource(s.certPath, s.tlsVerify)
d, err := dockerRef.NewImageSource(s.ctx, s.requestedManifestMIMETypes)
if err != nil {
return err
}
@ -283,8 +288,8 @@ type openshiftImageDestination struct {
imageStreamImageName string // "" if not yet known
}
// newImageDestination creates a new ImageDestination for the specified reference and connection specification.
func newImageDestination(ref openshiftReference, certPath string, tlsVerify bool) (types.ImageDestination, error) {
// newImageDestination creates a new ImageDestination for the specified reference.
func newImageDestination(ctx *types.SystemContext, ref openshiftReference) (types.ImageDestination, error) {
client, err := newOpenshiftClient(ref)
if err != nil {
return nil, err
@ -298,7 +303,7 @@ func newImageDestination(ref openshiftReference, certPath string, tlsVerify bool
if err != nil {
return nil, err
}
docker, err := dockerRef.NewImageDestination(certPath, tlsVerify)
docker, err := dockerRef.NewImageDestination(ctx)
if err != nil {
return nil, err
}
@ -512,7 +517,3 @@ type status struct {
// Details *StatusDetails `json:"details,omitempty"`
Code int32 `json:"code,omitempty"`
}
func (s *openshiftImageSource) Delete() error {
return fmt.Errorf("openshift#openshiftImageSource.Delete() not implmented")
}

View File

@ -154,16 +154,23 @@ func (ref openshiftReference) PolicyConfigurationNamespaces() []string {
}
// NewImage returns a types.Image for this reference.
func (ref openshiftReference) NewImage(certPath string, tlsVerify bool) (types.Image, error) {
func (ref openshiftReference) NewImage(ctx *types.SystemContext) (types.Image, error) {
return nil, errors.New("Full Image support not implemented for atomic: image names")
}
// NewImageSource returns a types.ImageSource for this reference.
func (ref openshiftReference) NewImageSource(certPath string, tlsVerify bool) (types.ImageSource, error) {
return newImageSource(ref, certPath, tlsVerify)
// NewImageSource returns a types.ImageSource for this reference,
// asking the backend to use a manifest from requestedManifestMIMETypes if possible
// nil requestedManifestMIMETypes means manifest.DefaultRequestedManifestMIMETypes.
func (ref openshiftReference) NewImageSource(ctx *types.SystemContext, requestedManifestMIMETypes []string) (types.ImageSource, error) {
return newImageSource(ctx, ref, requestedManifestMIMETypes)
}
// NewImageDestination returns a types.ImageDestination for this reference.
func (ref openshiftReference) NewImageDestination(certPath string, tlsVerify bool) (types.ImageDestination, error) {
return newImageDestination(ref, certPath, tlsVerify)
func (ref openshiftReference) NewImageDestination(ctx *types.SystemContext) (types.ImageDestination, error) {
return newImageDestination(ctx, ref)
}
// DeleteImage deletes the named image from the registry, if supported.
func (ref openshiftReference) DeleteImage(ctx *types.SystemContext) error {
return fmt.Errorf("Deleting images not implemented for atomic: images")
}

View File

@ -18,6 +18,7 @@ import (
"errors"
"fmt"
"io/ioutil"
"path/filepath"
"github.com/containers/image/transports"
"github.com/containers/image/types"
@ -54,8 +55,13 @@ func DefaultPolicy(ctx *types.SystemContext) (*Policy, error) {
// defaultPolicyPath returns a path to the default policy of the system.
func defaultPolicyPath(ctx *types.SystemContext) string {
if ctx != nil && ctx.SignaturePolicyPath != "" {
return ctx.SignaturePolicyPath
if ctx != nil {
if ctx.SignaturePolicyPath != "" {
return ctx.SignaturePolicyPath
}
if ctx.RootForImplicitAbsolutePaths != "" {
return filepath.Join(ctx.RootForImplicitAbsolutePaths, systemDefaultPolicyPath)
}
}
return systemDefaultPolicyPath
}

View File

@ -71,11 +71,16 @@ type ImageReference interface {
PolicyConfigurationNamespaces() []string
// NewImage returns a types.Image for this reference.
NewImage(certPath string, tlsVerify bool) (Image, error)
// NewImageSource returns a types.ImageSource for this reference.
NewImageSource(certPath string, tlsVerify bool) (ImageSource, error)
NewImage(ctx *SystemContext) (Image, 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.
NewImageSource(ctx *SystemContext, requestedManifestMIMETypes []string) (ImageSource, error)
// NewImageDestination returns a types.ImageDestination for this reference.
NewImageDestination(certPath string, tlsVerify bool) (ImageDestination, error)
NewImageDestination(ctx *SystemContext) (ImageDestination, error)
// DeleteImage deletes the named image from the registry, if supported.
DeleteImage(ctx *SystemContext) error
}
// ImageSource is a service, possibly remote (= slow), to download components of a single image.
@ -85,16 +90,14 @@ type ImageSource interface {
// Reference returns the reference used to set up this source, _as specified by the user_
// (not as the image itself, or its underlying storage, claims). This can be used e.g. to determine which public keys are trusted for this image.
Reference() ImageReference
// GetManifest returns the image's manifest along with its MIME type. The empty string is returned if the MIME type is unknown. The slice parameter indicates the supported mime types the manifest should be when getting it.
// GetManifest returns the image's manifest along with its MIME type. The empty string is returned if the MIME type is unknown.
// It may use a remote (= slow) service.
GetManifest([]string) ([]byte, string, error)
GetManifest() ([]byte, string, error)
// Note: Calling GetBlob() may have ordering dependencies WRT other methods of this type. FIXME: How does this work with (docker save) on stdin?
// the second return value is the size of the blob. If not known 0 is returned
GetBlob(digest string) (io.ReadCloser, int64, error)
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
GetSignatures() ([][]byte, error)
// Delete image from registry, if operation is supported
Delete() error
}
// ImageDestination is a service, possibly remote (= slow), to store components of a single image.
@ -154,5 +157,17 @@ type ImageInspectInfo struct {
// the same; if in doubt, add a new field.
// It is always OK to pass nil instead of a SystemContext.
type SystemContext struct {
SignaturePolicyPath string // If not "", overrides the system's default path for signature.Policy configuration.
// If not "", prefixed to any absolute paths used by default by the library (e.g. in /etc/).
// Not used for any of the more specific path overrides available in this struct.
// Not used for any paths specified by users in config files (even if the location of the config file _was_ affected by it).
// NOTE: This does NOT affect paths starting by $HOME.
RootForImplicitAbsolutePaths string
// === Global configuration overrides ===
// If not "", overrides the system's default path for signature.Policy configuration.
SignaturePolicyPath string
// === docker.Transport overrides ===
DockerCertPath string // If not "", a directory containing "cert.pem" and "key.pem" used when talking to a Docker Registry
DockerInsecureSkipTLSVerify bool
}