profile
viewpoint

containers/libpod 4015

libpod is a library used to create container pods. Home of Podman.

containers/buildah 2714

A tool that facilitates building OCI images

containers/skopeo 1920

Work with remote images registries - retrieving information, images, signing content

mtrmac/api 0

Canonical location of the OpenShift API definition.

mtrmac/atomic 0

Atomic Run Tool for installing/running/managing container images.

mtrmac/atomic-enterprise-training 0

Atomic Enterprise Training

mtrmac/buildah 0

A tool that facilitates building OCI images

mtrmac/builder 0

The image run by build pods to execute image building+pushing

mtrmac/cli 0

A simple, fast, and fun package for building command line apps in Go

pull request commentcontainers/image

Add client support for opencontainers/distribution-spec

Maybe one way to think about this: what’s the end-user use case / mechanism? So far, it seems to be possible to support Docker schema1+schema2 + OCI with a single syntax, single workflow, single transport, single set of mostly consistent features, mostly automatically doing the right thing (there are definitely a few cases where the code doesn’t detect limited-capability registries, even if it should be technically possible, and users have to explicitly choose a manifest format — but none of them are fundamentally impossible to fix, AFAIK).

If there are two different transports, how do users interact with this? Are they completely interchangeable? If users use CLIs that deemphasize the transport: syntax (like podman pull/podman push), or outright don’t support it, which transport is used? For direct users of the transport: syntax (e.g. users of skopeo copy), when should they switch to the OCI transport, and what is the benefit they get for that work?

Starting with a protocol implementation without being clear on how the software is going to be used seems backwards to me. Users, ultimately, care very little about specifications, specification names, and fairly little about conformance of any particular implementation to any particular standard — working UIs that don’t get in the way so often trump all that.

rchincha

comment created time in 3 hours

Pull request review commentcontainers/libpod

Refactor image tree for API usage

+package image

Definitely don’t wait for me, I’m still mostly in learning phase, and I can adjust for whatever happens here.

(Jumping into what I’m sure was a well-considered decision, I’d instinctively prefer to primarily have a well-typed API that returns the structure, and keep the text formatter in the CLI (allowing, at least in principle, a nice GUI to be built on top, for example). OTOH, I guess that exposing the complete tree structure over Varlink/whatever would be a lot of work and pain — and for no benefit at least now that the only consumer is the CLI.)

saschagrunert

comment created time in 4 hours

pull request commentcontainers/image

Add client support for opencontainers/distribution-spec

For reference, some previous conversation about the c/image/docker client vs. OCI spec compliance: https://github.com/containers/image/pull/527 .

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080+	err = nil++	if ref[0] == '/' {+		fullname = ref[1:]+		return fullname, "", port, nil+	}++	fields := strings.SplitN(ref, "/", 2)+	subFields := strings.Split(fields[0], ":")++	if len(subFields) > 2 {+		err = fmt.Errorf("bad server:port")+		return "", "", -1, err+	}++	server = subFields[0]++	if len(subFields) == 2 {+		port, err = strconv.Atoi(subFields[1])+		if err != nil {+			return "", "", -1, err+		}++		if port < 1 || port > 65535 {+			err = fmt.Errorf("bad port %d", port)+			return "", "", -1, err+		}+	}++	fullname = fields[1]++	return fullname, server, port, nil+}++// NOTE - the transport interface is defined in types/types.go.+// Valid uris are:+//    dist:///name1/name2/tag+//    dist://server/name1/name2/name3/tag+// The tag can be separated by either / or :+//    dist://server:port/name1/name2/name3/tag+//    dist://server:port/name1/name2/name3:tag+// So the reference passed in here would be e.g.+//    ///name1/name2/tag+//    //server:port/name1/name2/tag+func (s distTransport) ParseReference(reference string) (types.ImageReference, error) {+	if !strings.HasPrefix(reference, "//") {+		return nil, errors.Errorf("dist image reference %s does not start with //", reference)+	}++	fullname, server, port, err := splitReference(reference[2:])+	if err != nil {+		return nil, errors.Wrapf(err, "Failed parsing reference: '%s'", reference)+	}++	// support : for tag separateion+	var name, tag string++	fields := strings.Split(fullname, ":")++	if len(fields) != 2 || len(fields[0]) == 0 || len(fields[1]) == 0 {+		return nil, fmt.Errorf("no tag specified in '%s'", fullname)+	}++	name = fields[0]+	tag = fields[1]++	return distReference{+		server:   server,+		port:     port,+		fullname: fullname,+		name:     name,+		tag:      tag,+	}, nil+}++func (s distTransport) ValidatePolicyConfigurationScope(scope string) error {+	return nil+}++type distReference struct {+	server   string+	port     int+	fullname string+	name     string+	tag      string+}++func (ref distReference) Transport() types.ImageTransport {+	return Transport+}++func (ref distReference) StringWithinTransport() string {+	port := ""++	if ref.port != -1 {+		port = fmt.Sprintf("%d/", ref.port)+	}++	return fmt.Sprintf("//%s:%s%s", ref.server, port, ref.fullname)+}++func (ref distReference) DockerReference() reference.Named {+	return nil+}++func (ref distReference) PolicyConfigurationIdentity() string {+	return ref.StringWithinTransport()

PolicyConfigurationIdentity is supposed to be canonical, i.e. adjust for the defaulted server/port values.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

 github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=+github.com/containers/image v3.0.2+incompatible h1:B1lqAE8MUPCrsBLE86J0gnXleeRq8zJnQryhiiGQNyE=

Please drop this, to make sure the non-v5 imports never get in.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"

I suppose we will need bike-shedding over this :)

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080+	err = nil++	if ref[0] == '/' {+		fullname = ref[1:]+		return fullname, "", port, nil+	}++	fields := strings.SplitN(ref, "/", 2)+	subFields := strings.Split(fields[0], ":")++	if len(subFields) > 2 {+		err = fmt.Errorf("bad server:port")+		return "", "", -1, err+	}++	server = subFields[0]++	if len(subFields) == 2 {+		port, err = strconv.Atoi(subFields[1])+		if err != nil {+			return "", "", -1, err+		}++		if port < 1 || port > 65535 {+			err = fmt.Errorf("bad port %d", port)+			return "", "", -1, err+		}+	}++	fullname = fields[1]++	return fullname, server, port, nil+}++// NOTE - the transport interface is defined in types/types.go.+// Valid uris are:+//    dist:///name1/name2/tag+//    dist://server/name1/name2/name3/tag+// The tag can be separated by either / or :+//    dist://server:port/name1/name2/name3/tag+//    dist://server:port/name1/name2/name3:tag+// So the reference passed in here would be e.g.+//    ///name1/name2/tag+//    //server:port/name1/name2/tag+func (s distTransport) ParseReference(reference string) (types.ImageReference, error) {+	if !strings.HasPrefix(reference, "//") {+		return nil, errors.Errorf("dist image reference %s does not start with //", reference)+	}++	fullname, server, port, err := splitReference(reference[2:])+	if err != nil {+		return nil, errors.Wrapf(err, "Failed parsing reference: '%s'", reference)+	}++	// support : for tag separateion+	var name, tag string++	fields := strings.Split(fullname, ":")++	if len(fields) != 2 || len(fields[0]) == 0 || len(fields[1]) == 0 {

So, :tag is mandatory, and the /tag syntax is invalid, after all?

No :latest default? (I could well live with this decision, but it’s an important and I imagine controversial one.)

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080+	err = nil++	if ref[0] == '/' {+		fullname = ref[1:]+		return fullname, "", port, nil+	}++	fields := strings.SplitN(ref, "/", 2)+	subFields := strings.Split(fields[0], ":")++	if len(subFields) > 2 {+		err = fmt.Errorf("bad server:port")+		return "", "", -1, err+	}++	server = subFields[0]++	if len(subFields) == 2 {+		port, err = strconv.Atoi(subFields[1])+		if err != nil {+			return "", "", -1, err+		}++		if port < 1 || port > 65535 {+			err = fmt.Errorf("bad port %d", port)+			return "", "", -1, err+		}+	}++	fullname = fields[1]++	return fullname, server, port, nil+}++// NOTE - the transport interface is defined in types/types.go.+// Valid uris are:+//    dist:///name1/name2/tag+//    dist://server/name1/name2/name3/tag+// The tag can be separated by either / or :+//    dist://server:port/name1/name2/name3/tag+//    dist://server:port/name1/name2/name3:tag+// So the reference passed in here would be e.g.+//    ///name1/name2/tag+//    //server:port/name1/name2/tag
  • Overwhelming experience with the Docker references is that it is way too attractive to create them using Sprintf, and parse them using strings.Split, which almost always handles corner cases incorrectly. If this defines a new reference type of similar importance, it seems very necessary to provide a Go package that does all the parsing, validation and formatting for users, so that users at least have a chance to use something safer. I.e. I feel that something similar to {docker/distribution,containers/image}/docker/reference is absolutely necessary.
  • The // part is pointless visual noise. The values are not URLs (notably no URL escaping), it only leads to extra typing and confused users.
  • Why allow the /tag vs. :tag ambiguity? What’s the end-user benefit?
  • Are digest references not supported? Or does “tag” somehow include digests without documentation?
rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080+	err = nil++	if ref[0] == '/' {+		fullname = ref[1:]+		return fullname, "", port, nil+	}++	fields := strings.SplitN(ref, "/", 2)+	subFields := strings.Split(fields[0], ":")++	if len(subFields) > 2 {+		err = fmt.Errorf("bad server:port")+		return "", "", -1, err+	}++	server = subFields[0]++	if len(subFields) == 2 {+		port, err = strconv.Atoi(subFields[1])+		if err != nil {+			return "", "", -1, err+		}++		if port < 1 || port > 65535 {+			err = fmt.Errorf("bad port %d", port)+			return "", "", -1, err+		}+	}++	fullname = fields[1]++	return fullname, server, port, nil+}++// NOTE - the transport interface is defined in types/types.go.+// Valid uris are:+//    dist:///name1/name2/tag+//    dist://server/name1/name2/name3/tag+// The tag can be separated by either / or :+//    dist://server:port/name1/name2/name3/tag+//    dist://server:port/name1/name2/name3:tag+// So the reference passed in here would be e.g.+//    ///name1/name2/tag+//    //server:port/name1/name2/tag+func (s distTransport) ParseReference(reference string) (types.ImageReference, error) {+	if !strings.HasPrefix(reference, "//") {+		return nil, errors.Errorf("dist image reference %s does not start with //", reference)+	}++	fullname, server, port, err := splitReference(reference[2:])+	if err != nil {+		return nil, errors.Wrapf(err, "Failed parsing reference: '%s'", reference)+	}++	// support : for tag separateion+	var name, tag string++	fields := strings.Split(fullname, ":")++	if len(fields) != 2 || len(fields[0]) == 0 || len(fields[1]) == 0 {+		return nil, fmt.Errorf("no tag specified in '%s'", fullname)+	}++	name = fields[0]+	tag = fields[1]++	return distReference{+		server:   server,+		port:     port,+		fullname: fullname,+		name:     name,+		tag:      tag,+	}, nil+}++func (s distTransport) ValidatePolicyConfigurationScope(scope string) error {+	return nil+}++type distReference struct {+	server   string+	port     int+	fullname string+	name     string+	tag      string+}++func (ref distReference) Transport() types.ImageTransport {+	return Transport+}++func (ref distReference) StringWithinTransport() string {+	port := ""++	if ref.port != -1 {+		port = fmt.Sprintf("%d/", ref.port)+	}++	return fmt.Sprintf("//%s:%s%s", ref.server, port, ref.fullname)+}++func (ref distReference) DockerReference() reference.Named {+	return nil

Why? The references, AFAIK, use exactly the same namespace, and are pretty much 100% interoperable, and the DockerReference value is important for signing and for naming images in local storage (e.g. so that podman pull tags the result with the location of the image on the registry).

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080+	err = nil++	if ref[0] == '/' {+		fullname = ref[1:]+		return fullname, "", port, nil+	}++	fields := strings.SplitN(ref, "/", 2)+	subFields := strings.Split(fields[0], ":")++	if len(subFields) > 2 {+		err = fmt.Errorf("bad server:port")+		return "", "", -1, err+	}++	server = subFields[0]++	if len(subFields) == 2 {+		port, err = strconv.Atoi(subFields[1])+		if err != nil {+			return "", "", -1, err+		}++		if port < 1 || port > 65535 {+			err = fmt.Errorf("bad port %d", port)+			return "", "", -1, err+		}+	}++	fullname = fields[1]++	return fullname, server, port, nil+}++// NOTE - the transport interface is defined in types/types.go.+// Valid uris are:+//    dist:///name1/name2/tag+//    dist://server/name1/name2/name3/tag+// The tag can be separated by either / or :+//    dist://server:port/name1/name2/name3/tag+//    dist://server:port/name1/name2/name3:tag+// So the reference passed in here would be e.g.+//    ///name1/name2/tag+//    //server:port/name1/name2/tag+func (s distTransport) ParseReference(reference string) (types.ImageReference, error) {+	if !strings.HasPrefix(reference, "//") {+		return nil, errors.Errorf("dist image reference %s does not start with //", reference)+	}++	fullname, server, port, err := splitReference(reference[2:])+	if err != nil {+		return nil, errors.Wrapf(err, "Failed parsing reference: '%s'", reference)+	}++	// support : for tag separateion+	var name, tag string++	fields := strings.Split(fullname, ":")++	if len(fields) != 2 || len(fields[0]) == 0 || len(fields[1]) == 0 {+		return nil, fmt.Errorf("no tag specified in '%s'", fullname)+	}++	name = fields[0]+	tag = fields[1]++	return distReference{+		server:   server,+		port:     port,+		fullname: fullname,+		name:     name,+		tag:      tag,+	}, nil+}++func (s distTransport) ValidatePolicyConfigurationScope(scope string) error {+	return nil+}++type distReference struct {+	server   string+	port     int+	fullname string+	name     string+	tag      string+}++func (ref distReference) Transport() types.ImageTransport {+	return Transport+}++func (ref distReference) StringWithinTransport() string {+	port := ""++	if ref.port != -1 {+		port = fmt.Sprintf("%d/", ref.port)

