summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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())
})