Skip to content

Commit

Permalink
Merge pull request containers#3724 from mheon/v1.4.2-stable1
Browse files Browse the repository at this point in the history
V1.4.2 stable1
  • Loading branch information
openshift-merge-robot authored Aug 5, 2019
2 parents 3b1ee69 + 29c137f commit d46c764
Show file tree
Hide file tree
Showing 124 changed files with 59,300 additions and 251 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ RUN apt-get update && apt-get install -y \
libnl-3-dev \
libostree-dev \
libprotobuf-dev \
libprotobuf-c0-dev \
libprotobuf-c-dev \
libseccomp2 \
libseccomp-dev \
libtool \
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/cliconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type MainFlags struct {
CniConfigDir string
ConmonPath string
DefaultMountsFile string
EventsBackend string
HooksDir []string
MaxWorks int
Namespace string
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"systemd", cliconfig.DefaultSystemD,
"Run container in systemd mode if the command executable is systemd or init",
)
createFlags.StringSlice(
createFlags.StringArray(
"tmpfs", []string{},
"Mount a temporary filesystem (`tmpfs`) into a container (default [])",
)
Expand Down
4 changes: 4 additions & 0 deletions cmd/podman/libpodruntime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber bool,
options = append(options, libpod.WithNetworkCmdPath(c.GlobalFlags.NetworkCmdPath))
}

if c.Flags().Changed("events-backend") {
options = append(options, libpod.WithEventsLogger(c.GlobalFlags.EventsBackend))
}

if c.Flags().Changed("cgroup-manager") {
options = append(options, libpod.WithCgroupManager(c.GlobalFlags.CGroupManager))
} else {
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/main_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func init() {
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CniConfigDir, "cni-config-dir", "", "Path of the configuration directory for CNI networks")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.DefaultMountsFile, "default-mounts-file", "", "Path to default mounts file")
rootCmd.PersistentFlags().MarkHidden("defaults-mount-file")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.EventsBackend, "events-backend", "", "Events backend to use")
// Override default --help information of `--help` global flag
var dummyHelp bool
rootCmd.PersistentFlags().BoolVar(&dummyHelp, "help", false, "Help for podman")
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/shared/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
StopTimeout: c.Uint("stop-timeout"),
Sysctl: sysctl,
Systemd: systemd,
Tmpfs: c.StringSlice("tmpfs"),
Tmpfs: c.StringArray("tmpfs"),
Tty: tty,
User: user,
UsernsMode: usernsMode,
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/shared/intermediate.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["subuidname"] = newCRString(c, "subuidname")
m["sysctl"] = newCRStringSlice(c, "sysctl")
m["systemd"] = newCRBool(c, "systemd")
m["tmpfs"] = newCRStringSlice(c, "tmpfs")
m["tmpfs"] = newCRStringArray(c, "tmpfs")
m["tty"] = newCRBool(c, "tty")
m["uidmap"] = newCRStringSlice(c, "uidmap")
m["ulimit"] = newCRStringSlice(c, "ulimit")
Expand Down
2 changes: 1 addition & 1 deletion docs/libpod.conf.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ libpod to manage containers.
a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable.

**events_logger**=""
Default method to use when logging events. Valid values are "journald" and "file".
Default method to use when logging events. Valid values are "file", "journald", and "none".

## FILES
`/usr/share/containers/libpod.conf`, default libpod configuration path
Expand Down
4 changes: 4 additions & 0 deletions docs/podman.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ CGroup manager to use for container cgroups. Supported values are cgroupfs or sy

Path to where the cpu performance results should be written

**--events-logger**=*type*

Backend to use for storing events. Allowed values are **file**, **journald**, and **none**.

**--hooks-dir**=*path*

