summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2018-03-01 11:56:22 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-03-06 01:21:09 +0000
commitd589c9fc3874def8ec2ed09d66ca33180f053c39 (patch)
treed7e95d82c54561dbd8abfedac3ea7b4fb03efcb9
parent05c76f739c6c9d5237112cc53137842842d56e67 (diff)
downloadpodman-d589c9fc3874def8ec2ed09d66ca33180f053c39.tar.gz
podman-d589c9fc3874def8ec2ed09d66ca33180f053c39.tar.bz2
podman-d589c9fc3874def8ec2ed09d66ca33180f053c39.zip
Add support to load runtime configuration from config file
Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #430 Approved by: rhatdan
-rw-r--r--Makefile2
-rw-r--r--libpod/runtime.go116
2 files changed, 99 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 3fa9fa2ef..50766900a 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@ LIBEXECDIR ?= ${PREFIX}/libexec
MANDIR ?= ${PREFIX}/share/man
ETCDIR ?= ${DESTDIR}/etc
ETCDIR_LIBPOD ?= ${ETCDIR}/crio
+ETCDIR_CONTAINERS ?= ${ETCDIR}/containers
BUILDTAGS ?= seccomp $(shell hack/btrfs_tag.sh) $(shell hack/libdm_tag.sh) $(shell hack/btrfs_installed_tag.sh) $(shell hack/ostree_tag.sh) $(shell hack/selinux_tag.sh)
BASHINSTALLDIR=${PREFIX}/share/bash-completion/completions
@@ -151,6 +152,7 @@ install.man: docs
install ${SELINUXOPT} -m 644 $(filter %.1,$(MANPAGES)) -t $(MANDIR)/man1
install.config:
+ install ${SELINUXOPT} -D -m 644 libpod.conf ${ETCDIR_CONTAINERS}/libpod.conf
install ${SELINUXOPT} -D -m 644 seccomp.json $(ETCDIR_LIBPOD)/seccomp.json
install ${SELINUXOPT} -D -m 644 crio-umount.conf $(OCIUMOUNTINSTALLDIR)/crio-umount.conf
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 2876d8798..4e1a60ea6 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -37,6 +37,14 @@ const (
SeccompDefaultPath = "/usr/share/containers/seccomp.json"
// SeccompOverridePath if this exists it overrides the default seccomp path
SeccompOverridePath = "/etc/crio/seccomp.json"
+
+ // ConfigPath is the path to the libpod configuration file
+ // This file is loaded to replace the builtin default config before
+ // runtime options (e.g. WithStorageConfig) are applied.
+ // If it is not present, the builtin default config is used instead
+ // This path can be overridden when the runtime is created by using
+ // NewRuntimeFromConfig() instead of NewRuntime()
+ ConfigPath = "/etc/containers/libpod.conf"
)
// A RuntimeOption is a functional option which alters the Runtime created by
@@ -155,13 +163,83 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// Copy the default configuration
deepcopier.Copy(defaultRuntimeConfig).To(runtime.config)
- // Overwrite it with user-given configuration options
+ // Now overwrite it with the given configuration file, if it exists
+ // Do not fail on error, instead just use the builtin defaults
+ if _, err := os.Stat(ConfigPath); err == nil {
+ // Read the contents of the config file
+ contents, err := ioutil.ReadFile(ConfigPath)
+ if err == nil {
+ // Only proceed if we successfully read the file
+ _, err := toml.Decode(string(contents), runtime.config)
+ if err != nil {
+ // We may have just ruined our RuntimeConfig
+ // Make a new one to be safe
+ runtime.config = new(RuntimeConfig)
+ deepcopier.Copy(defaultRuntimeConfig).To(runtime.config)
+ }
+ }
+ }
+
+ // Overwrite config with user-given configuration options
for _, opt := range options {
if err := opt(runtime); err != nil {
return nil, errors.Wrapf(err, "error configuring runtime")
}
}
+ if err := makeRuntime(runtime); err != nil {
+ return nil, err
+ }
+
+ return runtime, nil
+}
+
+// NewRuntimeFromConfig creates a new container runtime using the given
+// configuration file for its default configuration. Passed RuntimeOption
+// functions can be used to mutate this configuration further.
+// An error will be returned if the configuration file at the given path does
+// not exist or cannot be loaded
+func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime *Runtime, err error) {
+ runtime = new(Runtime)
+ runtime.config = new(RuntimeConfig)
+
+ // Set two fields not in the TOML config
+ runtime.config.StateType = defaultRuntimeConfig.StateType
+ runtime.config.StorageConfig = storage.StoreOptions{}
+
+ // Check to see if the given configuration file exists
+ if _, err := os.Stat(configPath); err != nil {
+ return nil, errors.Wrapf(err, "error stating configuration file %s", configPath)
+ }
+
+ // Read contents of the config file
+ contents, err := ioutil.ReadFile(configPath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading configuration file %s", configPath)
+ }
+
+ // Decode configuration file
+ if _, err := toml.Decode(string(contents), runtime.config); err != nil {
+ return nil, errors.Wrapf(err, "error decoding configuration from file %s", configPath)
+ }
+
+ // Overwrite the config with user-given configuration options
+ for _, opt := range options {
+ if err := opt(runtime); err != nil {
+ return nil, errors.Wrapf(err, "error configuring runtime")
+ }
+ }
+
+ if err := makeRuntime(runtime); err != nil {
+ return nil, err
+ }
+
+ return runtime, nil
+}
+
+// Make a new runtime based on the given configuration
+// Sets up containers/storage, state store, OCI runtime
+func makeRuntime(runtime *Runtime) error {
// Find a working OCI runtime binary
foundRuntime := false
for _, path := range runtime.config.RuntimePath {
@@ -177,7 +255,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
break
}
if !foundRuntime {
- return nil, errors.Wrapf(ErrInvalidArg,
+ return errors.Wrapf(ErrInvalidArg,
"could not find a working runc binary (configured options: %v)",
runtime.config.RuntimePath)
}
@@ -197,7 +275,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
break
}
if !foundConmon {
- return nil, errors.Wrapf(ErrInvalidArg,
+ return errors.Wrapf(ErrInvalidArg,
"could not find a working conmon binary (configured options: %v)",
runtime.config.RuntimePath)
}
@@ -205,7 +283,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// Set up containers/storage
store, err := storage.GetStore(runtime.config.StorageConfig)
if err != nil {
- return nil, err
+ return err
}
runtime.store = store
is.Transport.SetStore(store)
@@ -224,7 +302,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// images
storageService, err := getStorageService(runtime.store)
if err != nil {
- return nil, err
+ return err
}
runtime.storageService = storageService
@@ -239,7 +317,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
runtime.config.CgroupManager, runtime.config.TmpDir,
runtime.config.MaxLogSize, runtime.config.NoPivotRoot)
if err != nil {
- return nil, err
+ return err
}
runtime.ociRuntime = ociRuntime
@@ -247,7 +325,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
if err := os.MkdirAll(runtime.config.StaticDir, 0755); err != nil {
// The directory is allowed to exist
if !os.IsExist(err) {
- return nil, errors.Wrapf(err, "error creating runtime static files directory %s",
+ return errors.Wrapf(err, "error creating runtime static files directory %s",
runtime.config.StaticDir)
}
}
@@ -257,7 +335,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
if err := os.MkdirAll(lockDir, 0755); err != nil {
// The directory is allowed to exist
if !os.IsExist(err) {
- return nil, errors.Wrapf(err, "error creating runtime lockfiles directory %s",
+ return errors.Wrapf(err, "error creating runtime lockfiles directory %s",
lockDir)
}
}
@@ -267,7 +345,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
if err := os.MkdirAll(runtime.config.TmpDir, 0755); err != nil {
// The directory is allowed to exist
if !os.IsExist(err) {
- return nil, errors.Wrapf(err, "error creating runtime temporary files directory %s",
+ return errors.Wrapf(err, "error creating runtime temporary files directory %s",
runtime.config.TmpDir)
}
}
@@ -275,7 +353,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// Set up the CNI net plugin
netPlugin, err := ocicni.InitCNI(runtime.config.CNIConfigDir, runtime.config.CNIPluginDir...)
if err != nil {
- return nil, errors.Wrapf(err, "error configuring CNI network plugin")
+ return errors.Wrapf(err, "error configuring CNI network plugin")
}
runtime.netPlugin = netPlugin
@@ -284,7 +362,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
case InMemoryStateStore:
state, err := NewInMemoryState()
if err != nil {
- return nil, err
+ return err
}
runtime.state = state
case SQLiteStateStore:
@@ -295,14 +373,14 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
if err := os.MkdirAll(specsDir, 0755); err != nil {
// The directory is allowed to exist
if !os.IsExist(err) {
- return nil, errors.Wrapf(err, "error creating runtime OCI specs directory %s",
+ return errors.Wrapf(err, "error creating runtime OCI specs directory %s",
specsDir)
}
}
state, err := NewSQLState(dbPath, specsDir, runtime.lockDir, runtime)
if err != nil {
- return nil, err
+ return err
}
runtime.state = state
case BoltDBStateStore:
@@ -310,11 +388,11 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
state, err := NewBoltState(dbPath, runtime.lockDir, runtime)
if err != nil {
- return nil, err
+ return err
}
runtime.state = state
default:
- return nil, errors.Wrapf(ErrInvalidArg, "unrecognized state type passed")
+ return errors.Wrapf(ErrInvalidArg, "unrecognized state type passed")
}
// We now need to see if the system has restarted
@@ -324,7 +402,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
runtimeAliveFile := filepath.Join(runtime.config.TmpDir, "alive")
aliveLock, err := storage.GetLockfile(runtimeAliveLock)
if err != nil {
- return nil, errors.Wrapf(err, "error acquiring runtime init lock")
+ return errors.Wrapf(err, "error acquiring runtime init lock")
}
// Acquire the lock and hold it until we return
// This ensures that no two processes will be in runtime.refresh at once
@@ -340,10 +418,10 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// As such, it's not really a performance concern
if os.IsNotExist(err) {
if err2 := runtime.refresh(runtimeAliveFile); err2 != nil {
- return nil, err2
+ return err2
}
} else {
- return nil, errors.Wrapf(err, "error reading runtime status file %s", runtimeAliveFile)
+ return errors.Wrapf(err, "error reading runtime status file %s", runtimeAliveFile)
}
}
@@ -351,7 +429,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
// further
runtime.valid = true
- return runtime, nil
+ return nil
}
// GetConfig returns a copy of the configuration used by the runtime