This does not look right; .port == -1 will result in "//server:fullname".

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080+	err = nil++	if ref[0] == '/' {+		fullname = ref[1:]+		return fullname, "", port, nil+	}++	fields := strings.SplitN(ref, "/", 2)+	subFields := strings.Split(fields[0], ":")++	if len(subFields) > 2 {+		err = fmt.Errorf("bad server:port")+		return "", "", -1, err+	}++	server = subFields[0]++	if len(subFields) == 2 {+		port, err = strconv.Atoi(subFields[1])+		if err != nil {+			return "", "", -1, err+		}++		if port < 1 || port > 65535 {+			err = fmt.Errorf("bad port %d", port)+			return "", "", -1, err+		}+	}++	fullname = fields[1]++	return fullname, server, port, nil+}++// NOTE - the transport interface is defined in types/types.go.+// Valid uris are:+//    dist:///name1/name2/tag+//    dist://server/name1/name2/name3/tag+// The tag can be separated by either / or :+//    dist://server:port/name1/name2/name3/tag+//    dist://server:port/name1/name2/name3:tag+// So the reference passed in here would be e.g.+//    ///name1/name2/tag+//    //server:port/name1/name2/tag+func (s distTransport) ParseReference(reference string) (types.ImageReference, error) {+	if !strings.HasPrefix(reference, "//") {+		return nil, errors.Errorf("dist image reference %s does not start with //", reference)+	}++	fullname, server, port, err := splitReference(reference[2:])+	if err != nil {+		return nil, errors.Wrapf(err, "Failed parsing reference: '%s'", reference)+	}++	// support : for tag separateion+	var name, tag string++	fields := strings.Split(fullname, ":")++	if len(fields) != 2 || len(fields[0]) == 0 || len(fields[1]) == 0 {+		return nil, fmt.Errorf("no tag specified in '%s'", fullname)+	}++	name = fields[0]+	tag = fields[1]++	return distReference{

At no point are contents of the fields validated in any substantial way, except for the one or two separators implicitly used when splitting the input string.

E.g. this allows the user to specify ?, %, or any other URL metacharacters, and they will be silently accepted and injected into URLs. That’s not completely impossible (garbage-in/garbage-out), but it makes the system susceptible to unnecessary risks. Given any kind of untrusted input, something should validate it and reject unwanted data, and it’s all too easy for every part of the chain to imagine that it’s someone else’s problem.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"fmt"+	"strconv"+	"strings"++	"github.com/containers/image/v5/docker/reference"+	"github.com/containers/image/v5/image"+	"github.com/containers/image/v5/transports"+	"github.com/containers/image/v5/types"+	"github.com/pkg/errors"+)++//nolint (gochecknoinits)+func init() {+	transports.Register(Transport)+}++// nolint (gochecknoglobals)+var Transport = distTransport{}++type distTransport struct{}++func (s distTransport) Name() string {+	return "dist"+}++func splitReference(ref string) (fullname, server string, port int, err error) {+	port = 8080

This value should be hard-coded in exactly one place, and in a top-level constant, not both here and in NewOciRepo.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist

Because naming has extremely important impact on security, and because it’s so easy to miss cases when parsing ambiguous strings, we typically require close to 100% unit test code coverage for the ImageTransport and ImageReference implementations.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"io"++	"github.com/containers/image/v5/pkg/blobinfocache/none"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"+	"github.com/pkg/errors"+)++// NOTE - the ImageDestination interface is defined in types.go++type distImageDest struct {+	s   *OciRepo+	ref distReference+}++func (o *distImageDest) Reference() types.ImageReference {+	return o.ref+}++func (o *distImageDest) Close() error {+	return nil+}++func (o *distImageDest) SupportedManifestMIMETypes() []string {+	return []string{+		ispec.MediaTypeImageManifest,+	}+}++func (o *distImageDest) SupportsSignatures(ctx context.Context) error {+	return nil+}++func (o *distImageDest) DesiredLayerCompression() types.LayerCompression {+	return types.PreserveOriginal+}++func (o *distImageDest) AcceptsForeignLayerURLs() bool {+	return true+}++func (o *distImageDest) MustMatchRuntimeOS() bool {+	return false+}++func (o *distImageDest) IgnoresEmbeddedDockerReference() bool {+	// Return value does not make a difference if Reference().DockerReference()+	// is nil.+	return true+}++// PutBlob writes contents of stream and returns data representing the result.+// inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it.+// inputInfo.Size is the expected length of stream, if known.+// inputInfo.MediaType describes the blob format, if known.+// May update cache.+// 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 (o *distImageDest) PutBlob(ctx context.Context, stream io.Reader,+	inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) {+	if inputInfo.Digest.String() != "" {+		ok, info, err := o.TryReusingBlob(ctx, inputInfo, none.NoCache, false)+		if err != nil {+			return types.BlobInfo{}, err+		}++		if ok {+			return info, nil+		}+	}++	// Do this as a chunked upload so we can calculate the digest, since+	// caller is not giving it to us.+	u, err := o.s.StartLayer()++	if err != nil {+		return types.BlobInfo{}, err+	}++	digest, size, err := o.s.CompleteLayer(u, stream)++	return types.BlobInfo{Digest: digest, Size: size}, err+}++// HasThreadSafePutBlob indicates whether PutBlob can be executed concurrently.+func (o *distImageDest) HasThreadSafePutBlob() bool {+	return true+}++func (o *distImageDest) TryReusingBlob(ctx context.Context, info types.BlobInfo,+	cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) {+	if info.Digest == "" {+		return false, types.BlobInfo{}, errors.Errorf(`"Can not check for a blob with unknown digest`)+	}++	if o.s.HasLayer(info.Digest.String()) {+		return true, types.BlobInfo{Digest: info.Digest, Size: -1}, nil+	}++	return false, types.BlobInfo{}, nil+}++func (o *distImageDest) PutManifest(ctx context.Context, m []byte, d *digest.Digest) error {+	return o.s.PutManifest(m)+}++func (o *distImageDest) PutSignatures(ctx context.Context, signatures [][]byte, d *digest.Digest) error {+	return nil

This should explicitly fail instead of silently ignoring data if len(signatures) != 0.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))+		} else {+			registry := fmt.Sprintf("%s:%s", server, port)+			if username, password, err := config.GetAuthentication(sys, registry); err == nil {+				creds = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))+			}+		}+	}++	r = OciRepo{ref: ref, authCreds: creds, client: client}++	ping := func(scheme string) error {+		u := url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port), Path: fmt.Sprintf("/v2/")}+		resp, err := client.Get(u.String())+		if err != nil {+			return err+		}+		defer resp.Body.Close()+		if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {+			return errors.Errorf("Error pinging registry %s:%s, response code %d (%s)",+				server, port, resp.StatusCode, http.StatusText(resp.StatusCode))+		}+		return nil+	}++	scheme := "https"+	err = ping(scheme)+	if err != nil && insecureSkipVerify {+		scheme = "http"+		err = ping(scheme)+	}+	if err != nil {+		return r, errors.Wrap(err, "unable to ping registry")+	}++	r.url = url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port)}+	return r, nil+}++func (o *OciRepo) GetManifest() ([]byte, *ispec.Manifest, error) {+	name := o.ref.name+	tag := o.ref.tag+	m := &ispec.Manifest{}++	var body []byte++	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))+	if err != nil {+		return body, m, errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodGet, manifestURI.String(), nil)++	if err != nil {+		return body, m, errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Add("Accept", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return body, m, errors.Wrapf(err, "Error getting manifest %s %s from %v", name, tag, o.url)+	}+	defer resp.Body.Close()++	if resp.StatusCode != http.StatusOK {+		return body, m, fmt.Errorf("bad return code %d getting manifest", resp.StatusCode)+	}++	body, err = ioutil.ReadAll(resp.Body)+	if err != nil {+		return body, m, errors.Wrapf(err, "Error reading response body for %s", tag)+	}++	err = json.Unmarshal(body, m)++	if err != nil {+		return body, m, errors.Wrap(err, "Failed decoding response")+	}++	return body, m, nil+}++func (o *OciRepo) RemoveManifest() error {+	name := o.ref.name+	tag := o.ref.tag+	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))++	if err != nil {+		return errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodDelete, manifestURI.String(), nil)++	if err != nil {+		return errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)+	if err != nil {+		return errors.Wrapf(err, "Error deleting manifest")+	}++	if resp.StatusCode != http.StatusAccepted {+		return fmt.Errorf("server returned unexpected code %d", resp.StatusCode)+	}++	defer resp.Body.Close()++	return nil+}++func (o *OciRepo) PutManifest(body []byte) error {+	name := o.ref.name+	tag := o.ref.tag+	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))++	if err != nil {+		return errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodPut, manifestURI.String(), bytes.NewReader(body))++	if err != nil {+		return errors.Wrapf(err, "Couldn't create PUT request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Set("Content-Type", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return errors.Wrapf(err, "Error posting manifest")+	}++	if resp.StatusCode != http.StatusCreated {+		return fmt.Errorf("server returned unexpected code %d", resp.StatusCode)+	}++	defer resp.Body.Close()++	return nil+}++//HEAD /v2/<name>/blobs/<digest>  -> 200 (has layer)+func (o *OciRepo) HasLayer(ldigest string) bool {+	name := o.ref.name+	blobURI, err := url.Parse(fmt.Sprintf("/v2/%s/blobs/%s", name, ldigest))++	if err != nil {+		return false+	}++	blobURI = o.url.ResolveReference(blobURI)+	req, err := http.NewRequest(http.MethodHead, blobURI.String(), nil)++	if err != nil {+		return false+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)++	if err != nil {+		return false+	}++	defer resp.Body.Close()++	return resp.StatusCode == http.StatusOK+}++func (o *OciRepo) GetLayer(ldigest string) (io.ReadCloser, int64, error) {+	name := o.ref.name+	blobURI, err := url.Parse(fmt.Sprintf("/v2/%s/blobs/%s", name, ldigest))++	if err != nil {+		return nil, -1, errors.Wrapf(err, "couldn't parse URL for repo %s blob %s", name, ldigest)+	}++	blobURI = o.url.ResolveReference(blobURI)+	req, err := http.NewRequest("GET", blobURI.String(), nil)++	if err != nil {+		return nil, -1, errors.Wrapf(err, "Couldn't create GET request for %v", blobURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)++	if err != nil {+		return nil, -1, errors.Wrapf(err, "Error getting layer %s", ldigest)+	}++	if resp.StatusCode != http.StatusOK {+		resp.Body.Close()+		return nil, -1, fmt.Errorf("bad return code %d getting layer", resp.StatusCode)+	}++	return resp.Body, -1, err+}++// StartLayer starts a blob upload session+func (o *OciRepo) StartLayer() (*url.URL, error) {+	name := o.ref.name+	uploadURI, err := url.Parse(fmt.Sprintf("/v2/%s/blobs/uploads/", name))++	if err != nil {+		return nil, errors.Wrap(err, "Failed to parse upload URL")+	}++	uploadURI = o.url.ResolveReference(uploadURI)+	req, err := http.NewRequest("POST", uploadURI.String(), nil)++	if err != nil {+		return nil, errors.Wrap(err, "Failed opening POST request")+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)++	if err != nil {+		return nil, errors.Wrapf(err, "Failed posting request %v", req)+	}++	defer resp.Body.Close()++	if resp.StatusCode != http.StatusAccepted {+		return nil, fmt.Errorf("server returned an error %d", resp.StatusCode)+	}++	_, err = ioutil.ReadAll(resp.Body)++	if err != nil {+		return nil, errors.Wrapf(err, "Error reading response body for %s", name)+	}++	session, err := resp.Location()++	if err != nil {+		return nil, errors.Wrap(err, "Failed decoding response")+	}++	return o.url.ResolveReference(session), nil+}++// @path is the uuid upload path returned by the server to our Post request.+// @stream is the data source for the layer.+// Return the digest and size of the layer that was uploaded.+//nolint (gocognit)+func (o *OciRepo) CompleteLayer(session *url.URL, stream io.Reader) (digest.Digest, int64, error) {+	digester := sha256.New()+	hashReader := io.TeeReader(stream, digester)+	// using "chunked" upload+	count := int64(0)+	for {+		const maxSize = 10 * 1024 * 1024+		var buf bytes.Buffer+		size, err := io.CopyN(&buf, hashReader, maxSize)+		if size == 0 {+			if err != io.EOF {+				return "", -1, errors.Wrapf(err, "Failed to copy stream")+			}+			break+		}+		req, err := http.NewRequest(http.MethodPatch, session.String(), &buf)+		if err != nil {+			return "", -1, errors.Wrap(err, "Failed opening Patch request")+		}+		if o.authCreds != "" {+			req.Header.Add("Authorization", "Basic "+o.authCreds)+		}++		req.ContentLength = size+		req.Header.Set("Content-Type", "application/octet-stream")+		req.Header.Set("Content-Range", fmt.Sprintf("%d-%d", count, count+size-1))+		resp, err := o.client.Do(req)+		if err != nil {+			return "", -1, errors.Wrapf(err, "Failed posting request %v", req)+		}+		defer resp.Body.Close()+		if resp.StatusCode != http.StatusAccepted {+			return "", -1, fmt.Errorf("Server returned an error %d", resp.StatusCode)+		}+		count += size+		session, err = resp.Location()+		if err != nil {+			return "", -1, errors.Wrap(err, "Failed decoding response")+		}++		session = o.url.ResolveReference(session)+	}++	ourDigest := fmt.Sprintf("%x", digester.Sum(nil))+	d := digest.NewDigestFromEncoded(digest.SHA256, ourDigest)+	q := session.Query()+	q.Set("digest", d.String())+	session.RawQuery = q.Encode()+	req, err := http.NewRequest(http.MethodPut, session.String(), nil)+	if err != nil {+		return "", -1, errors.Wrap(err, "Failed opening Put request")+	}+	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}+	req.Header.Set("Content-Type", "application/octet-stream")+	putResp, err := o.client.Do(req)+	if err != nil {+		return "", -1, errors.Wrapf(err, "Failed putting request %v", req)+	}+	defer putResp.Body.Close()+	if putResp.StatusCode != http.StatusCreated {+		return "", -1, fmt.Errorf("Server returned an error %d", putResp.StatusCode)+	}++	servDigest, ok := putResp.Header["Docker-Content-Digest"]+	if !ok || len(servDigest) != 1 {+		return "", -1, fmt.Errorf("Server returned incomplete headers")+	}++	blobLoc, err := putResp.Location()+	if err != nil {+		return "", -1, errors.Wrap(err, "Failed decoding response")+	}++	blobLoc = o.url.ResolveReference(blobLoc)+	req, err = http.NewRequest("HEAD", blobLoc.String(), nil)+	if err != nil {+		return "", -1, errors.Wrap(err, "Failed opening Head request")+	}+	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}+	resp, err := o.client.Do(req)+	if err != nil {+		return "", -1, errors.Wrapf(err, "Failed getting new layer %v", blobLoc)+	}++	Length, ok := resp.Header["Content-Length"]+	if !ok || len(Length) != 1 {+		return "", -1, fmt.Errorf("Server returned incomplete headers")+	}+	length, err := strconv.ParseInt(Length[0], 10, 64)+	if err != nil {+		return "", -1, errors.Wrap(err, "Failed decoding length in response")+	}++	if servDigest[0] != d.String() {+		return "", -1, errors.Wrapf(err, "Server calculated digest %s, not our %s", servDigest[0], ourDigest)+	}++	// TODO dist is returning the wrong thing - the hash,+	// not the "digest", which is "sha256:hash"++	return d, length, nil+}++// ociCertDir returns a path to a directory to be consumed by+// tlsclientconfig.SetupCertificates() depending on ctx and hostPort.+func ociCertDir(sys *types.SystemContext, hostPort string) (string, error) {+	if sys != nil && sys.DockerCertPath != "" {+		return sys.DockerCertPath, nil+	}++	if sys != nil && sys.DockerPerHostCertDirPath != "" {

Using the Docker* configuration options does not quite look good, especially not without any documentation about that effect.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"io"++	"github.com/containers/image/v5/pkg/blobinfocache/none"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"+	"github.com/pkg/errors"+)++// NOTE - the ImageDestination interface is defined in types.go++type distImageDest struct {+	s   *OciRepo+	ref distReference+}++func (o *distImageDest) Reference() types.ImageReference {+	return o.ref+}++func (o *distImageDest) Close() error {+	return nil+}++func (o *distImageDest) SupportedManifestMIMETypes() []string {+	return []string{+		ispec.MediaTypeImageManifest,

No OCI indices = no multi-arch support?!

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"context"+	"io"++	"github.com/containers/image/v5/pkg/blobinfocache/none"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"+	"github.com/pkg/errors"+)++// NOTE - the ImageDestination interface is defined in types.go++type distImageDest struct {+	s   *OciRepo+	ref distReference+}++func (o *distImageDest) Reference() types.ImageReference {+	return o.ref+}++func (o *distImageDest) Close() error {+	return nil+}++func (o *distImageDest) SupportedManifestMIMETypes() []string {+	return []string{+		ispec.MediaTypeImageManifest,+	}+}++func (o *distImageDest) SupportsSignatures(ctx context.Context) error {+	return nil+}++func (o *distImageDest) DesiredLayerCompression() types.LayerCompression {+	return types.PreserveOriginal+}++func (o *distImageDest) AcceptsForeignLayerURLs() bool {+	return true+}++func (o *distImageDest) MustMatchRuntimeOS() bool {+	return false+}++func (o *distImageDest) IgnoresEmbeddedDockerReference() bool {+	// Return value does not make a difference if Reference().DockerReference()+	// is nil.+	return true+}++// PutBlob writes contents of stream and returns data representing the result.+// inputInfo.Digest can be optionally provided if known; it is not mandatory for the implementation to verify it.+// inputInfo.Size is the expected length of stream, if known.+// inputInfo.MediaType describes the blob format, if known.+// May update cache.+// 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 (o *distImageDest) PutBlob(ctx context.Context, stream io.Reader,+	inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) {+	if inputInfo.Digest.String() != "" {+		ok, info, err := o.TryReusingBlob(ctx, inputInfo, none.NoCache, false)+		if err != nil {+			return types.BlobInfo{}, err+		}++		if ok {+			return info, nil+		}+	}++	// Do this as a chunked upload so we can calculate the digest, since+	// caller is not giving it to us.+	u, err := o.s.StartLayer()++	if err != nil {+		return types.BlobInfo{}, err+	}++	digest, size, err := o.s.CompleteLayer(u, stream)++	return types.BlobInfo{Digest: digest, Size: size}, err+}++// HasThreadSafePutBlob indicates whether PutBlob can be executed concurrently.+func (o *distImageDest) HasThreadSafePutBlob() bool {+	return true+}++func (o *distImageDest) TryReusingBlob(ctx context.Context, info types.BlobInfo,+	cache types.BlobInfoCache, canSubstitute bool) (bool, types.BlobInfo, error) {+	if info.Digest == "" {+		return false, types.BlobInfo{}, errors.Errorf(`"Can not check for a blob with unknown digest`)+	}++	if o.s.HasLayer(info.Digest.String()) {+		return true, types.BlobInfo{Digest: info.Digest, Size: -1}, nil

