File docker-mount-secrets.patch of Package docker.1168

diff -Naur b/daemon/container.go c/daemon/container.go
--- b/daemon/container.go	2015-08-13 03:54:41.000000000 +0200
+++ c/daemon/container.go	2015-08-13 13:38:56.519209134 +0200
@@ -289,13 +289,32 @@
 		return err
 	}
 
+	if err := container.setupSecretFiles(); err != nil {
+		return err
+	}
+
 	mounts, err := container.setupMounts()
 	if err != nil {
 		return err
 	}
 
 	container.command.Mounts = mounts
-	return container.waitForStart()
+
+	if err := container.waitForStart(); err != nil {
+		return err
+	}
+
+	// Now the container is running, unmount the secrets on the host
+	secretsPath, err := container.secretsPath()
+	if err != nil {
+		return err
+	}
+
+	if err := syscall.Unmount(secretsPath, syscall.MNT_DETACH); err != nil {
+		return err
+	}
+
+	return nil
 }
 
 func (container *Container) Run() error {
@@ -599,6 +618,10 @@
 	return container.GetRootResourcePath("config.json")
 }
 
+func (container *Container) secretsPath() (string, error) {
+	return container.GetRootResourcePath("secrets")
+}
+
 // This method must be exported to be used from the lxc template
 // This directory is only usable when the container is running
 func (container *Container) RootfsPath() string {
@@ -1241,3 +1264,28 @@
 
 	return v.Unmount()
 }
+
+func (container *Container) setupSecretFiles() error {
+	secretsPath, err := container.secretsPath()
+	if err != nil {
+		return err
+	}
+
+	if err := os.MkdirAll(secretsPath, 0700); err != nil {
+		return err
+	}
+
+	if err := syscall.Mount("tmpfs", secretsPath, "tmpfs", uintptr(syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV), label.FormatMountLabel("", container.GetMountLabel())); err != nil {
+		return fmt.Errorf("mounting secret tmpfs: %s", err)
+	}
+
+	data, err := getHostSecretData()
+	if err != nil {
+		return err
+	}
+	for _, s := range data {
+		s.SaveTo(secretsPath)
+	}
+
+	return nil
+}
diff -Naur b/daemon/secrets.go c/daemon/secrets.go
--- b/daemon/secrets.go	1970-01-01 01:00:00.000000000 +0100
+++ c/daemon/secrets.go	2015-08-13 13:38:56.520209134 +0200
@@ -0,0 +1,102 @@
+package daemon
+
+import (
+	log "github.com/Sirupsen/logrus"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+)
+
+type Secret struct {
+	Name      string
+	IsDir     bool
+	HostBased bool
+}
+
+type SecretData struct {
+	Name string
+	Data []byte
+}
+
+func (s SecretData) SaveTo(dir string) error {
+	path := filepath.Join(dir, s.Name)
+	if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil && !os.IsExist(err) {
+		return err
+	}
+	if err := ioutil.WriteFile(path, s.Data, 0755); err != nil {
+		return err
+	}
+	return nil
+}
+
+func readAll(root, prefix string) ([]SecretData, error) {
+	path := filepath.Join(root, prefix)
+
+	data := []SecretData{}
+
+	files, err := ioutil.ReadDir(path)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return data, nil
+		}
+
+		return nil, err
+	}
+
+	for _, f := range files {
+		fileData, err := readFile(root, filepath.Join(prefix, f.Name()))
+		if err != nil {
+			// If the file did not exist, might be a dangling symlink
+			// Ignore the error
+			if os.IsNotExist(err) {
+				continue
+			}
+			return nil, err
+		}
+		data = append(data, fileData...)
+	}
+
+	return data, nil
+}
+
+func readFile(root, name string) ([]SecretData, error) {
+	path := filepath.Join(root, name)
+
+	s, err := os.Stat(path)
+	if err != nil {
+		return nil, err
+	}
+
+	if s.IsDir() {
+		dirData, err := readAll(root, name)
+		if err != nil {
+			return nil, err
+		}
+		return dirData, nil
+	} else {
+		bytes, err := ioutil.ReadFile(path)
+		if err != nil {
+			return nil, err
+		}
+		return []SecretData{{Name: name, Data: bytes}}, nil
+	}
+}
+
+func getHostSecretData() ([]SecretData, error) {
+	credentials, err := readAll("/etc/zypp/", "credentials.d")
+	if err != nil {
+		log.Errorf("Error while reading zypp credentials: %s", err)
+		return credentials, err
+	}
+
+	suseConnect, err := readFile("/etc", "SUSEConnect")
+	if err != nil {
+		if os.IsNotExist(err) {
+			suseConnect = []SecretData{}
+		} else {
+			log.Errorf("Error while reading /etc/SUSEConnect: %s", err)
+			return nil, err
+		}
+	}
+	return append(credentials, suseConnect...), nil
+}
diff -Naur b/daemon/volumes_linux.go c/daemon/volumes_linux.go
--- b/daemon/volumes_linux.go	2015-08-13 03:54:41.000000000 +0200
+++ c/daemon/volumes_linux.go	2015-08-13 13:38:56.522209134 +0200
@@ -45,7 +45,19 @@
 		}
 	}
 
+	secretsPath, err := container.secretsPath()
+	if err != nil {
+		return nil, err
+	}
+
+	mounts = append(mounts, execdriver.Mount{
+		Source:      secretsPath,
+		Destination: "/run/secrets",
+		Writable:    true,
+	})
+
 	mounts = sortMounts(mounts)
+
 	return append(mounts, container.networkMounts()...), nil
 }
 
diff -Naur b/graph/graph_unix.go c/graph/graph_unix.go
--- b/graph/graph_unix.go	2015-08-13 03:54:41.000000000 +0200
+++ c/graph/graph_unix.go	2015-08-13 13:42:09.822212034 +0200
@@ -35,6 +35,7 @@
 		"/etc/hostname":    "file",
 		"/dev/console":     "file",
 		"/etc/mtab":        "/proc/mounts",
+		"/run/secrets":     "dir",
 	} {
 		parts := strings.Split(pth, "/")
 		prev := "/"
openSUSE Build Service is sponsored by