summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorumohnani8 <umohnani@redhat.com>2018-04-12 14:41:17 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-04-13 21:25:15 +0000
commit9aafc25a3d5c34b89ccd1e9866fbe57b171cf001 (patch)
tree86a0c5352bf5504b0a894bec653cacb3224a4171
parentac910c7aa8246669a9b5ef0957f825e81d09f044 (diff)
downloadpodman-9aafc25a3d5c34b89ccd1e9866fbe57b171cf001.tar.gz
podman-9aafc25a3d5c34b89ccd1e9866fbe57b171cf001.tar.bz2
podman-9aafc25a3d5c34b89ccd1e9866fbe57b171cf001.zip
Fix secrets patch
The secrets code was just tarring and copying the contents of the secrets directory on host as is. This meant it was not accounting for any symlinks inside the directory, leading up to the contents not being copied over. Signed-off-by: umohnani8 <umohnani@redhat.com> Closes: #611 Approved by: mheon
-rw-r--r--pkg/secrets/secrets.go88
-rw-r--r--test/e2e/run_test.go16
2 files changed, 101 insertions, 3 deletions
diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go
index 8227499e5..be825d906 100644
--- a/pkg/secrets/secrets.go
+++ b/pkg/secrets/secrets.go
@@ -3,11 +3,11 @@ package secrets
import (
"bufio"
"fmt"
+ "io/ioutil"
"os"
"path/filepath"
"strings"
- "github.com/containers/storage/pkg/chrootarchive"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
@@ -23,6 +23,82 @@ var (
OverrideMountsFile = "/etc/containers/mounts.conf"
)
+// secretData stores the name of the file and the content read from it
+type secretData struct {
+ name string
+ data []byte
+}
+
+// saveTo saves secret data to given directory
+func (s secretData) saveTo(dir string) error {
+ path := filepath.Join(dir, s.name)
+ if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil && !os.IsExist(err) {
+ return err
+ }
+ return ioutil.WriteFile(path, s.data, 0700)
+}
+
+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
+ }
+ bytes, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ return []secretData{{name: name, data: bytes}}, nil
+}
+
+func getHostSecretData(hostDir string) ([]secretData, error) {
+ var allSecrets []secretData
+ hostSecrets, err := readAll(hostDir, "")
+ if err != nil {
+ return nil, errors.Wrapf(err, "failed to read secrets from %q", hostDir)
+ }
+ return append(allSecrets, hostSecrets...), nil
+}
+
func getMounts(filePath string) []string {
file, err := os.Open(filePath)
if err != nil {
@@ -84,8 +160,14 @@ func SecretMounts(filePath, mountLabel, containerWorkingDir string) ([]rspec.Mou
return nil, err
}
- if err = chrootarchive.NewArchiver(nil).CopyWithTar(hostDir, ctrDirOnHost); err != nil && !os.IsNotExist(err) {
- return nil, errors.Wrapf(err, "error getting host secret data")
+ data, err := getHostSecretData(hostDir)
+ if err != nil {
+ return nil, errors.Wrapf(err, "getting host secret data failed")
+ }
+ for _, s := range data {
+ if err := s.saveTo(ctrDirOnHost); err != nil {
+ return nil, errors.Wrapf(err, "error saving data to container filesystem on host %q", ctrDirOnHost)
+ }
}
err = label.Relabel(ctrDirOnHost, mountLabel, false)
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 17b61533b..94a1fef57 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -278,10 +278,26 @@ var _ = Describe("Podman run", func() {
err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755)
Expect(err).To(BeNil())
+ targetDir := "/tmp/symlink/target"
+ err = os.MkdirAll(targetDir, 0755)
+ Expect(err).To(BeNil())
+ keyFile := filepath.Join(targetDir, "key.pem")
+ err = ioutil.WriteFile(keyFile, []byte(mountString), 0755)
+ Expect(err).To(BeNil())
+ execSession := podmanTest.SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")})
+ execSession.WaitWithDefaultTimeout()
+ Expect(execSession.ExitCode()).To(Equal(0))
+
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"})
session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal(secretsString))
+ session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(ContainSubstring("key.pem"))
+
err = os.RemoveAll(containersDir)
Expect(err).To(BeNil())
})