diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/client.go | 3 | ||||
-rw-r--r-- | pkg/adapter/containers.go | 1 | ||||
-rw-r--r-- | pkg/adapter/runtime.go | 26 | ||||
-rw-r--r-- | pkg/adapter/runtime_remote.go | 24 | ||||
-rw-r--r-- | pkg/namespaces/namespaces.go | 87 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 9 | ||||
-rw-r--r-- | pkg/spec/spec.go | 37 | ||||
-rw-r--r-- | pkg/spec/storage.go | 31 | ||||
-rw-r--r-- | pkg/util/utils.go | 6 | ||||
-rw-r--r-- | pkg/util/utils_supported.go | 36 | ||||
-rw-r--r-- | pkg/util/utils_windows.go | 5 | ||||
-rw-r--r-- | pkg/varlinkapi/images.go | 9 | ||||
-rw-r--r-- | pkg/varlinkapi/system.go | 1 |
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 |