File secrets-0001-daemon-allow-directory-creation-in-run-secrets.patch of Package docker.11169

From 6603582112f42cd00b84d62a5412f2380e55d7e3 Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <asarai@suse.de>
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.

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
Signed-off-by: Aleksa Sarai <asarai@suse.de>
---
 .../daemon/container_operations_unix.go       | 24 ++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/components/engine/daemon/container_operations_unix.go b/components/engine/daemon/container_operations_unix.go
index c0aab7234269..8d8b13d26cff 100644
--- a/components/engine/daemon/container_operations_unix.go
+++ b/components/engine/daemon/container_operations_unix.go
@@ -3,6 +3,7 @@
 package daemon // import "github.com/docker/docker/daemon"
 
 import (
+	"bytes"
 	"context"
 	"fmt"
 	"io/ioutil"
@@ -14,6 +15,7 @@ import (
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/links"
 	"github.com/docker/docker/errdefs"
+	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/stringid"
@@ -206,9 +208,6 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
 		if err != nil {
 			return errors.Wrap(err, "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")
-		}
 
 		uid, err := strconv.Atoi(s.File.UID)
 		if err != nil {
@@ -219,6 +218,25 @@ func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
 			return err
 		}
 
+		if s.File.Mode.IsDir() {
+			if err := os.Mkdir(fPath, s.File.Mode); err != nil {
+				return errors.Wrap(err, "error creating secretdir")
+			}
+			if secret.Spec.Data != nil {
+				// If the "file" is a directory, then s.File.Data is actually a tar
+				// archive of the directory. So we just do a tar extraction here.
+				if err := archive.UntarUncompressed(bytes.NewBuffer(secret.Spec.Data), fPath, &archive.TarOptions{
+					UIDMaps: daemon.idMapping.UIDs(),
+					GIDMaps: daemon.idMapping.GIDs(),
+				}); err != nil {
+					return errors.Wrap(err, "error injecting secretdir")
+				}
+			}
+		} else {
+			if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil {
+				return errors.Wrap(err, "error injecting secret")
+			}
+		}
 		if err := os.Chown(fPath, rootIDs.UID+uid, rootIDs.GID+gid); err != nil {
 			return errors.Wrap(err, "error setting ownership for secret")
 		}
-- 
2.21.0