summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/libpod/manifests.go18
-rw-r--r--pkg/api/server/register_manifest.go4
-rw-r--r--pkg/bindings/containers/attach.go2
-rw-r--r--pkg/bindings/containers/term_unix.go8
-rw-r--r--pkg/bindings/containers/term_windows.go10
-rw-r--r--pkg/bindings/test/images_test.go18
-rw-r--r--pkg/bindings/test/secrets_test.go2
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go6
-rw-r--r--pkg/domain/infra/runtime_libpod.go67
-rw-r--r--pkg/domain/infra/tunnel/pods.go4
-rw-r--r--pkg/machine/fcos.go4
-rw-r--r--pkg/namespaces/namespaces.go7
-rw-r--r--pkg/specgen/container_validate.go7
-rw-r--r--pkg/specgen/generate/kube/kube.go6
-rw-r--r--pkg/specgen/generate/namespaces.go26
-rw-r--r--pkg/specgen/namespaces.go53
-rw-r--r--pkg/systemd/dbus.go3
-rw-r--r--pkg/terminal/util.go6
-rw-r--r--pkg/util/utils.go109
19 files changed, 216 insertions, 144 deletions
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index b823a56b6..15d4b9f89 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -100,10 +100,10 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) {
// gather all images for manifest list
var images []string
if len(query.Images) > 0 {
- images = append(query.Images)
+ images = query.Images
}
if len(body.Images) > 0 {
- images = append(body.Images)
+ images = body.Images
}
id, err := imageEngine.ManifestAdd(r.Context(), query.Name, images, body.ManifestAddOptions)
@@ -153,10 +153,10 @@ func ManifestInspect(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, schema2List)
}
-// ManifestAdd remove digest from manifest list
+// ManifestAddV3 remove digest from manifest list
//
-// Deprecated: As of 4.0.0 use ManifestModify instead
-func ManifestAdd(w http.ResponseWriter, r *http.Request) {
+// As of 4.0.0 use ManifestModify instead
+func ManifestAddV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
// Wrapper to support 3.x with 4.x libpod
@@ -206,10 +206,10 @@ func ManifestAdd(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID})
}
-// ManifestRemoveDigest remove digest from manifest list
+// ManifestRemoveDigestV3 remove digest from manifest list
//
-// Deprecated: As of 4.0.0 use ManifestModify instead
-func ManifestRemoveDigest(w http.ResponseWriter, r *http.Request) {
+// As of 4.0.0 use ManifestModify instead
+func ManifestRemoveDigestV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
@@ -242,7 +242,7 @@ func ManifestRemoveDigest(w http.ResponseWriter, r *http.Request) {
// ManifestPushV3 push image to registry
//
-// Deprecated: As of 4.0.0 use ManifestPush instead
+// As of 4.0.0 use ManifestPush instead
func ManifestPushV3(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
diff --git a/pkg/api/server/register_manifest.go b/pkg/api/server/register_manifest.go
index 58def109e..50a49bc1e 100644
--- a/pkg/api/server/register_manifest.go
+++ b/pkg/api/server/register_manifest.go
@@ -167,7 +167,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// $ref: "#/responses/BadParamError"
// 500:
// $ref: "#/responses/InternalError"
- v3.Handle("/{name:.*}/add", s.APIHandler(libpod.ManifestAdd)).Methods(http.MethodPost)
+ v3.Handle("/{name:.*}/add", s.APIHandler(libpod.ManifestAddV3)).Methods(http.MethodPost)
// swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteV3Libpod
// ---
// summary: Remove image from a manifest list
@@ -197,7 +197,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// $ref: "#/responses/NoSuchManifest"
// 500:
// $ref: "#/responses/InternalError"
- v3.Handle("/{name:.*}", s.APIHandler(libpod.ManifestRemoveDigest)).Methods(http.MethodDelete)
+ v3.Handle("/{name:.*}", s.APIHandler(libpod.ManifestRemoveDigestV3)).Methods(http.MethodDelete)
// swagger:operation DELETE /libpod/manifests/{name} manifests ManifestDeleteLibpod
// ---
// summary: Delete manifest list
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index 80702ea98..d84b47052 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -20,7 +20,7 @@ import (
"github.com/moby/term"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
+ terminal "golang.org/x/term"
)
// The CloseWriter interface is used to determine whether we can do a one-sided
diff --git a/pkg/bindings/containers/term_unix.go b/pkg/bindings/containers/term_unix.go
index 2c976393f..e14f50813 100644
--- a/pkg/bindings/containers/term_unix.go
+++ b/pkg/bindings/containers/term_unix.go
@@ -9,11 +9,11 @@ import (
"os/signal"
sig "github.com/containers/podman/v4/pkg/signal"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
-func makeRawTerm(stdin *os.File) (*terminal.State, error) {
- return terminal.MakeRaw(int(stdin.Fd()))
+func makeRawTerm(stdin *os.File) (*term.State, error) {
+ return term.MakeRaw(int(stdin.Fd()))
}
func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.File, stdout *os.File) {
@@ -21,5 +21,5 @@ func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.Fi
}
func getTermSize(stdin *os.File, stdout *os.File) (width, height int, err error) {
- return terminal.GetSize(int(stdin.Fd()))
+ return term.GetSize(int(stdin.Fd()))
}
diff --git a/pkg/bindings/containers/term_windows.go b/pkg/bindings/containers/term_windows.go
index 11d4bd50d..e710e2998 100644
--- a/pkg/bindings/containers/term_windows.go
+++ b/pkg/bindings/containers/term_windows.go
@@ -6,12 +6,12 @@ import (
"time"
sig "github.com/containers/podman/v4/pkg/signal"
- "golang.org/x/crypto/ssh/terminal"
"golang.org/x/sys/windows"
+ "golang.org/x/term"
)
-func makeRawTerm(stdin *os.File) (*terminal.State, error) {
- state, err := terminal.MakeRaw(int(stdin.Fd()))
+func makeRawTerm(stdin *os.File) (*term.State, error) {
+ state, err := term.MakeRaw(int(stdin.Fd()))
if err != nil {
return nil, err
}
@@ -51,7 +51,7 @@ func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.Fi
break
}
- w, h, err := terminal.GetSize(int(stdout.Fd()))
+ w, h, err := term.GetSize(int(stdout.Fd()))
if err != nil {
continue
}
@@ -65,5 +65,5 @@ func notifyWinChange(ctx context.Context, winChange chan os.Signal, stdin *os.Fi
}
func getTermSize(stdin *os.File, stdout *os.File) (width, height int, err error) {
- return terminal.GetSize(int(stdout.Fd()))
+ return term.GetSize(int(stdout.Fd()))
}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index d667a2dee..a005be6ac 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -103,7 +103,7 @@ var _ = Describe("Podman images", func() {
Expect(len(errs)).To(BeZero())
Expect(inspectData.ID).To(Equal(response.Deleted[0]))
- inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil)
+ _, err = images.GetImage(bt.conn, busybox.shortName, nil)
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
@@ -118,7 +118,7 @@ var _ = Describe("Podman images", func() {
// try to remove the image "alpine". This should fail since we are not force
// deleting hence image cannot be deleted until the container is deleted.
- response, errs = images.Remove(bt.conn, []string{alpine.shortName}, nil)
+ _, errs = images.Remove(bt.conn, []string{alpine.shortName}, nil)
code, _ = bindings.CheckResponseCode(errs[0])
// FIXME FIXME FIXME: #12441: another invalid error
// FIXME FIXME FIXME: this time msg="Image used by SHA: ..."
@@ -126,7 +126,7 @@ var _ = Describe("Podman images", func() {
// Removing the image "alpine" where force = true
options := new(images.RemoveOptions).WithForce(true)
- response, errs = images.Remove(bt.conn, []string{alpine.shortName}, options)
+ _, errs = images.Remove(bt.conn, []string{alpine.shortName}, options)
Expect(errs).To(Or(HaveLen(0), BeNil()))
// To be extra sure, check if the previously created container
// is gone as well.
@@ -135,11 +135,11 @@ var _ = Describe("Podman images", func() {
Expect(code).To(BeNumerically("==", http.StatusNotFound))
// Now make sure both images are gone.
- inspectData, err = images.GetImage(bt.conn, busybox.shortName, nil)
+ _, err = images.GetImage(bt.conn, busybox.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
- inspectData, err = images.GetImage(bt.conn, alpine.shortName, nil)
+ _, err = images.GetImage(bt.conn, alpine.shortName, nil)
code, _ = bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
})
@@ -230,8 +230,8 @@ var _ = Describe("Podman images", func() {
Expect(err).ToNot(HaveOccurred())
Expect(exists).To(BeFalse())
f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
- defer f.Close()
Expect(err).ToNot(HaveOccurred())
+ defer f.Close()
names, err := images.Load(bt.conn, f)
Expect(err).ToNot(HaveOccurred())
Expect(names.Names[0]).To(Equal(alpine.name))
@@ -252,8 +252,6 @@ var _ = Describe("Podman images", func() {
Expect(names.Names[0]).To(Equal(alpine.name))
// load with a bad repo name should trigger a 500
- f, err = os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
- Expect(err).ToNot(HaveOccurred())
_, errs = images.Remove(bt.conn, []string{alpine.name}, nil)
Expect(len(errs)).To(BeZero())
exists, err = images.Exists(bt.conn, alpine.name, nil)
@@ -265,8 +263,8 @@ var _ = Describe("Podman images", func() {
// Export an image
exportPath := filepath.Join(bt.tempDirPath, alpine.tarballName)
w, err := os.Create(filepath.Join(bt.tempDirPath, alpine.tarballName))
- defer w.Close()
Expect(err).ToNot(HaveOccurred())
+ defer w.Close()
err = images.Export(bt.conn, []string{alpine.name}, w, nil)
Expect(err).ToNot(HaveOccurred())
_, err = os.Stat(exportPath)
@@ -283,8 +281,8 @@ var _ = Describe("Podman images", func() {
Expect(err).ToNot(HaveOccurred())
Expect(exists).To(BeFalse())
f, err := os.Open(filepath.Join(ImageCacheDir, alpine.tarballName))
- defer f.Close()
Expect(err).ToNot(HaveOccurred())
+ defer f.Close()
changes := []string{"CMD /bin/foobar"}
testMessage := "test_import"
options := new(images.ImportOptions).WithMessage(testMessage).WithChanges(changes).WithReference(alpine.name)
diff --git a/pkg/bindings/test/secrets_test.go b/pkg/bindings/test/secrets_test.go
index 377f49b2f..b4595f025 100644
--- a/pkg/bindings/test/secrets_test.go
+++ b/pkg/bindings/test/secrets_test.go
@@ -64,7 +64,7 @@ var _ = Describe("Podman secrets", func() {
Expect(data.Spec.Name).To(Equal(name))
// inspecting non-existent secret should fail
- data, err = secrets.Inspect(connText, "notasecret", nil)
+ _, err = secrets.Inspect(connText, "notasecret", nil)
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusNotFound))
})
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
index 153b19fdb..62d36f28d 100644
--- a/pkg/domain/infra/abi/terminal/terminal_linux.go
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -10,13 +10,13 @@ import (
"github.com/containers/podman/v4/libpod/define"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
// ExecAttachCtr execs and attaches to a container
func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) {
var resize chan define.TerminalSize
- haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
+ haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
@@ -42,7 +42,7 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error { //nolint: interfacer
resize := make(chan define.TerminalSize)
- haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
+ haveTerminal := term.IsTerminal(int(os.Stdin.Fd()))
// Check if we are attached to a terminal. If we are, generate resize
// events, and set the terminal to raw mode
diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go
index dffd90dbe..5fdc252e2 100644
--- a/pkg/domain/infra/runtime_libpod.go
+++ b/pkg/domain/infra/runtime_libpod.go
@@ -276,46 +276,47 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
if len(subUIDMap) > 0 || len(subGIDMap) > 0 {
return nil, errors.New("cannot specify subuidmap or subgidmap with --userns=keep-id")
}
- if rootless.IsRootless() {
- min := func(a, b int) int {
- if a < b {
- return a
- }
- return b
+ if !rootless.IsRootless() {
+ return nil, errors.New("keep-id is only supported in rootless mode")
+ }
+ min := func(a, b int) int {
+ if a < b {
+ return a
}
+ return b
+ }
- uid := rootless.GetRootlessUID()
- gid := rootless.GetRootlessGID()
-
- uids, gids, err := rootless.GetConfiguredMappings()
- if err != nil {
- return nil, errors.Wrapf(err, "cannot read mappings")
- }
- maxUID, maxGID := 0, 0
- for _, u := range uids {
- maxUID += u.Size
- }
- for _, g := range gids {
- maxGID += g.Size
- }
+ uid := rootless.GetRootlessUID()
+ gid := rootless.GetRootlessGID()
- options.UIDMap, options.GIDMap = nil, nil
+ uids, gids, err := rootless.GetConfiguredMappings()
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot read mappings")
+ }
+ maxUID, maxGID := 0, 0
+ for _, u := range uids {
+ maxUID += u.Size
+ }
+ for _, g := range gids {
+ maxGID += g.Size
+ }
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(uid, maxUID)})
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: 0, Size: 1})
- if maxUID > uid {
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid})
- }
+ options.UIDMap, options.GIDMap = nil, nil
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(gid, maxGID)})
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: 0, Size: 1})
- if maxGID > gid {
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid})
- }
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(uid, maxUID)})
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: 0, Size: 1})
+ if maxUID > uid {
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid})
+ }
- options.HostUIDMapping = false
- options.HostGIDMapping = false
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(gid, maxGID)})
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: 0, Size: 1})
+ if maxGID > gid {
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid})
}
+
+ options.HostUIDMapping = false
+ options.HostGIDMapping = false
// Simply ignore the setting and do not setup an inner namespace for root as it is a no-op
return &options, nil
}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 4f44e7e4a..2dbdfcf80 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -42,14 +42,14 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
return reports, nil
}
-func (ic *ContainerEngine) PodLogs(_ context.Context, nameOrIDs string, options entities.PodLogsOptions) error {
+func (ic *ContainerEngine) PodLogs(ctx context.Context, nameOrIDs string, options entities.PodLogsOptions) error {
// PodLogsOptions are similar but contains few extra fields like ctrName
// So cast other values as is so we can re-use the code
containerLogsOpts := entities.PodLogsOptionsToContainerLogsOptions(options)
// interface only accepts slice, keep everything consistent
name := []string{options.ContainerName}
- return ic.ContainerLogs(nil, name, containerLogsOpts)
+ return ic.ContainerLogs(ctx, name, containerLogsOpts)
}
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 6215ae08f..ad1be15c7 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -139,7 +139,7 @@ func getStreamURL(streamType string) url2.URL {
// This should get Exported and stay put as it will apply to all fcos downloads
// getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version
-func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
+func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { // nolint:staticcheck
var (
fcosstable stream.Stream
altMeta release.Release
@@ -149,6 +149,8 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
// This is being hard set to testing. Once podman4 is in the
// fcos trees, we should remove it and re-release at least on
// macs.
+ // TODO: remove when podman4.0 is in coreos
+ // nolint:staticcheck
imageStream = "podman-testing"
switch imageStream {
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index a264a5a0f..bdea7c310 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -96,6 +96,11 @@ func (n UsernsMode) IsKeepID() bool {
return n == "keep-id"
}
+// IsNoMap indicates whether container uses a mapping where the (uid, gid) on the host is not present in the namespace.
+func (n UsernsMode) IsNoMap() bool {
+ return n == "nomap"
+}
+
// IsAuto indicates whether container uses the "auto" userns mode.
func (n UsernsMode) IsAuto() bool {
parts := strings.Split(string(n), ":")
@@ -158,7 +163,7 @@ func (n UsernsMode) IsPrivate() bool {
func (n UsernsMode) Valid() bool {
parts := strings.Split(string(n), ":")
switch mode := parts[0]; mode {
- case "", privateType, hostType, "keep-id", nsType, "auto":
+ case "", privateType, hostType, "keep-id", nsType, "auto", "nomap":
case containerType:
if len(parts) != 2 || parts[1] == "" {
return false
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index 42b70e334..e06cd9a29 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -38,6 +38,13 @@ func (s *SpecGenerator) Validate() error {
if len(s.PortMappings) > 0 || s.PublishExposedPorts {
return errors.Wrap(define.ErrNetworkOnPodContainer, "published or exposed ports must be defined when the pod is created")
}
+ if len(s.HostAdd) > 0 {
+ return errors.Wrap(define.ErrNetworkOnPodContainer, "extra host entries must be specified on the pod")
+ }
+ }
+
+ if s.NetNS.IsContainer() && len(s.HostAdd) > 0 {
+ return errors.Wrap(ErrInvalidSpecConfig, "cannot set extra host entries when the container is joined to another containers network namespace")
}
//
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index df751a780..51f9fa535 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -82,7 +82,7 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
}
// dns options
if options := dnsConfig.Options; len(options) > 0 {
- dnsOptions := make([]string, 0)
+ dnsOptions := make([]string, 0, len(options))
for _, opts := range options {
d := opts.Name
if opts.Value != nil {
@@ -90,6 +90,7 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
}
dnsOptions = append(dnsOptions, d)
}
+ p.Net.DNSOptions = dnsOptions
}
}
return p, nil
@@ -281,9 +282,6 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
annotations = opts.Annotations
}
if opts.PodInfraID != "" {
- if annotations == nil {
-
- }
annotations[ann.SandboxID] = opts.PodInfraID
annotations[ann.ContainerType] = ann.ContainerTypeContainer
}
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index 05c2d1741..d8d1ae652 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -165,21 +165,19 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
// User
switch s.UserNS.NSMode {
case specgen.KeepID:
- if rootless.IsRootless() {
- toReturn = append(toReturn, libpod.WithAddCurrentUserPasswdEntry())
-
- // If user is not overridden, set user in the container
- // to user running Podman.
- if s.User == "" {
- _, uid, gid, err := util.GetKeepIDMapping()
- if err != nil {
- return nil, err
- }
- toReturn = append(toReturn, libpod.WithUser(fmt.Sprintf("%d:%d", uid, gid)))
+ if !rootless.IsRootless() {
+ return nil, errors.New("keep-id is only supported in rootless mode")
+ }
+ toReturn = append(toReturn, libpod.WithAddCurrentUserPasswdEntry())
+
+ // If user is not overridden, set user in the container
+ // to user running Podman.
+ if s.User == "" {
+ _, uid, gid, err := util.GetKeepIDMapping()
+ if err != nil {
+ return nil, err
}
- } else {
- // keep-id as root doesn't need a user namespace
- s.UserNS.NSMode = specgen.Host
+ toReturn = append(toReturn, libpod.WithUser(fmt.Sprintf("%d:%d", uid, gid)))
}
case specgen.FromPod:
if pod == nil || infraCtr == nil {
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go
index 4412eff29..eaf2daad9 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -55,6 +55,10 @@ const (
// of the namespace itself.
// Only used with the user namespace, invalid otherwise.
KeepID NamespaceMode = "keep-id"
+ // NoMap indicates a user namespace to keep the owner uid out
+ // of the namespace itself.
+ // Only used with the user namespace, invalid otherwise.
+ NoMap NamespaceMode = "no-map"
// Auto indicates to automatically create a user namespace.
// Only used with the user namespace, invalid otherwise.
Auto NamespaceMode = "auto"
@@ -121,6 +125,11 @@ func (n *Namespace) IsKeepID() bool {
return n.NSMode == KeepID
}
+// IsNoMap indicates the namespace is NoMap
+func (n *Namespace) IsNoMap() bool {
+ return n.NSMode == NoMap
+}
+
func (n *Namespace) String() string {
if n.Value != "" {
return fmt.Sprintf("%s:%s", n.NSMode, n.Value)
@@ -133,7 +142,7 @@ func validateUserNS(n *Namespace) error {
return nil
}
switch n.NSMode {
- case Auto, KeepID:
+ case Auto, KeepID, NoMap:
return nil
}
return n.validate()
@@ -299,6 +308,9 @@ func ParseUserNamespace(ns string) (Namespace, error) {
case ns == "keep-id":
toReturn.NSMode = KeepID
return toReturn, nil
+ case ns == "nomap":
+ toReturn.NSMode = NoMap
+ return toReturn, nil
case ns == "":
toReturn.NSMode = Host
return toReturn, nil
@@ -548,20 +560,41 @@ func SetupUserNS(idmappings *storage.IDMappingOptions, userns Namespace, g *gene
g.SetProcessUID(uint32(uid))
g.SetProcessGID(uint32(gid))
user = fmt.Sprintf("%d:%d", uid, gid)
- fallthrough
- case Private:
- if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil {
+ if err := privateUserNamespace(idmappings, g); err != nil {
return user, err
}
- if idmappings == nil || (len(idmappings.UIDMap) == 0 && len(idmappings.GIDMap) == 0) {
- return user, errors.Errorf("must provide at least one UID or GID mapping to configure a user namespace")
+ case NoMap:
+ mappings, uid, gid, err := util.GetNoMapMapping()
+ if err != nil {
+ return user, err
}
- for _, uidmap := range idmappings.UIDMap {
- g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
+ idmappings = mappings
+ g.SetProcessUID(uint32(uid))
+ g.SetProcessGID(uint32(gid))
+ user = fmt.Sprintf("%d:%d", uid, gid)
+ if err := privateUserNamespace(idmappings, g); err != nil {
+ return user, err
}
- for _, gidmap := range idmappings.GIDMap {
- g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size))
+ case Private:
+ if err := privateUserNamespace(idmappings, g); err != nil {
+ return user, err
}
}
return user, nil
}
+
+func privateUserNamespace(idmappings *storage.IDMappingOptions, g *generate.Generator) error {
+ if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil {
+ return err
+ }
+ if idmappings == nil || (len(idmappings.UIDMap) == 0 && len(idmappings.GIDMap) == 0) {
+ return errors.Errorf("must provide at least one UID or GID mapping to configure a user namespace")
+ }
+ for _, uidmap := range idmappings.UIDMap {
+ g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
+ }
+ for _, gidmap := range idmappings.GIDMap {
+ g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size))
+ }
+ return nil
+}
diff --git a/pkg/systemd/dbus.go b/pkg/systemd/dbus.go
index 44feb8308..b35f778ab 100644
--- a/pkg/systemd/dbus.go
+++ b/pkg/systemd/dbus.go
@@ -1,6 +1,7 @@
package systemd
import (
+ "context"
"fmt"
"os"
"path/filepath"
@@ -140,5 +141,5 @@ func ConnectToDBUS() (*dbus.Conn, error) {
if rootless.IsRootless() {
return newRootlessConnection()
}
- return dbus.NewSystemdConnection()
+ return dbus.NewSystemdConnectionContext(context.Background())
}
diff --git a/pkg/terminal/util.go b/pkg/terminal/util.go
index 04e12f6b3..0f0968c30 100644
--- a/pkg/terminal/util.go
+++ b/pkg/terminal/util.go
@@ -14,7 +14,7 @@ import (
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/knownhosts"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -29,9 +29,9 @@ var (
// Additionally, all input after `<secret>/n` is queued to podman command.
func ReadPassword(prompt string) (pw []byte, err error) {
fd := int(os.Stdin.Fd())
- if terminal.IsTerminal(fd) {
+ if term.IsTerminal(fd) {
fmt.Fprint(os.Stderr, prompt)
- pw, err = terminal.ReadPassword(fd)
+ pw, err = term.ReadPassword(fd)
fmt.Fprintln(os.Stderr)
return
}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index b89978601..9842a0f73 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -28,7 +28,7 @@ import (
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var containerConfig *config.Config
@@ -65,7 +65,7 @@ func ParseRegistryCreds(creds string) (*types.DockerAuthConfig, error) {
}
if password == "" {
fmt.Print("Password: ")
- termPassword, err := terminal.ReadPassword(0)
+ termPassword, err := term.ReadPassword(0)
if err != nil {
return nil, errors.Wrapf(err, "could not read password from terminal")
}
@@ -347,55 +347,84 @@ func ParseSignal(rawSignal string) (syscall.Signal, error) {
// GetKeepIDMapping returns the mappings and the user to use when keep-id is used
func GetKeepIDMapping() (*stypes.IDMappingOptions, int, int, error) {
+ if !rootless.IsRootless() {
+ return nil, -1, -1, errors.New("keep-id is only supported in rootless mode")
+ }
options := stypes.IDMappingOptions{
- HostUIDMapping: true,
- HostGIDMapping: true,
+ HostUIDMapping: false,
+ HostGIDMapping: false,
}
- uid, gid := 0, 0
- if rootless.IsRootless() {
- min := func(a, b int) int {
- if a < b {
- return a
- }
- return b
+ min := func(a, b int) int {
+ if a < b {
+ return a
}
+ return b
+ }
- uid = rootless.GetRootlessUID()
- gid = rootless.GetRootlessGID()
+ uid := rootless.GetRootlessUID()
+ gid := rootless.GetRootlessGID()
- uids, gids, err := rootless.GetConfiguredMappings()
- if err != nil {
- return nil, -1, -1, errors.Wrapf(err, "cannot read mappings")
- }
- maxUID, maxGID := 0, 0
- for _, u := range uids {
- maxUID += u.Size
- }
- for _, g := range gids {
- maxGID += g.Size
- }
-
- options.UIDMap, options.GIDMap = nil, nil
+ uids, gids, err := rootless.GetConfiguredMappings()
+ if err != nil {
+ return nil, -1, -1, errors.Wrapf(err, "cannot read mappings")
+ }
+ if len(uids) == 0 || len(gids) == 0 {
+ return nil, -1, -1, errors.Wrapf(err, "keep-id requires additional UIDs or GIDs defined in /etc/subuid and /etc/subgid to function correctly")
+ }
+ maxUID, maxGID := 0, 0
+ for _, u := range uids {
+ maxUID += u.Size
+ }
+ for _, g := range gids {
+ maxGID += g.Size
+ }
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(uid, maxUID)})
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: 0, Size: 1})
- if maxUID > uid {
- options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid})
- }
+ options.UIDMap, options.GIDMap = nil, nil
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(gid, maxGID)})
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: 0, Size: 1})
- if maxGID > gid {
- options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid})
- }
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(uid, maxUID)})
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: 0, Size: 1})
+ if maxUID > uid {
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid})
+ }
- options.HostUIDMapping = false
- options.HostGIDMapping = false
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(gid, maxGID)})
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: 0, Size: 1})
+ if maxGID > gid {
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid})
}
- // Simply ignore the setting and do not setup an inner namespace for root as it is a no-op
+
return &options, uid, gid, nil
}
+// GetNoMapMapping returns the mappings and the user to use when nomap is used
+func GetNoMapMapping() (*stypes.IDMappingOptions, int, int, error) {
+ if !rootless.IsRootless() {
+ return nil, -1, -1, errors.New("nomap is only supported in rootless mode")
+ }
+ options := stypes.IDMappingOptions{
+ HostUIDMapping: false,
+ HostGIDMapping: false,
+ }
+ uids, gids, err := rootless.GetConfiguredMappings()
+ if err != nil {
+ return nil, -1, -1, errors.Wrapf(err, "cannot read mappings")
+ }
+ if len(uids) == 0 || len(gids) == 0 {
+ return nil, -1, -1, errors.Wrapf(err, "nomap requires additional UIDs or GIDs defined in /etc/subuid and /etc/subgid to function correctly")
+ }
+ options.UIDMap, options.GIDMap = nil, nil
+ uid, gid := 0, 0
+ for _, u := range uids {
+ options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: uid + 1, Size: u.Size})
+ uid += u.Size
+ }
+ for _, g := range gids {
+ options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: gid + 1, Size: g.Size})
+ gid += g.Size
+ }
+ return &options, 0, 0, nil
+}
+
// ParseIDMapping takes idmappings and subuid and subgid maps and returns a storage mapping
func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []string, subUIDMap, subGIDMap string) (*stypes.IDMappingOptions, error) {
options := stypes.IDMappingOptions{
@@ -415,7 +444,7 @@ func ParseIDMapping(mode namespaces.UsernsMode, uidMapSlice, gidMapSlice []strin
options.AutoUserNsOpts = *opts
return &options, nil
}
- if mode.IsKeepID() {
+ if mode.IsKeepID() || mode.IsNoMap() {
options.HostUIDMapping = false
options.HostGIDMapping = false
return &options, nil