Size is required to be set in this case. (See why the function documentation from types.go is redundantly copy&pasted, and laboriously updated everywhere on any change, in all implementations?)

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))+		} else {+			registry := fmt.Sprintf("%s:%s", server, port)+			if username, password, err := config.GetAuthentication(sys, registry); err == nil {+				creds = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))+			}+		}+	}++	r = OciRepo{ref: ref, authCreds: creds, client: client}++	ping := func(scheme string) error {+		u := url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port), Path: fmt.Sprintf("/v2/")}+		resp, err := client.Get(u.String())+		if err != nil {+			return err+		}+		defer resp.Body.Close()+		if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {+			return errors.Errorf("Error pinging registry %s:%s, response code %d (%s)",+				server, port, resp.StatusCode, http.StatusText(resp.StatusCode))+		}+		return nil+	}++	scheme := "https"+	err = ping(scheme)+	if err != nil && insecureSkipVerify {+		scheme = "http"+		err = ping(scheme)+	}+	if err != nil {+		return r, errors.Wrap(err, "unable to ping registry")+	}++	r.url = url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port)}+	return r, nil+}++func (o *OciRepo) GetManifest() ([]byte, *ispec.Manifest, error) {+	name := o.ref.name+	tag := o.ref.tag+	m := &ispec.Manifest{}++	var body []byte++	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))+	if err != nil {+		return body, m, errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodGet, manifestURI.String(), nil)++	if err != nil {+		return body, m, errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Add("Accept", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return body, m, errors.Wrapf(err, "Error getting manifest %s %s from %v", name, tag, o.url)+	}+	defer resp.Body.Close()++	if resp.StatusCode != http.StatusOK {+		return body, m, fmt.Errorf("bad return code %d getting manifest", resp.StatusCode)+	}++	body, err = ioutil.ReadAll(resp.Body)+	if err != nil {+		return body, m, errors.Wrapf(err, "Error reading response body for %s", tag)+	}++	err = json.Unmarshal(body, m)++	if err != nil {+		return body, m, errors.Wrap(err, "Failed decoding response")+	}++	return body, m, nil+}++func (o *OciRepo) RemoveManifest() error {+	name := o.ref.name+	tag := o.ref.tag+	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))++	if err != nil {+		return errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodDelete, manifestURI.String(), nil)++	if err != nil {+		return errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)+	if err != nil {+		return errors.Wrapf(err, "Error deleting manifest")+	}++	if resp.StatusCode != http.StatusAccepted {+		return fmt.Errorf("server returned unexpected code %d", resp.StatusCode)+	}++	defer resp.Body.Close()++	return nil+}++func (o *OciRepo) PutManifest(body []byte) error {+	name := o.ref.name+	tag := o.ref.tag+	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))++	if err != nil {+		return errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodPut, manifestURI.String(), bytes.NewReader(body))++	if err != nil {+		return errors.Wrapf(err, "Couldn't create PUT request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Set("Content-Type", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return errors.Wrapf(err, "Error posting manifest")+	}++	if resp.StatusCode != http.StatusCreated {+		return fmt.Errorf("server returned unexpected code %d", resp.StatusCode)+	}++	defer resp.Body.Close()++	return nil+}++//HEAD /v2/<name>/blobs/<digest>  -> 200 (has layer)+func (o *OciRepo) HasLayer(ldigest string) bool {+	name := o.ref.name+	blobURI, err := url.Parse(fmt.Sprintf("/v2/%s/blobs/%s", name, ldigest))++	if err != nil {+		return false+	}++	blobURI = o.url.ResolveReference(blobURI)+	req, err := http.NewRequest(http.MethodHead, blobURI.String(), nil)++	if err != nil {+		return false+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)++	if err != nil {+		return false+	}++	defer resp.Body.Close()++	return resp.StatusCode == http.StatusOK+}++func (o *OciRepo) GetLayer(ldigest string) (io.ReadCloser, int64, error) {+	name := o.ref.name+	blobURI, err := url.Parse(fmt.Sprintf("/v2/%s/blobs/%s", name, ldigest))++	if err != nil {+		return nil, -1, errors.Wrapf(err, "couldn't parse URL for repo %s blob %s", name, ldigest)+	}++	blobURI = o.url.ResolveReference(blobURI)+	req, err := http.NewRequest("GET", blobURI.String(), nil)++	if err != nil {+		return nil, -1, errors.Wrapf(err, "Couldn't create GET request for %v", blobURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)++	if err != nil {+		return nil, -1, errors.Wrapf(err, "Error getting layer %s", ldigest)+	}++	if resp.StatusCode != http.StatusOK {+		resp.Body.Close()+		return nil, -1, fmt.Errorf("bad return code %d getting layer", resp.StatusCode)+	}++	return resp.Body, -1, err+}++// StartLayer starts a blob upload session+func (o *OciRepo) StartLayer() (*url.URL, error) {+	name := o.ref.name+	uploadURI, err := url.Parse(fmt.Sprintf("/v2/%s/blobs/uploads/", name))++	if err != nil {+		return nil, errors.Wrap(err, "Failed to parse upload URL")+	}++	uploadURI = o.url.ResolveReference(uploadURI)+	req, err := http.NewRequest("POST", uploadURI.String(), nil)++	if err != nil {+		return nil, errors.Wrap(err, "Failed opening POST request")+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	resp, err := o.client.Do(req)++	if err != nil {+		return nil, errors.Wrapf(err, "Failed posting request %v", req)+	}++	defer resp.Body.Close()++	if resp.StatusCode != http.StatusAccepted {+		return nil, fmt.Errorf("server returned an error %d", resp.StatusCode)+	}++	_, err = ioutil.ReadAll(resp.Body)++	if err != nil {+		return nil, errors.Wrapf(err, "Error reading response body for %s", name)+	}++	session, err := resp.Location()++	if err != nil {+		return nil, errors.Wrap(err, "Failed decoding response")+	}++	return o.url.ResolveReference(session), nil+}++// @path is the uuid upload path returned by the server to our Post request.+// @stream is the data source for the layer.+// Return the digest and size of the layer that was uploaded.+//nolint (gocognit)+func (o *OciRepo) CompleteLayer(session *url.URL, stream io.Reader) (digest.Digest, int64, error) {+	digester := sha256.New()+	hashReader := io.TeeReader(stream, digester)+	// using "chunked" upload+	count := int64(0)+	for {+		const maxSize = 10 * 1024 * 1024+		var buf bytes.Buffer+		size, err := io.CopyN(&buf, hashReader, maxSize)

What’s the benefit of using chunked upload instead of a single long-lived request? AFAICS this only adds overhead with no benefit I can see (e.g. I could imagine that chunked upload might allow restarting on partial failure, but this code doesn’t do that).

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))+		} else {+			registry := fmt.Sprintf("%s:%s", server, port)+			if username, password, err := config.GetAuthentication(sys, registry); err == nil {+				creds = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))+			}+		}+	}++	r = OciRepo{ref: ref, authCreds: creds, client: client}++	ping := func(scheme string) error {+		u := url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port), Path: fmt.Sprintf("/v2/")}+		resp, err := client.Get(u.String())+		if err != nil {+			return err+		}+		defer resp.Body.Close()+		if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {+			return errors.Errorf("Error pinging registry %s:%s, response code %d (%s)",+				server, port, resp.StatusCode, http.StatusText(resp.StatusCode))+		}+		return nil+	}++	scheme := "https"+	err = ping(scheme)+	if err != nil && insecureSkipVerify {+		scheme = "http"+		err = ping(scheme)+	}+	if err != nil {+		return r, errors.Wrap(err, "unable to ping registry")+	}++	r.url = url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port)}+	return r, nil+}++func (o *OciRepo) GetManifest() ([]byte, *ispec.Manifest, error) {+	name := o.ref.name+	tag := o.ref.tag+	m := &ispec.Manifest{}++	var body []byte++	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))+	if err != nil {+		return body, m, errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodGet, manifestURI.String(), nil)++	if err != nil {+		return body, m, errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Add("Accept", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return body, m, errors.Wrapf(err, "Error getting manifest %s %s from %v", name, tag, o.url)+	}+	defer resp.Body.Close()++	if resp.StatusCode != http.StatusOK {+		return body, m, fmt.Errorf("bad return code %d getting manifest", resp.StatusCode)+	}++	body, err = ioutil.ReadAll(resp.Body)+	if err != nil {+		return body, m, errors.Wrapf(err, "Error reading response body for %s", tag)+	}++	err = json.Unmarshal(body, m)++	if err != nil {+		return body, m, errors.Wrap(err, "Failed decoding response")+	}++	return body, m, nil+}++func (o *OciRepo) RemoveManifest() error {+	name := o.ref.name+	tag := o.ref.tag+	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))++	if err != nil {+		return errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodDelete, manifestURI.String(), nil)++	if err != nil {+		return errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {

(I can’t quite see the point of having code like this copy&pasted all over the place, when the original has this factored out to a single dockerClient.makeRequest* path.)

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))+		} else {+			registry := fmt.Sprintf("%s:%s", server, port)+			if username, password, err := config.GetAuthentication(sys, registry); err == nil {+				creds = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))+			}+		}+	}++	r = OciRepo{ref: ref, authCreds: creds, client: client}++	ping := func(scheme string) error {+		u := url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port), Path: fmt.Sprintf("/v2/")}+		resp, err := client.Get(u.String())+		if err != nil {+			return err+		}+		defer resp.Body.Close()+		if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {+			return errors.Errorf("Error pinging registry %s:%s, response code %d (%s)",+				server, port, resp.StatusCode, http.StatusText(resp.StatusCode))+		}+		return nil+	}++	scheme := "https"+	err = ping(scheme)+	if err != nil && insecureSkipVerify {+		scheme = "http"+		err = ping(scheme)+	}+	if err != nil {+		return r, errors.Wrap(err, "unable to ping registry")+	}++	r.url = url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port)}+	return r, nil+}++func (o *OciRepo) GetManifest() ([]byte, *ispec.Manifest, error) {+	name := o.ref.name+	tag := o.ref.tag+	m := &ispec.Manifest{}++	var body []byte++	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))+	if err != nil {+		return body, m, errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodGet, manifestURI.String(), nil)++	if err != nil {+		return body, m, errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Add("Accept", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return body, m, errors.Wrapf(err, "Error getting manifest %s %s from %v", name, tag, o.url)+	}+	defer resp.Body.Close()++	if resp.StatusCode != http.StatusOK {+		return body, m, fmt.Errorf("bad return code %d getting manifest", resp.StatusCode)+	}++	body, err = ioutil.ReadAll(resp.Body)+	if err != nil {+		return body, m, errors.Wrapf(err, "Error reading response body for %s", tag)+	}++	err = json.Unmarshal(body, m)

Why? Nothing uses the value AFAICS, and it’s, in general, not the job of the transport to worry about contents of the data (unless the transport is simulating something or doing internal conversions, I guess, like the docker/tarfile ones, and arguably that code should be moved into the generic conversion mechanism instead).

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))+		} else {+			registry := fmt.Sprintf("%s:%s", server, port)+			if username, password, err := config.GetAuthentication(sys, registry); err == nil {+				creds = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))+			}+		}+	}++	r = OciRepo{ref: ref, authCreds: creds, client: client}++	ping := func(scheme string) error {+		u := url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port), Path: fmt.Sprintf("/v2/")}+		resp, err := client.Get(u.String())+		if err != nil {+			return err+		}+		defer resp.Body.Close()+		if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {+			return errors.Errorf("Error pinging registry %s:%s, response code %d (%s)",+				server, port, resp.StatusCode, http.StatusText(resp.StatusCode))+		}+		return nil+	}++	scheme := "https"+	err = ping(scheme)+	if err != nil && insecureSkipVerify {+		scheme = "http"+		err = ping(scheme)+	}+	if err != nil {+		return r, errors.Wrap(err, "unable to ping registry")+	}++	r.url = url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%s", server, port)}+	return r, nil+}++func (o *OciRepo) GetManifest() ([]byte, *ispec.Manifest, error) {+	name := o.ref.name+	tag := o.ref.tag+	m := &ispec.Manifest{}++	var body []byte++	manifestURI, err := url.Parse(fmt.Sprintf("/v2/%s/manifests/%s", name, tag))+	if err != nil {+		return body, m, errors.Wrapf(err, "couldn't parse manifest url for repo %s and image %s", name, tag)+	}++	manifestURI = o.url.ResolveReference(manifestURI)+	req, err := http.NewRequest(http.MethodGet, manifestURI.String(), nil)++	if err != nil {+		return body, m, errors.Wrapf(err, "Couldn't create DELETE request for %v", manifestURI)+	}++	if o.authCreds != "" {+		req.Header.Add("Authorization", "Basic "+o.authCreds)+	}++	req.Header.Add("Accept", "application/vnd.oci.image.manifest.v1+json")+	resp, err := o.client.Do(req)++	if err != nil {+		return body, m, errors.Wrapf(err, "Error getting manifest %s %s from %v", name, tag, o.url)+	}+	defer resp.Body.Close()++	if resp.StatusCode != http.StatusOK {+		return body, m, fmt.Errorf("bad return code %d getting manifest", resp.StatusCode)+	}++	body, err = ioutil.ReadAll(resp.Body)

