diff options
-rw-r--r-- | contrib/python/podman/podman/libs/containers.py | 52 | ||||
-rw-r--r-- | contrib/python/pypodman/docs/man1/pypodman.1 | 2 | ||||
-rw-r--r-- | contrib/python/pypodman/pypodman/lib/podman_parser.py | 15 | ||||
-rw-r--r-- | libpod/runtime.go | 22 | ||||
-rw-r--r-- | pkg/registries/registries.go | 6 | ||||
-rw-r--r-- | pkg/secrets/secrets.go | 9 | ||||
-rw-r--r-- | pkg/util/utils.go | 13 |
7 files changed, 79 insertions, 40 deletions
diff --git a/contrib/python/podman/podman/libs/containers.py b/contrib/python/podman/podman/libs/containers.py index e211a284e..21a94557a 100644 --- a/contrib/python/podman/podman/libs/containers.py +++ b/contrib/python/podman/podman/libs/containers.py @@ -1,12 +1,12 @@ """Models for manipulating containers and storage.""" import collections -import functools import getpass import json import logging import signal import time +from . import fold_keys from ._containers_attach import Mixin as AttachMixin from ._containers_start import Mixin as StartMixin @@ -14,25 +14,27 @@ from ._containers_start import Mixin as StartMixin class Container(AttachMixin, StartMixin, collections.UserDict): """Model for a container.""" - def __init__(self, client, id, data): + def __init__(self, client, ident, data, refresh=True): """Construct Container Model.""" super(Container, self).__init__(data) - self._client = client - self._id = id + self._id = ident - with client() as podman: - self._refresh(podman) + if refresh: + with client() as podman: + self._refresh(podman) + else: + for k, v in self.data.items(): + setattr(self, k, v) + if 'containerrunning' in self.data: + setattr(self, 'running', self.data['containerrunning']) + self.data['running'] = self.data['containerrunning'] assert self._id == data['id'],\ 'Requested container id({}) does not match store id({})'.format( self._id, data['id'] ) - def __getitem__(self, key): - """Get items from parent dict.""" - return super().__getitem__(key) - def _refresh(self, podman, tries=1): try: ctnr = podman.GetContainer(self._id) @@ -71,18 +73,18 @@ class Container(AttachMixin, StartMixin, collections.UserDict): results = podman.ListContainerChanges(self._id) return results['container'] - def kill(self, signal=signal.SIGTERM, wait=25): + def kill(self, sig=signal.SIGTERM, wait=25): """Send signal to container. default signal is signal.SIGTERM. wait n of seconds, 0 waits forever. """ with self._client() as podman: - podman.KillContainer(self._id, signal) + podman.KillContainer(self._id, sig) timeout = time.time() + wait while True: self._refresh(podman) - if self.status != 'running': + if self.status != 'running': # pylint: disable=no-member return self if wait and timeout < time.time(): @@ -90,20 +92,11 @@ class Container(AttachMixin, StartMixin, collections.UserDict): time.sleep(0.5) - def _lower_hook(self): - """Convert all keys to lowercase.""" - - @functools.wraps(self._lower_hook) - def wrapped(input_): - return {k.lower(): v for (k, v) in input_.items()} - - return wrapped - def inspect(self): """Retrieve details about containers.""" with self._client() as podman: results = podman.InspectContainer(self._id) - obj = json.loads(results['container'], object_hook=self._lower_hook()) + obj = json.loads(results['container'], object_hook=fold_keys()) return collections.namedtuple('ContainerInspect', obj.keys())(**obj) def export(self, target): @@ -121,7 +114,7 @@ class Container(AttachMixin, StartMixin, collections.UserDict): changes=[], message='', pause=True, - **kwargs): + **kwargs): # pylint: disable=unused-argument """Create image from container. All changes overwrite existing values. @@ -175,7 +168,7 @@ class Container(AttachMixin, StartMixin, collections.UserDict): podman.RestartContainer(self._id, timeout) return self._refresh(podman) - def rename(self, target): + def rename(self, target): # pylint: disable=unused-argument """Rename container, return id on success.""" with self._client() as podman: # TODO: Need arguments @@ -183,7 +176,7 @@ class Container(AttachMixin, StartMixin, collections.UserDict): # TODO: fixup objects cached information return results['container'] - def resize_tty(self, width, height): + def resize_tty(self, width, height): # pylint: disable=unused-argument """Resize container tty.""" with self._client() as podman: # TODO: magic re: attach(), arguments @@ -201,7 +194,8 @@ class Container(AttachMixin, StartMixin, collections.UserDict): podman.UnpauseContainer(self._id) return self._refresh(podman) - def update_container(self, *args, **kwargs): + def update_container(self, *args, **kwargs): \ + # pylint: disable=unused-argument """TODO: Update container..., return id on success.""" with self._client() as podman: podman.UpdateContainer() @@ -220,7 +214,7 @@ class Container(AttachMixin, StartMixin, collections.UserDict): obj = results['container'] return collections.namedtuple('StatDetail', obj.keys())(**obj) - def logs(self, *args, **kwargs): + def logs(self, *args, **kwargs): # pylint: disable=unused-argument """Retrieve container logs.""" with self._client() as podman: results = podman.GetContainerLogs(self._id) @@ -239,7 +233,7 @@ class Containers(): with self._client() as podman: results = podman.ListContainers() for cntr in results['containers']: - yield Container(self._client, cntr['id'], cntr) + yield Container(self._client, cntr['id'], cntr, refresh=False) def delete_stopped(self): """Delete all stopped containers.""" diff --git a/contrib/python/pypodman/docs/man1/pypodman.1 b/contrib/python/pypodman/docs/man1/pypodman.1 index 09acb205b..45472dab0 100644 --- a/contrib/python/pypodman/docs/man1/pypodman.1 +++ b/contrib/python/pypodman/docs/man1/pypodman.1 @@ -85,7 +85,7 @@ overwriting earlier. Any missing items are ignored. .IP \[bu] 2 From \f[C]\-\-config\-home\f[] command line option + \f[C]pypodman/pypodman.conf\f[] .IP \[bu] 2 -From environment variable, for example: RUN_DIR +From environment variable prefixed with PODMAN_, for example: PODMAN_RUN_DIR .IP \[bu] 2 From command line option, for example: \[en]run\-dir .PP diff --git a/contrib/python/pypodman/pypodman/lib/podman_parser.py b/contrib/python/pypodman/pypodman/lib/podman_parser.py index d3c84224f..28fb44cf0 100644 --- a/contrib/python/pypodman/pypodman/lib/podman_parser.py +++ b/contrib/python/pypodman/pypodman/lib/podman_parser.py @@ -152,7 +152,7 @@ class PodmanArgumentParser(argparse.ArgumentParser): reqattr( 'run_dir', getattr(args, 'run_dir') - or os.environ.get('RUN_DIR') + or os.environ.get('PODMAN_RUN_DIR') or config['default'].get('run_dir') or str(Path(args.xdg_runtime_dir, 'pypodman')) ) # yapf: disable @@ -161,23 +161,24 @@ class PodmanArgumentParser(argparse.ArgumentParser): args, 'host', getattr(args, 'host') - or os.environ.get('HOST') + or os.environ.get('PODMAN_HOST') or config['default'].get('host') ) # yapf:disable reqattr( 'username', getattr(args, 'username') + or os.environ.get('PODMAN_USER') + or config['default'].get('username') or os.environ.get('USER') or os.environ.get('LOGNAME') - or config['default'].get('username') or getpass.getuser() ) # yapf:disable reqattr( 'port', getattr(args, 'port') - or os.environ.get('PORT') + or os.environ.get('PODMAN_PORT') or config['default'].get('port', None) or 22 ) # yapf:disable @@ -185,7 +186,7 @@ class PodmanArgumentParser(argparse.ArgumentParser): reqattr( 'remote_socket_path', getattr(args, 'remote_socket_path') - or os.environ.get('REMOTE_SOCKET_PATH') + or os.environ.get('PODMAN_REMOTE_SOCKET_PATH') or config['default'].get('remote_socket_path') or '/run/podman/io.podman' ) # yapf:disable @@ -193,7 +194,7 @@ class PodmanArgumentParser(argparse.ArgumentParser): reqattr( 'log_level', getattr(args, 'log_level') - or os.environ.get('LOG_LEVEL') + or os.environ.get('PODMAN_LOG_LEVEL') or config['default'].get('log_level') or logging.WARNING ) # yapf:disable @@ -202,7 +203,7 @@ class PodmanArgumentParser(argparse.ArgumentParser): args, 'identity_file', getattr(args, 'identity_file') - or os.environ.get('IDENTITY_FILE') + or os.environ.get('PODMAN_IDENTITY_FILE') or config['default'].get('identity_file') or os.path.expanduser('~{}/.ssh/id_dsa'.format(args.username)) ) # yapf:disable diff --git a/libpod/runtime.go b/libpod/runtime.go index 318cd0369..9feae03fc 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -264,6 +264,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { configPath := ConfigPath foundConfig := true + rootlessConfigPath := "" if rootless.IsRootless() { home := os.Getenv("HOME") if runtime.config.SignaturePolicyPath == "" { @@ -272,7 +273,10 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { runtime.config.SignaturePolicyPath = newPath } } - configPath = filepath.Join(home, ".config/containers/libpod.conf") + + rootlessConfigPath = filepath.Join(home, ".config/containers/libpod.conf") + + configPath = rootlessConfigPath if _, err := os.Stat(configPath); err != nil { foundConfig = false } @@ -317,6 +321,22 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { if err := makeRuntime(runtime); err != nil { return nil, err } + + if !foundConfig && rootlessConfigPath != "" { + os.MkdirAll(filepath.Dir(rootlessConfigPath), 0755) + file, err := os.OpenFile(rootlessConfigPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + if err != nil && !os.IsExist(err) { + return nil, errors.Wrapf(err, "cannot open file %s", rootlessConfigPath) + } + if err == nil { + defer file.Close() + enc := toml.NewEncoder(file) + if err := enc.Encode(runtime.config); err != nil { + os.Remove(rootlessConfigPath) + } + } + } + return runtime, nil } diff --git a/pkg/registries/registries.go b/pkg/registries/registries.go index 73aa93d68..c26f15cb6 100644 --- a/pkg/registries/registries.go +++ b/pkg/registries/registries.go @@ -38,8 +38,10 @@ func GetRegistries() ([]string, error) { func GetInsecureRegistries() ([]string, error) { registryConfigPath := "" - if _, err := os.Stat(userRegistriesFile); err == nil { - registryConfigPath = userRegistriesFile + if rootless.IsRootless() { + if _, err := os.Stat(userRegistriesFile); err == nil { + registryConfigPath = userRegistriesFile + } } envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go index 7208f53b7..242953609 100644 --- a/pkg/secrets/secrets.go +++ b/pkg/secrets/secrets.go @@ -149,6 +149,15 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPre mountFiles = append(mountFiles, []string{OverrideMountsFile, DefaultMountsFile}...) if rootless.IsRootless() { mountFiles = append([]string{UserOverrideMountsFile}, mountFiles...) + _, err := os.Stat(UserOverrideMountsFile) + if err != nil && os.IsNotExist(err) { + os.MkdirAll(filepath.Dir(UserOverrideMountsFile), 0755) + if f, err := os.Create(UserOverrideMountsFile); err != nil { + logrus.Warnf("could not create file %s: %v", UserOverrideMountsFile, err) + } else { + f.Close() + } + } } } else { mountFiles = append(mountFiles, mountFile) diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 3b43489b2..c5ba38b9f 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -9,6 +9,7 @@ import ( "strings" "syscall" + "github.com/BurntSushi/toml" "github.com/containers/image/types" "github.com/containers/libpod/pkg/rootless" "github.com/containers/storage" @@ -296,6 +297,18 @@ func GetDefaultStoreOptions() (storage.StoreOptions, error) { storageConf := filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf") if _, err := os.Stat(storageConf); err == nil { storage.ReloadConfigurationFile(storageConf, &storageOpts) + } else if os.IsNotExist(err) { + os.MkdirAll(filepath.Dir(storageConf), 0755) + file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + return storageOpts, errors.Wrapf(err, "cannot open %s", storageConf) + } + + defer file.Close() + enc := toml.NewEncoder(file) + if err := enc.Encode(storageOpts); err != nil { + os.Remove(storageConf) + } } } return storageOpts, nil |