summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers.go12
-rw-r--r--pkg/api/handlers/libpod/info.go4
-rw-r--r--pkg/api/handlers/utils/containers.go2
-rw-r--r--pkg/domain/infra/abi/images.go4
-rw-r--r--pkg/domain/infra/abi/play.go4
-rw-r--r--pkg/domain/infra/abi/system.go17
-rw-r--r--pkg/machine/pull.go2
-rw-r--r--pkg/rootless/rootless_linux.go65
-rw-r--r--pkg/specgen/generate/kube/kube.go2
-rw-r--r--pkg/systemd/generate/common_test.go4
-rw-r--r--pkg/util/filters.go2
-rw-r--r--pkg/util/utils.go23
12 files changed, 109 insertions, 32 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index e7146a5d8..d97a4d3bd 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -26,6 +26,7 @@ import (
"github.com/docker/go-units"
"github.com/gorilla/schema"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
func RemoveContainer(w http.ResponseWriter, r *http.Request) {
@@ -148,14 +149,19 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
containers = containers[:query.Limit]
}
}
- var list = make([]*handlers.Container, len(containers))
- for i, ctnr := range containers {
+ list := make([]*handlers.Container, 0, len(containers))
+ for _, ctnr := range containers {
api, err := LibpodToContainer(ctnr, query.Size)
if err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ // container was removed between the initial fetch of the list and conversion
+ logrus.Debugf("Container %s removed between initial fetch and conversion, ignoring in output", ctnr.ID())
+ continue
+ }
utils.InternalServerError(w, err)
return
}
- list[i] = api
+ list = append(list, api)
}
utils.WriteResponse(w, http.StatusOK, list)
}
diff --git a/pkg/api/handlers/libpod/info.go b/pkg/api/handlers/libpod/info.go
index 546609451..8868d563d 100644
--- a/pkg/api/handlers/libpod/info.go
+++ b/pkg/api/handlers/libpod/info.go
@@ -5,11 +5,13 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
+ "github.com/containers/podman/v3/pkg/domain/infra/abi"
)
func GetInfo(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- info, err := runtime.Info()
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+ info, err := containerEngine.Info(r.Context())
if err != nil {
utils.InternalServerError(w, err)
return
diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go
index 91e02abf1..c4c9cc2ea 100644
--- a/pkg/api/handlers/utils/containers.go
+++ b/pkg/api/handlers/utils/containers.go
@@ -76,7 +76,7 @@ func WaitContainerDocker(w http.ResponseWriter, r *http.Request) {
exitCode, err := waitDockerCondition(ctx, name, interval, condition)
msg := ""
if err != nil {
- logrus.Errorf("error while waiting on condtion: %q", err)
+ logrus.Errorf("error while waiting on condition: %q", err)
msg = err.Error()
}
responseData := handlers.ContainerWaitOKBody{
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index c02eb2bfc..84c7ebecd 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -620,8 +620,8 @@ func (ir *ImageEngine) Remove(ctx context.Context, images []string, opts entitie
for _, img := range storageImages {
isParent, err := img.IsParent(ctx)
if err != nil {
- rmErrors = append(rmErrors, err)
- continue
+ logrus.Warnf("%v, ignoring the error", err)
+ isParent = false
}
// Skip parent images.
if isParent {
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 4a13a8029..6ddd4a042 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -428,7 +428,7 @@ func readConfigMapFromFile(r io.Reader) (v1.ConfigMap, error) {
return cm, nil
}
-// splitMultiDocYAML reads mutiple documents in a YAML file and
+// splitMultiDocYAML reads multiple documents in a YAML file and
// returns them as a list.
func splitMultiDocYAML(yamlContent []byte) ([][]byte, error) {
var documentList [][]byte
@@ -471,7 +471,7 @@ func getKubeKind(obj []byte) (string, error) {
}
// sortKubeKinds adds the correct creation order for the kube kinds.
-// Any pod dependecy will be created first like volumes, secrets, etc.
+// Any pod dependency will be created first like volumes, secrets, etc.
func sortKubeKinds(documentList [][]byte) ([][]byte, error) {
var sortedDocumentList [][]byte
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
index f87f9e370..9bba0fa6c 100644
--- a/pkg/domain/infra/abi/system.go
+++ b/pkg/domain/infra/abi/system.go
@@ -21,6 +21,7 @@ import (
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/podman/v3/utils"
"github.com/containers/storage"
+ "github.com/containers/storage/pkg/unshare"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -32,17 +33,11 @@ func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) {
if err != nil {
return nil, err
}
- xdg, err := util.GetRuntimeDir()
+
+ socketPath, err := util.SocketPath()
if err != nil {
return nil, err
}
- if len(xdg) == 0 {
- // If no xdg is returned, assume root socket
- xdg = "/run"
- }
-
- // Glue the socket path together
- socketPath := filepath.Join(xdg, "podman", "podman.sock")
rs := define.RemoteSocket{
Path: socketPath,
Exists: false,
@@ -64,7 +59,11 @@ func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) {
func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) error {
// do it only after podman has already re-execed and running with uid==0.
- if os.Geteuid() == 0 {
+ hasCapSysAdmin, err := unshare.HasCapSysAdmin()
+ if err != nil {
+ return err
+ }
+ if hasCapSysAdmin {
ownsCgroup, err := cgroups.UserOwnsCurrentSystemdCgroup()
if err != nil {
logrus.Infof("Failed to detect the owner for the current cgroup: %v", err)
diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go
index 41abe6993..d9f34057f 100644
--- a/pkg/machine/pull.go
+++ b/pkg/machine/pull.go
@@ -170,7 +170,7 @@ func Decompress(localPath, uncompressedPath string) error {
// Will error out if file without .xz already exists
// Maybe extracting then renameing is a good idea here..
-// depends on xz: not pre-installed on mac, so it becomes a brew dependecy
+// depends on xz: not pre-installed on mac, so it becomes a brew dependency
func decompressXZ(src string, output io.Writer) error {
fmt.Println("Extracting compressed file")
cmd := exec.Command("xzcat", "-k", src)
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index dda230dbc..fdfeed854 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -4,6 +4,7 @@ package rootless
import (
"bufio"
+ "bytes"
"fmt"
"io"
"io/ioutil"
@@ -18,6 +19,7 @@ import (
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/storage/pkg/idtools"
+ "github.com/containers/storage/pkg/unshare"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@@ -67,6 +69,15 @@ func IsRootless() bool {
}
}
isRootless = os.Geteuid() != 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != ""
+ if !isRootless {
+ hasCapSysAdmin, err := unshare.HasCapSysAdmin()
+ if err != nil {
+ logrus.Warnf("failed to read CAP_SYS_ADMIN presence for the current process")
+ }
+ if err == nil && !hasCapSysAdmin {
+ isRootless = true
+ }
+ }
})
return isRootless
}
@@ -142,8 +153,12 @@ func tryMappingTool(uid bool, pid int, hostID int, mappings []idtools.IDMap) err
// namespace of the specified PID without looking up its parent. Useful to join directly
// the conmon process.
func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
- if os.Geteuid() == 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
- return false, -1, nil
+ hasCapSysAdmin, err := unshare.HasCapSysAdmin()
+ if err != nil {
+ return false, 0, err
+ }
+ if hasCapSysAdmin || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
+ return false, 0, nil
}
cPausePid := C.CString(pausePid)
@@ -180,8 +195,11 @@ func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) {
}
mappings, err := idtools.NewIDMappings(username, username)
if err != nil {
- logrus.Errorf(
- "cannot find UID/GID for user %s: %v - check rootless mode in man pages.", username, err)
+ logLevel := logrus.ErrorLevel
+ if os.Geteuid() == 0 && GetRootlessUID() == 0 {
+ logLevel = logrus.DebugLevel
+ }
+ logrus.StandardLogger().Logf(logLevel, "cannot find UID/GID for user %s: %v - check rootless mode in man pages.", username, err)
} else {
uids = mappings.UIDs()
gids = mappings.GIDs()
@@ -189,8 +207,28 @@ func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) {
return uids, gids, nil
}
+func copyMappings(from, to string) error {
+ content, err := ioutil.ReadFile(from)
+ if err != nil {
+ return err
+ }
+ // Both runc and crun check whether the current process is in a user namespace
+ // by looking up 4294967295 in /proc/self/uid_map. If the mappings would be
+ // copied as they are, the check in the OCI runtimes would fail. So just split
+ // it in two different ranges.
+ if bytes.Contains(content, []byte("4294967295")) {
+ content = []byte("0 0 1\n1 1 4294967294\n")
+ }
+ return ioutil.WriteFile(to, content, 0600)
+}
+
func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ bool, _ int, retErr error) {
- if os.Geteuid() == 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
+ hasCapSysAdmin, err := unshare.HasCapSysAdmin()
+ if err != nil {
+ return false, 0, err
+ }
+
+ if hasCapSysAdmin || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
if os.Getenv("_CONTAINERS_USERNS_CONFIGURED") == "init" {
return false, 0, runInUser()
}
@@ -247,8 +285,16 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
return false, -1, err
}
+ uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
+ gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
+
uidsMapped := false
- if uids != nil {
+
+ if err := copyMappings("/proc/self/uid_map", uidMap); err == nil {
+ uidsMapped = true
+ }
+
+ if uids != nil && !uidsMapped {
err := tryMappingTool(true, pid, os.Geteuid(), uids)
// If some mappings were specified, do not ignore the error
if err != nil && len(uids) > 0 {
@@ -265,7 +311,6 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
}
logrus.Debugf("write setgroups file exited with 0")
- uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666)
if err != nil {
return false, -1, errors.Wrapf(err, "cannot write uid_map")
@@ -274,7 +319,10 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
}
gidsMapped := false
- if gids != nil {
+ if err := copyMappings("/proc/self/gid_map", gidMap); err == nil {
+ gidsMapped = true
+ }
+ if gids != nil && !gidsMapped {
err := tryMappingTool(false, pid, os.Getegid(), gids)
// If some mappings were specified, do not ignore the error
if err != nil && len(gids) > 0 {
@@ -283,7 +331,6 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
gidsMapped = err == nil
}
if !gidsMapped {
- gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getegid())), 0666)
if err != nil {
return false, -1, errors.Wrapf(err, "cannot write gid_map")
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 7aeec9d41..1347ed1e0 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -56,7 +56,7 @@ func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec)
}
p.DNSServer = servers
}
- // search domans
+ // search domains
if domains := dnsConfig.Searches; len(domains) > 0 {
p.DNSSearch = domains
}
diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go
index 30e758127..fdcc9d21b 100644
--- a/pkg/systemd/generate/common_test.go
+++ b/pkg/systemd/generate/common_test.go
@@ -199,8 +199,8 @@ func TestEscapeSystemdArguments(t *testing.T) {
[]string{"foo", `"command with backslash \\"`},
},
{
- []string{"foo", `command with two backslashs \\`},
- []string{"foo", `"command with two backslashs \\\\"`},
+ []string{"foo", `command with two backslashes \\`},
+ []string{"foo", `"command with two backslashes \\\\"`},
},
}
diff --git a/pkg/util/filters.go b/pkg/util/filters.go
index 43bf646f1..e252c1ddf 100644
--- a/pkg/util/filters.go
+++ b/pkg/util/filters.go
@@ -94,7 +94,7 @@ func PrepareFilters(r *http.Request) (*map[string][]string, error) {
return &filterMap, nil
}
-// MatchLabelFilters matches labels and returs true if they are valid
+// MatchLabelFilters matches labels and returns true if they are valid
func MatchLabelFilters(filterValues []string, labels map[string]string) bool {
outer:
for _, filterValue := range filterValues {
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index bbaf72981..622fbde99 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -706,3 +706,26 @@ func IDtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxI
}
return convertedIDMap
}
+
+var socketPath string
+
+func SetSocketPath(path string) {
+ socketPath = path
+}
+
+func SocketPath() (string, error) {
+ if socketPath != "" {
+ return socketPath, nil
+ }
+ xdg, err := GetRuntimeDir()
+ if err != nil {
+ return "", err
+ }
+ if len(xdg) == 0 {
+ // If no xdg is returned, assume root socket
+ xdg = "/run"
+ }
+
+ // Glue the socket path together
+ return filepath.Join(xdg, "podman", "podman.sock"), nil
+}