summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/client.go3
-rw-r--r--pkg/adapter/containers.go1
-rw-r--r--pkg/adapter/runtime.go26
-rw-r--r--pkg/adapter/runtime_remote.go24
-rw-r--r--pkg/namespaces/namespaces.go87
-rw-r--r--pkg/spec/createconfig.go9
-rw-r--r--pkg/spec/spec.go37
-rw-r--r--pkg/spec/storage.go31
-rw-r--r--pkg/util/utils.go6
-rw-r--r--pkg/util/utils_supported.go36
-rw-r--r--pkg/util/utils_windows.go5
-rw-r--r--pkg/varlinkapi/images.go9
-rw-r--r--pkg/varlinkapi/system.go1
13 files changed, 201 insertions, 74 deletions
diff --git a/pkg/adapter/client.go b/pkg/adapter/client.go
index 694d9f961..da6ff5fd0 100644
--- a/pkg/adapter/client.go
+++ b/pkg/adapter/client.go
@@ -16,7 +16,7 @@ var remoteEndpoint *Endpoint
func (r RemoteRuntime) RemoteEndpoint() (remoteEndpoint *Endpoint, err error) {
remoteConfigConnections, err := remoteclientconfig.ReadRemoteConfig(r.config)
- if errors.Cause(err) != remoteclientconfig.ErrNoConfigationFile {
+ if err != nil && errors.Cause(err) != remoteclientconfig.ErrNoConfigationFile {
return nil, err
}
// If the user defines an env variable for podman_varlink_bridge
@@ -68,7 +68,6 @@ func (r RemoteRuntime) Connect() (*varlink.Connection, error) {
if err != nil {
return nil, err
}
-
switch ep.Type {
case DirectConnection:
return varlink.NewConnection(ep.Connection)
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 155454e21..b712bd9aa 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -539,6 +539,7 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues)
TargetFile: c.Import,
Name: c.Name,
IgnoreRootfs: c.IgnoreRootfs,
+ IgnoreStaticIP: c.IgnoreStaticIP,
}
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index ee6913cc0..4a3b41297 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -5,22 +5,22 @@ package adapter
import (
"bufio"
"context"
- "github.com/containers/libpod/libpod/define"
"io"
"io/ioutil"
"os"
"text/template"
- "github.com/containers/libpod/cmd/podman/shared"
-
"github.com/containers/buildah"
"github.com/containers/buildah/imagebuildah"
+ "github.com/containers/buildah/pkg/formats"
"github.com/containers/buildah/pkg/parse"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
+ "github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/rootless"
@@ -351,9 +351,13 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error {
fromStart bool
eventsError error
)
- tmpl, err := template.New("events").Parse(c.Format)
- if err != nil {
- return err
+ var tmpl *template.Template
+ if c.Format != formats.JSONString {
+ template, err := template.New("events").Parse(c.Format)
+ if err != nil {
+ return err
+ }
+ tmpl = template
}
if len(c.Since) > 0 || len(c.Until) > 0 {
fromStart = true
@@ -369,7 +373,15 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error {
}
w := bufio.NewWriter(os.Stdout)
for event := range eventChannel {
- if len(c.Format) > 0 {
+ if c.Format == formats.JSONString {
+ jsonStr, err := event.ToJSONString()
+ if err != nil {
+ return errors.Wrapf(err, "unable to format json")
+ }
+ if _, err := w.Write([]byte(jsonStr)); err != nil {
+ return err
+ }
+ } else if len(c.Format) > 0 {
if err := tmpl.Execute(w, event); err != nil {
return err
}
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 9fae39df0..828838bde 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -14,9 +14,8 @@ import (
"text/template"
"time"
- v1 "k8s.io/api/core/v1"
-
"github.com/containers/buildah/imagebuildah"
+ "github.com/containers/buildah/pkg/formats"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
@@ -32,6 +31,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/varlink/go/varlink"
+ v1 "k8s.io/api/core/v1"
)
// ImageRuntime is wrapper for image runtime
@@ -820,9 +820,13 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error {
}
w := bufio.NewWriter(os.Stdout)
- tmpl, err := template.New("events").Parse(c.Format)
- if err != nil {
- return err
+ var tmpl *template.Template
+ if c.Format != formats.JSONString {
+ template, err := template.New("events").Parse(c.Format)
+ if err != nil {
+ return err
+ }
+ tmpl = template
}
for {
@@ -856,7 +860,15 @@ func (r *LocalRuntime) Events(c *cliconfig.EventValues) error {
Time: eTime,
Type: eType,
}
- if len(c.Format) > 0 {
+ if c.Format == formats.JSONString {
+ jsonStr, err := event.ToJSONString()
+ if err != nil {
+ return errors.Wrapf(err, "unable to format json")
+ }
+ if _, err := w.Write([]byte(jsonStr)); err != nil {
+ return err
+ }
+ } else if len(c.Format) > 0 {
if err := tmpl.Execute(w, event); err != nil {
return err
}
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index 35298796f..9d1033b93 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -4,17 +4,30 @@ import (
"strings"
)
+const (
+ bridgeType = "bridge"
+ containerType = "container"
+ defaultType = "default"
+ hostType = "host"
+ noneType = "none"
+ nsType = "ns"
+ podType = "pod"
+ privateType = "private"
+ shareableType = "shareable"
+ slirpType = "slirp4netns"
+)
+
// CgroupMode represents cgroup mode in the container.
type CgroupMode string
// IsHost indicates whether the container uses the host's cgroup.
func (n CgroupMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsNS indicates a cgroup namespace passed in by path (ns:<path>)
func (n CgroupMode) IsNS() bool {
- return strings.HasPrefix(string(n), "ns:")
+ return strings.HasPrefix(string(n), nsType)
}
// NS gets the path associated with a ns:<path> cgroup ns
@@ -29,13 +42,13 @@ func (n CgroupMode) NS() string {
// IsContainer indicates whether the container uses a new cgroup namespace.
func (n CgroupMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container returns the name of the container whose cgroup namespace is going to be used.
func (n CgroupMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -43,15 +56,15 @@ func (n CgroupMode) Container() string {
// IsPrivate indicates whether the container uses the a private cgroup.
func (n CgroupMode) IsPrivate() bool {
- return n == "private"
+ return n == privateType
}
// Valid indicates whether the Cgroup namespace is valid.
func (n CgroupMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host", "private", "ns":
- case "container":
+ case "", hostType, privateType, nsType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -66,7 +79,7 @@ type UsernsMode string
// IsHost indicates whether the container uses the host's userns.
func (n UsernsMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsKeepID indicates whether container uses a mapping where the (uid, gid) on the host is lept inside of the namespace.
@@ -83,8 +96,8 @@ func (n UsernsMode) IsPrivate() bool {
func (n UsernsMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host", "keep-id", "ns":
- case "container":
+ case "", hostType, "keep-id", nsType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -111,13 +124,13 @@ func (n UsernsMode) NS() string {
// IsContainer indicates whether container uses a container userns.
func (n UsernsMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container is the id of the container which network this container is connected to.
func (n UsernsMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -133,19 +146,19 @@ func (n UTSMode) IsPrivate() bool {
// IsHost indicates whether the container uses the host's UTS namespace.
func (n UTSMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsContainer indicates whether the container uses a container's UTS namespace.
func (n UTSMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container returns the name of the container whose uts namespace is going to be used.
func (n UTSMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -155,8 +168,8 @@ func (n UTSMode) Container() string {
func (n UTSMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host":
- case "container":
+ case "", hostType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -171,28 +184,28 @@ type IpcMode string
// IsPrivate indicates whether the container uses its own private ipc namespace which cannot be shared.
func (n IpcMode) IsPrivate() bool {
- return n == "private"
+ return n == privateType
}
// IsHost indicates whether the container shares the host's ipc namespace.
func (n IpcMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsShareable indicates whether the container's ipc namespace can be shared with another container.
func (n IpcMode) IsShareable() bool {
- return n == "shareable"
+ return n == shareableType
}
// IsContainer indicates whether the container uses another container's ipc namespace.
func (n IpcMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// IsNone indicates whether container IpcMode is set to "none".
func (n IpcMode) IsNone() bool {
- return n == "none"
+ return n == noneType
}
// IsEmpty indicates whether container IpcMode is empty
@@ -208,7 +221,7 @@ func (n IpcMode) Valid() bool {
// Container returns the name of the container ipc stack is going to be used.
func (n IpcMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 && parts[0] == "container" {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -224,21 +237,21 @@ func (n PidMode) IsPrivate() bool {
// IsHost indicates whether the container uses the host's pid namespace.
func (n PidMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsContainer indicates whether the container uses a container's pid namespace.
func (n PidMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Valid indicates whether the pid namespace is valid.
func (n PidMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", "host":
- case "container":
+ case "", hostType:
+ case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
}
@@ -251,7 +264,7 @@ func (n PidMode) Valid() bool {
// Container returns the name of the container whose pid namespace is going to be used.
func (n PidMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -262,17 +275,17 @@ type NetworkMode string
// IsNone indicates whether container isn't using a network stack.
func (n NetworkMode) IsNone() bool {
- return n == "none"
+ return n == noneType
}
// IsHost indicates whether the container uses the host's network stack.
func (n NetworkMode) IsHost() bool {
- return n == "host"
+ return n == hostType
}
// IsDefault indicates whether container uses the default network stack.
func (n NetworkMode) IsDefault() bool {
- return n == "default"
+ return n == defaultType
}
// IsPrivate indicates whether container uses its private network stack.
@@ -283,13 +296,13 @@ func (n NetworkMode) IsPrivate() bool {
// IsContainer indicates whether container uses a container network stack.
func (n NetworkMode) IsContainer() bool {
parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[0] == "container"
+ return len(parts) > 1 && parts[0] == containerType
}
// Container is the id of the container which network this container is connected to.
func (n NetworkMode) Container() string {
parts := strings.SplitN(string(n), ":", 2)
- if len(parts) > 1 {
+ if len(parts) > 1 && parts[0] == containerType {
return parts[1]
}
return ""
@@ -305,17 +318,17 @@ func (n NetworkMode) UserDefined() string {
// IsBridge indicates whether container uses the bridge network stack
func (n NetworkMode) IsBridge() bool {
- return n == "bridge"
+ return n == bridgeType
}
// IsSlirp4netns indicates if we are running a rootless network stack
func (n NetworkMode) IsSlirp4netns() bool {
- return n == "slirp4netns"
+ return n == slirpType
}
// IsNS indicates a network namespace passed in by path (ns:<path>)
func (n NetworkMode) IsNS() bool {
- return strings.HasPrefix(string(n), "ns:")
+ return strings.HasPrefix(string(n), nsType)
}
// NS gets the path associated with a ns:<path> network ns
@@ -329,7 +342,7 @@ func (n NetworkMode) NS() string {
// IsPod returns whether the network refers to pod networking
func (n NetworkMode) IsPod() bool {
- return n == "pod"
+ return n == podType
}
// IsUserDefined indicates user-created network
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index f21ae2831..3f70e5935 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -64,8 +64,9 @@ type CreateConfig struct {
CidFile string
ConmonPidFile string
Cgroupns string
- CgroupParent string // cgroup-parent
- Command []string
+ CgroupParent string // cgroup-parent
+ Command []string // Full command that will be used
+ UserCommand []string // User-entered command (or image CMD)
Detach bool // detach
Devices []string // device
DNSOpt []string //dns-opt
@@ -230,8 +231,8 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
options = append(options, libpod.WithNamedVolumes(namedVolumes))
}
- if len(c.Command) != 0 {
- options = append(options, libpod.WithCommand(c.Command))
+ if len(c.UserCommand) != 0 {
+ options = append(options, libpod.WithCommand(c.UserCommand))
}
// Add entrypoint unconditionally
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index c94746767..156d6849d 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -174,10 +174,20 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
}
hostname := config.Hostname
- if hostname == "" && (config.NetMode.IsHost() || config.UtsMode.IsHost()) {
- hostname, err = os.Hostname()
- if err != nil {
- return nil, errors.Wrap(err, "unable to retrieve hostname")
+ if hostname == "" {
+ if utsCtrID := config.UtsMode.Container(); utsCtrID != "" {
+ utsCtr, err := runtime.GetContainer(utsCtrID)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to retrieve hostname from dependency container %s", utsCtrID)
+ }
+ hostname = utsCtr.Hostname()
+ } else if config.NetMode.IsHost() || config.UtsMode.IsHost() {
+ hostname, err = os.Hostname()
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to retrieve hostname of the host")
+ }
+ } else {
+ logrus.Debug("No hostname set; container's hostname will default to runtime default")
}
}
g.RemoveHostname()
@@ -541,8 +551,8 @@ func addPidNS(config *CreateConfig, g *generate.Generator) error {
if pidMode.IsHost() {
return g.RemoveLinuxNamespace(string(spec.PIDNamespace))
}
- if pidMode.IsContainer() {
- logrus.Debug("using container pidmode")
+ if pidCtr := pidMode.Container(); pidCtr != "" {
+ logrus.Debugf("using container %s pidmode", pidCtr)
}
if IsPod(string(pidMode)) {
logrus.Debug("using pod pidmode")
@@ -579,8 +589,8 @@ func addNetNS(config *CreateConfig, g *generate.Generator) error {
} else if netMode.IsBridge() {
logrus.Debug("Using bridge netmode")
return nil
- } else if netMode.IsContainer() {
- logrus.Debug("Using container netmode")
+ } else if netCtr := netMode.Container(); netCtr != "" {
+ logrus.Debugf("using container %s netmode", netCtr)
return nil
} else if IsNS(string(netMode)) {
logrus.Debug("Using ns netmode")
@@ -606,6 +616,9 @@ func addUTSNS(config *CreateConfig, g *generate.Generator) error {
if utsMode.IsHost() {
return g.RemoveLinuxNamespace(string(spec.UTSNamespace))
}
+ if utsCtr := utsMode.Container(); utsCtr != "" {
+ logrus.Debugf("using container %s utsmode", utsCtr)
+ }
return nil
}
@@ -617,8 +630,8 @@ func addIpcNS(config *CreateConfig, g *generate.Generator) error {
if ipcMode.IsHost() {
return g.RemoveLinuxNamespace(string(spec.IPCNamespace))
}
- if ipcMode.IsContainer() {
- logrus.Debug("Using container ipcmode")
+ if ipcCtr := ipcMode.Container(); ipcCtr != "" {
+ logrus.Debugf("Using container %s ipcmode", ipcCtr)
}
return nil
@@ -635,8 +648,8 @@ func addCgroupNS(config *CreateConfig, g *generate.Generator) error {
if cgroupMode.IsPrivate() {
return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), "")
}
- if cgroupMode.IsContainer() {
- logrus.Debug("Using container cgroup mode")
+ if cgCtr := cgroupMode.Container(); cgCtr != "" {
+ logrus.Debugf("Using container %s cgroup mode", cgCtr)
}
return nil
}
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index ac7a2c30f..e0bb48a9c 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -410,13 +410,42 @@ func getBindMount(args []string) (spec.Mount, error) {
setSource := false
setDest := false
+ setRORW := false
for _, val := range args {
kv := strings.Split(val, "=")
switch kv[0] {
case "bind-nonrecursive":
newMount.Options = append(newMount.Options, "bind")
- case "ro", "nosuid", "nodev", "noexec":
+ case "ro", "rw":
+ if setRORW {
+ return newMount, errors.Wrapf(optionArgError, "cannot pass 'ro' or 'rw' options more than once")
+ }
+ setRORW = true
+ // Can be formatted as one of:
+ // ro
+ // ro=[true|false]
+ // rw
+ // rw=[true|false]
+ if len(kv) == 1 {
+ newMount.Options = append(newMount.Options, kv[0])
+ } else if len(kv) == 2 {
+ switch strings.ToLower(kv[1]) {
+ case "true":
+ newMount.Options = append(newMount.Options, kv[0])
+ case "false":
+ // Set the opposite only for rw
+ // ro's opposite is the default
+ if kv[0] == "rw" {
+ newMount.Options = append(newMount.Options, "ro")
+ }
+ default:
+ return newMount, errors.Wrapf(optionArgError, "%s must be set to true or false, instead received %q", kv[0], kv[1])
+ }
+ } else {
+ return newMount, errors.Wrapf(optionArgError, "badly formatted option %q", val)
+ }
+ case "nosuid", "nodev", "noexec":
// TODO: detect duplication of these options.
// (Is this necessary?)
newMount.Options = append(newMount.Options, kv[0])
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index fba34a337..520e41438 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -239,8 +239,10 @@ func ParseIDMapping(mode namespaces.UsernsMode, UIDMapSlice, GIDMapSlice []strin
}
var (
- rootlessRuntimeDirOnce sync.Once
- rootlessRuntimeDir string
+ rootlessConfigHomeDirOnce sync.Once
+ rootlessConfigHomeDir string
+ rootlessRuntimeDirOnce sync.Once
+ rootlessRuntimeDir string
)
type tomlOptionsConfig struct {
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index af55689a6..c7c8787a0 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -26,7 +26,7 @@ func GetRootlessRuntimeDir() (string, error) {
if runtimeDir == "" {
tmpDir := filepath.Join("/run", "user", uid)
if err := os.MkdirAll(tmpDir, 0700); err != nil {
- logrus.Errorf("unable to make temp dir %s", tmpDir)
+ logrus.Debugf("unable to make temp dir %s", tmpDir)
}
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
@@ -36,7 +36,7 @@ func GetRootlessRuntimeDir() (string, error) {
if runtimeDir == "" {
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid))
if err := os.MkdirAll(tmpDir, 0700); err != nil {
- logrus.Errorf("unable to make temp dir %s", tmpDir)
+ logrus.Debugf("unable to make temp dir %s", tmpDir)
}
st, err := os.Stat(tmpDir)
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
@@ -65,6 +65,38 @@ func GetRootlessRuntimeDir() (string, error) {
return rootlessRuntimeDir, nil
}
+// GetRootlessConfigHomeDir returns the config home directory when running as non root
+func GetRootlessConfigHomeDir() (string, error) {
+ var rootlessConfigHomeDirError error
+
+ rootlessConfigHomeDirOnce.Do(func() {
+ cfgHomeDir := os.Getenv("XDG_CONFIG_HOME")
+ if cfgHomeDir == "" {
+ home := os.Getenv("HOME")
+ resolvedHome, err := filepath.EvalSymlinks(home)
+ if err != nil {
+ rootlessConfigHomeDirError = errors.Wrapf(err, "cannot resolve %s", home)
+ return
+ }
+ tmpDir := filepath.Join(resolvedHome, ".config")
+ if err := os.MkdirAll(tmpDir, 0755); err != nil {
+ logrus.Errorf("unable to make temp dir %s", tmpDir)
+ }
+ st, err := os.Stat(tmpDir)
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0755 {
+ cfgHomeDir = tmpDir
+ }
+ }
+ rootlessConfigHomeDir = cfgHomeDir
+ })
+
+ if rootlessConfigHomeDirError != nil {
+ return "", rootlessConfigHomeDirError
+ }
+
+ return rootlessConfigHomeDir, nil
+}
+
// GetRootlessPauseProcessPidPath returns the path to the file that holds the pid for
// the pause process
func GetRootlessPauseProcessPidPath() (string, error) {
diff --git a/pkg/util/utils_windows.go b/pkg/util/utils_windows.go
index 635558bf7..e7b2a272e 100644
--- a/pkg/util/utils_windows.go
+++ b/pkg/util/utils_windows.go
@@ -27,3 +27,8 @@ func GetRootlessPauseProcessPidPath() (string, error) {
func GetRootlessRuntimeDir() (string, error) {
return "", errors.New("this function is not implemented for windows")
}
+
+// GetRootlessConfigHomeDir returns the config home directory when running as non root
+func GetRootlessConfigHomeDir() (string, error) {
+ return "", errors.New("this function is not implemented for windows")
+}
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index 338499bd4..b5a711dfd 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -198,6 +198,8 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
if call.WantsMore() {
call.Continues = true
+ } else {
+ return call.ReplyErrorOccurred("endpoint requires a more connection")
}
var newPathDockerFiles []string
@@ -642,6 +644,7 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error {
defer close(c)
go func() {
+ var foundError bool
if strings.HasPrefix(name, dockerarchive.Transport.Name()+":") {
srcRef, err := alltransports.ParseImageName(name)
if err != nil {
@@ -649,6 +652,7 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error {
}
newImage, err := i.Runtime.ImageRuntime().LoadFromArchiveReference(getContext(), srcRef, "", output)
if err != nil {
+ foundError = true
c <- errors.Wrapf(err, "error pulling image from %q", name)
} else {
imageID = newImage[0].ID()
@@ -656,12 +660,15 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error {
} else {
newImage, err := i.Runtime.ImageRuntime().New(getContext(), name, "", "", output, &dockerRegistryOptions, so, false, nil)
if err != nil {
+ foundError = true
c <- errors.Wrapf(err, "unable to pull %s", name)
} else {
imageID = newImage.ID()
}
}
- c <- nil
+ if !foundError {
+ c <- nil
+ }
}()
var log []string
diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go
index 9b5b3a5b1..2de785b79 100644
--- a/pkg/varlinkapi/system.go
+++ b/pkg/varlinkapi/system.go
@@ -61,6 +61,7 @@ func (i *LibpodAPI) GetInfo(call iopodman.VarlinkCall) error {
Kernel: host["kernel"].(string),
Os: host["os"].(string),
Uptime: host["uptime"].(string),
+ Eventlogger: host["eventlogger"].(string),
}
podmanInfo.Host = infoHost
store := info[1].Data