summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/containers/buildah/CHANGELOG.md8
-rw-r--r--vendor/github.com/containers/buildah/buildah.go2
-rw-r--r--vendor/github.com/containers/buildah/changelog.txt8
-rw-r--r--vendor/github.com/containers/buildah/commit.go22
-rw-r--r--vendor/github.com/containers/buildah/go.mod2
-rw-r--r--vendor/github.com/containers/buildah/go.sum4
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/executor.go4
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/stage_executor.go3
-rw-r--r--vendor/github.com/containers/buildah/run_linux.go2
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go158
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/secrets.go282
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/secretsdb.go211
12 files changed, 688 insertions, 18 deletions
diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md
index 0ad3069ce..ccf46b324 100644
--- a/vendor/github.com/containers/buildah/CHANGELOG.md
+++ b/vendor/github.com/containers/buildah/CHANGELOG.md
@@ -2,6 +2,14 @@
# Changelog
+## v1.19.4 (2021-02-06)
+ run: fix check for host pid namespace
+ bump containernetworking/cni library to v0.8.1 - fix for CVE-2021-20206
+ Finish plumbing for buildah bud --manifest
+ buildah manifest add localimage should work
+ Fix build arg check
+ --iidfile: print hash prefix
+
## v1.19.3 (2021-01-28)
[ci:docs] Fix man page for buildah push
Vendor in containers/image v5.10.1
diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go
index 4fbc475c2..7065e00e4 100644
--- a/vendor/github.com/containers/buildah/buildah.go
+++ b/vendor/github.com/containers/buildah/buildah.go
@@ -28,7 +28,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.19.3"
+ Version = "1.19.4"
// The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to
diff --git a/vendor/github.com/containers/buildah/changelog.txt b/vendor/github.com/containers/buildah/changelog.txt
index db2faf71a..4a0f81b04 100644
--- a/vendor/github.com/containers/buildah/changelog.txt
+++ b/vendor/github.com/containers/buildah/changelog.txt
@@ -1,3 +1,11 @@
+- Changelog for v1.19.4 (2021-02-06)
+ * run: fix check for host pid namespace
+ * bump containernetworking/cni library to v0.8.1 - fix for CVE-2021-20206
+ * Finish plumbing for buildah bud --manifest
+ * buildah manifest add localimage should work
+ * Fix build arg check
+ * --iidfile: print hash prefix
+
- Changelog for v1.19.3 (2021-01-28)
* [ci:docs] Fix man page for buildah push
* Vendor in containers/image v5.10.1
diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go
index 9c6831601..f588c8043 100644
--- a/vendor/github.com/containers/buildah/commit.go
+++ b/vendor/github.com/containers/buildah/commit.go
@@ -224,7 +224,7 @@ func checkRegistrySourcesAllows(forWhat string, dest types.ImageReference) (inse
return false, nil
}
-func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpec string) error {
+func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpec string) (string, error) {
var create bool
systemContext := &types.SystemContext{}
var list manifests.List
@@ -235,13 +235,13 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe
} else {
_, list, err = manifests.LoadFromImage(b.store, listImage.ID)
if err != nil {
- return err
+ return "", err
}
}
names, err := util.ExpandNames([]string{manifestName}, "", systemContext, b.store)
if err != nil {
- return errors.Wrapf(err, "error encountered while expanding image name %q", manifestName)
+ return "", errors.Wrapf(err, "error encountered while expanding image name %q", manifestName)
}
ref, err := alltransports.ParseImageName(imageSpec)
@@ -249,13 +249,13 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe
if ref, err = alltransports.ParseImageName(util.DefaultTransport + imageSpec); err != nil {
// check if the local image exists
if ref, _, err = util.FindImage(b.store, "", systemContext, imageSpec); err != nil {
- return err
+ return "", err
}
}
}
if _, err = list.Add(ctx, systemContext, ref, true); err != nil {
- return err
+ return "", err
}
var imageID string
if create {
@@ -263,10 +263,7 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe
} else {
imageID, err = list.SaveToImage(b.store, listImage.ID, nil, "")
}
- if err == nil {
- fmt.Printf("%s\n", imageID)
- }
- return err
+ return imageID, err
}
// Commit writes the contents of the container, along with its updated
@@ -469,7 +466,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
dest = dest2
}
if options.IIDFile != "" {
- if err = ioutil.WriteFile(options.IIDFile, []byte(img.ID), 0644); err != nil {
+ if err = ioutil.WriteFile(options.IIDFile, []byte("sha256:"+img.ID), 0644); err != nil {
return imgID, nil, "", err
}
}
@@ -489,9 +486,12 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
}
if options.Manifest != "" {
- if err := b.addManifest(ctx, options.Manifest, imgID); err != nil {
+ manifestID, err := b.addManifest(ctx, options.Manifest, imgID)
+ if err != nil {
return imgID, nil, "", err
}
+ logrus.Debugf("added imgID %s to manifestID %s", imgID, manifestID)
+
}
return imgID, ref, manifestDigest, nil
}
diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod
index cccf42895..17469ad12 100644
--- a/vendor/github.com/containers/buildah/go.mod
+++ b/vendor/github.com/containers/buildah/go.mod
@@ -4,7 +4,7 @@ go 1.12
require (
github.com/containerd/containerd v1.4.1 // indirect
- github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784
+ github.com/containernetworking/cni v0.8.1
github.com/containers/common v0.33.1
github.com/containers/image/v5 v5.10.1
github.com/containers/ocicrypt v1.0.3
diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum
index bf796c496..cab904fcf 100644
--- a/vendor/github.com/containers/buildah/go.sum
+++ b/vendor/github.com/containers/buildah/go.sum
@@ -76,8 +76,8 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
-github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc=
-github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI=
+github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containers/common v0.33.1 h1:XpDiq8Cta8+u1s4kpYSEWdB140ZmqgyIXfWkLqKx3z0=
github.com/containers/common v0.33.1/go.mod h1:mjDo/NKeweL/onaspLhZ38WnHXaYmrELHclIdvSnYpY=
github.com/containers/image/v5 v5.9.0 h1:dRmUtcluQcmasNo3DpnRoZjfU0rOu1qZeL6wlDJr10Q=
diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go
index a72e24eea..74ed9a42b 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go
@@ -115,6 +115,7 @@ type Executor struct {
imageInfoLock sync.Mutex
imageInfoCache map[string]imageTypeAndHistoryAndDiffIDs
fromOverride string
+ manifest string
}
type imageTypeAndHistoryAndDiffIDs struct {
@@ -231,6 +232,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod
logRusage: options.LogRusage,
imageInfoCache: make(map[string]imageTypeAndHistoryAndDiffIDs),
fromOverride: options.From,
+ manifest: options.Manifest,
}
if exec.err == nil {
exec.err = os.Stderr
@@ -679,7 +681,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image
}
logrus.Debugf("printing final image id %q", imageID)
if b.iidfile != "" {
- if err = ioutil.WriteFile(b.iidfile, []byte(imageID), 0644); err != nil {
+ if err = ioutil.WriteFile(b.iidfile, []byte("sha256:"+imageID), 0644); err != nil {
return imageID, ref, errors.Wrapf(err, "failed to write image ID to file %q", b.iidfile)
}
} else {
diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
index 9c15785bc..13631108e 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
@@ -838,7 +838,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string,
// we need to call ib.Run() to correctly put the args together before
// determining if a cached layer with the same build args already exists
// and that is done in the if block below.
- if checkForLayers && s.builder.Args == nil {
+ if checkForLayers && len(s.builder.Args) == 0 {
cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step))
if err != nil {
return "", nil, errors.Wrap(err, "error checking if cached image exists from a previous build")
@@ -1276,6 +1276,7 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer
MaxRetries: s.executor.maxPullPushRetries,
RetryDelay: s.executor.retryPullPushDelay,
HistoryTimestamp: s.executor.timestamp,
+ Manifest: s.executor.manifest,
}
imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options)
if err != nil {
diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go
index 66c856884..8c7c1bbc0 100644
--- a/vendor/github.com/containers/buildah/run_linux.go
+++ b/vendor/github.com/containers/buildah/run_linux.go
@@ -2210,7 +2210,7 @@ func checkAndOverrideIsolationOptions(isolation Isolation, options *RunOptions)
case IsolationOCI:
pidns := options.NamespaceOptions.Find(string(specs.PIDNamespace))
userns := options.NamespaceOptions.Find(string(specs.UserNamespace))
- if (pidns == nil || pidns.Host) && (userns != nil && !userns.Host) {
+ if (pidns != nil && pidns.Host) && (userns != nil && !userns.Host) {
return errors.Errorf("not allowed to mix host PID namespace with container user namespace")
}
}
diff --git a/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go b/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go
new file mode 100644
index 000000000..37edc16be
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/secrets/filedriver/filedriver.go
@@ -0,0 +1,158 @@
+package filedriver
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "sort"
+
+ "github.com/containers/storage/pkg/lockfile"
+ "github.com/pkg/errors"
+)
+
+// secretsDataFile is the file where secrets data/payload will be stored
+var secretsDataFile = "secretsdata.json"
+
+// errNoSecretData indicates that there is not data associated with an id
+var errNoSecretData = errors.New("no secret data with ID")
+
+// errNoSecretData indicates that there is secret data already associated with an id
+var errSecretIDExists = errors.New("secret data with ID already exists")
+
+// Driver is the filedriver object
+type Driver struct {
+ // secretsDataFilePath is the path to the secretsfile
+ secretsDataFilePath string
+ // lockfile is the filedriver lockfile
+ lockfile lockfile.Locker
+}
+
+// NewDriver creates a new file driver.
+// rootPath is the directory where the secrets data file resides.
+func NewDriver(rootPath string) (*Driver, error) {
+ fileDriver := new(Driver)
+ fileDriver.secretsDataFilePath = filepath.Join(rootPath, secretsDataFile)
+ // the lockfile functions requre that the rootPath dir is executable
+ if err := os.MkdirAll(rootPath, 0700); err != nil {
+ return nil, err
+ }
+
+ lock, err := lockfile.GetLockfile(filepath.Join(rootPath, "secretsdata.lock"))
+ if err != nil {
+ return nil, err
+ }
+ fileDriver.lockfile = lock
+
+ return fileDriver, nil
+}
+
+// List returns all secret IDs
+func (d *Driver) List() ([]string, error) {
+ d.lockfile.Lock()
+ defer d.lockfile.Unlock()
+ secretData, err := d.getAllData()
+ if err != nil {
+ return nil, err
+ }
+ var allID []string
+ for k := range secretData {
+ allID = append(allID, k)
+ }
+ sort.Strings(allID)
+ return allID, err
+}
+
+// Lookup returns the bytes associated with a secret ID
+func (d *Driver) Lookup(id string) ([]byte, error) {
+ d.lockfile.Lock()
+ defer d.lockfile.Unlock()
+
+ secretData, err := d.getAllData()
+ if err != nil {
+ return nil, err
+ }
+ if data, ok := secretData[id]; ok {
+ return data, nil
+ }
+ return nil, errors.Wrapf(errNoSecretData, "%s", id)
+}
+
+// Store stores the bytes associated with an ID. An error is returned if the ID arleady exists
+func (d *Driver) Store(id string, data []byte) error {
+ d.lockfile.Lock()
+ defer d.lockfile.Unlock()
+
+ secretData, err := d.getAllData()
+ if err != nil {
+ return err
+ }
+ if _, ok := secretData[id]; ok {
+ return errors.Wrapf(errSecretIDExists, "%s", id)
+ }
+ secretData[id] = data
+ marshalled, err := json.MarshalIndent(secretData, "", " ")
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(d.secretsDataFilePath, marshalled, 0600)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// Delete deletes the secret associated with the specified ID. An error is returned if no matching secret is found.
+func (d *Driver) Delete(id string) error {
+ d.lockfile.Lock()
+ defer d.lockfile.Unlock()
+ secretData, err := d.getAllData()
+ if err != nil {
+ return err
+ }
+ if _, ok := secretData[id]; ok {
+ delete(secretData, id)
+ } else {
+ return errors.Wrap(errNoSecretData, id)
+ }
+ marshalled, err := json.MarshalIndent(secretData, "", " ")
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(d.secretsDataFilePath, marshalled, 0600)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// getAllData reads the data file and returns all data
+func (d *Driver) getAllData() (map[string][]byte, error) {
+ // check if the db file exists
+ _, err := os.Stat(d.secretsDataFilePath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // the file will be created later on a store()
+ return make(map[string][]byte), nil
+ } else {
+ return nil, err
+ }
+ }
+
+ file, err := os.Open(d.secretsDataFilePath)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ byteValue, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ secretData := new(map[string][]byte)
+ err = json.Unmarshal([]byte(byteValue), secretData)
+ if err != nil {
+ return nil, err
+ }
+ return *secretData, nil
+}
diff --git a/vendor/github.com/containers/common/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/secrets/secrets.go
new file mode 100644
index 000000000..5e0fb3e9d
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/secrets/secrets.go
@@ -0,0 +1,282 @@
+package secrets
+
+import (
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "time"
+
+ "github.com/containers/common/pkg/secrets/filedriver"
+ "github.com/containers/storage/pkg/lockfile"
+ "github.com/containers/storage/pkg/stringid"
+ "github.com/pkg/errors"
+)
+
+// maxSecretSize is the max size for secret data - 512kB
+const maxSecretSize = 512000
+
+// secretIDLength is the character length of a secret ID - 25
+const secretIDLength = 25
+
+// errInvalidPath indicates that the secrets path is invalid
+var errInvalidPath = errors.New("invalid secrets path")
+
+// errNoSuchSecret indicates that the secret does not exist
+var errNoSuchSecret = errors.New("no such secret")
+
+// errSecretNameInUse indicates that the secret name is already in use
+var errSecretNameInUse = errors.New("secret name in use")
+
+// errInvalidSecretName indicates that the secret name is invalid
+var errInvalidSecretName = errors.New("invalid secret name")
+
+// errInvalidDriver indicates that the driver type is invalid
+var errInvalidDriver = errors.New("invalid driver")
+
+// errInvalidDriverOpt indicates that a driver option is invalid
+var errInvalidDriverOpt = errors.New("invalid driver option")
+
+// errAmbiguous indicates that a secret is ambiguous
+var errAmbiguous = errors.New("secret is ambiguous")
+
+// errDataSize indicates that the secret data is too large or too small
+var errDataSize = errors.New("secret data must be larger than 0 and less than 512000 bytes")
+
+// secretsFile is the name of the file that the secrets database will be stored in
+var secretsFile = "secrets.json"
+
+// secretNameRegexp matches valid secret names
+// Allowed: 64 [a-zA-Z0-9-_.] characters, and the start and end character must be [a-zA-Z0-9]
+var secretNameRegexp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]*$`)
+
+// SecretsManager holds information on handling secrets
+type SecretsManager struct {
+ // secretsPath is the path to the db file where secrets are stored
+ secretsDBPath string
+ // lockfile is the locker for the secrets file
+ lockfile lockfile.Locker
+ // db is an in-memory cache of the database of secrets
+ db *db
+}
+
+// Secret defines a secret
+type Secret struct {
+ // Name is the name of the secret
+ Name string `json:"name"`
+ // ID is the unique secret ID
+ ID string `json:"id"`
+ // Metadata stores other metadata on the secret
+ Metadata map[string]string `json:"metadata,omitempty"`
+ // CreatedAt is when the secret was created
+ CreatedAt time.Time `json:"createdAt"`
+ // Driver is the driver used to store secret data
+ Driver string `json:"driver"`
+ // DriverOptions is other metadata needed to use the driver
+ DriverOptions map[string]string `json:"driverOptions"`
+}
+
+// SecretsDriver interfaces with the secrets data store.
+// The driver stores the actual bytes of secret data, as opposed to
+// the secret metadata.
+// Currently only the unencrypted filedriver is implemented.
+type SecretsDriver interface {
+ // List lists all secret ids in the secrets data store
+ List() ([]string, error)
+ // Lookup gets the secret's data bytes
+ Lookup(id string) ([]byte, error)
+ // Store stores the secret's data bytes
+ Store(id string, data []byte) error
+ // Delete deletes a secret's data from the driver
+ Delete(id string) error
+}
+
+// NewManager creates a new secrets manager
+// rootPath is the directory where the secrets data file resides
+func NewManager(rootPath string) (*SecretsManager, error) {
+ manager := new(SecretsManager)
+
+ if !filepath.IsAbs(rootPath) {
+ return nil, errors.Wrapf(errInvalidPath, "path must be absolute: %s", rootPath)
+ }
+ // the lockfile functions requre that the rootPath dir is executable
+ if err := os.MkdirAll(rootPath, 0700); err != nil {
+ return nil, err
+ }
+
+ lock, err := lockfile.GetLockfile(filepath.Join(rootPath, "secrets.lock"))
+ if err != nil {
+ return nil, err
+ }
+ manager.lockfile = lock
+ manager.secretsDBPath = filepath.Join(rootPath, secretsFile)
+ manager.db = new(db)
+ manager.db.Secrets = make(map[string]Secret)
+ manager.db.NameToID = make(map[string]string)
+ manager.db.IDToName = make(map[string]string)
+ return manager, nil
+}
+
+// Store takes a name, creates a secret and stores the secret metadata and the secret payload.
+// It returns a generated ID that is associated with the secret.
+// The max size for secret data is 512kB.
+func (s *SecretsManager) Store(name string, data []byte, driverType string, driverOpts map[string]string) (string, error) {
+ err := validateSecretName(name)
+ if err != nil {
+ return "", err
+ }
+
+ if !(len(data) > 0 && len(data) < maxSecretSize) {
+ return "", errDataSize
+ }
+
+ s.lockfile.Lock()
+ defer s.lockfile.Unlock()
+
+ exist, err := s.exactSecretExists(name)
+ if err != nil {
+ return "", err
+ }
+ if exist {
+ return "", errors.Wrapf(errSecretNameInUse, name)
+ }
+
+ secr := new(Secret)
+ secr.Name = name
+
+ for {
+ newID := stringid.GenerateNonCryptoID()
+ // GenerateNonCryptoID() gives 64 characters, so we truncate to correct length
+ newID = newID[0:secretIDLength]
+ _, err := s.lookupSecret(newID)
+ if err != nil {
+ if errors.Cause(err) == errNoSuchSecret {
+ secr.ID = newID
+ break
+ } else {
+ return "", err
+ }
+ }
+ }
+
+ secr.Driver = driverType
+ secr.Metadata = make(map[string]string)
+ secr.CreatedAt = time.Now()
+ secr.DriverOptions = driverOpts
+
+ driver, err := getDriver(driverType, driverOpts)
+ if err != nil {
+ return "", err
+ }
+ err = driver.Store(secr.ID, data)
+ if err != nil {
+ return "", errors.Wrapf(err, "error creating secret %s", name)
+ }
+
+ err = s.store(secr)
+ if err != nil {
+ return "", errors.Wrapf(err, "error creating secret %s", name)
+ }
+
+ return secr.ID, nil
+}
+
+// Delete removes all secret metadata and secret data associated with the specified secret.
+// Delete takes a name, ID, or partial ID.
+func (s *SecretsManager) Delete(nameOrID string) (string, error) {
+ err := validateSecretName(nameOrID)
+ if err != nil {
+ return "", err
+ }
+
+ s.lockfile.Lock()
+ defer s.lockfile.Unlock()
+
+ secret, err := s.lookupSecret(nameOrID)
+ if err != nil {
+ return "", err
+ }
+ secretID := secret.ID
+
+ driver, err := getDriver(secret.Driver, secret.DriverOptions)
+ if err != nil {
+ return "", err
+ }
+
+ err = driver.Delete(secretID)
+ if err != nil {
+ return "", errors.Wrapf(err, "error deleting secret %s", nameOrID)
+ }
+
+ err = s.delete(secretID)
+ if err != nil {
+ return "", errors.Wrapf(err, "error deleting secret %s", nameOrID)
+ }
+ return secretID, nil
+}
+
+// Lookup gives a secret's metadata given its name, ID, or partial ID.
+func (s *SecretsManager) Lookup(nameOrID string) (*Secret, error) {
+ s.lockfile.Lock()
+ defer s.lockfile.Unlock()
+
+ return s.lookupSecret(nameOrID)
+}
+
+// List lists all secrets.
+func (s *SecretsManager) List() ([]Secret, error) {
+ s.lockfile.Lock()
+ defer s.lockfile.Unlock()
+
+ secrets, err := s.lookupAll()
+ if err != nil {
+ return nil, err
+ }
+ var ls []Secret
+ for _, v := range secrets {
+ ls = append(ls, v)
+
+ }
+ return ls, nil
+}
+
+// LookupSecretData returns secret metadata as well as secret data in bytes.
+// The secret data can be looked up using its name, ID, or partial ID.
+func (s *SecretsManager) LookupSecretData(nameOrID string) (*Secret, []byte, error) {
+ s.lockfile.Lock()
+ defer s.lockfile.Unlock()
+
+ secret, err := s.lookupSecret(nameOrID)
+ if err != nil {
+ return nil, nil, err
+ }
+ driver, err := getDriver(secret.Driver, secret.DriverOptions)
+ if err != nil {
+ return nil, nil, err
+ }
+ data, err := driver.Lookup(secret.ID)
+ if err != nil {
+ return nil, nil, err
+ }
+ return secret, data, nil
+}
+
+// validateSecretName checks if the secret name is valid.
+func validateSecretName(name string) error {
+ if !secretNameRegexp.MatchString(name) || len(name) > 64 || strings.HasSuffix(name, "-") || strings.HasSuffix(name, ".") {
+ return errors.Wrapf(errInvalidSecretName, "only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]: %s", name)
+ }
+ return nil
+}
+
+// getDriver creates a new driver.
+func getDriver(name string, opts map[string]string) (SecretsDriver, error) {
+ if name == "file" {
+ if path, ok := opts["path"]; ok {
+ return filedriver.NewDriver(path)
+ } else {
+ return nil, errors.Wrap(errInvalidDriverOpt, "need path for filedriver")
+ }
+ }
+ return nil, errInvalidDriver
+}
diff --git a/vendor/github.com/containers/common/pkg/secrets/secretsdb.go b/vendor/github.com/containers/common/pkg/secrets/secretsdb.go
new file mode 100644
index 000000000..22db97c12
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/secrets/secretsdb.go
@@ -0,0 +1,211 @@
+package secrets
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/pkg/errors"
+)
+
+type db struct {
+ // Secrets maps a secret id to secret metadata
+ Secrets map[string]Secret `json:"secrets"`
+ // NameToID maps a secret name to a secret id
+ NameToID map[string]string `json:"nameToID"`
+ // IDToName maps a secret id to a secret name
+ IDToName map[string]string `json:"idToName"`
+ // lastModified is the time when the database was last modified on the file system
+ lastModified time.Time
+}
+
+// loadDB loads database data into the in-memory cache if it has been modified
+func (s *SecretsManager) loadDB() error {
+ // check if the db file exists
+ fileInfo, err := os.Stat(s.secretsDBPath)
+ if err != nil {
+ if !os.IsExist(err) {
+ // If the file doesn't exist, then there's no reason to update the db cache,
+ // the db cache will show no entries anyway.
+ // The file will be created later on a store()
+ return nil
+ } else {
+ return err
+ }
+ }
+
+ // We check if the file has been modified after the last time it was loaded into the cache.
+ // If the file has been modified, then we know that our cache is not up-to-date, so we load
+ // the db into the cache.
+ if s.db.lastModified.Equal(fileInfo.ModTime()) {
+ return nil
+ }
+
+ file, err := os.Open(s.secretsDBPath)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ if err != nil {
+ return err
+ }
+
+ byteValue, err := ioutil.ReadAll(file)
+ if err != nil {
+ return err
+ }
+ unmarshalled := new(db)
+ if err := json.Unmarshal(byteValue, unmarshalled); err != nil {
+ return err
+ }
+ s.db = unmarshalled
+ s.db.lastModified = fileInfo.ModTime()
+
+ return nil
+}
+
+// getNameAndID takes a secret's name, ID, or partial ID, and returns both its name and full ID.
+func (s *SecretsManager) getNameAndID(nameOrID string) (name, id string, err error) {
+ name, id, err = s.getExactNameAndID(nameOrID)
+ if err == nil {
+ return name, id, nil
+ } else if errors.Cause(err) != errNoSuchSecret {
+ return "", "", err
+ }
+
+ // ID prefix may have been given, iterate through all IDs.
+ // ID and partial ID has a max lenth of 25, so we return if its greater than that.
+ if len(nameOrID) > secretIDLength {
+ return "", "", errors.Wrapf(errNoSuchSecret, "no secret with name or id %q", nameOrID)
+ }
+ exists := false
+ var foundID, foundName string
+ for id, name := range s.db.IDToName {
+ if strings.HasPrefix(id, nameOrID) {
+ if exists {
+ return "", "", errors.Wrapf(errAmbiguous, "more than one result secret with prefix %s", nameOrID)
+ }
+ exists = true
+ foundID = id
+ foundName = name
+ }
+ }
+
+ if exists {
+ return foundName, foundID, nil
+ }
+ return "", "", errors.Wrapf(errNoSuchSecret, "no secret with name or id %q", nameOrID)
+}
+
+// getExactNameAndID takes a secret's name or ID and returns both its name and full ID.
+func (s *SecretsManager) getExactNameAndID(nameOrID string) (name, id string, err error) {
+ err = s.loadDB()
+ if err != nil {
+ return "", "", err
+ }
+ if name, ok := s.db.IDToName[nameOrID]; ok {
+ id := nameOrID
+ return name, id, nil
+ }
+
+ if id, ok := s.db.NameToID[nameOrID]; ok {
+ name := nameOrID
+ return name, id, nil
+ }
+
+ return "", "", errors.Wrapf(errNoSuchSecret, "no secret with name or id %q", nameOrID)
+}
+
+// exactSecretExists checks if the secret exists, given a name or ID
+// Does not match partial name or IDs
+func (s *SecretsManager) exactSecretExists(nameOrID string) (bool, error) {
+ _, _, err := s.getExactNameAndID(nameOrID)
+ if err != nil {
+ if errors.Cause(err) == errNoSuchSecret {
+ return false, nil
+ }
+ return false, err
+ }
+ return true, nil
+}
+
+// lookupAll gets all secrets stored.
+func (s *SecretsManager) lookupAll() (map[string]Secret, error) {
+ err := s.loadDB()
+ if err != nil {
+ return nil, err
+ }
+ return s.db.Secrets, nil
+}
+
+// lookupSecret returns a secret with the given name, ID, or partial ID.
+func (s *SecretsManager) lookupSecret(nameOrID string) (*Secret, error) {
+ err := s.loadDB()
+ if err != nil {
+ return nil, err
+ }
+ _, id, err := s.getNameAndID(nameOrID)
+ if err != nil {
+ return nil, err
+ }
+ allSecrets, err := s.lookupAll()
+ if err != nil {
+ return nil, err
+ }
+ if secret, ok := allSecrets[id]; ok {
+ return &secret, nil
+ }
+
+ return nil, errors.Wrapf(errNoSuchSecret, "no secret with name or id %q", nameOrID)
+}
+
+// Store creates a new secret in the secrets database.
+// It deals with only storing metadata, not data payload.
+func (s *SecretsManager) store(entry *Secret) error {
+ err := s.loadDB()
+ if err != nil {
+ return err
+ }
+
+ s.db.Secrets[entry.ID] = *entry
+ s.db.NameToID[entry.Name] = entry.ID
+ s.db.IDToName[entry.ID] = entry.Name
+
+ marshalled, err := json.MarshalIndent(s.db, "", " ")
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(s.secretsDBPath, marshalled, 0600)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// delete deletes a secret from the secrets database, given a name, ID, or partial ID.
+// It deals with only deleting metadata, not data payload.
+func (s *SecretsManager) delete(nameOrID string) error {
+ name, id, err := s.getNameAndID(nameOrID)
+ if err != nil {
+ return err
+ }
+ err = s.loadDB()
+ if err != nil {
+ return err
+ }
+ delete(s.db.Secrets, id)
+ delete(s.db.NameToID, name)
+ delete(s.db.IDToName, id)
+ marshalled, err := json.MarshalIndent(s.db, "", " ")
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(s.secretsDBPath, marshalled, 0600)
+ if err != nil {
+ return err
+ }
+ return nil
+}