Each `*.json` file in the path configures a hook for Podman containers. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`. Podman and libpod currently support both the 1.0.0 and 0.1.0 hook schemas, although the 0.1.0 schema is deprecated.
Expand Down
70 changes: 39 additions & 31 deletions libpod/boltdb_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,42 +73,50 @@ func NewBoltState(path string, runtime *Runtime) (State, error) {
// As such, just a db.Close() is fine here.
defer db.Close()

// Perform initial database setup
err = db.Update(func(tx *bolt.Tx) error {
if _, err := tx.CreateBucketIfNotExists(idRegistryBkt); err != nil {
return errors.Wrapf(err, "error creating id-registry bucket")
}
if _, err := tx.CreateBucketIfNotExists(nameRegistryBkt); err != nil {
return errors.Wrapf(err, "error creating name-registry bucket")
}
if _, err := tx.CreateBucketIfNotExists(nsRegistryBkt); err != nil {
return errors.Wrapf(err, "error creating ns-registry bucket")
}
if _, err := tx.CreateBucketIfNotExists(ctrBkt); err != nil {
return errors.Wrapf(err, "error creating containers bucket")
}
if _, err := tx.CreateBucketIfNotExists(allCtrsBkt); err != nil {
return errors.Wrapf(err, "error creating all containers bucket")
}
if _, err := tx.CreateBucketIfNotExists(podBkt); err != nil {
return errors.Wrapf(err, "error creating pods bucket")
}
if _, err := tx.CreateBucketIfNotExists(allPodsBkt); err != nil {
return errors.Wrapf(err, "error creating all pods bucket")
}
if _, err := tx.CreateBucketIfNotExists(volBkt); err != nil {
return errors.Wrapf(err, "error creating volume bucket")
}
if _, err := tx.CreateBucketIfNotExists(allVolsBkt); err != nil {
return errors.Wrapf(err, "error creating all volumes bucket")
createBuckets := [][]byte{
idRegistryBkt,
nameRegistryBkt,
nsRegistryBkt,
ctrBkt,
allCtrsBkt,
podBkt,
allPodsBkt,
volBkt,
allVolsBkt,
runtimeConfigBkt,
}

// Does the DB need an update?
needsUpdate := false
err = db.View(func(tx *bolt.Tx) error {
for _, bkt := range createBuckets {
if test := tx.Bucket(bkt); test == nil {
needsUpdate = true
break
}
}
if _, err := tx.CreateBucketIfNotExists(runtimeConfigBkt); err != nil {
return errors.Wrapf(err, "error creating runtime-config bucket")
return nil
})
if err != nil {
return nil, errors.Wrapf(err, "error checking DB schema")
}

if !needsUpdate {
state.valid = true
return state, nil
}

// Ensure schema is properly created in DB
err = db.Update(func(tx *bolt.Tx) error {
for _, bkt := range createBuckets {
if _, err := tx.CreateBucketIfNotExists(bkt); err != nil {
return errors.Wrapf(err, "error creating bucket %s", string(bkt))
}
}
return nil
})
if err != nil {
return nil, errors.Wrapf(err, "error creating initial database layout")
return nil, errors.Wrapf(err, "error creating buckets for DB")
}

state.valid = true
Expand Down
186 changes: 124 additions & 62 deletions libpod/boltdb_state_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,98 +72,160 @@ var (
volPathKey = []byte(volPathName)
)

// This represents a field in the runtime configuration that will be validated
// against the DB to ensure no configuration mismatches occur.
type dbConfigValidation struct {
name string // Only used for error messages
runtimeValue string
key []byte
defaultValue string
}

// Check if the configuration of the database is compatible with the
// configuration of the runtime opening it
// If there is no runtime configuration loaded, load our own
func checkRuntimeConfig(db *bolt.DB, rt *Runtime) error {
err := db.Update(func(tx *bolt.Tx) error {
storeOpts, err := storage.DefaultStoreOptions(rootless.IsRootless(), rootless.GetRootlessUID())
if err != nil {
return err
}

// We need to validate the following things
checks := []dbConfigValidation{
{
"OS",
runtime.GOOS,
osKey,
runtime.GOOS,
},
{
"libpod root directory (staticdir)",
rt.config.StaticDir,
staticDirKey,
"",
},
{
"libpod temporary files directory (tmpdir)",
rt.config.TmpDir,
tmpDirKey,
"",
},
{
"storage temporary directory (runroot)",
rt.config.StorageConfig.RunRoot,
runRootKey,
storeOpts.RunRoot,
},
{
"storage graph root directory (graphroot)",
rt.config.StorageConfig.GraphRoot,
graphRootKey,
storeOpts.GraphRoot,
},
{
"storage graph driver",
rt.config.StorageConfig.GraphDriverName,
graphDriverKey,
storeOpts.GraphDriverName,
},
{
"volume path",
rt.config.VolumePath,
volPathKey,
"",
},
}

// These fields were missing and will have to be recreated.
missingFields := []dbConfigValidation{}

// Let's try and validate read-only first
err = db.View(func(tx *bolt.Tx) error {
configBkt, err := getRuntimeConfigBucket(tx)
if err != nil {
return err
}

if err := validateDBAgainstConfig(configBkt, "OS", runtime.GOOS, osKey, runtime.GOOS); err != nil {
return err
for _, check := range checks {
exists, err := readOnlyValidateConfig(configBkt, check)
if err != nil {
return err
}
if !exists {
missingFields = append(missingFields, check)
}
}

if err := validateDBAgainstConfig(configBkt, "libpod root directory (staticdir)",
rt.config.StaticDir, staticDirKey, ""); err != nil {
return err
}
return nil
})
if err != nil {
return err
}

if err := validateDBAgainstConfig(configBkt, "libpod temporary files directory (tmpdir)",
rt.config.TmpDir, tmpDirKey, ""); err != nil {
return err
}
if len(missingFields) == 0 {
return nil
}

storeOpts, err := storage.DefaultStoreOptions(rootless.IsRootless(), rootless.GetRootlessUID())
// Populate missing fields
return db.Update(func(tx *bolt.Tx) error {
configBkt, err := getRuntimeConfigBucket(tx)
if err != nil {
return err
}
if err := validateDBAgainstConfig(configBkt, "storage temporary directory (runroot)",
rt.config.StorageConfig.RunRoot, runRootKey,
storeOpts.RunRoot); err != nil {
return err
}

if err := validateDBAgainstConfig(configBkt, "storage graph root directory (graphroot)",
rt.config.StorageConfig.GraphRoot, graphRootKey,
storeOpts.GraphRoot); err != nil {
return err
}
for _, missing := range missingFields {
dbValue := []byte(missing.runtimeValue)
if missing.runtimeValue == "" && missing.defaultValue != "" {
dbValue = []byte(missing.defaultValue)
}

if err := validateDBAgainstConfig(configBkt, "storage graph driver",
rt.config.StorageConfig.GraphDriverName,
graphDriverKey,
storeOpts.GraphDriverName); err != nil {
return err
if err := configBkt.Put(missing.key, dbValue); err != nil {
return errors.Wrapf(err, "error updating %s in DB runtime config", missing.name)
}
}

return validateDBAgainstConfig(configBkt, "volume path",
rt.config.VolumePath, volPathKey, "")
return nil
})

return err
}

// Validate a configuration entry in the DB against current runtime config
// If the given configuration key does not exist it will be created
// If the given runtimeValue or value retrieved from the database are the empty
// string and defaultValue is not, defaultValue will be checked instead. This
// ensures that we will not fail on configuration changes in configured c/storage.
func validateDBAgainstConfig(bucket *bolt.Bucket, fieldName, runtimeValue string, keyName []byte, defaultValue string) error {
keyBytes := bucket.Get(keyName)
// Attempt a read-only validation of a configuration entry in the DB against an
// element of the current runtime configuration.
// If the configuration key in question does not exist, (false, nil) will be
// returned.
// If the configuration key does exist, and matches the runtime configuration
// successfully, (true, nil) is returned.
// An error is only returned when validation fails.
// if the given runtimeValue or value retrieved from the database are empty,
// and defaultValue is not, defaultValue will be checked instead. This ensures
// that we will not fail on configuration changes in c/storage (where we may
// pass the empty string to use defaults).
func readOnlyValidateConfig(bucket *bolt.Bucket, toCheck dbConfigValidation) (bool, error) {
keyBytes := bucket.Get(toCheck.key)
if keyBytes == nil {
dbValue := []byte(runtimeValue)
if runtimeValue == "" && defaultValue != "" {
dbValue = []byte(defaultValue)
}
// False return indicates missing key
return false, nil
}

if err := bucket.Put(keyName, dbValue); err != nil {
return errors.Wrapf(err, "error updating %s in DB runtime config", fieldName)
}
} else {
if runtimeValue != string(keyBytes) {
// If runtimeValue is the empty string, check against
// the default
if runtimeValue == "" && defaultValue != "" &&
string(keyBytes) == defaultValue {
return nil
}
dbValue := string(keyBytes)

// If DB value is the empty string, check that the
// runtime value is the default
if string(keyBytes) == "" && defaultValue != "" &&
runtimeValue == defaultValue {
return nil
}
if toCheck.runtimeValue != dbValue {
// If the runtime value is the empty string and default is not,
// check against default.
if toCheck.runtimeValue == "" && toCheck.defaultValue != "" && dbValue == toCheck.defaultValue {
return true, nil
}

return errors.Wrapf(ErrDBBadConfig, "database %s %s does not match our %s %s",
fieldName, string(keyBytes), fieldName, runtimeValue)
// If the DB value is the empty string, check that the runtime
// value is the default.
if dbValue == "" && toCheck.defaultValue != "" && toCheck.runtimeValue == toCheck.defaultValue {
return true, nil
}

return true, errors.Wrapf(ErrDBBadConfig, "database %s %q does not match our %s %q",
toCheck.name, dbValue, toCheck.name, toCheck.runtimeValue)
}

return nil
return true, nil
}

// Open a connection to the database.
Expand Down
Loading

0 comments on commit d46c764

Please sign in to comment.