diff --git a/_service b/_service
index 6520ecd..e2962f5 100644
--- a/_service
+++ b/_service
@@ -3,8 +3,8 @@
https://github.com/docker/docker.git
git
.git
- 1.12.6
- v1.12.6
+ 1.13.0
+ v1.13.0
docker-*.tar
diff --git a/docker-1.12.6.tar.xz b/docker-1.12.6.tar.xz
deleted file mode 100644
index 250ec17..0000000
--- a/docker-1.12.6.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ade8df08afa29834e772ae9061975801ff35bd2b4c7979df4ff4df8f22ffce8c
-size 11190120
diff --git a/docker-1.13.0.tar.xz b/docker-1.13.0.tar.xz
new file mode 100644
index 0000000..8e5b482
--- /dev/null
+++ b/docker-1.13.0.tar.xz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1da90f2f637d55c7bef034761f0781a7cc4facdefc50b9d77f0c6a78185efe0a
+size 5130016
diff --git a/docker-mount-secrets.patch b/docker-mount-secrets.patch
deleted file mode 100644
index b6e8963..0000000
--- a/docker-mount-secrets.patch
+++ /dev/null
@@ -1,413 +0,0 @@
-From 17cd15ba4160f0e0830453529b9b01edc308d847 Mon Sep 17 00:00:00 2001
-From: Aleksa Sarai
-Date: Mon, 11 Apr 2016 22:54:35 +1000
-Subject: [PATCH] SUSE: implement SUSE container secrets
-
-This allows for us to pass in host credentials to a container, allowing
-for SUSEConnect to work with containers.
-
-THIS PATCH IS NOT TO BE UPSTREAMED, DUE TO THE FACT THAT IT IS
-SUSE-SPECIFIC, AND UPSTREAM DOES NOT APPROVE OF THIS CONCEPT BECAUSE IT
-MAKES BUILDS NOT ENTIRELY REPRODUCIBLE.
-
-Signed-off-by: Aleksa Sarai
----
- container/container_unix.go | 63 ++++++++++++
- daemon/container_operations_unix.go | 50 ++++++++++
- daemon/daemon_unix.go | 6 +-
- daemon/oci_linux.go | 6 ++
- daemon/start.go | 6 ++
- daemon/suse_secrets.go | 184 ++++++++++++++++++++++++++++++++++++
- 6 files changed, 313 insertions(+), 2 deletions(-)
- create mode 100644 daemon/suse_secrets.go
-
-diff --git a/container/container_unix.go b/container/container_unix.go
-index 2727b81..07a0710 100644
---- a/container/container_unix.go
-+++ b/container/container_unix.go
-@@ -35,6 +35,8 @@ type Container struct {
- HostsPath string
- ShmPath string
- ResolvConfPath string
-+ // SUSE:secrets :: We need to add the container-specific secrets path here.
-+ SuseSecretsPath string
- SeccompProfile string
- NoNewPrivileges bool
- }
-@@ -256,6 +258,67 @@ func (container *Container) IpcMounts() []Mount {
- return mounts
- }
-
-+// SUSE:secrets :: SuseSecretsResourcePath returns the path to the container's
-+// personal /run/secrets tmpfs.
-+func (container *Container) SuseSecretsResourcePath() (string, error) {
-+ return container.GetRootResourcePath("suse.secrets")
-+}
-+
-+// SUSE:secrets :: SuseSecretMounts returns the list of mounts required for the
-+// SUSE-specific /run/secrets patch. The container's personal /run/secrets tmpfs
-+// has already been set up at this point.
-+func (container *Container) SuseSecretMounts() []Mount {
-+ var mounts []Mount
-+
-+ logrus.WithFields(logrus.Fields{
-+ "container": container.ID,
-+ "path": container.SuseSecretsPath,
-+ "hasmount": container.HasMountFor("/run/secrets"),
-+ }).Debug("SUSE:secrets :: adding container secrets to mountpoint")
-+
-+ // TODO(SUSE): How do we register for HasMountFor().
-+ if !container.HasMountFor("/run/secrets") {
-+ label.SetFileLabel(container.SuseSecretsPath, container.MountLabel)
-+ mounts = append(mounts, Mount{
-+ Source: container.SuseSecretsPath,
-+ Destination: "/run/secrets",
-+ Writable: true,
-+ Propagation: volume.DefaultPropagationMode,
-+ })
-+ }
-+
-+ return mounts
-+}
-+
-+// SUSE:secrets :: Unmounts the container's personal /run/secrets tmpfs using the
-+// provided function. This is done to clean up the mountpoints properly.
-+func (container *Container) UnmountSuseSecretMounts(unmount func(string) error) {
-+ logrus.WithFields(logrus.Fields{
-+ "container": container.ID,
-+ "hasmount": container.HasMountFor("/run/secrets"),
-+ }).Debug("SUSE:secrets :: requested to clean up container secrets")
-+
-+ if !container.HasMountFor("/run/secrets") {
-+ logrus.Debugf("SUSE:secrets :: cleaning up secrets mount for container")
-+
-+ suseSecretsPath, err := container.SuseSecretsResourcePath()
-+ if err != nil {
-+ logrus.Error("SUSE:secrets :: failed to clean up secrets mounts: no secrets resource path found for container %v: %v", container.ID, err)
-+ }
-+
-+ if suseSecretsPath != "" {
-+ logrus.WithFields(logrus.Fields{
-+ "path": suseSecretsPath,
-+ }).Debugf("SUSE:secrets :: actually unmounting conatiner secrets")
-+
-+ if err := unmount(suseSecretsPath); err != nil && !os.IsNotExist(err) {
-+ // We can't error out here.
-+ logrus.Warnf("SUSE:secrets :: failed to clean up secrets mounts: failed to umount %s: %v", suseSecretsPath, err)
-+ }
-+ }
-+ }
-+}
-+
- // UpdateContainer updates configuration of a container.
- func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error {
- container.Lock()
-diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go
-index 55bd3fc..a3ab7fb 100644
---- a/daemon/container_operations_unix.go
-+++ b/daemon/container_operations_unix.go
-@@ -184,6 +184,56 @@ func (daemon *Daemon) getPidContainer(container *container.Container) (*containe
- return c, nil
- }
-
-+// SUSE:secrets :: Create a container's personal /run/secrets tmpfs and fill it
-+// with the host's credentials.
-+func (daemon *Daemon) setupSuseSecrets(c *container.Container) (err error) {
-+ c.SuseSecretsPath, err = c.SuseSecretsResourcePath()
-+ if err != nil {
-+ return err
-+ }
-+
-+ if !c.HasMountFor("/run/secrets") {
-+ rootUID, rootGID := daemon.GetRemappedUIDGID()
-+ if err = idtools.MkdirAllAs(c.SuseSecretsPath, 0700, rootUID, rootGID); err != nil {
-+ return fmt.Errorf("SUSE:secrets :: failed to create container secret: %v", err)
-+ }
-+ if err = syscall.Mount("tmpfs", c.SuseSecretsPath, "tmpfs", uintptr(syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV), label.FormatMountLabel("", c.GetMountLabel())); err != nil {
-+ return fmt.Errorf("SUSE:secrets :: mounting secrets tmpfs: %v", err)
-+ }
-+ // We need to defer a cleanup, to make sure errors that occur before the container
-+ // starts don't cause wasted memory due to tmpfs-es that aren't being used.
-+ defer func() {
-+ if err != nil {
-+ logrus.Infof("SUSE::secrets :: cleaning up secrets mount due to failed setup")
-+ c.UnmountSuseSecretMounts(detachMounted)
-+ }
-+ }()
-+ if err = os.Chown(c.SuseSecretsPath, rootUID, rootGID); err != nil {
-+ return fmt.Errorf("SUSE:secrets :: failed to chown container secret to (uid=%d,gid=%d): %v", rootUID, rootGID, err)
-+ }
-+
-+ // Now we need to inject the credentials. But in order to play properly with
-+ // user namespaces, they must be owned by rootUID:rootGID.
-+
-+ data, err := getHostSuseSecretData()
-+ if err != nil {
-+ return fmt.Errorf("SUSE:secrets :: failed to get host secret data: %v", err)
-+ }
-+
-+ uidMap, gidMap := daemon.GetUIDGIDMaps()
-+ for _, s := range data {
-+ if err := s.SaveTo(c.SuseSecretsPath, uidMap, gidMap); err != nil {
-+ logrus.WithFields(logrus.Fields{
-+ "s.path": s.Path,
-+ "path": c.SuseSecretsPath,
-+ }).Errorf("SUSE:secrets :: failed to save secret data: %v", err)
-+ }
-+ }
-+ }
-+
-+ return
-+}
-+
- func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
- var err error
-
-diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go
-index f266912..2ced1b8 100644
---- a/daemon/daemon_unix.go
-+++ b/daemon/daemon_unix.go
-@@ -809,8 +809,10 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
- // the container from unwanted side-effects on the rw layer.
- func setupInitLayer(initLayer string, rootUID, rootGID int) error {
- for pth, typ := range map[string]string{
-- "/dev/pts": "dir",
-- "/dev/shm": "dir",
-+ "/dev/pts": "dir",
-+ "/dev/shm": "dir",
-+ // SUSE:secrets :: We need to add the mountpoint in the init layer.
-+ "/run/secrets": "dir",
- "/proc": "dir",
- "/sys": "dir",
- "/.dockerenv": "file",
-diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go
-index 4459d02..6af7d35 100644
---- a/daemon/oci_linux.go
-+++ b/daemon/oci_linux.go
-@@ -656,6 +656,10 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
- if err := daemon.setupIpcDirs(c); err != nil {
- return nil, err
- }
-+ // SUSE:secrets :: We need to set up the container-specific secrets tmpfs here.
-+ if err := daemon.setupSuseSecrets(c); err != nil {
-+ return nil, err
-+ }
-
- ms, err := daemon.setupMounts(c)
- if err != nil {
-@@ -663,6 +667,8 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
- }
- ms = append(ms, c.IpcMounts()...)
- ms = append(ms, c.TmpfsMounts()...)
-+ // SUSE:secrets :: We add the mounts to the OCI config which containerd then uses.
-+ ms = append(ms, c.SuseSecretMounts()...)
- sort.Sort(mounts(ms))
- if err := setMounts(daemon, &s, c, ms); err != nil {
- return nil, fmt.Errorf("linux mounts: %v", err)
-diff --git a/daemon/start.go b/daemon/start.go
-index fcf24c5..57a8c33 100644
---- a/daemon/start.go
-+++ b/daemon/start.go
-@@ -173,6 +173,12 @@ func (daemon *Daemon) Cleanup(container *container.Container) {
-
- container.UnmountIpcMounts(detachMounted)
-
-+ // TODO(SUSE): Make sure this gets called by containerCleanup. Do we need to
-+ // port this part of the patch there as well?
-+
-+ // SUSE:secrets :: We need to unmount stuff here so that we clean up properly.
-+ container.UnmountSuseSecretMounts(detachMounted)
-+
- if err := daemon.conditionalUnmountOnCleanup(container); err != nil {
- // FIXME: remove once reference counting for graphdrivers has been refactored
- // Ensure that all the mounts are gone
-diff --git a/daemon/suse_secrets.go b/daemon/suse_secrets.go
-new file mode 100644
-index 0000000..417a1a9
---- /dev/null
-+++ b/daemon/suse_secrets.go
-@@ -0,0 +1,184 @@
-+package daemon
-+
-+// SUSE:secrets :: This is a set of functions to copy host credentials into a
-+// container's /run/secrets.
-+
-+import (
-+ "io/ioutil"
-+ "os"
-+ "path/filepath"
-+ "syscall"
-+
-+ "github.com/Sirupsen/logrus"
-+ "github.com/docker/docker/pkg/idtools"
-+)
-+
-+// TODO(SUSE): We need to reimplement this to use tar. Immediately.
-+
-+// Creating a fake file.
-+type SuseFakeFile struct {
-+ Path string
-+ Uid int
-+ Gid int
-+ Mode os.FileMode
-+ Data []byte
-+}
-+
-+func (s *SuseFakeFile) SaveTo(dir string, uidMap, gidMap []idtools.IDMap) error {
-+ // Create non-existant path components with an owner of root (other FakeFiles
-+ // will clean this up if the owner is critical).
-+ rootUid, rootGid, err := idtools.GetRootUIDGID(uidMap, gidMap)
-+
-+ path := filepath.Join(dir, s.Path)
-+ if err := idtools.MkdirAllNewAs(filepath.Dir(path), 0755, rootUid, rootGid); err != nil && !os.IsExist(err) {
-+ return err
-+ }
-+
-+ uid, err := idtools.ToHost(s.Uid, uidMap)
-+ if err != nil {
-+ return err
-+ }
-+
-+ gid, err := idtools.ToHost(s.Gid, gidMap)
-+ if err != nil {
-+ return err
-+ }
-+
-+ if s.Mode.IsDir() {
-+ if err := idtools.MkdirAs(path, s.Mode, uid, gid); err != nil {
-+ return err
-+ }
-+ } else {
-+ if err := ioutil.WriteFile(path, s.Data, s.Mode); err != nil {
-+ return err
-+ }
-+ }
-+
-+ return os.Chown(path, uid, gid)
-+}
-+
-+// readDir will recurse into a directory prefix/dir, and return the set of secrets
-+// in that directory. The Path attribute of each has the prefix stripped. Symlinks
-+// are evaluated.
-+func readDir(prefix, dir string) ([]*SuseFakeFile, error) {
-+ var suseFiles []*SuseFakeFile
-+
-+ path := filepath.Join(prefix, dir)
-+
-+ fi, err := os.Stat(path)
-+ if err != nil {
-+ // Ignore dangling symlinks.
-+ if os.IsNotExist(err) {
-+ logrus.Warnf("SUSE:secrets :: dangling symlink: %s", path)
-+ return suseFiles, nil
-+ }
-+ return nil, err
-+ }
-+
-+ stat, ok := fi.Sys().(*syscall.Stat_t)
-+ if !ok {
-+ logrus.Warnf("SUSE:secrets :: failed to cast directory stat_t: defaulting to owned by root:root: %s", path)
-+ }
-+
-+ suseFiles = append(suseFiles, &SuseFakeFile{
-+ Path: dir,
-+ Uid: int(stat.Uid),
-+ Gid: int(stat.Gid),
-+ Mode: fi.Mode(),
-+ })
-+
-+ files, err := ioutil.ReadDir(path)
-+ if err != nil {
-+ return nil, err
-+ }
-+
-+ for _, f := range files {
-+ subpath := filepath.Join(dir, f.Name())
-+
-+ if f.IsDir() {
-+ secrets, err := readDir(prefix, subpath)
-+ if err != nil {
-+ return nil, err
-+ }
-+ suseFiles = append(suseFiles, secrets...)
-+ } else {
-+ secrets, err := readFile(prefix, subpath)
-+ if err != nil {
-+ return nil, err
-+ }
-+ suseFiles = append(suseFiles, secrets...)
-+ }
-+ }
-+
-+ return suseFiles, nil
-+}
-+
-+func readFile(prefix, file string) ([]*SuseFakeFile, error) {
-+ var suseFiles []*SuseFakeFile
-+
-+ path := filepath.Join(prefix, file)
-+ fi, err := os.Stat(path)
-+ if err != nil {
-+ // Ignore dangling symlinks.
-+ if os.IsNotExist(err) {
-+ logrus.Warnf("SUSE:secrets :: dangling symlink: %s", path)
-+ return suseFiles, nil
-+ }
-+ return nil, err
-+ }
-+
-+ stat, ok := fi.Sys().(*syscall.Stat_t)
-+ if !ok {
-+ logrus.Warnf("SUSE:secrets :: failed to cast file stat_t: defaulting to owned by root:root: %s", path)
-+ }
-+
-+ if fi.IsDir() {
-+ secrets, err := readDir(prefix, file)
-+ if err != nil {
-+ return nil, err
-+ }
-+ suseFiles = append(suseFiles, secrets...)
-+ } else {
-+ bytes, err := ioutil.ReadFile(path)
-+ if err != nil {
-+ return nil, err
-+ }
-+ suseFiles = append(suseFiles, &SuseFakeFile{
-+ Path: file,
-+ Uid: int(stat.Uid),
-+ Gid: int(stat.Gid),
-+ Mode: fi.Mode(),
-+ Data: bytes,
-+ })
-+ }
-+
-+ return suseFiles, nil
-+}
-+
-+func getHostSuseSecretData() ([]*SuseFakeFile, error) {
-+ secrets := []*SuseFakeFile{}
-+
-+ credentials, err := readDir("/etc/zypp", "credentials.d")
-+ if err != nil {
-+ if os.IsNotExist(err) {
-+ credentials = []*SuseFakeFile{}
-+ } else {
-+ logrus.Errorf("SUSE:secrets :: error while reading zypp credentials: %s", err)
-+ return nil, err
-+ }
-+ }
-+ secrets = append(secrets, credentials...)
-+
-+ suseConnect, err := readFile("/etc", "SUSEConnect")
-+ if err != nil {
-+ if os.IsNotExist(err) {
-+ suseConnect = []*SuseFakeFile{}
-+ } else {
-+ logrus.Errorf("SUSE:secrets :: error while reading /etc/SUSEConnect: %s", err)
-+ return nil, err
-+ }
-+ }
-+ secrets = append(secrets, suseConnect...)
-+
-+ return secrets, nil
-+}
diff --git a/docker.changes b/docker.changes
index 779dc97..1e620f2 100644
--- a/docker.changes
+++ b/docker.changes
@@ -1,3 +1,56 @@
+-------------------------------------------------------------------
+Fri Mar 17 11:08:03 UTC 2017 - asarai@suse.com
+
+- Add a backport of fix to AppArmor lazy loading docker-exec case.
+ https://github.com/docker/docker/pull/31773
+ + pr31773-daemon-also-ensureDefaultApparmorProfile-in-exec-pat.patch
+
+-------------------------------------------------------------------
+Wed Mar 8 00:48:46 UTC 2017 - asarai@suse.com
+
+- Clean up docker-mount-secrets.patch to use the new swarm secrets internals of
+ Docker 1.13.0, which removes the need to implement any secret handling
+ ourselves. This resulted in a split up of the patch.
+ - docker-mount-secrets.patch
+ + secrets-0001-daemon-allow-directory-creation-in-run-secrets.patch
+ + secrets-0002-SUSE-implement-SUSE-container-secrets.patch
+
+-------------------------------------------------------------------
+Mon Mar 6 15:31:02 UTC 2017 - jmassaguerpla@suse.com
+
+- Remove old plugins.json to prevent docker-1.13 to fail to start
+
+-------------------------------------------------------------------
+Mon Mar 6 12:52:14 UTC 2017 - jmassaguerpla@suse.com
+
+- Fix bsc#1026827: systemd TasksMax default throttles docker
+
+-------------------------------------------------------------------
+Mon Mar 6 10:09:14 UTC 2017 - jmassaguerpla@suse.com
+
+- Fix post section by adding shadow as a package requirement
+ Otherwise the groupadd instruction fails
+
+-------------------------------------------------------------------
+Sun Mar 5 04:54:52 UTC 2017 - asarai@suse.com
+
+- Add patch to fix TestDaemonCommand failure in %check. This is an upstream
+ bug, and has an upstream PR to fix it https://github.com/docker/docker/pull/31549.
+ + pr31549-cmd-docker-fix-TestDaemonCommand.patch
+
+-------------------------------------------------------------------
+Wed Feb 1 15:59:40 UTC 2017 - jmassaguerpla@suse.com
+
+- update docker to 1.13.0
+
+ see details in https://github.com/docker/docker/releases/tag/v1.13.0
+
+- use the same buildflags for building docker and for building the
+ tests.
+
+- enable pkcs11:
+ https://github.com/docker/docker/commit/37fa75b3447007bb8ea311f02610bb383b0db77f
+
-------------------------------------------------------------------
Fri Jan 27 12:30:18 UTC 2017 - bg@suse.com
@@ -8,20 +61,20 @@ Thu Jan 26 15:43:38 UTC 2017 - jmassaguerpla@suse.com
- provide the oci runtime so that containers which were using an old
runtime option, when started on the new docker version, the runtime
- is changed to the new one. fix bsc#1020806 bsc#1016992
+ is changed to the new one. fix bsc#1020806 bsc#1016992
-------------------------------------------------------------------
Fri Jan 13 13:56:15 UTC 2017 - jmassaguerpla@suse.com
- fix CVE-2016-9962 bsc#1012568 . Fix it by updating to 1.12.6
plus an extra commit to fix liverestore:
- https://github.com/docker/docker/commit/97cd32a6a9076306baa637a29bba84c3f1f3d218
+ https://github.com/docker/docker/commit/97cd32a6a9076306baa637a29bba84c3f1f3d218
-------------------------------------------------------------------
Wed Jan 11 12:47:16 UTC 2017 - jmassaguerpla@suse.com
- add "a wait" when starting docker service to fix
- bsc#1019251
+ bsc#1019251
-------------------------------------------------------------------
Tue Dec 20 12:41:33 UTC 2016 - normand@linux.vnet.ibm.com
diff --git a/docker.service b/docker.service
index e654024..4b5b5d4 100644
--- a/docker.service
+++ b/docker.service
@@ -23,7 +23,7 @@ LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this property.
-#TasksMax=infinity
+TasksMax=infinity
# Set delegate yes so that systemd does not reset the cgroups of docker containers
# Only systemd 218 and above support this property.
diff --git a/docker.spec b/docker.spec
index 553f681..9705ee9 100644
--- a/docker.spec
+++ b/docker.spec
@@ -36,7 +36,7 @@
%global docker_migration_warnfile %{docker_store}/docker-update-message.txt
%define docker_graph %{docker_store}/graph
%define git_version 78d1802
-%define version_unconverted 1.12.6
+%define version_unconverted 1.13.0
%define __arch_install_post export NO_BRP_STRIP_DEBUG=true
# When upgrading to a new version requires the service not to be restarted
# Due to a long migration process update last_migration_version to the new version
@@ -44,7 +44,7 @@
# 1.10.1
%global last_migration_version 1.10.1
Name: docker
-Version: 1.12.6
+Version: 1.13.0
Release: 0
Summary: The Linux container runtime
License: Apache-2.0
@@ -59,7 +59,7 @@ Source7: README_SUSE.md
Source8: docker-audit.rules
Source9: docker-update-message.txt
Source10: tests.sh
-Source11: docker_service_helper.sh
+Source11: docker_service_helper.sh
# Fixes for architecture-specific issues (gcc-go).
Patch100: gcc-go-patches.patch
Patch102: netlink_netns_powerpc.patch
@@ -68,14 +68,21 @@ Patch103: boltdb_bolt_add_brokenUnaligned.patch
# which is not snapshotted when images are committed. Note that if you modify
# this patch, please also modify the patch in the suse-secrets-v
# branch in http://github.com/suse/docker.mirror.
-Patch200: docker-mount-secrets.patch
+Patch200: secrets-0001-daemon-allow-directory-creation-in-run-secrets.patch
+Patch201: secrets-0002-SUSE-implement-SUSE-container-secrets.patch
+# PATCH-FIX-UPSTREAM: Backports.
Patch300: integration-cli-fix-TestInfoEnsureSucceeds.patch
+Patch301: pr31549-cmd-docker-fix-TestDaemonCommand.patch
+Patch302: pr31773-daemon-also-ensureDefaultApparmorProfile-in-exec-pat.patch
BuildRequires: audit
BuildRequires: bash-completion
+BuildRequires: ca-certificates
BuildRequires: device-mapper-devel >= 1.2.68
BuildRequires: glibc-devel-static
BuildRequires: libapparmor-devel
BuildRequires: libbtrfs-devel >= 3.8
+BuildRequires: libseccomp-devel
+BuildRequires: libtool
BuildRequires: procps
BuildRequires: sqlite3-devel
BuildRequires: systemd-devel
@@ -83,12 +90,13 @@ BuildRequires: zsh
Requires: apparmor-parser
Requires: bridge-utils
Requires: ca-certificates-mozilla
+Requires: docker-libnetwork = 0.0.0+git20161019.0f53435
# Containerd and runC are required as they are the only currently supported
# execdrivers of Docker. NOTE: The version pinning here matches upstream's
# Dockerfile to ensure that we don't use a slightly incompatible version of
# runC or containerd (which would be bad).
-Requires: containerd = 0.2.5+gitr569_2a5e70c
-Requires: runc = 0.1.1+gitr2819_50a19c6
+Requires: containerd = 0.2.5+gitr608_03e5862
+Requires: runc = 0.1.1+gitr2942_2f7393a
# Provides mkfs.ext4 - used by Docker when devicemapper storage driver is used
Requires: e2fsprogs
Requires: git-core >= 1.7
@@ -100,6 +108,7 @@ Requires: tar >= 1.26
Requires: xz >= 4.9
Requires(post): %fillup_prereq
Requires(post): udev
+Requires(post): shadow
# Not necessary, but must be installed to have a smooth upgrade.
Recommends: docker-image-migrator
Conflicts: lxc < 1.0
@@ -169,6 +178,7 @@ Test package for docker. It contains the source code and the tests.
# nothing
%else
%patch200 -p1
+%patch201 -p1
%endif
%ifnarch %{go_arches}
%patch100 -p1
@@ -176,6 +186,8 @@ Test package for docker. It contains the source code and the tests.
%patch103 -p1
%endif
%patch300 -p1
+%patch301 -p1
+%patch302 -p1
cp %{SOURCE7} .
cp %{SOURCE10} .
@@ -188,9 +200,18 @@ ln -s %{_bindir}/go-6 $tmphack/go
export PATH=$tmphack:$PATH
%endif
+# Note that these commands do not allow %%elseif.
+# For versions equal to or below SLE12 && openSUSE_13.2 libdevmapper.h is not
+# recent enough to define dm_task_deferred_remove(). (This is not true of
+# SLE12_SP1 but we cannot distinguish it with this macro.)
+BUILDTAGS="exclude_graphdriver_aufs apparmor seccomp selinux pkcs11"
+%if 0%{?suse_version} <= 1320
+ BUILDTAGS="libdm_no_deferred_remove $BUILDTAGS"
+%endif
+
(cat < docker_build_env
@@ -233,22 +254,13 @@ cp -avr %{buildroot}/usr/src/%{name} $HOME/go/src/github.com/docker/docker
cd $HOME/go/src/github.com/docker/docker
-# Note that these commands do not allow %%elseif.
-# For versions equal to or below SLE12 && openSUSE_13.2 libdevmapper.h is not
-# recent enough to define dm_task_deferred_remove(). (This is not true of
-# SLE12_SP1 but we cannot distinguish it with this macro.)
-EXCLUDE_TAGS=
-%if 0%{?suse_version} <= 1320
- EXCLUDE_TAGS="libdm_no_deferred_remove $EXCLUDE_TAGS"
-%endif
-
# The command is taken from hack/make/test-unit and various test runs.
# Everything that follows github.com/docker/pkg/integration-cli are packages
# containing tests that cannot run in an obs build context.
PKG_LIST=$(go list -e \
-f '{{if ne .Name "github.com/docker/docker"}} {{.ImportPath}}
{{end}}' \
- -tags $EXCLUDE_TAGS \
+ -tags "$DOCKER_BUILDTAGS" \
-a "${BUILDFLAGS[@]}" ... \
| grep 'github.com/docker/docker' \
| grep -v 'github.com/docker/docker/vendor' \
@@ -273,7 +285,7 @@ PKG_LIST=$(go list -e \
| grep -v 'github.com/docker/docker/man$' \
| grep -v 'github.com/docker/docker/pkg/integration$')
-go test -cover -ldflags -w -tags $EXCLUDE_TAGS -a -test.timeout=10m $PKG_LIST
+go test -cover -ldflags -w -tags "$DOCKER_BUILDTAGS" -a -test.timeout=10m $PKG_LIST
%endif
%install
@@ -282,11 +294,9 @@ install -d %{buildroot}%{_bindir}
%ifarch %{go_arches}
install -D -m755 bundles/latest/dynbinary-client/%{name} %{buildroot}/%{_bindir}/%{name}
install -D -m755 bundles/latest/dynbinary-daemon/%{name}d %{buildroot}/%{_bindir}/%{name}d
-install -D -m755 bundles/latest/dynbinary-daemon/%{name}-proxy %{buildroot}/%{_bindir}/%{name}-proxy
%else
install -D -m755 bundles/latest/dyngccgo/%{name} %{buildroot}/%{_bindir}/%{name}
install -D -m755 bundles/latest/dyngccgo/%{name}d %{buildroot}/%{_bindir}/%{name}d
-install -D -m755 bundles/latest/dyngccgo/%{name}-proxy %{buildroot}/%{_bindir}/%{name}-proxy
%endif
install -d %{buildroot}/%{_prefix}/lib/docker
install -Dd -m 0755 \
@@ -374,6 +384,13 @@ else
rm %{docker_migration_warnfile}
fi
fi
+# If plugins.json is present, docker will fail to start
+# https://github.com/docker/docker/releases/1.13.0
+if [ -e /var/lib/docker/plugins/plugins.json ];then
+ echo "Warning: Disabling previous installed plugins"
+ echo "Otherwise docker will fail to boot"
+ mv /var/lib/docker/plugins/plugins.json /var/lib/docker/plugins/_plugins.json.old
+fi
%service_add_post %{name}.service
%{fillup_only -n docker}
@@ -392,7 +409,6 @@ fi
%doc README.md LICENSE README_SUSE.md
%{_bindir}/docker
%{_bindir}/dockerd
-%{_bindir}/docker-proxy
%{_sbindir}/rcdocker
%{_libexecdir}/docker/
%{_unitdir}/%{name}.service
diff --git a/integration-cli-fix-TestInfoEnsureSucceeds.patch b/integration-cli-fix-TestInfoEnsureSucceeds.patch
index e7c1dc0..fd4d91b 100644
--- a/integration-cli-fix-TestInfoEnsureSucceeds.patch
+++ b/integration-cli-fix-TestInfoEnsureSucceeds.patch
@@ -1,18 +1,8 @@
-From 0f0c0fcb5b956782385e25c7c6c625e6c79ac78f Mon Sep 17 00:00:00 2001
-From: Thomas Hipp
-Date: Wed, 7 Sep 2016 10:54:09 +0200
-Subject: [PATCH] integration-cli: fix TestInfoEnsureSucceeds
-
-Signed-off-by: Thomas Hipp
----
- integration-cli/docker_cli_info_test.go | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go
-index a48e69a..c265a36 100644
+index 62ce7e2..46516f9 100644
--- a/integration-cli/docker_cli_info_test.go
+++ b/integration-cli/docker_cli_info_test.go
-@@ -36,7 +36,7 @@ func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) {
+@@ -40,7 +40,7 @@ func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) {
}
if DaemonIsLinux.Condition() {
@@ -20,7 +10,4 @@ index a48e69a..c265a36 100644
+ stringsToCheck = append(stringsToCheck, "Runtimes:", "Default Runtime: oci")
}
- if utils.ExperimentalBuild() {
---
-2.9.3
-
+ if experimentalDaemon {
diff --git a/pr31549-cmd-docker-fix-TestDaemonCommand.patch b/pr31549-cmd-docker-fix-TestDaemonCommand.patch
new file mode 100644
index 0000000..3cad3ae
--- /dev/null
+++ b/pr31549-cmd-docker-fix-TestDaemonCommand.patch
@@ -0,0 +1,49 @@
+From dd7159060f60ea04007c069df189a29fda2c655f Mon Sep 17 00:00:00 2001
+From: Aleksa Sarai
+Date: Sun, 5 Mar 2017 15:25:11 +1100
+Subject: [PATCH] cmd: docker: fix TestDaemonCommand
+
+In more recent versions of Cobra, `--help` parsing is done before
+anything else resulting in TestDaemonCommand not actually passing. I'm
+actually unsure if this test ever passed since it appears that !daemon
+is not being run as part of the test suite.
+
+Signed-off-by: Aleksa Sarai
+---
+ cmd/docker/daemon_none.go | 6 ++++--
+ cmd/docker/daemon_none_test.go | 2 +-
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/cmd/docker/daemon_none.go b/cmd/docker/daemon_none.go
+index 65f9f37be22f..6fbd00012526 100644
+--- a/cmd/docker/daemon_none.go
++++ b/cmd/docker/daemon_none.go
+@@ -12,8 +12,10 @@ import (
+
+ func newDaemonCommand() *cobra.Command {
+ return &cobra.Command{
+- Use: "daemon",
+- Hidden: true,
++ Use: "daemon",
++ Hidden: true,
++ Args: cobra.ArbitraryArgs,
++ DisableFlagParsing: true,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return runDaemon()
+ },
+diff --git a/cmd/docker/daemon_none_test.go b/cmd/docker/daemon_none_test.go
+index 32032fe1b344..bd42add98696 100644
+--- a/cmd/docker/daemon_none_test.go
++++ b/cmd/docker/daemon_none_test.go
+@@ -10,7 +10,7 @@ import (
+
+ func TestDaemonCommand(t *testing.T) {
+ cmd := newDaemonCommand()
+- cmd.SetArgs([]string{"--help"})
++ cmd.SetArgs([]string{"--version"})
+ err := cmd.Execute()
+
+ assert.Error(t, err, "Please run `dockerd`")
+--
+2.12.0
+
diff --git a/pr31773-daemon-also-ensureDefaultApparmorProfile-in-exec-pat.patch b/pr31773-daemon-also-ensureDefaultApparmorProfile-in-exec-pat.patch
new file mode 100644
index 0000000..0e853d5
--- /dev/null
+++ b/pr31773-daemon-also-ensureDefaultApparmorProfile-in-exec-pat.patch
@@ -0,0 +1,59 @@
+From 790a81ea9acce318d0e037771c253951b874140b Mon Sep 17 00:00:00 2001
+From: Aleksa Sarai
+Date: Mon, 13 Mar 2017 14:57:35 +1100
+Subject: [PATCH] daemon: also ensureDefaultApparmorProfile in exec path
+
+When 567ef8e7858c ("daemon: switch to 'ensure' workflow for AppArmor
+profiles") was merged, it didn't correctly handle the exec path if
+AppArmor profiles were deleted. Fix this by duplicating the
+ensureDefaultApparmorProfile code in the exec code.
+
+Fixes: 567ef8e7858c ("daemon: switch to 'ensure' workflow for AppArmor profiles")
+Signed-off-by: Aleksa Sarai
+---
+ daemon/exec_linux.go | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/daemon/exec_linux.go b/daemon/exec_linux.go
+index 5aeedc347027..bb11c11e447c 100644
+--- a/daemon/exec_linux.go
++++ b/daemon/exec_linux.go
+@@ -5,6 +5,7 @@ import (
+ "github.com/docker/docker/daemon/caps"
+ "github.com/docker/docker/daemon/exec"
+ "github.com/docker/docker/libcontainerd"
++ "github.com/opencontainers/runc/libcontainer/apparmor"
+ "github.com/opencontainers/runtime-spec/specs-go"
+ )
+
+@@ -23,5 +24,27 @@ func execSetPlatformOpt(c *container.Container, ec *exec.Config, p *libcontainer
+ if ec.Privileged {
+ p.Capabilities = caps.GetAllCapabilities()
+ }
++ if apparmor.IsEnabled() {
++ var appArmorProfile string
++ if c.AppArmorProfile != "" {
++ appArmorProfile = c.AppArmorProfile
++ } else if c.HostConfig.Privileged {
++ appArmorProfile = "unconfined"
++ } else {
++ appArmorProfile = "docker-default"
++ }
++
++ if appArmorProfile == "docker-default" {
++ // Unattended upgrades and other fun services can unload AppArmor
++ // profiles inadvertently. Since we cannot store our profile in
++ // /etc/apparmor.d, nor can we practically add other ways of
++ // telling the system to keep our profile loaded, in order to make
++ // sure that we keep the default profile enabled we dynamically
++ // reload it if necessary.
++ if err := ensureDefaultAppArmorProfile(); err != nil {
++ return err
++ }
++ }
++ }
+ return nil
+ }
+--
+2.12.0
+
diff --git a/secrets-0001-daemon-allow-directory-creation-in-run-secrets.patch b/secrets-0001-daemon-allow-directory-creation-in-run-secrets.patch
new file mode 100644
index 0000000..c1665a2
--- /dev/null
+++ b/secrets-0001-daemon-allow-directory-creation-in-run-secrets.patch
@@ -0,0 +1,39 @@
+From 0c4cf4fac76f2a5272a808665985a2e0df6af0db Mon Sep 17 00:00:00 2001
+From: Aleksa Sarai
+Date: Wed, 8 Mar 2017 12:41:54 +1100
+Subject: [PATCH 1/2] daemon: allow directory creation in /run/secrets
+
+Since FileMode can have the directory bit set, allow a SecretStore
+implementation to return secrets that are actually directories. This is
+useful for creating directories and subdirectories of secrets.
+
+Backport: https://github.com/docker/docker/pull/31632
+Signed-off-by: Aleksa Sarai
+---
+ daemon/container_operations_unix.go | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go
+index 2296045765d4..8527a7907373 100644
+--- a/daemon/container_operations_unix.go
++++ b/daemon/container_operations_unix.go
+@@ -195,8 +195,14 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
+ if secret == nil {
+ return fmt.Errorf("unable to get secret from secret store")
+ }
+- if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil {
+- return errors.Wrap(err, "error injecting secret")
++ if s.File.Mode.IsDir() {
++ if err := os.Mkdir(fPath, s.File.Mode); err != nil {
++ return errors.Wrap(err, "error injecting secret dir")
++ }
++ } else {
++ if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil {
++ return errors.Wrap(err, "error injecting secret")
++ }
+ }
+
+ uid, err := strconv.Atoi(s.File.UID)
+--
+2.12.0
+
diff --git a/secrets-0002-SUSE-implement-SUSE-container-secrets.patch b/secrets-0002-SUSE-implement-SUSE-container-secrets.patch
new file mode 100644
index 0000000..a785381
--- /dev/null
+++ b/secrets-0002-SUSE-implement-SUSE-container-secrets.patch
@@ -0,0 +1,290 @@
+From a3106907d4786ed7d624201debdd43dc41fb4b97 Mon Sep 17 00:00:00 2001
+From: Aleksa Sarai
+Date: Wed, 8 Mar 2017 11:43:29 +1100
+Subject: [PATCH 2/2] SUSE: implement SUSE container secrets
+
+This allows for us to pass in host credentials to a container, allowing
+for SUSEConnect to work with containers.
+
+THIS PATCH IS NOT TO BE UPSTREAMED, DUE TO THE FACT THAT IT IS
+SUSE-SPECIFIC, AND UPSTREAM DOES NOT APPROVE OF THIS CONCEPT BECAUSE IT
+MAKES BUILDS NOT ENTIRELY REPRODUCIBLE.
+
+Signed-off-by: Aleksa Sarai
+---
+ daemon/start.go | 5 +
+ daemon/suse_secrets.go | 246 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 251 insertions(+)
+ create mode 100644 daemon/suse_secrets.go
+
+diff --git a/daemon/start.go b/daemon/start.go
+index 6c94fd5482d0..3c06eed778d7 100644
+--- a/daemon/start.go
++++ b/daemon/start.go
+@@ -146,6 +146,11 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint
+ return err
+ }
+
++ // SUSE:secrets -- inject the SUSE secret store
++ if err := daemon.injectSuseSecretStore(container); err != nil {
++ return err
++ }
++
+ spec, err := daemon.createSpec(container)
+ if err != nil {
+ return err
+diff --git a/daemon/suse_secrets.go b/daemon/suse_secrets.go
+new file mode 100644
+index 000000000000..591abc998e67
+--- /dev/null
++++ b/daemon/suse_secrets.go
+@@ -0,0 +1,246 @@
++/*
++ * suse-secrets: patch for Docker to implement SUSE secrets
++ * Copyright (C) 2017 SUSE LLC.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++package daemon
++
++import (
++ "fmt"
++ "io/ioutil"
++ "os"
++ "path/filepath"
++ "syscall"
++
++ "github.com/Sirupsen/logrus"
++ "github.com/docker/distribution/digest"
++ "github.com/docker/docker/container"
++
++ swarmtypes "github.com/docker/docker/api/types/swarm"
++ swarmexec "github.com/docker/swarmkit/agent/exec"
++ swarmapi "github.com/docker/swarmkit/api"
++)
++
++func init() {
++ // Output to tell us in logs that SUSE:secrets is enabled.
++ logrus.Infof("SUSE:secrets :: enabled")
++}
++
++// Creating a fake file.
++type SuseFakeFile struct {
++ Path string
++ Uid int
++ Gid int
++ Mode os.FileMode
++ Data []byte
++}
++
++func (s SuseFakeFile) id() string {
++ return fmt.Sprintf("suse::%s:%s", digest.FromBytes(s.Data), s.Path)
++}
++
++func (s SuseFakeFile) toSecret() *swarmapi.Secret {
++ return &swarmapi.Secret{
++ ID: s.id(),
++ Internal: true,
++ Spec: swarmapi.SecretSpec{
++ Data: s.Data,
++ },
++ }
++}
++
++func (s SuseFakeFile) toSecretReference() *swarmtypes.SecretReference {
++ return &swarmtypes.SecretReference{
++ SecretID: s.id(),
++ SecretName: s.id(),
++ File: &swarmtypes.SecretReferenceFileTarget{
++ Name: s.Path,
++ UID: fmt.Sprintf("%d", s.Uid),
++ GID: fmt.Sprintf("%d", s.Gid),
++ Mode: s.Mode,
++ },
++ }
++}
++
++// readDir will recurse into a directory prefix/dir, and return the set of secrets
++// in that directory. The Path attribute of each has the prefix stripped. Symlinks
++// are evaluated.
++func readDir(prefix, dir string) ([]*SuseFakeFile, error) {
++ var suseFiles []*SuseFakeFile
++
++ path := filepath.Join(prefix, dir)
++
++ fi, err := os.Stat(path)
++ if err != nil {
++ // Ignore dangling symlinks.
++ if os.IsNotExist(err) {
++ logrus.Warnf("SUSE:secrets :: dangling symlink: %s", path)
++ return suseFiles, nil
++ }
++ return nil, err
++ }
++
++ stat, ok := fi.Sys().(*syscall.Stat_t)
++ if !ok {
++ logrus.Warnf("SUSE:secrets :: failed to cast directory stat_t: defaulting to owned by root:root: %s", path)
++ }
++
++ suseFiles = append(suseFiles, &SuseFakeFile{
++ Path: dir,
++ Uid: int(stat.Uid),
++ Gid: int(stat.Gid),
++ Mode: fi.Mode(),
++ })
++
++ files, err := ioutil.ReadDir(path)
++ if err != nil {
++ return nil, err
++ }
++
++ for _, f := range files {
++ subpath := filepath.Join(dir, f.Name())
++
++ if f.IsDir() {
++ secrets, err := readDir(prefix, subpath)
++ if err != nil {
++ return nil, err
++ }
++ suseFiles = append(suseFiles, secrets...)
++ } else {
++ secrets, err := readFile(prefix, subpath)
++ if err != nil {
++ return nil, err
++ }
++ suseFiles = append(suseFiles, secrets...)
++ }
++ }
++
++ return suseFiles, nil
++}
++
++// readFile returns a secret given a file under a given prefix.
++func readFile(prefix, file string) ([]*SuseFakeFile, error) {
++ var suseFiles []*SuseFakeFile
++
++ path := filepath.Join(prefix, file)
++ fi, err := os.Stat(path)
++ if err != nil {
++ // Ignore dangling symlinks.
++ if os.IsNotExist(err) {
++ logrus.Warnf("SUSE:secrets :: dangling symlink: %s", path)
++ return suseFiles, nil
++ }
++ return nil, err
++ }
++
++ stat, ok := fi.Sys().(*syscall.Stat_t)
++ if !ok {
++ logrus.Warnf("SUSE:secrets :: failed to cast file stat_t: defaulting to owned by root:root: %s", path)
++ }
++
++ if fi.IsDir() {
++ secrets, err := readDir(prefix, file)
++ if err != nil {
++ return nil, err
++ }
++ suseFiles = append(suseFiles, secrets...)
++ } else {
++ bytes, err := ioutil.ReadFile(path)
++ if err != nil {
++ return nil, err
++ }
++ suseFiles = append(suseFiles, &SuseFakeFile{
++ Path: file,
++ Uid: int(stat.Uid),
++ Gid: int(stat.Gid),
++ Mode: fi.Mode(),
++ Data: bytes,
++ })
++ }
++
++ return suseFiles, nil
++}
++
++// getHostSuseSecretData returns the list of SuseFakeFiles the need to be added
++// as SUSE secrets.
++func getHostSuseSecretData() ([]*SuseFakeFile, error) {
++ secrets := []*SuseFakeFile{}
++
++ credentials, err := readDir("/etc/zypp", "credentials.d")
++ if err != nil {
++ if os.IsNotExist(err) {
++ credentials = []*SuseFakeFile{}
++ } else {
++ logrus.Errorf("SUSE:secrets :: error while reading zypp credentials: %s", err)
++ return nil, err
++ }
++ }
++ secrets = append(secrets, credentials...)
++
++ suseConnect, err := readFile("/etc", "SUSEConnect")
++ if err != nil {
++ if os.IsNotExist(err) {
++ suseConnect = []*SuseFakeFile{}
++ } else {
++ logrus.Errorf("SUSE:secrets :: error while reading /etc/SUSEConnect: %s", err)
++ return nil, err
++ }
++ }
++ secrets = append(secrets, suseConnect...)
++
++ return secrets, nil
++}
++
++// In order to reduce the amount of code touched outside of this file, we
++// implement the swarm API for SecretGetter. This asserts that this requirement
++// will always be matched.
++var _ swarmexec.SecretGetter = &suseSecretGetter{}
++
++type suseSecretGetter struct {
++ dfl swarmexec.SecretGetter
++ secrets map[string]*swarmapi.Secret
++}
++
++func (s *suseSecretGetter) Get(id string) *swarmapi.Secret {
++ logrus.Debugf("SUSE:secrets :: id=%s requested from suseSecretGetter", id)
++
++ secret, ok := s.secrets[id]
++ if !ok {
++ // fallthrough
++ return s.dfl.Get(id)
++ }
++
++ return secret
++}
++
++func (daemon *Daemon) injectSuseSecretStore(c *container.Container) error {
++ newSecretStore := &suseSecretGetter{
++ dfl: c.SecretStore,
++ secrets: make(map[string]*swarmapi.Secret),
++ }
++
++ secrets, err := getHostSuseSecretData()
++ if err != nil {
++ return err
++ }
++
++ for _, secret := range secrets {
++ newSecretStore.secrets[secret.id()] = secret.toSecret()
++ c.SecretReferences = append(c.SecretReferences, secret.toSecretReference())
++ }
++
++ c.SecretStore = newSecretStore
++ return nil
++}
+--
+2.12.0
+