mirror of https://github.com/containers/podman.git
Merge pull request #1918 from mheon/use_db_paths
Use paths written in DB instead if they differ from our defaults
This commit is contained in:
commit
50e754cd57
|
@ -67,7 +67,7 @@ func createCmd(c *cli.Context) error {
|
|||
rootless.SetSkipStorageSetup(true)
|
||||
}
|
||||
|
||||
runtime, err := libpodruntime.GetContainerRuntime(c)
|
||||
runtime, err := libpodruntime.GetRuntime(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating libpod runtime")
|
||||
}
|
||||
|
|
|
@ -11,32 +11,18 @@ import (
|
|||
|
||||
// GetRuntime generates a new libpod runtime configured by command line options
|
||||
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
|
||||
storageOpts, err := util.GetDefaultStoreOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetRuntimeWithStorageOpts(c, &storageOpts)
|
||||
}
|
||||
|
||||
// GetContainerRuntime generates a new libpod runtime configured by command line options for containers
|
||||
func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) {
|
||||
mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storageOpts, err := util.GetDefaultStoreOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storageOpts.UIDMap = mappings.UIDMap
|
||||
storageOpts.GIDMap = mappings.GIDMap
|
||||
return GetRuntimeWithStorageOpts(c, &storageOpts)
|
||||
}
|
||||
|
||||
// GetRuntime generates a new libpod runtime configured by command line options
|
||||
func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) {
|
||||
storageOpts := new(storage.StoreOptions)
|
||||
options := []libpod.RuntimeOption{}
|
||||
|
||||
if c.IsSet("uidmap") || c.IsSet("gidmap") || c.IsSet("subuidmap") || c.IsSet("subgidmap") {
|
||||
mappings, err := util.ParseIDMapping(c.StringSlice("uidmap"), c.StringSlice("gidmap"), c.String("subuidmap"), c.String("subgidmap"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storageOpts.UIDMap = mappings.UIDMap
|
||||
storageOpts.GIDMap = mappings.GIDMap
|
||||
}
|
||||
|
||||
if c.GlobalIsSet("root") {
|
||||
storageOpts.GraphRoot = c.GlobalString("root")
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func runCmd(c *cli.Context) error {
|
|||
rootless.SetSkipStorageSetup(true)
|
||||
}
|
||||
|
||||
runtime, err := libpodruntime.GetContainerRuntime(c)
|
||||
runtime, err := libpodruntime.GetRuntime(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating libpod runtime")
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package libpod
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
|
@ -19,7 +18,6 @@ type BoltState struct {
|
|||
dbLock sync.Mutex
|
||||
namespace string
|
||||
namespaceBytes []byte
|
||||
lockDir string
|
||||
runtime *Runtime
|
||||
}
|
||||
|
||||
|
@ -52,25 +50,15 @@ type BoltState struct {
|
|||
// containers/storage do not occur.
|
||||
|
||||
// NewBoltState creates a new bolt-backed state database
|
||||
func NewBoltState(path, lockDir string, runtime *Runtime) (State, error) {
|
||||
func NewBoltState(path string, runtime *Runtime) (State, error) {
|
||||
state := new(BoltState)
|
||||
state.dbPath = path
|
||||
state.lockDir = lockDir
|
||||
state.runtime = runtime
|
||||
state.namespace = ""
|
||||
state.namespaceBytes = nil
|
||||
|
||||
logrus.Debugf("Initializing boltdb state at %s", path)
|
||||
|
||||
// Make the directory that will hold container lockfiles
|
||||
if err := os.MkdirAll(lockDir, 0750); err != nil {
|
||||
// The directory is allowed to exist
|
||||
if !os.IsExist(err) {
|
||||
return nil, errors.Wrapf(err, "error creating lockfiles dir %s", lockDir)
|
||||
}
|
||||
}
|
||||
state.lockDir = lockDir
|
||||
|
||||
db, err := bolt.Open(path, 0600, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error opening database %s", path)
|
||||
|
@ -115,11 +103,6 @@ func NewBoltState(path, lockDir string, runtime *Runtime) (State, error) {
|
|||
return nil, errors.Wrapf(err, "error creating initial database layout")
|
||||
}
|
||||
|
||||
// Check runtime configuration
|
||||
if err := checkRuntimeConfig(db, runtime); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
state.valid = true
|
||||
|
||||
return state, nil
|
||||
|
@ -240,6 +223,72 @@ func (s *BoltState) Refresh() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// GetDBConfig retrieves runtime configuration fields that were created when
|
||||
// the database was first initialized
|
||||
func (s *BoltState) GetDBConfig() (*DBConfig, error) {
|
||||
if !s.valid {
|
||||
return nil, ErrDBClosed
|
||||
}
|
||||
|
||||
cfg := new(DBConfig)
|
||||
|
||||
db, err := s.getDBCon()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.closeDBCon(db)
|
||||
|
||||
err = db.View(func(tx *bolt.Tx) error {
|
||||
configBucket, err := getRuntimeConfigBucket(tx)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Some of these may be nil
|
||||
// When we convert to string, Go will coerce them to ""
|
||||
// That's probably fine - we could raise an error if the key is
|
||||
// missing, but just not including it is also OK.
|
||||
libpodRoot := configBucket.Get(staticDirKey)
|
||||
libpodTmp := configBucket.Get(tmpDirKey)
|
||||
storageRoot := configBucket.Get(graphRootKey)
|
||||
storageTmp := configBucket.Get(runRootKey)
|
||||
graphDriver := configBucket.Get(graphDriverKey)
|
||||
|
||||
cfg.LibpodRoot = string(libpodRoot)
|
||||
cfg.LibpodTmp = string(libpodTmp)
|
||||
cfg.StorageRoot = string(storageRoot)
|
||||
cfg.StorageTmp = string(storageTmp)
|
||||
cfg.GraphDriver = string(graphDriver)
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// ValidateDBConfig validates paths in the given runtime against the database
|
||||
func (s *BoltState) ValidateDBConfig(runtime *Runtime) error {
|
||||
if !s.valid {
|
||||
return ErrDBClosed
|
||||
}
|
||||
|
||||
db, err := s.getDBCon()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.closeDBCon(db)
|
||||
|
||||
// Check runtime configuration
|
||||
if err := checkRuntimeConfig(db, runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetNamespace sets the namespace that will be used for container and pod
|
||||
// retrieval
|
||||
func (s *BoltState) SetNamespace(ns string) error {
|
||||
|
|
|
@ -30,6 +30,13 @@ const (
|
|||
containersName = "containers"
|
||||
podIDName = "pod-id"
|
||||
namespaceName = "namespace"
|
||||
|
||||
staticDirName = "static-dir"
|
||||
tmpDirName = "tmp-dir"
|
||||
runRootName = "run-root"
|
||||
graphRootName = "graph-root"
|
||||
graphDriverName = "graph-driver-name"
|
||||
osName = "os"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -49,21 +56,19 @@ var (
|
|||
containersBkt = []byte(containersName)
|
||||
podIDKey = []byte(podIDName)
|
||||
namespaceKey = []byte(namespaceName)
|
||||
|
||||
staticDirKey = []byte(staticDirName)
|
||||
tmpDirKey = []byte(tmpDirName)
|
||||
runRootKey = []byte(runRootName)
|
||||
graphRootKey = []byte(graphRootName)
|
||||
graphDriverKey = []byte(graphDriverName)
|
||||
osKey = []byte(osName)
|
||||
)
|
||||
|
||||
// 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 {
|
||||
var (
|
||||
staticDir = []byte("static-dir")
|
||||
tmpDir = []byte("tmp-dir")
|
||||
runRoot = []byte("run-root")
|
||||
graphRoot = []byte("graph-root")
|
||||
graphDriverName = []byte("graph-driver-name")
|
||||
osKey = []byte("os")
|
||||
)
|
||||
|
||||
err := db.Update(func(tx *bolt.Tx) error {
|
||||
configBkt, err := getRuntimeConfigBucket(tx)
|
||||
if err != nil {
|
||||
|
@ -74,31 +79,31 @@ func checkRuntimeConfig(db *bolt.DB, rt *Runtime) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := validateDBAgainstConfig(configBkt, "static dir",
|
||||
rt.config.StaticDir, staticDir, ""); err != nil {
|
||||
if err := validateDBAgainstConfig(configBkt, "libpod root directory (staticdir)",
|
||||
rt.config.StaticDir, staticDirKey, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateDBAgainstConfig(configBkt, "tmp dir",
|
||||
rt.config.TmpDir, tmpDir, ""); err != nil {
|
||||
if err := validateDBAgainstConfig(configBkt, "libpod temporary files directory (tmpdir)",
|
||||
rt.config.TmpDir, tmpDirKey, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateDBAgainstConfig(configBkt, "run root",
|
||||
rt.config.StorageConfig.RunRoot, runRoot,
|
||||
if err := validateDBAgainstConfig(configBkt, "storage temporary directory (runroot)",
|
||||
rt.config.StorageConfig.RunRoot, runRootKey,
|
||||
storage.DefaultStoreOptions.RunRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateDBAgainstConfig(configBkt, "graph root",
|
||||
rt.config.StorageConfig.GraphRoot, graphRoot,
|
||||
if err := validateDBAgainstConfig(configBkt, "storage graph root directory (graphroot)",
|
||||
rt.config.StorageConfig.GraphRoot, graphRootKey,
|
||||
storage.DefaultStoreOptions.GraphRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validateDBAgainstConfig(configBkt, "graph driver name",
|
||||
return validateDBAgainstConfig(configBkt, "storage graph driver",
|
||||
rt.config.StorageConfig.GraphDriverName,
|
||||
graphDriverName,
|
||||
graphDriverKey,
|
||||
storage.DefaultStoreOptions.GraphDriverName)
|
||||
})
|
||||
|
||||
|
@ -261,7 +266,7 @@ func (s *BoltState) getContainerFromDB(id []byte, ctr *Container, ctrsBkt *bolt.
|
|||
}
|
||||
|
||||
// Get the lock
|
||||
lockPath := filepath.Join(s.lockDir, string(id))
|
||||
lockPath := filepath.Join(s.runtime.lockDir, string(id))
|
||||
lock, err := storage.GetLockfile(lockPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error retrieving lockfile for container %s", string(id))
|
||||
|
@ -297,7 +302,7 @@ func (s *BoltState) getPodFromDB(id []byte, pod *Pod, podBkt *bolt.Bucket) error
|
|||
}
|
||||
|
||||
// Get the lock
|
||||
lockPath := filepath.Join(s.lockDir, string(id))
|
||||
lockPath := filepath.Join(s.runtime.lockDir, string(id))
|
||||
lock, err := storage.GetLockfile(lockPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error retrieving lockfile for pod %s", string(id))
|
||||
|
|
|
@ -73,6 +73,18 @@ func (s *InMemoryState) Refresh() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetDBConfig is not implemented for in-memory state.
|
||||
// As we do not store a config, return an empty one.
|
||||
func (s *InMemoryState) GetDBConfig() (*DBConfig, error) {
|
||||
return &DBConfig{}, nil
|
||||
}
|
||||
|
||||
// ValidateDBConfig is not implemented for the in-memory state.
|
||||
// Since we do nothing just return no error.
|
||||
func (s *InMemoryState) ValidateDBConfig(runtime *Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetNamespace sets the namespace for container and pod retrieval.
|
||||
func (s *InMemoryState) SetNamespace(ns string) error {
|
||||
s.namespace = ns
|
||||
|
|
|
@ -29,19 +29,40 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
|
|||
return ErrRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.StorageConfig.RunRoot = config.RunRoot
|
||||
rt.config.StorageConfig.GraphRoot = config.GraphRoot
|
||||
rt.config.StorageConfig.GraphDriverName = config.GraphDriverName
|
||||
rt.config.StaticDir = filepath.Join(config.GraphRoot, "libpod")
|
||||
if config.RunRoot != "" {
|
||||
rt.config.StorageConfig.RunRoot = config.RunRoot
|
||||
rt.configuredFrom.storageRunRootSet = true
|
||||
}
|
||||
|
||||
rt.config.StorageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions))
|
||||
copy(rt.config.StorageConfig.GraphDriverOptions, config.GraphDriverOptions)
|
||||
if config.GraphRoot != "" {
|
||||
rt.config.StorageConfig.GraphRoot = config.GraphRoot
|
||||
rt.configuredFrom.storageGraphRootSet = true
|
||||
|
||||
rt.config.StorageConfig.UIDMap = make([]idtools.IDMap, len(config.UIDMap))
|
||||
copy(rt.config.StorageConfig.UIDMap, config.UIDMap)
|
||||
// Also set libpod static dir, so we are a subdirectory
|
||||
// of the c/storage store by default
|
||||
rt.config.StaticDir = filepath.Join(config.GraphRoot, "libpod")
|
||||
rt.configuredFrom.libpodStaticDirSet = true
|
||||
}
|
||||
|
||||
rt.config.StorageConfig.GIDMap = make([]idtools.IDMap, len(config.GIDMap))
|
||||
copy(rt.config.StorageConfig.GIDMap, config.GIDMap)
|
||||
if config.GraphDriverName != "" {
|
||||
rt.config.StorageConfig.GraphDriverName = config.GraphDriverName
|
||||
rt.configuredFrom.storageGraphDriverSet = true
|
||||
}
|
||||
|
||||
if config.GraphDriverOptions != nil {
|
||||
rt.config.StorageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions))
|
||||
copy(rt.config.StorageConfig.GraphDriverOptions, config.GraphDriverOptions)
|
||||
}
|
||||
|
||||
if config.UIDMap != nil {
|
||||
rt.config.StorageConfig.UIDMap = make([]idtools.IDMap, len(config.UIDMap))
|
||||
copy(rt.config.StorageConfig.UIDMap, config.UIDMap)
|
||||
}
|
||||
|
||||
if config.GIDMap != nil {
|
||||
rt.config.StorageConfig.GIDMap = make([]idtools.IDMap, len(config.GIDMap))
|
||||
copy(rt.config.StorageConfig.GIDMap, config.GIDMap)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -174,6 +195,7 @@ func WithStaticDir(dir string) RuntimeOption {
|
|||
}
|
||||
|
||||
rt.config.StaticDir = dir
|
||||
rt.configuredFrom.libpodStaticDirSet = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -225,6 +247,7 @@ func WithTmpDir(dir string) RuntimeOption {
|
|||
}
|
||||
|
||||
rt.config.TmpDir = dir
|
||||
rt.configuredFrom.libpodTmpDirSet = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ type Runtime struct {
|
|||
lock sync.RWMutex
|
||||
imageRuntime *image.Runtime
|
||||
firewallBackend firewall.FirewallBackend
|
||||
configuredFrom *runtimeConfiguredFrom
|
||||
}
|
||||
|
||||
// RuntimeConfig contains configuration options used to set up the runtime
|
||||
|
@ -174,6 +175,20 @@ type RuntimeConfig struct {
|
|||
EnableLabeling bool `toml:"label"`
|
||||
}
|
||||
|
||||
// runtimeConfiguredFrom is a struct used during early runtime init to help
|
||||
// assemble the full RuntimeConfig struct from defaults.
|
||||
// It indicated whether several fields in the runtime configuration were set
|
||||
// explicitly.
|
||||
// If they were not, we may override them with information from the database,
|
||||
// if it exists and differs from what is present in the system already.
|
||||
type runtimeConfiguredFrom struct {
|
||||
storageGraphDriverSet bool
|
||||
storageGraphRootSet bool
|
||||
storageRunRootSet bool
|
||||
libpodStaticDirSet bool
|
||||
libpodTmpDirSet bool
|
||||
}
|
||||
|
||||
var (
|
||||
defaultRuntimeConfig = RuntimeConfig{
|
||||
// Leave this empty so containers/storage will use its defaults
|
||||
|
@ -251,6 +266,7 @@ func SetXdgRuntimeDir(val string) error {
|
|||
func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
|
||||
runtime = new(Runtime)
|
||||
runtime.config = new(RuntimeConfig)
|
||||
runtime.configuredFrom = new(runtimeConfiguredFrom)
|
||||
|
||||
// Copy the default configuration
|
||||
tmpDir, err := getDefaultTmpDir()
|
||||
|
@ -260,6 +276,16 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
|
|||
deepcopier.Copy(defaultRuntimeConfig).To(runtime.config)
|
||||
runtime.config.TmpDir = tmpDir
|
||||
|
||||
if rootless.IsRootless() {
|
||||
// If we're rootless, override the default storage config
|
||||
storageConf, err := util.GetDefaultStoreOptions()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error retrieving rootless storage config")
|
||||
}
|
||||
runtime.config.StorageConfig = storageConf
|
||||
runtime.config.StaticDir = filepath.Join(storageConf.GraphRoot, "libpod")
|
||||
}
|
||||
|
||||
configPath := ConfigPath
|
||||
foundConfig := true
|
||||
rootlessConfigPath := ""
|
||||
|
@ -305,6 +331,25 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading configuration file %s", configPath)
|
||||
}
|
||||
|
||||
// This is ugly, but we need to decode twice.
|
||||
// Once to check if libpod static and tmp dirs were explicitly
|
||||
// set (not enough to check if they're not the default value,
|
||||
// might have been explicitly configured to the default).
|
||||
// A second time to actually get a usable config.
|
||||
tmpConfig := new(RuntimeConfig)
|
||||
if _, err := toml.Decode(string(contents), tmpConfig); err != nil {
|
||||
return nil, errors.Wrapf(err, "error decoding configuration file %s",
|
||||
configPath)
|
||||
}
|
||||
|
||||
if tmpConfig.StaticDir != "" {
|
||||
runtime.configuredFrom.libpodStaticDirSet = true
|
||||
}
|
||||
if tmpConfig.TmpDir != "" {
|
||||
runtime.configuredFrom.libpodTmpDirSet = true
|
||||
}
|
||||
|
||||
if _, err := toml.Decode(string(contents), runtime.config); err != nil {
|
||||
return nil, errors.Wrapf(err, "error decoding configuration file %s", configPath)
|
||||
}
|
||||
|
@ -346,6 +391,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
|
|||
func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime *Runtime, err error) {
|
||||
runtime = new(Runtime)
|
||||
runtime.config = new(RuntimeConfig)
|
||||
runtime.configuredFrom = new(runtimeConfiguredFrom)
|
||||
|
||||
// Set two fields not in the TOML config
|
||||
runtime.config.StateType = defaultRuntimeConfig.StateType
|
||||
|
@ -424,6 +470,77 @@ func makeRuntime(runtime *Runtime) (err error) {
|
|||
runtime.config.ConmonPath)
|
||||
}
|
||||
|
||||
// Make the static files directory if it does not exist
|
||||
if err := os.MkdirAll(runtime.config.StaticDir, 0700); err != nil {
|
||||
// The directory is allowed to exist
|
||||
if !os.IsExist(err) {
|
||||
return errors.Wrapf(err, "error creating runtime static files directory %s",
|
||||
runtime.config.StaticDir)
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the state
|
||||
switch runtime.config.StateType {
|
||||
case InMemoryStateStore:
|
||||
state, err := NewInMemoryState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.state = state
|
||||
case SQLiteStateStore:
|
||||
return errors.Wrapf(ErrInvalidArg, "SQLite state is currently disabled")
|
||||
case BoltDBStateStore:
|
||||
dbPath := filepath.Join(runtime.config.StaticDir, "bolt_state.db")
|
||||
|
||||
state, err := NewBoltState(dbPath, runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.state = state
|
||||
default:
|
||||
return errors.Wrapf(ErrInvalidArg, "unrecognized state type passed")
|
||||
}
|
||||
|
||||
// Grab config from the database so we can reset some defaults
|
||||
dbConfig, err := runtime.state.GetDBConfig()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error retrieving runtime configuration from database")
|
||||
}
|
||||
|
||||
// Reset defaults if they were not explicitly set
|
||||
if !runtime.configuredFrom.storageGraphDriverSet && dbConfig.GraphDriver != "" {
|
||||
runtime.config.StorageConfig.GraphDriverName = dbConfig.GraphDriver
|
||||
}
|
||||
if !runtime.configuredFrom.storageGraphRootSet && dbConfig.StorageRoot != "" {
|
||||
runtime.config.StorageConfig.GraphRoot = dbConfig.StorageRoot
|
||||
}
|
||||
if !runtime.configuredFrom.storageRunRootSet && dbConfig.StorageTmp != "" {
|
||||
runtime.config.StorageConfig.RunRoot = dbConfig.StorageTmp
|
||||
}
|
||||
if !runtime.configuredFrom.libpodStaticDirSet && dbConfig.LibpodRoot != "" {
|
||||
runtime.config.StaticDir = dbConfig.LibpodRoot
|
||||
}
|
||||
if !runtime.configuredFrom.libpodTmpDirSet && dbConfig.LibpodTmp != "" {
|
||||
runtime.config.TmpDir = dbConfig.LibpodTmp
|
||||
}
|
||||
|
||||
logrus.Debugf("Using graph driver %s", runtime.config.StorageConfig.GraphDriverName)
|
||||
logrus.Debugf("Using graph root %s", runtime.config.StorageConfig.GraphRoot)
|
||||
logrus.Debugf("Using run root %s", runtime.config.StorageConfig.RunRoot)
|
||||
logrus.Debugf("Using static dir %s", runtime.config.StaticDir)
|
||||
logrus.Debugf("Using tmp dir %s", runtime.config.TmpDir)
|
||||
|
||||
// Validate our config against the database, now that we've set our
|
||||
// final storage configuration
|
||||
if err := runtime.state.ValidateDBConfig(runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := runtime.state.SetNamespace(runtime.config.Namespace); err != nil {
|
||||
return errors.Wrapf(err, "error setting libpod namespace in state")
|
||||
}
|
||||
logrus.Debugf("Set libpod namespace to %q", runtime.config.Namespace)
|
||||
|
||||
// Set up containers/storage
|
||||
var store storage.Store
|
||||
if rootless.SkipStorageSetup() {
|
||||
|
@ -491,15 +608,6 @@ func makeRuntime(runtime *Runtime) (err error) {
|
|||
}
|
||||
runtime.ociRuntime = ociRuntime
|
||||
|
||||
// Make the static files directory if it does not exist
|
||||
if err := os.MkdirAll(runtime.config.StaticDir, 0755); err != nil {
|
||||
// The directory is allowed to exist
|
||||
if !os.IsExist(err) {
|
||||
return errors.Wrapf(err, "error creating runtime static files directory %s",
|
||||
runtime.config.StaticDir)
|
||||
}
|
||||
}
|
||||
|
||||
// Make a directory to hold container lockfiles
|
||||
lockDir := filepath.Join(runtime.config.TmpDir, "lock")
|
||||
if err := os.MkdirAll(lockDir, 0755); err != nil {
|
||||
|
@ -540,33 +648,6 @@ func makeRuntime(runtime *Runtime) (err error) {
|
|||
}
|
||||
runtime.firewallBackend = fwBackend
|
||||
|
||||
// Set up the state
|
||||
switch runtime.config.StateType {
|
||||
case InMemoryStateStore:
|
||||
state, err := NewInMemoryState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.state = state
|
||||
case SQLiteStateStore:
|
||||
return errors.Wrapf(ErrInvalidArg, "SQLite state is currently disabled")
|
||||
case BoltDBStateStore:
|
||||
dbPath := filepath.Join(runtime.config.StaticDir, "bolt_state.db")
|
||||
|
||||
state, err := NewBoltState(dbPath, runtime.lockDir, runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.state = state
|
||||
default:
|
||||
return errors.Wrapf(ErrInvalidArg, "unrecognized state type passed")
|
||||
}
|
||||
|
||||
if err := runtime.state.SetNamespace(runtime.config.Namespace); err != nil {
|
||||
return errors.Wrapf(err, "error setting libpod namespace in state")
|
||||
}
|
||||
logrus.Debugf("Set libpod namespace to %q", runtime.config.Namespace)
|
||||
|
||||
// We now need to see if the system has restarted
|
||||
// We check for the presence of a file in our tmp directory to verify this
|
||||
// This check must be locked to prevent races
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
package libpod
|
||||
|
||||
// DBConfig is a set of Libpod runtime configuration settings that are saved
|
||||
// in a State when it is first created, and can subsequently be retrieved.
|
||||
type DBConfig struct {
|
||||
LibpodRoot string
|
||||
LibpodTmp string
|
||||
StorageRoot string
|
||||
StorageTmp string
|
||||
GraphDriver string
|
||||
}
|
||||
|
||||
// State is a storage backend for libpod's current state.
|
||||
// A State is only initialized once per instance of libpod.
|
||||
// As such, initialization methods for State implementations may safely assume
|
||||
|
@ -21,6 +31,22 @@ type State interface {
|
|||
// Refresh clears container and pod states after a reboot
|
||||
Refresh() error
|
||||
|
||||
// GetDBConfig retrieves several paths configured within the database
|
||||
// when it was created - namely, Libpod root and tmp dirs, c/storage
|
||||
// root and tmp dirs, and c/storage graph driver.
|
||||
// This is not implemented by the in-memory state, as it has no need to
|
||||
// validate runtime configuration.
|
||||
GetDBConfig() (*DBConfig, error)
|
||||
|
||||
// ValidateDBConfig validates the config in the given Runtime struct
|
||||
// against paths stored in the configured database.
|
||||
// Libpod root and tmp dirs and c/storage root and tmp dirs and graph
|
||||
// driver are validated.
|
||||
// This is not implemented by the in-memory state, as it has no need to
|
||||
// validate runtime configuration that may change over multiple runs of
|
||||
// the program.
|
||||
ValidateDBConfig(runtime *Runtime) error
|
||||
|
||||
// SetNamespace() sets the namespace for the store, and will determine
|
||||
// what containers are retrieved with container and pod retrieval calls.
|
||||
// A namespace of "", the empty string, acts as no namespace, and
|
||||
|
|
|
@ -45,11 +45,16 @@ func getEmptyBoltState() (s State, p string, p2 string, err error) {
|
|||
dbPath := filepath.Join(tmpDir, "db.sql")
|
||||
lockDir := filepath.Join(tmpDir, "locks")
|
||||
|
||||
if err := os.Mkdir(lockDir, 0755); err != nil {
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
||||
runtime := new(Runtime)
|
||||
runtime.config = new(RuntimeConfig)
|
||||
runtime.config.StorageConfig = storage.StoreOptions{}
|
||||
runtime.lockDir = lockDir
|
||||
|
||||
state, err := NewBoltState(dbPath, lockDir, runtime)
|
||||
state, err := NewBoltState(dbPath, runtime)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ func getTomlStorage(storeOptions *storage.StoreOptions) *tomlConfig {
|
|||
return config
|
||||
}
|
||||
|
||||
// GetDefaultStoreOptions returns the storage ops for containers
|
||||
// GetDefaultStoreOptions returns the default storage options for containers.
|
||||
func GetDefaultStoreOptions() (storage.StoreOptions, error) {
|
||||
storageOpts := storage.DefaultStoreOptions
|
||||
if rootless.IsRootless() {
|
||||
|
|
Loading…
Reference in New Issue