Hello community,

here is the log from the commit of package docker_1_12_6 for openSUSE:Factory 
checked in at 2018-01-09 14:55:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/docker_1_12_6 (Old)
 and      /work/SRC/openSUSE:Factory/.docker_1_12_6.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "docker_1_12_6"

Tue Jan  9 14:55:02 2018 rev:6 rq:562494 version:1.12.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/docker_1_12_6/docker_1_12_6.changes      
2017-11-30 12:45:05.794561824 +0100
+++ /work/SRC/openSUSE:Factory/.docker_1_12_6.new/docker_1_12_6.changes 
2018-01-09 14:55:07.322376841 +0100
@@ -1,0 +2,29 @@
+Thu Dec 21 12:21:06 UTC 2017 - [email protected]
+
+- Enable libseccomp for Docker package build, bsc#1072367
+
+-------------------------------------------------------------------
+Tue Dec 19 12:44:25 UTC 2017 - [email protected]
+
+- Add buildmode=pie for tests and binary build. bsc#1048046 bsc#1051429
+  (similar as sr#514245 for docker package)
+
+-------------------------------------------------------------------
+Mon Dec 18 10:32:36 UTC 2017 - [email protected]
+
+- Update private-registry mirroring patch to the newest version of the
+  upstream pull request (https://github.com/moby/moby/pull/34319) to
+  improve sanity and consistency checks.
+  * private-registry-0001-Add-private-registry-mirror-support.patch
+
+-------------------------------------------------------------------
+Tue Dec 12 09:52:24 UTC 2017 - [email protected]
+
+- Update private-registry mirroring patch to reflect some feedback from
+  upstream and change the JSON config options to the Prefix/Mirrors one.
+  Notice that this patch is still subject to change until the final pull
+  request (https://github.com/moby/moby/pull/34319) is merged upstream.
+  + private-registry-0001-Implement-private-registry-mirror-support.patch
+  - private-registry-0001-Add-private-registry-mirror-support.patch
+
+-------------------------------------------------------------------
@@ -30,0 +60 @@
+  fix bsc#1074971

Old:
----
  private-registry-0001-Implement-private-registry-mirror-support.patch

New:
----
  private-registry-0001-Add-private-registry-mirror-support.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ docker_1_12_6.spec ++++++
--- /var/tmp/diff_new_pack.lpjzRV/_old  2018-01-09 14:55:09.278285151 +0100
+++ /var/tmp/diff_new_pack.lpjzRV/_new  2018-01-09 14:55:09.278285151 +0100
@@ -95,14 +95,19 @@
 # SUSE-BACKPORT: Patch fixing a DoS bug that makes certain operations fail on
 #                a libdm device. bsc#1045628
 Patch500:       
bsc1045628-0001-devicemapper-remove-container-rootfs-mountPath-after.patch
-# SUSE-FEATURE: Add support to mirror non-upstream/private registries.
-Patch600:       
private-registry-0001-Implement-private-registry-mirror-support.patch
+# SUSE-FEATURE: Add support to mirror inofficial/private registries
+#               (https://github.com/moby/moby/pull/34319)
+Patch600:       private-registry-0001-Add-private-registry-mirror-support.patch
 BuildRequires:  audit
 BuildRequires:  bash-completion
 BuildRequires:  device-mapper-devel >= 1.2.68
 BuildRequires:  glibc-devel-static
 BuildRequires:  libapparmor-devel
 BuildRequires:  libbtrfs-devel >= 3.8
+%define with_libseccomp 1
+%if 0%{?with_libseccomp}
+BuildRequires:  libseccomp-devel
+%endif
 BuildRequires:  procps
 BuildRequires:  sqlite3-devel
 BuildRequires:  systemd-devel
@@ -248,7 +253,11 @@
 (cat <<EOF
 export AUTO_GOPATH=1
 export DOCKER_BUILDTAGS="exclude_graphdriver_aufs apparmor selinux"
+%if 0%{?with_libseccomp}
+export BUILDTAGS="seccomp $BUILDTAGS"
+%endif
 export DOCKER_GITCOMMIT=%{git_version}
+export BUILDFLAGS="-buildmode=pie"
 EOF
 ) > docker_build_env
 . ./docker_build_env
@@ -262,6 +271,7 @@
 
 # build the tests binary
 GOPATH=$(pwd)/vendor:$(pwd)/.gopath/ go test \
+    -buildmode=pie \
     -tags "$DOCKER_BUILDTAGS daemon autogen" \
     -c github.com/docker/docker/integration-cli -o tests.main
 
@@ -328,9 +338,12 @@
                | grep -v 'github.com/docker/docker/cmd/dockerd$' \
                | grep -v 'github.com/docker/docker/builder/dockerfile/parser$' 
\
                | grep -v 'github.com/docker/docker/man$' \
+%if ! 0%{?with_libseccomp}
+               | grep -v 'github.com/docker/docker/profiles/seccomp$' \
+%endif
                | grep -v 'github.com/docker/docker/pkg/integration$')
 
-go test -cover -ldflags -w -tags $EXCLUDE_TAGS -a -test.timeout=10m $PKG_LIST
+go test -buildmode=pie -cover -ldflags -w -tags $EXCLUDE_TAGS -a 
-test.timeout=10m $PKG_LIST
 %endif
 
 %install

++++++ private-registry-0001-Add-private-registry-mirror-support.patch ++++++
>From cee4836847f76d3f7120489d17fa6e705da197a4 Mon Sep 17 00:00:00 2001
From: Valentin Rothberg <[email protected]>
Date: Fri, 28 Jul 2017 16:15:04 +0200
Subject: [PATCH] Add private-registry mirror support

NOTE: This backport patch does NOT support the prefix semantics as
described below.  Instead, only the host of each prefix will be used.
Therefore, there can only be one prefix for a given host.  The daemon
will panic in case more than one prefix point to the same host.

Add support for mirroring private registries.  The daemon.json config
can now be configured as exemplified below:

```json
{
"registries": [
        {
        "Prefix": "docker.io/alpine",
        "Mirrors": [
                {
                        "URL": "http://local-alpine-mirror.lan";,
                }
        ]
        },
        {
        "Prefix": "registry.suse.com",
        "Mirrors": [
                {
                        "URL": "https://remote.suse.mirror.com";
                }
        ]
        },
        {
        "Prefix": "http://insecure.registry.org:5000";
        }
],
"registry-mirrors": ["https://deprecated-mirror.com";]
}
```

With the new semantics, a mirror will be selected as an endpoint if the
specified prefix matches the prefix of the requested resource (e.g., an
image reference).  In the upper example, "local-alpine-mirror" will only
serve as a mirror for docker.io if the requested resource matches the
"alpine" prefix, such as "alpine:latest" or "alpine-foo/bar".

Furthermore, private registries can now be mirrored as well.  In the
example above, "remote.suse.mirror.com" will serve as a mirror for all
requests to "registry.suse.com".  Notice that if no http{s,} scheme is
specified, the URI will always default to https without fallback to
http.  An insecure registry can now be specified by adding the "http://";
scheme to the corresponding prefix.

Note that the configuration is sanity checked, so that a given mirror
can serve multiple prefixes if they all point to the same registry,
while a registry cannot simultaneously serve as a mirror.  The daemon
will warn in case the URI schemes of a registry and one of its mirrors
do not correspond.

This change deprecates the "insecure-regestries" and "registry-mirrors"
options, while the "insecure-registries" cannot be used simultaneously
with the new "registries", which doesn't allow a fallback from https to
http for security reasons.

Signed-off-by: Flavio Castelli <[email protected]>
Signed-off-by: Valentin Rothberg <[email protected]>
---
 daemon/config.go                        |   4 +
 distribution/pull.go                    |   3 +-
 distribution/pull_v2.go                 |   2 +-
 integration-cli/docker_api_auth_test.go |   2 +-
 registry/config.go                      | 212 +++++++++++++++++++++++++++++++-
 registry/service_v2.go                  |  64 +++++++---
 6 files changed, 266 insertions(+), 21 deletions(-)

diff --git a/daemon/config.go b/daemon/config.go
index bf568efefa5c..3542d0508c45 100644
--- a/daemon/config.go
+++ b/daemon/config.go
@@ -340,6 +340,10 @@ func findConfigurationConflicts(config 
map[string]interface{}, flags *flag.FlagS
        // 1. Search keys from the file that we don't recognize as flags.
        unknownKeys := make(map[string]interface{})
        for key, value := range config {
+               // skip config-only options (daemon.json)
+               if key == "registries" {
+                       continue
+               }
                flagName := "-" + key
                if flag := flags.Lookup(flagName); flag == nil {
                        unknownKeys[key] = value
diff --git a/distribution/pull.go b/distribution/pull.go
index dad93b656d65..707a918e8ae6 100644
--- a/distribution/pull.go
+++ b/distribution/pull.go
@@ -129,10 +129,11 @@ func Pull(ctx context.Context, ref reference.Named, 
imagePullConfig *ImagePullCo
                        }
                }
 
-               logrus.Debugf("Trying to pull %s from %s %s", repoInfo.Name(), 
endpoint.URL, endpoint.Version)
+               logrus.Infof("Trying to pull %s from %s %s", repoInfo.Name(), 
endpoint.URL, endpoint.Version)
 
                puller, err := newPuller(endpoint, repoInfo, imagePullConfig)
                if err != nil {
+                       logrus.Infof("Error pulling %s from %s %s: %v", 
repoInfo.Name(), endpoint.URL, endpoint.Version, err)
                        lastErr = err
                        continue
                }
diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go
index 5a786fba4bb5..f0d77245d4c8 100644
--- a/distribution/pull_v2.go
+++ b/distribution/pull_v2.go
@@ -371,7 +371,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref 
reference.Named) (tagUpdat
        // the other side speaks the v2 protocol.
        p.confirmedV2 = true
 
-       logrus.Debugf("Pulling ref from V2 registry: %s", ref.String())
+       logrus.Infof("Pulling ref %s from V2 registry %s", ref.String(), 
p.endpoint.URL)
        progress.Message(p.config.ProgressOutput, tagOrDigest, "Pulling from 
"+p.repo.Named().Name())
 
        var (
diff --git a/integration-cli/docker_api_auth_test.go 
b/integration-cli/docker_api_auth_test.go
index d73c61d4116f..7e9f64329a5f 100644
--- a/integration-cli/docker_api_auth_test.go
+++ b/integration-cli/docker_api_auth_test.go
@@ -16,7 +16,7 @@ func (s *DockerSuite) TestAuthApi(c *check.C) {
                Password: "no-password",
        }
 
-       expected := "Get https://registry-1.docker.io/v2/: unauthorized: 
incorrect username or password"
+       expected := "Get https://index.docker.io/v2/: unauthorized: incorrect 
username or password"
        status, body, err := sockRequest("POST", "/auth", config)
        c.Assert(err, check.IsNil)
        c.Assert(status, check.Equals, http.StatusUnauthorized)
diff --git a/registry/config.go b/registry/config.go
index e349660e3261..d456abc2244c 100644
--- a/registry/config.go
+++ b/registry/config.go
@@ -11,9 +11,40 @@ import (
        flag "github.com/docker/docker/pkg/mflag"
        "github.com/docker/docker/reference"
        registrytypes "github.com/docker/engine-api/types/registry"
+       "github.com/Sirupsen/logrus"
 )
 
-// ServiceOptions holds command line options.
+// Registry holds information for a registry and its mirrors.
+type Registry struct {
+       // Prefix is used for the lookup of endpoints, where the given registry
+       // is selected when its Prefix is a prefix of the passed reference, for
+       // instance, Prefix:"docker.io/opensuse" will match a `docker pull
+       // opensuse:tumleweed`.
+       Prefix string `json:"Prefix,omitempty"`
+       // The mirrors will be selected prior to the registry during lookup of
+       // endpoints.
+       Mirrors []Mirror `json:"Mirrors,omitempty"`
+       // Host is the host of the registry (e.g., "docker.io")
+       Host string
+       // This avoids to parse the URL of each new endpoint lookup.
+       URL *url.URL
+       // True if the host is "docker.io".
+       Official bool
+       // True if URL.Scheme == "https".
+       Secure bool
+}
+
+// Mirror holds information for a given registry mirror.
+type Mirror struct {
+       // Host is the URL specified by the user.  At deamon start, the passed
+       // URL will be loaded into Mirror.URL and corresponding host stored in
+       // Mirror.Host.
+       Host string `json:"URL"`
+       // This avoids to parse the URL of each new endpoint lookup.
+       URL *url.URL
+}
+
+// ServiceOptions holds the user-specified configuration options.
 type ServiceOptions struct {
        Mirrors            []string `json:"registry-mirrors,omitempty"`
        InsecureRegistries []string `json:"insecure-registries,omitempty"`
@@ -21,12 +52,18 @@ type ServiceOptions struct {
        // V2Only controls access to legacy registries.  If it is set to true 
via the
        // command line flag the daemon will not attempt to contact v1 legacy 
registries
        V2Only bool `json:"disable-legacy-registry,omitempty"`
+
+       // Registries holds information associated with the specified 
registries.
+       Registries []Registry `json:"registries,omitempty"`
 }
 
 // serviceConfig holds daemon configuration for the registry service.
 type serviceConfig struct {
        registrytypes.ServiceConfig
        V2Only bool
+
+       // Registries holds information associated with the specified 
registries.
+       Registries map[string]Registry
 }
 
 var (
@@ -82,6 +119,13 @@ func (options *ServiceOptions) InstallCliFlags(cmd 
*flag.FlagSet, usageFn func(s
 
 // newServiceConfig returns a new instance of ServiceConfig
 func newServiceConfig(options ServiceOptions) *serviceConfig {
+       // The deprecated insecure-regitry flag conflicts with the semantics of
+       // the new Registries options, as they do NOT fallback to an insecure
+       // connection.
+       if len(options.InsecureRegistries) > 0 && len(options.Registries) > 0 {
+               panic("error: usage of \"registries\" with deprecated option 
\"insecure-registries\" is not supported")
+       }
+
        // Localhost is by default considered as an insecure registry
        // This is a stop-gap for people who are running a private registry on 
localhost (especially on Boot2docker).
        //
@@ -125,9 +169,175 @@ func newServiceConfig(options ServiceOptions) 
*serviceConfig {
                Official: true,
        }
 
+       if err := config.LoadRegistries(options.Registries); err != nil {
+               panic(fmt.Sprintf("[proxy path] Error loading registries: 
%s\n", err))
+       }
+
+       // Only print if registries are specified.  This avoids some annoying
+       // logs from the client, which still shares code in this version of
+       // Docker.
+       if len(options.Registries) > 0 {
+               logrus.Infof("[proxy patch] loaded registries: %v", 
config.Registries)
+       }
+
        return config
 }
 
+// checkRegistries makes sure that no mirror serves more than one registry and
+// that no host is used as a registry and as a mirror simultaneously.  Notice
+// that different registry prefixes can share a mirror as long as they point to
+// the same registry.  It also warns if the URI schemes of a given registry and
+// one of its mirrors differ.
+func (config *serviceConfig) checkRegistries() error {
+       inUse := make(map[string]string) // key: host, value: user
+
+       // make sure that each mirror serves only one registry
+       for _, reg := range config.Registries {
+               for _, mirror := range reg.Mirrors {
+                       if used, conflict := inUse[mirror.Host]; conflict {
+                               if used != reg.URL.Host {
+                                       return fmt.Errorf("mirror '%s' can only 
serve one registry", mirror.Host)
+                               }
+                       }
+                       inUse[mirror.Host] = reg.Host
+                       // also warnf if seucurity levels differ
+                       if reg.URL.Scheme != mirror.URL.Scheme {
+                               logrus.Warnf("registry '%s' and mirror '%s' 
have different security levels", reg.URL, mirror.URL)
+                       }
+               }
+               if reg.Secure && len(reg.Mirrors) == 0 {
+                       logrus.Warnf("specifying secure registry '%s' without 
mirrors has no effect", reg.Prefix)
+               }
+       }
+
+       // make sure that no registry host is used as a mirror
+       for _, reg := range config.Registries {
+               if _, conflict := inUse[reg.Host]; conflict {
+                       return fmt.Errorf("registry '%s' cannot simultaneously 
serve as a mirror for '%s'", reg.URL.Host, inUse[reg.Host])
+               }
+       }
+       return nil
+}
+
+// FindRegistry returns a registry based on the passed reference.  If more than
+// one index-prefix match the reference, the longest index is returned.  In
+// case of no match, regFound is false.
+func (config *serviceConfig) FindRegistry(reference string) (reg Registry, 
regFound bool) {
+       prefixStr := ""
+       prefixLen := 0
+       for _, reg := range config.Registries {
+               if strings.HasPrefix(reference, reg.Prefix) {
+                       length := len(reg.Prefix)
+                       if length > prefixLen {
+                               prefixStr = reg.Prefix
+                               prefixLen = length
+                       }
+               }
+       }
+       if prefixLen > 0 {
+               logrus.Debugf("[findRegistry] found registry %v for '%s'", 
config.Registries[prefixStr], reference)
+               return config.Registries[prefixStr], true
+       }
+       logrus.Debugf("[findRegistry] couldn't find registry for '%s'", 
reference)
+       return Registry{}, false
+}
+
+// prepareMirror sets the corresponding data in mirror based on its host.
+func prepareMirror(mirror *Mirror) error {
+       var err error
+
+       if !strings.HasPrefix(mirror.Host, "http://";) && 
!strings.HasPrefix(mirror.Host, "https://";) {
+               mirror.Host = "https://"; + mirror.Host
+       }
+
+       mirror.Host, err = ValidateMirror(mirror.Host)
+       if err != nil {
+               return fmt.Errorf("invalid mirror: %s", err)
+       }
+
+       mirror.URL, _ = url.Parse(mirror.Host)
+       mirror.Host = mirror.URL.Host // host:port
+       return nil
+}
+
+// loadRegistry loads the specified registry into config.Registries, which is
+// used for endpoint lookups.  Notice that all sanity and consistency checks
+// are deferred to config.checkRegistries().
+func (config *serviceConfig) loadRegistry(reg Registry) error {
+       if reg.Prefix == "" {
+               reg.Prefix = IndexName
+       }
+       reg.Prefix = strings.ToLower(reg.Prefix)
+
+       // parse and set the URL of the registry
+       prefURL := reg.Prefix
+       if !strings.HasPrefix(reg.Prefix, "http://";) && 
!strings.HasPrefix(reg.Prefix, "https://";) {
+               prefURL = "https://"; + prefURL
+       }
+       u, err := url.Parse(prefURL)
+       if err != nil {
+               return fmt.Errorf("cannot parse prefix '%s'", reg.Prefix)
+       }
+       // XXX: the host is used as the prefix
+       reg.Prefix = u.Host // host:port
+       reg.Host = u.Host   // host:port
+       reg.URL = u
+
+       if _, exists := config.Registries[reg.Prefix]; exists {
+               return fmt.Errorf("multiple prefixes pointing to host '%s': 
unsupported for this version of Docker", reg.Host)
+       }
+
+       if reg.URL.Scheme == "https" {
+               reg.Secure = true
+       }
+
+       if reg.URL.Host == IndexName || reg.URL.Host == DefaultNamespace {
+               reg.Official = true
+       }
+
+       // validate and set mirrors
+       for i := range reg.Mirrors {
+               if err := prepareMirror(&reg.Mirrors[i]); err != nil {
+                       return err
+               }
+       }
+
+       config.Registries[reg.Prefix] = reg
+
+       return nil
+}
+
+// LoadRegistries loads the user-specified configuration options for 
registries.
+func (config *serviceConfig) LoadRegistries(registries []Registry) error {
+       config.Registries = make(map[string]Registry)
+
+       for _, reg := range registries {
+               if err := config.loadRegistry(reg); err != nil {
+                       return err
+               }
+       }
+
+       if len(config.Mirrors) > 0 {
+               mirrors := []Mirror{}
+               for _, host := range config.Mirrors {
+                       mirror := Mirror{Host: host}
+                       if err := prepareMirror(&mirror); err != nil {
+                               return err
+                       }
+                       mirrors = append(mirrors, mirror)
+               }
+               if _, exists := config.Registries[IndexName]; !exists {
+                       if err := config.loadRegistry(Registry{Prefix: 
IndexName}); err != nil {
+                               return err
+                       }
+               }
+               reg := config.Registries[IndexName]
+               reg.Mirrors = append(reg.Mirrors, mirrors...)
+               config.Registries[IndexName] = reg
+       }
+       return config.checkRegistries()
+}
+
 // isSecureIndex returns false if the provided indexName is part of the list 
of insecure registries
 // Insecure registries accept HTTP and/or accept HTTPS with certificates from 
unknown CAs.
 //
diff --git a/registry/service_v2.go b/registry/service_v2.go
index 5e62f8ff8c68..20cc8ce4c0c0 100644
--- a/registry/service_v2.go
+++ b/registry/service_v2.go
@@ -1,43 +1,73 @@
 package registry
 
 import (
+       "fmt"
        "net/url"
        "strings"
 
        "github.com/docker/go-connections/tlsconfig"
+       "github.com/Sirupsen/logrus"
 )
 
-func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints 
[]APIEndpoint, err error) {
+func (s *DefaultService) lookupV2Endpoints(reference string) (endpoints 
[]APIEndpoint, err error) {
        var cfg = tlsconfig.ServerDefault
        tlsConfig := &cfg
-       if hostname == DefaultNamespace || hostname == DefaultV1Registry.Host {
-               // v2 mirrors
-               for _, mirror := range s.config.Mirrors {
-                       if !strings.HasPrefix(mirror, "http://";) && 
!strings.HasPrefix(mirror, "https://";) {
-                               mirror = "https://"; + mirror
-                       }
-                       mirrorURL, err := url.Parse(mirror)
-                       if err != nil {
-                               return nil, err
+
+       logrus.Debugf("[lookupV2Endpoints] reference: %s", reference)
+
+       // as the reference can be a prefix, extract the hostname with 
URL.Parse()
+       refURL := reference
+       if !strings.HasPrefix(refURL, "http://";) && !strings.HasPrefix(refURL, 
"https://";) {
+               refURL = "https://"; + refURL
+       }
+       u, err := url.Parse(refURL)
+       if err != nil {
+               return nil, fmt.Errorf("[lookupV2Endpoints] error parsing 
reference %s: %s", reference, err)
+       }
+
+       hostname := u.Host // hostname + port (if present)
+       if hostname == "" {
+               return nil, fmt.Errorf("[lookupV2Endpoints] cannot determine 
hostname of reference %s", reference)
+       }
+
+       // create endpoints for official and configured registries
+       reg, foundReg := s.config.FindRegistry(reference)
+       official := false
+       if hostname == DefaultNamespace || hostname == IndexName || 
reg.Official {
+               official = true
+       }
+       if foundReg || official {
+               // set the URL of the registry
+               var endpointURL *url.URL
+               if official {
+                       endpointURL = DefaultV2Registry
+               } else {
+                       endpointURL = &url.URL{
+                               Scheme: reg.URL.Scheme,
+                               Host:   reg.URL.Host,
                        }
-                       mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL)
+               }
+
+               // if present, add mirrors before the registry
+               for _, mirror := range reg.Mirrors {
+                       mirrorTLSConfig, err := s.tlsConfigForMirror(mirror.URL)
                        if err != nil {
-                               return nil, err
+                               return nil, fmt.Errorf("[lookupV2Endpoints] 
%s", err)
                        }
                        endpoints = append(endpoints, APIEndpoint{
-                               URL: mirrorURL,
-                               // guess mirrors are v2
+                               URL:          mirror.URL,
                                Version:      APIVersion2,
                                Mirror:       true,
                                TrimHostname: true,
                                TLSConfig:    mirrorTLSConfig,
                        })
                }
-               // v2 registry
+
+               // add the registry
                endpoints = append(endpoints, APIEndpoint{
-                       URL:          DefaultV2Registry,
+                       URL:          endpointURL,
                        Version:      APIVersion2,
-                       Official:     true,
+                       Official:     official,
                        TrimHostname: true,
                        TLSConfig:    tlsConfig,
                })
-- 
2.13.6


Reply via email to