Every single ReadAll must use iolimits.ReadAtMost.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"

Does the OCI spec say anything about the default port? Won’t changing the default require users to explicitly add ports to interact with the vast majority of currently used public registries? and, see below, that would mean that the credential items set by podman login wouldn’t be found.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))+		} else {+			registry := fmt.Sprintf("%s:%s", server, port)+			if username, password, err := config.GetAuthentication(sys, registry); err == nil {

This is not how config typically refers to registries: if the user does not specify a port, the registry parameter should not explicitly include one. If this code does not handle input the same way, things like podman login won’t create entries that will work.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {+		server = ref.server+		hostName = server+	}++	if ref.port != -1 {+		port = fmt.Sprintf("%d", ref.port)+		hostName += ":" + port+	}++	insecureSkipVerify := false+	if sys != nil {+		insecureSkipVerify = (sys.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue)+	}++	tlsClientConfig := &tls.Config{+		MinVersion:               tls.VersionTLS10,+		PreferServerCipherSuites: true,+		InsecureSkipVerify:       insecureSkipVerify,+	}++	certDir, err := ociCertDir(sys, hostName)+	if err != nil {+		return r, err+	}+	if err := tlsclientconfig.SetupCertificates(certDir, tlsClientConfig); err != nil {+		return r, err+	}++	transport := &http.Transport{TLSClientConfig: tlsClientConfig}+	client := &http.Client{Transport: transport}+	creds := ""+	if sys != nil {+		if sys.DockerAuthConfig != nil {+			a := sys.DockerAuthConfig+			creds = base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password))

Why hard-code the implementation details here, when the code could store the user name and password separately, and have req.SetBasicAuth deal with the HTTP specifics?

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {+	server := "127.0.0.1"+	port := "8080"+	hostName := ""++	if ref.server != "" {

No, please. A localhost registry seems like a pretty rare case to me, not really worth introducing a syntax variation (and especially not worth worrying about whether the user uses localhost or 127.0.0.1 for certificate names). String parsing of references is hard enough in the best cases.

Just have the user specify the server explicitly.

rchincha

comment created time in 3 days

Pull request review commentcontainers/image

Add client support for opencontainers/distribution-spec

+package dist++import (+	"bytes"+	"crypto/sha256"+	"crypto/tls"+	"encoding/base64"+	"encoding/json"+	"fmt"+	"io"+	"io/ioutil"+	"net/http"+	"net/url"+	"os"+	"path/filepath"+	"strconv"++	"github.com/containers/image/v5/pkg/docker/config"+	"github.com/containers/image/v5/pkg/tlsclientconfig"+	"github.com/containers/image/v5/types"+	"github.com/opencontainers/go-digest"+	ispec "github.com/opencontainers/image-spec/specs-go/v1"++	"github.com/pkg/errors"+)++type OciRepo struct {+	url       url.URL+	ref       *distReference+	authCreds string+	client    *http.Client+}++//nolint (funlen)+func NewOciRepo(ref *distReference, sys *types.SystemContext) (r OciRepo, err error) {

Does this have to be public at all? The c/image transports primarily exist provide an unified interface, and we have a lot of trouble keeping the API stable enough, so I’m very hesitant about introducing new symbols without a good justification.

rchincha

comment created time in 3 days

pull request commentcontainers/image

Add client support for opencontainers/distribution-spec

Thanks for the PR. I’ll make a quick pass through the code and add a few notes in a while.

Most importantly, though, are there actually any real differences between docker:// and the proposed transport?

  • You yourself say in the quoted thread that

    That said the actual differences between docker:// and proposed dist:// transports are very slim

  • The original motivation for the PR, that Content-Type used when writing manifests is Docker-specific, is simply incorrect; dockerImageDestination.SupportedManifestMIMETypes does support both OCI manifests and indexes (unlike this PR, which only considers manifests, i.e. can’t handle multi-arch images), and the OCI types will be used by c/image/copy.Image if:
    • the original image is OCI, or
    • OCI conversion was explicitly required by copy.Options.ForceManifestMIMEType, or
    • the source image is not OCI, but the destination registry rejects Docker manifest formats.
  • Looking at the commit history https://github.com/opencontainers/distribution-spec/commits/master/spec.md , the changes are overwhelmingly trivial clean-ups with no functional impact (the only non-trivial change I have noticed is the renaming of the session ID parameter during uploads, but the previous code didn’t use that at all anyway).

From a maintenance point of view, it is rather burdensome to have two significantly different implementations of substantially the same functionality, including one of the two transports that are most important and most often updated, for little end-user benefit. I don’t doubt that eventually there will be a fairly significant divergence, and I’m sure the docker:// transport name should eventually be retired in favor of a name that references the OCI distribution specification in some way, but in my view, neither of that, at least currently justifies:

  • ~doubling the maintenance overhead
  • introducing the OCI transport in a way that has noticeably fewer features — and that makes it unattractive for users to even start to use the new transport, when they can use docker:// that auto-detects OCI support in most cases, and has more features. E.g.: missing support for registries.conf (registry blocking, redirection, mirrors), bearer token authentication (required for anonymous access to Docker Hub at least), Retry-After, blob info cache, multi-arch image, external layer

If it makes sense to introduce the new transport name and syntax right now, at all (which is unclear, especially WRT bothering users with the transition, given ~zero end-user benefit),but I’m open to considering that), I’m very insistent that it should share 99% of the code with the existing docker:// transport (probably by moving most of the implementation into a shared c/image/internal/… subpackage, and using it in both). Taking partial copies of the docker:// transport that are stripped of much of the functionality, and linking it to a separate HTTP client implementation that does mostly the same things, but differently, and having to maintain both is just not at all attractive, in my personal opinion, right now. (Note that other maintainers like @vrothberg might well disagree.)

But my first instinct is that the current docker:// transport can technically do, or should be easy to modify to do, everything that is necessary, and there’s just no technical need for this; all that I can see so far is the PR aspect of using a different name. Sure, that’s something but it’s also not all that compelling from a technical point of view, and I’d prefer to discuss that before delving into implementation details.

rchincha

comment created time in 3 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 To decrypt an image that requires more than one key: ```sh skopeo copy --decryption-key ./private1.key --decryption-key ./private2.key --decryption-key ./private3.key oci:try-encrypt:encrypted oci:try-decrypt:decrypted ```++Container images can also be partially encrypted by specifying the index of the layer. Layers are 0-indexed indices, with support for negative indexing. i.e. 0 is the first layer, -1 is the last layer.++Let's say out of 3 layers that the image `docker.io/library/nginx:1.17.8` is made up of, we only want to encrypt the 2nd layer,+```sh+skopeo  copy --encryption-key jwe:./public.key --encrypt-layer 1 oci:local_nginx oci:try-encrypt:encrypted

Should this be oci:local_nginx:1.17.8, then?

harche

comment created time in 4 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 func (s *CopySuite) TestCopyEncryption(c *check.C) { 		"oci:"+encryptedImgDir+":encrypted", "oci:"+decryptedImgDir+":decrypted")  	// Copy a standard busybox image locally-	assertSkopeoSucceeds(c, "", "copy", "docker://busybox", "oci:"+originalImageDir+":latest")+	assertSkopeoSucceeds(c, "", "copy", "docker://busybox:1.31.1", "oci:"+originalImageDir+":latest")

Thanks!

harche

comment created time in 4 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 To copy and sign an image:  To encrypt an image: ```sh-skopeo copy docker://docker.io/library/nginx:latest oci:local_nginx:latest+skopeo copy docker://docker.io/library/nginx:1.17.8 oci:local_nginx:1.17.8

Ah, I didn’t realize this is directly connected to the new example. The new example does benefit from fixing a version, sure.

harche

comment created time in 4 days

Pull request review commentopenshift/machine-config-operator

Make `mcfgv1` the canonical name for importing api package

 import ( 	clientcmd "k8s.io/client-go/tools/clientcmd" 	clientcmdv1 "k8s.io/client-go/tools/clientcmd/api/v1" -	v1 "github.com/openshift/machine-config-operator/pkg/generated/clientset/versioned/typed/machineconfiguration.openshift.io/v1"+	mcfgv1 "github.com/openshift/machine-config-operator/pkg/generated/clientset/versioned/typed/machineconfiguration.openshift.io/v1"

…/pkg/generated/… is a different package; should it use the same prefix?

LorbusChris

comment created time in 4 days

pull request commentcontainers/skopeo

Bump github.com/containers/common from 0.1.4 to 0.2.0

Yeah, that would be much more important. The updates that change nothing are a rare corner case that don’t really matter one way or the other.

dependabot-preview[bot]

comment created time in 4 days

Pull request review commentcontainers/image

Add $HOME/.config/containers/certs.d to ssytemPerHostCertDirPath

 func dockerCertDir(sys *types.SystemContext, hostPort string) (string, error) { 	var ( 		hostCertDir     string 		fullCertDirPath string+		homeCertDir     string 	)-	for _, systemPerHostCertDirPath := range systemPerHostCertDirPaths {+	home := os.Getenv("HOME")+	if home != "" {+		homeCertDir = filepath.Join(home, ".config", "containers", ".certs.d")+	}+	for _, systemPerHostCertDirPath := range append([]string{homeCertDir}, systemPerHostCertDirPaths...) {
  • I don’t think this works correctly for homeCertDir == ""
  • RootForImplicitAbsolutePaths should not be used for the home directory.
  • We use docker/docker/pkg/homedir when looking up credentials, it would be nice to be consistent.
rhatdan

comment created time in 6 days

Pull request review commentcontainers/image

Add $HOME/.config/containers/certs.d to ssytemPerHostCertDirPath

 func dockerCertDir(sys *types.SystemContext, hostPort string) (string, error) { 	var ( 		hostCertDir     string 		fullCertDirPath string+		homeCertDir     string 	)-	for _, systemPerHostCertDirPath := range systemPerHostCertDirPaths {+	home := os.Getenv("HOME")+	if home != "" {+		homeCertDir = filepath.Join(home, ".config", "containers", ".certs.d")

Please make this a global constant defined near systemPerHostCertDirPaths (compare dockerHomePath).

rhatdan

comment created time in 6 days

push eventcontainers/image

dependabot-preview[bot]

commit sha e6eb408f62ebc16780d8747e944b4e1581fb452a

Bump github.com/klauspost/compress from 1.9.8 to 1.10.0 Bumps [github.com/klauspost/compress](https://github.com/klauspost/compress) from 1.9.8 to 1.10.0. - [Release notes](https://github.com/klauspost/compress/releases) - [Changelog](https://github.com/klauspost/compress/blob/master/.goreleaser.yml) - [Commits](https://github.com/klauspost/compress/compare/v1.9.8...v1.10.0) Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

view details

Miloslav Trmač

commit sha 75391a1f2a6afd8071feeb59db1036d8dc53c4e6

Merge pull request #818 from containers/dependabot/go_modules/github.com/klauspost/compress-1.10.0 Bump github.com/klauspost/compress from 1.9.8 to 1.10.0

view details

push time in 6 days

PR merged containers/image

Bump github.com/klauspost/compress from 1.9.8 to 1.10.0 dependencies

Bumps github.com/klauspost/compress from 1.9.8 to 1.10.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/klauspost/compress/releases">github.com/klauspost/compress's releases</a>.</em></p> <blockquote> <h2>v1.10.0</h2> <h2>Changelog</h2> <p>26bacdf Add compressed ZIP copying (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/214">#214</a>) e1f2a6e Add empty Go mod file (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/213">#213</a>) b7ccab8 Add stateless dictionary support (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/216">#216</a>) 4f93024 Fix reset overflow (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/218">#218</a>) a8f0b11 Merge pull request <a href="https://github-redirect.dependabot.com/klauspost/compress/issues/186">#186</a> from klauspost/s2-assembler-encode e75fbf6 Merge pull request <a href="https://github-redirect.dependabot.com/klauspost/compress/issues/212">#212</a> from klauspost/add-deb-rpm ccd3322 Merge pull request <a href="https://github-redirect.dependabot.com/klauspost/compress/issues/215">#215</a> from klauspost/s2-single-threaded-readerfrom</p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/klauspost/compress/commit/b9d5dc7bd435c628cb0c658ce7f556409007ea71"><code>b9d5dc7</code></a> test: Skip if no enwik9</li> <li><a href="https://github.com/klauspost/compress/commit/b7ccab840e50d2c3fbfdb00c8949cc32e31cd459"><code>b7ccab8</code></a> Add stateless dictionary support (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/216">#216</a>)</li> <li><a href="https://github.com/klauspost/compress/commit/4f9302400b3ad4bc5279311103f68b02eac86130"><code>4f93024</code></a> Fix reset overflow (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/218">#218</a>)</li> <li><a href="https://github.com/klauspost/compress/commit/26bacdfece2923f6b0b4c7abb1a9527628c73c89"><code>26bacdf</code></a> Add compressed ZIP copying (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/214">#214</a>)</li> <li><a href="https://github.com/klauspost/compress/commit/e1f2a6ed3f88ef9f4e580f9f933280a67da073ef"><code>e1f2a6e</code></a> Add empty Go mod file (<a href="https://github-redirect.dependabot.com/klauspost/compress/issues/213">#213</a>)</li> <li><a href="https://github.com/klauspost/compress/commit/ccd332220b913055122ff98485b37dfe309a1c1b"><code>ccd3322</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/klauspost/compress/issues/215">#215</a> from klauspost/s2-single-threaded-readerfrom</li> <li><a href="https://github.com/klauspost/compress/commit/738844705438b332a3f5fae9725d8c4ce01febc5"><code>7388447</code></a> Fix single threaded S2 ReadFrom</li> <li><a href="https://github.com/klauspost/compress/commit/b69de4d8d7566990b9ba768e04a17eecbe788658"><code>b69de4d</code></a> Update README.md</li> <li><a href="https://github.com/klauspost/compress/commit/23a5980ed240fd76b89481403c834f48943b3788"><code>23a5980</code></a> Clarify/simplify benchmarks.</li> <li><a href="https://github.com/klauspost/compress/commit/ff328a016f3c23912bf4a294bf7d2dbf90fe66d9"><code>ff328a0</code></a> Update block benchmark with final numbers.</li> <li>Additional commits viewable in <a href="https://github.com/klauspost/compress/compare/v1.9.8...v1.10.0">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
  • @dependabot badge me will comment on this PR with code to add a "Dependabot enabled" badge to your readme

Additionally, you can set the following in your Dependabot dashboard:

  • Update frequency (including time of day and day of week)
  • Pull request limits (per update run and/or open at any time)
  • Out-of-range updates (receive only lockfile updates, if desired)
  • Security updates (receive only security updates, if desired)

</details>

+3 -1

1 comment

2 changed files

dependabot-preview[bot]

pr closed time in 6 days

delete branch mtrmac/image

delete branch : new-reference

delete time in 6 days

pull request commentcontainers/image

Bump github.com/klauspost/compress from 1.9.8 to 1.10.0

@dependabot rebase

dependabot-preview[bot]

comment created time in 6 days

push eventcontainers/skopeo

dependabot-preview[bot]

commit sha f8302650349986784d85ef61ae466bc9f969c112

Bump github.com/containers/common from 0.1.4 to 0.2.0 Bumps [github.com/containers/common](https://github.com/containers/common) from 0.1.4 to 0.2.0. - [Release notes](https://github.com/containers/common/releases) - [Commits](https://github.com/containers/common/compare/v0.1.4...v0.2.0) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Signed-off-by: Valentin Rothberg <rothberg@redhat.com>

view details

Miloslav Trmač

commit sha c8e025090308795d5eaca0eede602551127d3085

Merge pull request #817 from containers/dependabot/go_modules/github.com/containers/common-0.2.0 Bump github.com/containers/common from 0.1.4 to 0.2.0

view details

push time in 6 days

PR merged containers/skopeo

Bump github.com/containers/common from 0.1.4 to 0.2.0 dependencies

Bumps github.com/containers/common from 0.1.4 to 0.2.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/containers/common/releases">github.com/containers/common's releases</a>.</em></p> <blockquote> <h2>v0.2.0</h2> <pre><code>Add Default function to read containers config Don't up the default number of open files, just processes. </code></pre> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/containers/common/commit/42826c44ccbc9b50c163820704ae9de497384256"><code>42826c4</code></a> Bump to v0.2.0</li> <li><a href="https://github.com/containers/common/commit/027e027fc3b1616124036fde7e5070674658df66"><code>027e027</code></a> Merge branch 'master' of github.com:containers/common into version</li> <li><a href="https://github.com/containers/common/commit/1f9c394bc5aeb30ea8269c8f69935216383c25c4"><code>1f9c394</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/containers/common/issues/58">#58</a> from rhatdan/nofile</li> <li><a href="https://github.com/containers/common/commit/0f993399ff69c3e88eeff014feda303c80444885"><code>0f99339</code></a> Add Default function to read containers config</li> <li><a href="https://github.com/containers/common/commit/c46056cc074ebbec7bc409fc9af9570e2f2d1176"><code>c46056c</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/containers/common/issues/57">#57</a> from rhatdan/nofile</li> <li><a href="https://github.com/containers/common/commit/87408938ab3442226536e0122983ceb928d1b913"><code>8740893</code></a> Don't up the default number of open files, just processes.</li> <li><a href="https://github.com/containers/common/commit/a85dc61a8f4c7457b9b8208d533a1deee0686ab4"><code>a85dc61</code></a> Don't up the default number of open files, just processes.</li> <li><a href="https://github.com/containers/common/commit/8178c299203672355231d0230d093731f888fb28"><code>8178c29</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/containers/common/issues/55">#55</a> from rhatdan/version</li> <li><a href="https://github.com/containers/common/commit/02f1f714308348630ae9e91bc7c4dbfc26e3ca24"><code>02f1f71</code></a> Move to v0.1.5-dev</li> <li>See full diff in <a href="https://github.com/containers/common/compare/v0.1.4...v0.2.0">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
  • @dependabot badge me will comment on this PR with code to add a "Dependabot enabled" badge to your readme

Additionally, you can set the following in your Dependabot dashboard:

  • Update frequency (including time of day and day of week)
  • Pull request limits (per update run and/or open at any time)
  • Out-of-range updates (receive only lockfile updates, if desired)
  • Security updates (receive only security updates, if desired)

</details>

+4 -2

1 comment

3 changed files

dependabot-preview[bot]

pr closed time in 6 days

pull request commentcontainers/image

Add AdditionalCertDirPaths to system context

I’d much prefer for the per-user path to be used by c/image by default without having every consumer of c/image to opt in, and to independently hard-code the path. I can’t see much downside to having per-user configuration, even if run as root (I suppose determining which configuration is used could be a bit confusing with sudo).

WRT containers.conf, are you suggesting that it should point at locations of other config files, by explicit paths inside containers.conf (i.e. that the file is not portable from one user account to another)? Or maybe the other config files should be located in exactly the same directory (i.e. use one lookup path/logic for config files)? Or that the TLS blobs (keys, certificates) should be recorded inside containers.conf instead of using separate files on the filesystem?

rhatdan

comment created time in 6 days

pull request commentcontainers/image

Add AdditionalCertDirPaths to system context

If it makes sense to have per-user configuration of certificates (which is not 100% clear but it probably does), why should it be only applicable to rootless, and not an universal default? (Compare https://github.com/containers/skopeo/issues/800 ).

And even if it had to be rootless-specific, is the right design having Podman+Buildah hard-code a path, or should that ultimately just be a boolean? (Or maybe the hard-coded path should exist but live in c/common, I guess.)

rhatdan

comment created time in 7 days

push eventmtrmac/image

TomSweeneyRedHat

commit sha e9d9ec93758d0f74f1687ed52feb61bb5fc0c835

Add Code of Conduct Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com>

view details

Daniel J Walsh

commit sha b53b8f36e4154bda4f104b71654370fafd2c913e

Merge pull request #815 from TomSweeneyRedHat/coc Add Code of Conduct

view details

Miloslav Trmač

commit sha 1e56cac5989202ddf6a80585732ec0f22fe1140d

Re-order the members of archiveReference to a more logical order Path is the primary input, which is always used; destinationRef is scoped within that path. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 3dbdded682c853200508f46017db4019ad491587

Add docker/archive.NewReference ... to allow passing data without ambiguous parsing. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 18b9d7a77e02277e855a5905f79de0ac367b804d

Remove tarballReference.transport It is only ever a single value. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha df220110753224619c3b07ad3d4a64368ba5b22b

Add tarball.NewReference ... continuing the tradition, with no tests. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha d516c52dbb8eac94134d297da1de84308214ecf1

Add storage.Transport.GetStoreIfSet ... which can be used to ensure the global store pointer only ever points at one store throughout a process. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha bae43ecff5bcc066c4a70730345807626bbe2459

Simplify ID value check digest.Parse already calls Validate on the result, no need to call it again. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 0c46986b65794a20bde0f5671d516c45e902cfa9

Add validateImageID ... to share the string parsing logic in a single place. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha b8cb49436ff31f4228f3a4811968ad0f2aab143d

Add storage.Transport.NewStoreReference To allow callers to create storage reference without having to parse strings. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 7 days

delete branch mtrmac/libpod

delete branch : image-object-creation

delete time in 7 days

Pull request review commentcontainers/image

Add NewReference to a few transports, + storage.GetStoreIfSet

 func newReference(transport storageTransport, named reference.Named, id string) 	if named == nil && id == "" { 		return nil, ErrInvalidReference 	}+	if named != nil {

Thanks, fixed.

mtrmac

comment created time in 7 days

push eventmtrmac/image

Miloslav Trmač

commit sha 7479b52db385c075445b526511c39f96ed75f84f

Add storage.Transport.NewStoreReference To allow callers to create storage reference without having to parse strings. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 7 days

Pull request review commentcontainers/image

Add NewReference to a few transports, + storage.GetStoreIfSet

 func newReference(transport storageTransport, named reference.Named, id string) 	if named == nil && id == "" { 		return nil, ErrInvalidReference 	}+	if named != nil {+		if reference.IsNameOnly(named) {+			return nil, errors.Wrapf(ErrInvalidReference, "reference %s has neither a tag nor a digest", named.String())+		}+	}+	if id != "" {

It’s not possible to do if (expression) && newVariable := …; expression(newVariable).

mtrmac

comment created time in 7 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha ba419cc0336b6fbf877a2464b40426b8990a9c57

BEHAVIOR CHANGE: Use NewReference instead of ParseReference ... for dockerarchive and tarball transports, now that it is available, to make parsing less ambiguous. Changes behavior: in both cases, paths with colons are now rejected instead of having unexpected effects. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha b79d191334d5d0d2a919c2ffce3b63fba9b6dfe2

Use storage.Transport.NewStoreReference for ID values ... to make their parsing unambiguous. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 10 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 688ebc1f8545e4a51344eb9c23945cd37b082e1f

DO NOT MERGE: image new-reference go mod edit -replace github.com/containers/image/v5=github.com/mtrmac/image/v5@new-reference make vendor Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 4bcd6f51fbc3ced96c888850e4f3423ac67a5a5a

Introduce localimage.Storage ... and create it from image.Runtime. For now, this does nothing at all. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 1755d1aa5a0d763984300a0b451b02e9d14f1520

Introduce localimage.Image ... and create it from image.Image. For now, this does nothing at all. Should not change behavior, the error creating that object should never happen. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 255d109057291c716ef8d789df4976c541d00c25

WIP add Image.AddTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ba859b5f76c010d117700a9bec11f2627f4cbaed

WIP: Add Image.RemoveTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 3ad1166d30e2ee5e19a2deadd11aac46d030f979

WIP: Introduce Image.GetHealthCheckIfSupported .. and deprecate Image.GetHealthCheck, which required callers to deal with MIME types manually. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 1a44724cad83547825c018cce16492e185deb7b5

Add Deprecated: notices to reduce scope a bit. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha d044515a61e397cb6f4c0d9bbd473fd2ec8d29a4

Add FIXMEs to Image.History() output data structure Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha f14b637c476c0e282867ebef02766bd856d5e3e1

Consolidate layer-dependent history content ... to be computed in a single "if layer != nil" block, and similarly consolidate the "not an empty layer" block. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha e398777c1cffa27ed5ab62ca43debfb9054893c7

Rename numHistories to topHistoryIndex Having "numHistories" be the number of history entries MINUS ONE hurts my brain. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha eac9e98eb1bc555f9c6c1c496544c5c587b97ef6

BEHAVIOR CHANGE: Fix top-level image ID in history Use the ID of the input image, not a random ID of any image with the same top layer. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 44248c310b5dd6aee5652f746b1de07f3e2778d9

Simplify the history loop to maintain a layer ID instead of a layer pointer ... which consolidates the layer loading code, and the "no layer ID", logic into just one place. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 5bbd38977d066f9761ccb9e796735e2b1a964a7f

Add FIXME Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 34ff399731601f3f6a9b857309d6a3d2a835cc1d

Add FIXMEs Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 6c305912f24ac68b39a9885acfe22e2ad33cbda0

INCOMPLETE: Remove uses of Image.InputName Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 3d15065ee3745d2fe62df374cebee1e1be43b587

Add FIXME *sigh* Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha f163d6cd01a8c391df73105e789788c230d7473d

Return a []pullRefPair as pull results ... instead of image names; use the []pullRefPair data to reuse the original storage references directly (NOTE: this is still racy against tag changes) instead of involving the names and extra uncertainty. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha f611fd11ceea57415b3c51dea753c9b2c7420fde

BEHAVIOR CHANGE: Don't ignore error sending local image over Varlink Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 0f7eb56eaa654960a8d1bcabecbe7dcb62abacfb

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 3b7a568733ddc3b9577ec259702d63be39ed5728

Use docker.NewReference instead of docker.ParseReference It's a bit more code, but we get rid of more strings. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 10 days

PR opened containers/image

Add NewReference to a few transports, + storage.GetStoreIfSet

New*Reference allows creating references from well-typed data without string formatting and parsing; this adds it to a few transports that were missing the functionality.

Also adds storage.Transport.GetStoreIfSet (naming?) to allow checking that the default store is not set to two different values in a single application.

See individual commit messages for details.

+125 -19

0 comment

9 changed files

pr created time in 10 days

create barnchmtrmac/image

branch : new-reference

created branch time in 10 days

push eventmtrmac/libpod

Matthew Heon

commit sha 2ced9094d4728dd09f60a177faa32339a8d0f721

Bump to v1.8.0 Signed-off-by: Matthew Heon <matthew.heon@pm.me>

view details

Matthew Heon

commit sha dc940f90d8e8b8486c892d2d57575f278749ce15

Bump to v1.8.1-dev Signed-off-by: Matthew Heon <matthew.heon@pm.me>

view details

Nalin Dahyabhai

commit sha e6c7ccc06700ee7e91a265462d1eed5fb574a4bb

LibpodAPI.BuildImage: don't require a name for the new image When we finish building an image, we try to look up its ID by looking up the image using the name that we were asked to assign to the image. If we weren't asked to assign a name to the image, that would produce an error. The BuildImage() API we're using returns the image's ID anyway, so we can skip the lookup and just return the ID directly. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>

view details

dependabot-preview[bot]

commit sha 93b9008540a08c0c596719d872065090652ad594

build(deps): bump github.com/containers/image/v5 from 5.2.0 to 5.2.1 Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.2.0 to 5.2.1. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.2.0...v5.2.1) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>

view details

OpenShift Merge Robot

commit sha fc5ed23560aba091256fb9d792c542fd0ea0384c

Merge pull request #5119 from mheon/bump-1.8.0 Bump to v1.8.0

view details

OpenShift Merge Robot

commit sha c895d844d448e6890ce80fe81eaf1bf535a1d50e

Merge pull request #5120 from nalind/varlink-build-id LibpodAPI.BuildImage: don't require a name for the new image

view details

Sascha Grunert

commit sha 9bc171b86d9ce511ab3c5dc823047e4ad89b102a

Refactor runtime functions to pass options structure This makes the code easier to read but should not change the overall behavior. Signed-off-by: Sascha Grunert <sgrunert@suse.com>

view details

OpenShift Merge Robot

commit sha 29d76a4cb2c93818041e14f2bebe35dd1bbea087

Merge pull request #5104 from containers/dependabot/go_modules/github.com/containers/image/v5-5.2.1 build(deps): bump github.com/containers/image/v5 from 5.2.0 to 5.2.1

view details

Matthew Heon

commit sha 562d3b09d0dcceea30ed6a61d9fa06a52df20d90

Update readme to 1.8.0 release Signed-off-by: Matthew Heon <mheon@redhat.com>

view details

OpenShift Merge Robot

commit sha 86a51df18e53d7e5870de2d7f9355704576f8ab0

Merge pull request #5126 from openSUSE/runtime-struct Refactor runtime functions to pass options structure

view details

OpenShift Merge Robot

commit sha c02b3b5e139de90f7e03a5b08b5c49add8107380

Merge pull request #5129 from mheon/update_release_for_18 [CI:DOCS] Update readme to 1.8.0 release

view details

Miloslav Trmač

commit sha 0f0bac4ab31f06403a567d9f28ee4ef69cfe94ca

Call NewImageRuntimeFromStore from NewImageRuntimeFromOptions ... so that there ultimately is only one constructor. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha d9bfaf51977cdc7088fe168d871ac5ce787c9d6a

Create two separate newImage instances in Runtime.New This is not _trivially_ safe because newImage.getLocalImage() modifies newImage.ImageName, but we overwrite that value anyway. So, this should not change behavior, and it will make future refactoring easier to verify. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha a433b858d275557e1469fdcd917f1ef2a93011cd

Trivial simplification Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ede412f40f662b506d1d7d44d51cd51ef5922f64

Use Runtime.NewFromLocal instead of open-coded copies All code creating an Image by looking up a name now uses Runtime.NewFromLocal. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 1ab4038807eb1586901460119820a4b865ac644f

Remove the getLocalImage() call from Image.Size All ways to create an Image{} have a non-nil .image field, and it is never set to nil, so this is dead code. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 933edf4a3767a1431257ba9d2948821eba967c23

Move Image.getLocalImage to Runtime.getLocalImage Instead of the function updating image.InputName (the only reason for it to need an image), have it return the updated value separately. This will allow simplifying the constructors of Image further. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 972df82632bf0840ac84756306ef607ea5be72d8

Introduce a Runtime.newImage constructor ... so that _all_ Image objects are created in a single place that is easy to update. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 5b5bacbd95fb4a87bdb294504621dba766aed626

Document an aspect of newFromStorage behavior Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha dafd212870585313442de0342c5455ef42099d5e

Modify Runtime.getImage to return a storage.Image ... because both callers only care about that aspect of the return value. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 10 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha c167f21276e12117d4f36237e5afe58e10a86b9a

Use docker.NewReference instead of docker.ParseReference It's a bit more code, but we get rid of more strings. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 10 days

push eventmtrmac/libpod

Matthew Heon

commit sha 2ced9094d4728dd09f60a177faa32339a8d0f721

Bump to v1.8.0 Signed-off-by: Matthew Heon <matthew.heon@pm.me>

view details

Matthew Heon

commit sha dc940f90d8e8b8486c892d2d57575f278749ce15

Bump to v1.8.1-dev Signed-off-by: Matthew Heon <matthew.heon@pm.me>

view details

Nalin Dahyabhai

commit sha e6c7ccc06700ee7e91a265462d1eed5fb574a4bb

LibpodAPI.BuildImage: don't require a name for the new image When we finish building an image, we try to look up its ID by looking up the image using the name that we were asked to assign to the image. If we weren't asked to assign a name to the image, that would produce an error. The BuildImage() API we're using returns the image's ID anyway, so we can skip the lookup and just return the ID directly. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>

view details

dependabot-preview[bot]

commit sha 93b9008540a08c0c596719d872065090652ad594

build(deps): bump github.com/containers/image/v5 from 5.2.0 to 5.2.1 Bumps [github.com/containers/image/v5](https://github.com/containers/image) from 5.2.0 to 5.2.1. - [Release notes](https://github.com/containers/image/releases) - [Commits](https://github.com/containers/image/compare/v5.2.0...v5.2.1) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>

view details

OpenShift Merge Robot

commit sha fc5ed23560aba091256fb9d792c542fd0ea0384c

Merge pull request #5119 from mheon/bump-1.8.0 Bump to v1.8.0

view details

OpenShift Merge Robot

commit sha c895d844d448e6890ce80fe81eaf1bf535a1d50e

Merge pull request #5120 from nalind/varlink-build-id LibpodAPI.BuildImage: don't require a name for the new image

view details

Sascha Grunert

commit sha 9bc171b86d9ce511ab3c5dc823047e4ad89b102a

Refactor runtime functions to pass options structure This makes the code easier to read but should not change the overall behavior. Signed-off-by: Sascha Grunert <sgrunert@suse.com>

view details

OpenShift Merge Robot

commit sha 29d76a4cb2c93818041e14f2bebe35dd1bbea087

Merge pull request #5104 from containers/dependabot/go_modules/github.com/containers/image/v5-5.2.1 build(deps): bump github.com/containers/image/v5 from 5.2.0 to 5.2.1

view details

Matthew Heon

commit sha 562d3b09d0dcceea30ed6a61d9fa06a52df20d90

Update readme to 1.8.0 release Signed-off-by: Matthew Heon <mheon@redhat.com>

view details

OpenShift Merge Robot

commit sha 86a51df18e53d7e5870de2d7f9355704576f8ab0

Merge pull request #5126 from openSUSE/runtime-struct Refactor runtime functions to pass options structure

view details

OpenShift Merge Robot

commit sha c02b3b5e139de90f7e03a5b08b5c49add8107380

Merge pull request #5129 from mheon/update_release_for_18 [CI:DOCS] Update readme to 1.8.0 release

view details

Miloslav Trmač

commit sha 0f0bac4ab31f06403a567d9f28ee4ef69cfe94ca

Call NewImageRuntimeFromStore from NewImageRuntimeFromOptions ... so that there ultimately is only one constructor. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha d9bfaf51977cdc7088fe168d871ac5ce787c9d6a

Create two separate newImage instances in Runtime.New This is not _trivially_ safe because newImage.getLocalImage() modifies newImage.ImageName, but we overwrite that value anyway. So, this should not change behavior, and it will make future refactoring easier to verify. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha a433b858d275557e1469fdcd917f1ef2a93011cd

Trivial simplification Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ede412f40f662b506d1d7d44d51cd51ef5922f64

Use Runtime.NewFromLocal instead of open-coded copies All code creating an Image by looking up a name now uses Runtime.NewFromLocal. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 1ab4038807eb1586901460119820a4b865ac644f

Remove the getLocalImage() call from Image.Size All ways to create an Image{} have a non-nil .image field, and it is never set to nil, so this is dead code. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 933edf4a3767a1431257ba9d2948821eba967c23

Move Image.getLocalImage to Runtime.getLocalImage Instead of the function updating image.InputName (the only reason for it to need an image), have it return the updated value separately. This will allow simplifying the constructors of Image further. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 972df82632bf0840ac84756306ef607ea5be72d8

Introduce a Runtime.newImage constructor ... so that _all_ Image objects are created in a single place that is easy to update. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 5b5bacbd95fb4a87bdb294504621dba766aed626

Document an aspect of newFromStorage behavior Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha dafd212870585313442de0342c5455ef42099d5e

Modify Runtime.getImage to return a storage.Image ... because both callers only care about that aspect of the return value. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 10 days

push eventmtrmac/skopeo

Miloslav Trmač

commit sha 2c0a4c9c17b0a149422e8010a04a67650d61b6ed

Remove the reference to openshift/api The referenced tag has been removed, which breaks dependabot (#791). This is another attempt to fix it, by removing an explicit reference (which was added when updating Buildah, because the version seemed newer than Buildah's v0.0.0 with a newer commit). The referenced package is never even physically vendored in here, so remove the reference: > go mod edit -droprequire=github.com/openshift/api > make vendor Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 97aae7a7e453bec01b650797c24c3543698a3d6f

Merge pull request #810 from mtrmac/openshift-api-reference Remove the reference to openshift/api

view details

push time in 10 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 4e0f26c769bccea2198fcc69f302a5fd24bb22b4

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 10 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 8c1aaaa2b39828d75ddceca21673650aebdf4eea

BEHAVIOR CHANGE: Don't ignore error sending local image over Varlink Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ed0312d6f885c7e97a981067ce527a1a4ab1936b

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 2de39ea7322bdc3997a6d2b871c720f09da3c277

WIP add Image.AddTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha f7a40dcb24158b88e3cdb83d9240465504d847ac

WIP: Add Image.RemoveTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ed23360f6ff17dba0175685cb87826a178c37090

WIP: Introduce Image.GetHealthCheckIfSupported .. and deprecate Image.GetHealthCheck, which required callers to deal with MIME types manually. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ca691b6cb5970a6bf62ac9be9ad2e1a054499c2b

Add Deprecated: notices to reduce scope a bit. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 57202635164480e802a24496f648f6d80dad6342

Add FIXMEs to Image.History() output data structure Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ec74ce72f68120ce0b45972f5d2bbbfaf05134d7

Consolidate layer-dependent history content ... to be computed in a single "if layer != nil" block, and similarly consolidate the "not an empty layer" block. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 61f3f5bb59d343a68250fef6a1c9c9aaaec89f93

Rename numHistories to topHistoryIndex Having "numHistories" be the number of history entries MINUS ONE hurts my brain. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 87876c0fce8f14cfeabdc78cde8f313e7b86001d

BEHAVIOR CHANGE: Fix top-level image ID in history Use the ID of the input image, not a random ID of any image with the same top layer. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 6b9121615ea7336ad5bc1d5b9691cc1d8101191e

Simplify the history loop to maintain a layer ID instead of a layer pointer ... which consolidates the layer loading code, and the "no layer ID", logic into just one place. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 757b0cb0f2f2cfd091dc2d954fd4fb95db52bff4

Add FIXME Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 019bcddcc9d852eb3991264c476596d324099002

Add FIXMEs Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha dd5430c6dddf36c2128aaf3be1a12b793caeefb5

INCOMPLETE: Remove uses of Image.InputName Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 23f6edc878dae1b54e1bbbcaceb4d81c8e29475b

Add FIXME *sigh* Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 534f93461857443e35236d0e6617e3774c141485

Return a []pullRefPair as pull results ... instead of image names; use the []pullRefPair data to reuse the original storage references directly (NOTE: this is still racy against tag changes) instead of involving the names and extra uncertainty. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha a3817590fbd744ac007b58ee02d08e8e72beb1f3

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 19bca356fbde0db87b2df5913fdae8791deada8e

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha eb0fa41b4b22369420eb78be74330b84ed0ebbc6

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha c4a2f1b964de0b2a3b3d4a64fbd46e6a41b8a683

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha bfee75974b0fc58b6a7158c17cc6d60be154c30d

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha f11910773dff7547c0f7c9b63a8f924959d429fa

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

PR opened containers/libpod

WIP DO NOT MERGE: local-image, to run tests only

DO NOT MERGE

This is completely unfinished intermediate state, occasionally pushed just to run e2e CI, to benefit from its better coverage than unit tests.

Feel free to unsubscribe from changes, I’ll file a separate PR when ready / with parts that are ready.

+402 -228

0 comment

17 changed files

pr created time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 186ec048840e7d07578f1cedd77c94079b861f9c

Introduce localimage.Storage ... and create it from image.Runtime. For now, this does nothing at all. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 9f61b6e8a21e51816fdb5dda5ee47451c62152ff

Introduce localimage.Image ... and create it from image.Image. For now, this does nothing at all. Should not change behavior, the error creating that object should never happen. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 1f77809b8201f69d7c8cf3b3c71c298b963a3fc5

WIP add Image.AddTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 58e3fd1aed8ff3f4814dd8f3bd82ca98bcfac31e

WIP: Add Image.RemoveTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha b73ef4419e2fdefbc34077510357aa7b233e6e53

WIP: Introduce Image.GetHealthCheckIfSupported .. and deprecate Image.GetHealthCheck, which required callers to deal with MIME types manually. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha c2d0efa82e73542a84df9b09c9dac43d14eab7d2

Add Deprecated: notices to reduce scope a bit. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 8517e5e049fa9b573921b8b515861935363eadbc

Add FIXMEs to Image.History() output data structure Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 19820c78819a38654ce9d19df570d47db66d341c

Consolidate layer-dependent history content ... to be computed in a single "if layer != nil" block, and similarly consolidate the "not an empty layer" block. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 09282fe3c1bab2397671241a15daa422c980bd04

Rename numHistories to topHistoryIndex Having "numHistories" be the number of history entries MINUS ONE hurts my brain. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 51ba9163db9e79583161865eab93aef67e0f3043

BEHAVIOR CHANGE: Fix top-level image ID in history Use the ID of the input image, not a random ID of any image with the same top layer. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha e3191a33f641ecbac961cb0ba29f2bf1d3e597bb

Simplify the history loop to maintain a layer ID instead of a layer pointer ... which consolidates the layer loading code, and the "no layer ID", logic into just one place. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 13651c5035ae7eb83aefbd255eddc503b174e72d

Add FIXME Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha f036e391ae8b2aa2e3a4407372a1ef14d605a7cb

Add FIXMEs Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha e820a5c3999c149627d71f0c8b83d514cd9e035d

INCOMPLETE: Remove uses of Image.InputName Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 8886cdaf1d41c4fc33ecf1384952f7ee1cc83590

Add FIXME *sigh* Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 98aaf41dae598c70910e70678124b027325dee5c

Return a []pullRefPair as pull results ... instead of image names; use the []pullRefPair data to reuse the original storage references directly (NOTE: this is still racy against tag changes) instead of involving the names and extra uncertainty. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 93552b25297fa0009b06cf4f6c3f2f085969adc1

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

push eventmtrmac/libpod

Miloslav Trmač

commit sha 054688039ceb89598390e06a07f4c7336f5eceab

WIP add Image.AddTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha e7b89130aa2343d47127c52f9ee702106c8af452

WIP: Add Image.RemoveTag Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 7c197ef06ba7cde55a2398783d33195d9389da3b

WIP: Introduce Image.GetHealthCheckIfSupported .. and deprecate Image.GetHealthCheck, which required callers to deal with MIME types manually. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 8eaa55edabb60c949e9acbb84943b4555286d139

Add Deprecated: notices to reduce scope a bit. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 055bd352ac4732b34d5bd1ff43e1dbe22edd82c4

Add FIXMEs to Image.History() output data structure Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 489d365257c0bb5d4e029025fa8961a8cfc1ab69

Consolidate layer-dependent history content ... to be computed in a single "if layer != nil" block, and similarly consolidate the "not an empty layer" block. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 9333cef1709d5267647ed2a0d0c1a92c35e649bf

Rename numHistories to topHistoryIndex Having "numHistories" be the number of history entries MINUS ONE hurts my brain. Should not change behavior. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha d053794fa294dec0af88cd4e346f50adf470e67c

BEHAVIOR CHANGE: Fix top-level image ID in history Use the ID of the input image, not a random ID of any image with the same top layer. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha d43c6a6d02ab5ef3111e0cc57765c6f32a7e9947

Simplify the history loop to maintain a layer ID instead of a layer pointer ... which consolidates the layer loading code, and the "no layer ID", logic into just one place. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha ff3fc0dc30444bd4a3c822c1857007ed2d64751a

Add FIXME

view details

Miloslav Trmač

commit sha 469ceea42931ae946eb404afa8b145d62a924e0c

Add FIXMEs

view details

Miloslav Trmač

commit sha dc71ff5728872e7a6e2f2de7afdabe0774d2596a

INCOMPLETE: Remove uses of Image.InputName Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 0d05b02aea65d01e4113fec9c3f150f03bac3b0d

Add FIXME WTF

view details

Miloslav Trmač

commit sha fade920bfeecea183519cc25a8d26e0ad9b8c45f

Return a []pullRefPair as pull results ... instead of image names; use the []pullRefPair data to reuse the original storage references directly (NOTE: this is still racy against tag changes) instead of involving the names and extra uncertainty. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 943fc52a9eaff1d93e65b9e38104670009074e22

API BREAK(?) Add Runtime.LoadImages to replace Runtime.LoadImage ... returning well-typed []*Image instead of a highly dubious single ", "-separated string(!!) Make a similar incompatible change to the adapter, without keeping compatibility. The varlink API was left unchanged. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

push time in 11 days

PR opened containers/libpod

Simplify image object creation

This is a refactoring that should not change behavior. Originally created primarily so that both image.Runtime and image.Image have a single constructor where I can hook the WIP new API, this:

  • Simplifies creation of Image by name, so that each caller doesn’t have to create it manually, call getLocalImage which modifies one member, and then modify another member manually
  • Modifies Runtime.getImage to return a storage.Image instead of wrapping it in an image.Image that every caller discards.
  • Removes dead code in Image.Size

See the individual commit messages for details.

+40 -64

0 comment

1 changed file

pr created time in 11 days

create barnchmtrmac/libpod

branch : image-object-creation

created branch time in 11 days

create barnchmtrmac/libpod

branch : localimage

created branch time in 11 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 To copy and sign an image:  To encrypt an image: ```sh-skopeo copy docker://docker.io/library/nginx:latest oci:local_nginx:latest+skopeo copy docker://docker.io/library/nginx:1.17.8 oci:local_nginx:1.17.8

Why this change? (It’s not obviously undesirable, but it seems quite unrelated and I can’t see why it is necessary.)

harche

comment created time in 11 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 func (s *CopySuite) TestCopyEncryption(c *check.C) { 		"oci:"+encryptedImgDir+":encrypted", "oci:"+decryptedImgDir+":decrypted")  	// Copy a standard busybox image locally-	assertSkopeoSucceeds(c, "", "copy", "docker://busybox", "oci:"+originalImageDir+":latest")+	assertSkopeoSucceeds(c, "", "copy", "docker://busybox:1.31.1", "oci:"+originalImageDir+":latest")

Why this change? (It’s not obviously undesirable, but it seems quite unrelated and I can’t see why it is necessary.)

harche

comment created time in 11 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 func (s *CopySuite) TestCopyEncryption(c *check.C) { 	defer os.RemoveAll(keysDir) 	undecryptedImgDir, err := ioutil.TempDir("", "copy-5") 	defer os.RemoveAll(undecryptedImgDir)+	MultiLayerImageDir, err := ioutil.TempDir("", "copy-6")

(lower-case first letter?)

harche

comment created time in 11 days

Pull request review commentcontainers/skopeo

Partial image encryption support

 func (opts *copyOptions) run(args []string, stdout io.Writer) error {  	if len(opts.encryptionKeys.Value()) > 0 {

Please add a check to reject the command if the user specifies --encrypt-layer without --encryption-key.

harche

comment created time in 11 days

issue openedcontainers/image

Speed up signature verification in policy evaluation

After policy evaluation is merged (but filing now as a reminder to myself), signature verification in policy evaluation, with its temporary directory creation, will take about a second per case. Both general performance and test suite interactivity would greatly benefit from speeding this up.

At the very least we can reuse the temporary directories across all verifications with a single policy; that’s why PolicyContext exists in the first place. Also look into speeding up the verification as such, there might be a cheap optimization somewhere.

created time in 13 days

issue commentcontainers/skopeo

[RFE] Support manifests list (Docker & OCI)

Skopeo has skopeo copy --all after #741.

runcom

comment created time in 13 days

issue closedcontainers/skopeo

Add configuration option for compression level

Currently, compression during copying uses the default compression level. When pushing to a registry on my LAN I don't need compression, so I'd like to set gzip.NoCompression instead (I have a local fork that hardcodes this). Other people might want to set gzip.BestCompression.

closed time in 13 days

jethrogb

issue commentcontainers/skopeo

Add configuration option for compression level

There is now --dest-compress-format and --dest-compress-level.

jethrogb

comment created time in 13 days

issue commentcontainers/skopeo

skopeo inspect command errors out with 0.1.36-dev for xenial release

@khandelwalankit04 Is this still an issue for you? It should have been fixed in Skopeo 0.1.36 and later.

khandelwalankit04

comment created time in 13 days

issue closedcontainers/skopeo

Unable to copy from ostree to docker-archive or oci-archive without compression

Related to #702, if I try to export from ostree storage to docker-archive, I get similar results as previously reported.

mkdir -p repo archives
ostree --repo=repo init
skopeo copy docker://docker.io/library/alpine:latest ostree:docker.io/library/alpine:latest@${PWD}/repo
skopeo copy ostree:docker.io/library/alpine:latest@${PWD}/repo docker-archive:archives/alpine_latest.tar

Output:

Getting image source signatures
Copying blob 1bfeebd65323 done
FATA[0000] Error writing blob: archive/tar: write too long

Similarly, if I allow uncompressed layers in an OCI archive, it also fails.

skopeo copy ostree:docker.io/library/alpine:latest@${PWD}/repo oci-archive:archives/alpine_latest.tar --dest-oci-accept-uncompressed-layers

Output:

Getting image source signatures
Copying blob 1bfeebd65323 done
FATA[0000] Error writing blob: Size mismatch when copying sha256:1bfeebd65323b8ddf5bd6a51cc7097b72788bc982e9ab3280d53d3c613adffa7, expected 2789742, got 5843968

It appears to be size calculation mismatch in both instances.

Note that copy to oci-archive with the default settings works just fine (and of course saves disk space):

skopeo copy ostree:docker.io/library/alpine:latest@${PWD}/repo oci-archive:archives/alpine_latest.tar

Output:

Getting image source signatures
Copying blob 1bfeebd65323 done
Copying config 4fa153a824 done
Writing manifest to image destination
Storing signatures

Version:

skopeo --version
skopeo version 0.1.40-dev commit: 1e044e42246c98ef7e118a07d5b4089f4957b8d7

I'm using the package I built in COPR here: https://copr.fedorainfracloud.org/coprs/g/rocknsm/testing/package/skopeo/

closed time in 13 days

dcode

issue commentcontainers/skopeo

Unable to copy from ostree to docker-archive or oci-archive without compression

This works for me now, and was probably fixed in https://github.com/containers/skopeo/commit/a36d81c55c91de002bf2db10bb39c1bad84536ef , i.e. should be available in 0.1.40.

(Note that future Skopeo versions will not build with OSTree support by default, though it is, at least currently, still possible to explicitly enable it using a build tag.)

dcode

comment created time in 13 days

delete branch mtrmac/skopeo

delete branch : openshift-api-reference

delete time in 13 days

push eventcontainers/skopeo

Miloslav Trmač

commit sha 2c0a4c9c17b0a149422e8010a04a67650d61b6ed

Remove the reference to openshift/api The referenced tag has been removed, which breaks dependabot (#791). This is another attempt to fix it, by removing an explicit reference (which was added when updating Buildah, because the version seemed newer than Buildah's v0.0.0 with a newer commit). The referenced package is never even physically vendored in here, so remove the reference: > go mod edit -droprequire=github.com/openshift/api > make vendor Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Miloslav Trmač

commit sha 97aae7a7e453bec01b650797c24c3543698a3d6f

Merge pull request #810 from mtrmac/openshift-api-reference Remove the reference to openshift/api

view details

push time in 13 days

PR merged containers/skopeo

Remove the reference to openshift/api

This is another attempt to fix #791 after ineffective #802.

The referenced tag has been removed, which breaks dependabot (#791).

This is another attempt to fix it, by removing an explicit reference (which was added when updating Buildah, because the version seemed newer than Buildah's v0.0.0 with a newer commit).

The referenced package is never even physically vendored in here, so remove the reference:

go mod edit -droprequire=github.com/openshift/api
make vendor
+0 -1

1 comment

1 changed file

mtrmac

pr closed time in 13 days

issue closedcontainers/skopeo

Dependabot can't parse your go.mod

Dependabot couldn't parse the go.mod found at /go.mod.

The error Dependabot encountered was:

go: github.com/containers/buildah@v1.11.6 requires
	github.com/openshift/api@v3.9.1-0.20190810003144-27fb16909b15+incompatible: invalid pseudo-version: preceding tag (v3.9.0) not found

View the update logs.

closed time in 13 days

dependabot-preview[bot]

pull request commentcontainers/skopeo

Remove the reference to openshift/api

(Merging without review to hopefully fix this and allow Dependabot to file PRs and run tests overnight, when Travis might be a bit less loaded.)

mtrmac

comment created time in 13 days

pull request commentcontainers/image

oci manifest: do not require whitelist of layer types

Seems like travis might be stuck? :(

Not stuck, just very slow; I’m afraid multi-hour delays are common. We do plan to move to a different infrastructure, eventually.

tych0

comment created time in 13 days

Pull request review commentcontainers/image

oci manifest: do not require whitelist of layer types

 func (list *Schema2List) UpdateInstances(updates []ListUpdate) error { 		if updates[i].MediaType == "" { 			return errors.Errorf("update %d of %d passed to Schema2List.UpdateInstances had no media type (was %q)", i+1, len(updates), list.Manifests[i].MediaType) 		}-		if err := SupportedSchema2MediaType(updates[i].MediaType); err != nil && SupportedOCI1MediaType(updates[i].MediaType) != nil {

If we are relaxing the schema2 checks here, why not do it in the other places as well (i.e. do the same edits for SupportedSchema2MediaType)? That way OCI and schema2 remain consistent.

tych0

comment created time in 13 days

Pull request review commentcontainers/image

oci manifest: do not require whitelist of layer types

 type OCI1 struct { 	imgspecv1.Manifest } -// SupportedOCI1MediaType checks if the specified string is a supported OCI1 media type.-func SupportedOCI1MediaType(m string) error {

Removing a public function would be an API break.

Please keep it around, including tests, with a https://github.com/golang/go/wiki/Deprecated comment (saying something to the effect that blindly rejecting unknown MIME types when the consumer does not need to process the input just reduces interoperability with no benefit, and that this function does not check that the media type is appropriate for any specific purpose, so it’s not all that useful for validation anyway).

tych0

comment created time in 13 days

pull request commentcontainers/image

Bump github.com/mtrmac/gpgme from 0.1.1 to 0.1.2

@dependabot rebase

dependabot-preview[bot]

comment created time in 13 days

push eventcontainers/image

Nalin Dahyabhai

commit sha 32644feb6761953669e2ad4a4c8c53fe43d12f9f

copyMultipleImages: re-serialize the list if we changed it If the only change we were making to a manifest list was to change its MIME type (i.e., other updates to the list didn't materially change its contents), we wouldn't re-serialize the list, so change how we detect that the list changed by encoding both it and the original version, and replacing the encoded copy that we'll send if they're different. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>

view details

Nalin Dahyabhai

commit sha 46d9b121c9abe9ec28c638e1eafc83bf17dd645e

determineListConversion: check forced type If determineListConversion() is given a forced type, change how we decide which type to use by treating that value as the lone supported type. This will reject unrecognized manifest types which we would have quietly accepted here, only to fail to convert them later. Add some debug messages so that we know what determineListConversion() decided, even if its decision was forced. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>

view details

Miloslav Trmač

commit sha 0e9c228071943eb3e6068ba5ac51100b69948991

Merge pull request #809 from nalind/list-conversion copyMultipleImages: re-serialize the list if we only want to change its MIME type

view details

push time in 13 days

PR merged containers/image

copyMultipleImages: re-serialize the list if we only want to change its MIME type

If the only change we were making to a manifest list was to change its MIME type (i.e., other updates to the list didn't materially change its contents), we wouldn't re-serialize the list, so we wouldn't actually change its MIME type.

+27 -16

1 comment

2 changed files

nalind

pr closed time in 13 days

PR opened containers/skopeo

Remove the reference to openshift/api

This is another attempt to fix #791 after ineffective #802.

The referenced tag has been removed, which breaks dependabot (#791).

This is another attempt to fix it, by removing an explicit reference (which was added when updating Buildah, because the version seemed newer than Buildah's v0.0.0 with a newer commit).

The referenced package is never even physically vendored in here, so remove the reference:

go mod edit -droprequire=github.com/openshift/api
make vendor
+0 -1

0 comment

1 changed file

pr created time in 13 days

create barnchmtrmac/skopeo

branch : openshift-api-reference

created branch time in 13 days

push eventmtrmac/skopeo

Daniel Strobusch

commit sha 4489ddd8a5caa0181575620c56e912032582374b

add specific authfile options to copy (and sync) command. With additional prefixed flags for authfiles, it is possible to override the shared authfile flag to use different authfiles for src and dest registries. This is an important feature if the two registries have the same domain (but different paths) and require separate credentials. Closes #773. Signed-off-by: Daniel Strobusch <1847260+dastrobu@users.noreply.github.com>

view details

Miloslav Trmač

commit sha 7cbb8ad3bab065128fdb080e4b7001832d65f9f7

Manually update buildah to v1.13.1 Should help with #791. Signed-off-by: Miloslav Trmač <mitr@redhat.com>

view details

Valentin Rothberg

commit sha a7297d4db76da41b9c593c24ace6712d72b0da61

vendor github.com/containers/image/v5@v5.2.0 See release notes: https://github.com/containers/image/releases/tag/v5.2.0 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>

view details

Daniel J Walsh

commit sha 9a0dba940db353f83a0a40eb517b661815ec1e3a

Merge pull request #807 from vrothberg/update-image vendor github.com/containers/image/v5@v5.2.0

view details

push time in 13 days

pull request commentcontainers/libpod

vendor github.com/containers/image/v5@v5.2.0

This should be fixed in github.com/mtrmac/gpgme@v0.1.2; hopefully Dependabot will propagate that throughout the stack (like https://github.com/containers/image/pull/810 ), though a new c/image release explicitly dragging it in might make sense anyway.

(Sadly, with semantic versioning enforcing vX.Y.Z, we can’t make a v0.1.1.1, and the version will drift from proglottis/gpgme. The alternative, using something like v0.1.2-mtrmac.1, would not be picked up by other consumers by default.)

vrothberg

comment created time in 13 days

created tagmtrmac/gpgme

tagv0.1.2

Go wrapper for the GPGME library

created time in 13 days

delete tag mtrmac/gpgme

delete tag : v0.1.2-mtrmac.1

delete time in 13 days

delete tag mtrmac/gpgme

delete tag : v0.1.1-mtrmac.1

delete time in 13 days

created tagmtrmac/gpgme

tagv0.1.2-mtrmac.1

Go wrapper for the GPGME library

created time in 13 days

more