diff options
Diffstat (limited to 'pkg/secrets')
-rw-r--r-- | pkg/secrets/secrets.go | 88 |
1 files changed, 85 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) |