summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.golangci.yml1
-rw-r--r--Makefile2
-rw-r--r--cmd/podman/common/completion.go2
-rw-r--r--cmd/podman/containers/create.go6
-rw-r--r--cmd/podman/containers/export.go4
-rw-r--r--cmd/podman/containers/run.go4
-rw-r--r--cmd/podman/images/load.go4
-rw-r--r--cmd/podman/images/save.go4
-rw-r--r--cmd/podman/machine/init.go15
-rw-r--r--cmd/podman/machine/set.go7
-rw-r--r--cmd/podman/volumes/unmount.go1
-rwxr-xr-xcontrib/cirrus/logformatter2
-rw-r--r--contrib/podmanimage/README.md2
-rw-r--r--contrib/remote/containers.conf2
-rw-r--r--docs/source/markdown/podman-build.1.md2
-rw-r--r--docs/source/markdown/podman-create.1.md11
-rw-r--r--docs/source/markdown/podman-image-scp.1.md2
-rw-r--r--docs/source/markdown/podman-machine-init.1.md6
-rw-r--r--docs/source/markdown/podman-machine-set.1.md20
-rw-r--r--docs/source/markdown/podman-pod-create.1.md22
-rw-r--r--docs/source/markdown/podman-run.1.md13
-rw-r--r--go.mod1
-rw-r--r--libpod/container_inspect.go2
-rw-r--r--libpod/container_internal_linux.go7
-rw-r--r--libpod/healthcheck_linux.go2
-rw-r--r--libpod/networking_slirp4netns.go2
-rw-r--r--libpod/options.go3
-rw-r--r--libpod/runtime_ctr.go4
-rw-r--r--pkg/api/handlers/libpod/manifests.go18
-rw-r--r--pkg/api/server/register_manifest.go4
-rw-r--r--pkg/bindings/README.md8
-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/images.go6
-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/config.go4
-rw-r--r--pkg/machine/fcos.go4
-rw-r--r--pkg/machine/qemu/config.go8
-rw-r--r--pkg/machine/qemu/machine.go20
-rw-r--r--pkg/machine/wsl/machine.go22
-rw-r--r--pkg/namespaces/namespaces.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/specgenutil/volumes.go11
-rw-r--r--pkg/systemd/dbus.go3
-rw-r--r--pkg/terminal/util.go6
-rw-r--r--pkg/util/utils.go109
-rw-r--r--rootless.md2
-rw-r--r--test/e2e/checkpoint_test.go2
-rw-r--r--test/e2e/common_test.go4
-rw-r--r--test/e2e/exec_test.go2
-rw-r--r--test/e2e/login_logout_test.go2
-rw-r--r--test/e2e/mount_rootless_test.go2
-rw-r--r--test/e2e/network_test.go2
-rw-r--r--test/e2e/push_test.go1
-rw-r--r--test/e2e/run_userns_test.go13
-rw-r--r--test/e2e/run_volume_test.go5
-rw-r--r--test/e2e/systemd_activate_test.go2
-rw-r--r--test/e2e/toolbox_test.go9
-rw-r--r--test/system/030-run.bats11
-rw-r--r--test/system/065-cp.bats8
-rw-r--r--test/system/075-exec.bats1
-rw-r--r--test/system/160-volumes.bats13
-rw-r--r--test/system/170-run-userns.bats14
-rw-r--r--test/system/270-socket-activation.bats2
-rw-r--r--test/system/500-networking.bats1
-rw-r--r--test/system/helpers.bash2
-rw-r--r--test/utils/common_function_test.go3
-rw-r--r--test/utils/utils.go2
-rw-r--r--test/version/main.go2
-rw-r--r--utils/utils_supported.go7
-rw-r--r--vendor/golang.org/x/crypto/ssh/terminal/terminal.go76
-rw-r--r--vendor/modules.txt2
79 files changed, 441 insertions, 334 deletions
diff --git a/.golangci.yml b/.golangci.yml
index 956e528ef..8a922775a 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -32,7 +32,6 @@ linters:
- predeclared
- thelper
- ifshort
- - staticcheck
- forbidigo
- exhaustive
- unparam
diff --git a/Makefile b/Makefile
index e94d4cf73..502323906 100644
--- a/Makefile
+++ b/Makefile
@@ -877,7 +877,7 @@ install.tools: .install.goimports .install.gitvalidation .install.md2man .instal
.PHONY: .install.golangci-lint
.install.golangci-lint: .gopathok
- VERSION=1.45.0 GOBIN=$(GOBIN) ./hack/install_golangci.sh
+ VERSION=1.45.2 GOBIN=$(GOBIN) ./hack/install_golangci.sh
.PHONY: .install.bats
.install.bats: .gopathok
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 3d36162ee..abb943942 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -756,7 +756,7 @@ func AutocompleteNamespace(cmd *cobra.Command, args []string, toComplete string)
// -> same as AutocompleteNamespace with "auto", "keep-id" added
func AutocompleteUserNamespace(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
results, directive := AutocompleteNamespace(cmd, args, toComplete)
- results = append(results, "auto", "keep-id")
+ results = append(results, "auto", "keep-id", "nomap")
return results, directive
}
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index bbc449a1e..b202e404f 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -286,8 +286,6 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
if !isInfra && c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String()
vals.Entrypoint = &val
- } else if isInfra && c.Flag("infra-command").Changed {
-
}
// Docker-compatibility: the "-h" flag for run/create is reserved for
@@ -297,7 +295,7 @@ func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra
}
func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (string, error) {
- pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
+ pullPolicy, err := config.ParsePullPolicy(cliVals.Pull)
if err != nil {
return "", err
}
@@ -383,7 +381,7 @@ func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts
podSpec := entities.PodSpec{}
podGen := specgen.NewPodSpecGenerator()
podSpec.PodSpecGen = *podGen
- podGen, err = entities.ToPodSpecGen(*&podSpec.PodSpecGen, &createOptions)
+ podGen, err = entities.ToPodSpecGen(podSpec.PodSpecGen, &createOptions)
if err != nil {
return nil, err
}
diff --git a/cmd/podman/containers/export.go b/cmd/podman/containers/export.go
index 0fed94e86..681df93e0 100644
--- a/cmd/podman/containers/export.go
+++ b/cmd/podman/containers/export.go
@@ -11,7 +11,7 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -69,7 +69,7 @@ func init() {
func export(cmd *cobra.Command, args []string) error {
if len(exportOpts.Output) == 0 {
file := os.Stdout
- if terminal.IsTerminal(int(file.Fd())) {
+ if term.IsTerminal(int(file.Fd())) {
return errors.Errorf("refusing to export to terminal. Use -o flag or redirect")
}
exportOpts.Output = "/dev/stdout"
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 1d98eb3b3..4ad8d3183 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -18,7 +18,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -112,7 +112,7 @@ func run(cmd *cobra.Command, args []string) error {
var err error
// TODO: Breaking change should be made fatal in next major Release
- if cliVals.TTY && cliVals.Interactive && !terminal.IsTerminal(int(os.Stdin.Fd())) {
+ if cliVals.TTY && cliVals.Interactive && !term.IsTerminal(int(os.Stdin.Fd())) {
logrus.Warnf("The input device is not a TTY. The --tty and --interactive flags might not work properly")
}
diff --git a/cmd/podman/images/load.go b/cmd/podman/images/load.go
index 30f88b02b..6f85fb7e7 100644
--- a/cmd/podman/images/load.go
+++ b/cmd/podman/images/load.go
@@ -16,7 +16,7 @@ import (
"github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -90,7 +90,7 @@ func load(cmd *cobra.Command, args []string) error {
return err
}
} else {
- if terminal.IsTerminal(int(os.Stdin.Fd())) {
+ if term.IsTerminal(int(os.Stdin.Fd())) {
return errors.Errorf("cannot read from terminal. Use command-line redirection or the --input flag.")
}
outFile, err := ioutil.TempFile(util.Tmpdir(), "podman")
diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go
index a9fe675e1..fb642bafd 100644
--- a/cmd/podman/images/save.go
+++ b/cmd/podman/images/save.go
@@ -14,7 +14,7 @@ import (
"github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "golang.org/x/crypto/ssh/terminal"
+ "golang.org/x/term"
)
var (
@@ -109,7 +109,7 @@ func save(cmd *cobra.Command, args []string) (finalErr error) {
if len(saveOpts.Output) == 0 {
saveOpts.Quiet = true
fi := os.Stdout
- if terminal.IsTerminal(int(fi.Fd())) {
+ if term.IsTerminal(int(fi.Fd())) {
return errors.Errorf("refusing to save to terminal. Use -o flag or redirect")
}
pipePath, cleanup, err := setupPipe()
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
index 2d0afbf05..06c1f7248 100644
--- a/cmd/podman/machine/init.go
+++ b/cmd/podman/machine/init.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v4/pkg/machine"
"github.com/pkg/errors"
"github.com/spf13/cobra"
+ "github.com/spf13/pflag"
)
var (
@@ -106,8 +107,18 @@ func init() {
flags.StringVar(&initOpts.IgnitionPath, IgnitionPathFlagName, "", "Path to ignition file")
_ = initCmd.RegisterFlagCompletionFunc(IgnitionPathFlagName, completion.AutocompleteDefault)
- rootfulFlagName := "rootful"
- flags.BoolVar(&initOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ rootfullFlagName := "rootfull"
+ flags.BoolVar(&initOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
+ flags.SetNormalizeFunc(aliasFlags)
+}
+
+// aliasFlags is a function to handle backwards compatibility with old flags
+func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ switch name {
+ case "rootful":
+ name = "rootfull"
+ }
+ return pflag.NormalizedName(name)
}
// TODO should we allow for a users to append to the qemu cmdline?
diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go
index 4c15f1de1..b1dfb51da 100644
--- a/cmd/podman/machine/set.go
+++ b/cmd/podman/machine/set.go
@@ -17,7 +17,7 @@ var (
Long: "Sets an updatable virtual machine setting",
RunE: setMachine,
Args: cobra.MaximumNArgs(1),
- Example: `podman machine set --rootful=false`,
+ Example: `podman machine set --rootfull=false`,
ValidArgsFunction: completion.AutocompleteNone,
}
)
@@ -33,8 +33,9 @@ func init() {
})
flags := setCmd.Flags()
- rootfulFlagName := "rootful"
- flags.BoolVar(&setOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ rootfullFlagName := "rootfull"
+ flags.BoolVar(&setOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
+ flags.SetNormalizeFunc(aliasFlags)
}
func setMachine(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/volumes/unmount.go b/cmd/podman/volumes/unmount.go
index dd0cebc06..af79e49ef 100644
--- a/cmd/podman/volumes/unmount.go
+++ b/cmd/podman/volumes/unmount.go
@@ -37,7 +37,6 @@ func volumeUnmount(cmd *cobra.Command, args []string) error {
return err
}
for _, r := range reports {
- var errs utils.OutputErrors
if r.Err == nil {
fmt.Println(r.Id)
} else {
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 3ec839aa8..3c52e612b 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -204,7 +204,7 @@ END_HTML
print { $out_fh } "<pre> <!-- begin processed output -->\n";
- # Assume rootful prompt, check for rootless (here and in log itself, below)
+ # Assume rootfull prompt, check for rootless (here and in log itself, below)
my $Prompt = '#';
$Prompt = '$' if $test_name =~ /rootless/;
diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md
index 4f184ca28..58c14be72 100644
--- a/contrib/podmanimage/README.md
+++ b/contrib/podmanimage/README.md
@@ -70,4 +70,4 @@ file to `/etc/modules.load.d`. See `man modules-load.d` for more details.
### Blog Post with Details
-Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootful and as a rootless user. Please refer to this blog for more detailed information.
+Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootfull and as a rootless user. Please refer to this blog for more detailed information.
diff --git a/contrib/remote/containers.conf b/contrib/remote/containers.conf
index 9b0b62c42..45f58171a 100644
--- a/contrib/remote/containers.conf
+++ b/contrib/remote/containers.conf
@@ -7,5 +7,5 @@
# Default Remote URI to access the Podman service.
# Examples:
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
-# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
+# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
# remote_uri= ""
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 86801c72f..406dfcd89 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -429,7 +429,7 @@ container full access to local system services such as D-bus and is therefore
considered insecure.
- **ns:**_path_: path to a network namespace to join.
- **private**: create a new namespace for the container (default)
-- **\<network name|ID\>**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootful users.
+- **\<network name|ID\>**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootfull users.
#### **--no-cache**
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 9b2a4fd27..15ae28dc3 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -1225,6 +1225,15 @@ Without this argument the command will be run as root in the container.
Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled unless an explicit mapping is set with the **--uidmap** and **--gidmap** options.
+Rootless user --userns=Key mappings:
+
+Key | Host User | Container User
+----------|---------------|---------------------
+"" |$UID |0 (Default User account mapped to root user in container.)
+keep-id |$UID |$UID (Map user account to same UID within container.)
+auto |$UID | nil (Host User UID is not mapped into container.)
+nomap |$UID | nil (Host User UID is not mapped into container.)
+
Valid _mode_ values are:
**auto**[:_OPTIONS,..._]: automatically create a unique user namespace.
@@ -1247,6 +1256,8 @@ Podman allocates unique ranges of UIDs and GIDs from the `containers` subordinat
**keep-id**: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user.
+**nomap**: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is ignored for containers created by the root user.
+
**ns:**_namespace_: run the container in the given existing user namespace.
**private**: create a new namespace for the container.
diff --git a/docs/source/markdown/podman-image-scp.1.md b/docs/source/markdown/podman-image-scp.1.md
index 1d902da91..6d5a51298 100644
--- a/docs/source/markdown/podman-image-scp.1.md
+++ b/docs/source/markdown/podman-image-scp.1.md
@@ -8,7 +8,7 @@ podman-image-scp - Securely copy an image from one host to another
## DESCRIPTION
**podman image scp** copies container images between hosts on a network. You can load to the remote host or from the remote host as well as in between two remote hosts.
-Note: `::` is used to specify the image name depending on if you are saving or loading. Images can also be transferred from rootful to rootless storage on the same machine without using sshd. This feature is not supported on the remote client, including Mac and Windows (excluding WSL2) machines.
+Note: `::` is used to specify the image name depending on if you are saving or loading. Images can also be transferred from rootfull to rootless storage on the same machine without using sshd. This feature is not supported on the remote client, including Mac and Windows (excluding WSL2) machines.
**podman image scp [GLOBAL OPTIONS]**
diff --git a/docs/source/markdown/podman-machine-init.1.md b/docs/source/markdown/podman-machine-init.1.md
index 33947bbba..e42c5025b 100644
--- a/docs/source/markdown/podman-machine-init.1.md
+++ b/docs/source/markdown/podman-machine-init.1.md
@@ -59,9 +59,9 @@ Memory (in MB).
Start the virtual machine immediately after it has been initialized.
-#### **--rootful**=*true|false*
+#### **--rootfull**=*true|false*
-Whether this machine should prefer rootful (`true`) or rootless (`false`)
+Whether this machine should prefer rootfull (`true`) or rootless (`false`)
container execution. This option will also determine the remote connection default
if there is no existing remote connection configurations.
@@ -95,7 +95,7 @@ Driver to use for mounting volumes from the host, such as `virtfs`.
```
$ podman machine init
$ podman machine init myvm
-$ podman machine init --rootful
+$ podman machine init --rootfull
$ podman machine init --disk-size 50
$ podman machine init --memory=1024 myvm
$ podman machine init -v /Users:/mnt/Users
diff --git a/docs/source/markdown/podman-machine-set.1.md b/docs/source/markdown/podman-machine-set.1.md
index a4918eacf..e69a7dc14 100644
--- a/docs/source/markdown/podman-machine-set.1.md
+++ b/docs/source/markdown/podman-machine-set.1.md
@@ -19,39 +19,39 @@ subset can be changed after machine initialization.
Print usage statement.
-#### **--rootful**=*true|false*
+#### **--rootfull**=*true|false*
-Whether this machine should prefer rootful (`true`) or rootless (`false`)
+Whether this machine should prefer rootfull (`true`) or rootless (`false`)
container execution. This option will also update the current podman
remote connection default if it is currently pointing at the specified
machine name (or `podman-machine-default` if no name is specified).
Unlike [**podman system connection default**](podman-system-connection-default.1.md)
-this option will also make the API socket, if available, forward to the rootful/rootless
+this option will also make the API socket, if available, forward to the rootfull/rootless
socket in the VM.
## EXAMPLES
-To switch the default VM `podman-machine-default` from rootless to rootful:
+To switch the default VM `podman-machine-default` from rootless to rootfull:
```
-$ podman machine set --rootful
+$ podman machine set --rootfull
```
or more explicitly:
```
-$ podman machine set --rootful=true
+$ podman machine set --rootfull=true
```
-To switch the default VM `podman-machine-default` from rootful to rootless:
+To switch the default VM `podman-machine-default` from rootfull to rootless:
```
-$ podman machine set --rootful=false
+$ podman machine set --rootfull=false
```
-To switch the VM `myvm` from rootless to rootful:
+To switch the VM `myvm` from rootless to rootfull:
```
-$ podman machine set --rootful myvm
+$ podman machine set --rootfull myvm
```
## SEE ALSO
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index ce70678de..403a317ea 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -315,14 +315,30 @@ several times to map different ranges.
Set the user namespace mode for all the containers in a pod. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled.
+Rootless user --userns=Key mappings:
+
+Key | Host User | Container User
+----------|---------------|---------------------
+"" |$UID |0 (Default User account mapped to root user in container.)
+keep-id |$UID |$UID (Map user account to same UID within container.)
+auto |$UID | nil (Host User UID is not mapped into container.)
+nomap |$UID | nil (Host User UID is not mapped into container.)
+
Valid _mode_ values are:
-- *auto[:*_OPTIONS,..._*]*: automatically create a namespace. It is possible to specify these options to `auto`:
+ - *auto[:*_OPTIONS,..._*]*: automatically create a namespace. It is possible to specify these options to `auto`:
+
- *gidmapping=*_CONTAINER_GID:HOST_GID:SIZE_ to force a GID mapping to be present in the user namespace.
+
- *size=*_SIZE_: to specify an explicit size for the automatic user namespace. e.g. `--userns=auto:size=8192`. If `size` is not specified, `auto` will estimate a size for the user namespace.
+
- *uidmapping=*_CONTAINER_UID:HOST_UID:SIZE_ to force a UID mapping to be present in the user namespace.
-- *host*: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default).
-- *keep-id*: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user.
+
+ - *host*: run in the user namespace of the caller. The processes running in the container will have the same privileges on the host as any other process launched by the calling user (default).
+
+ - *keep-id*: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user.
+
+ - *nomap*: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is ignored for containers created by the root user.
#### **--volume**, **-v**[=*[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 06fd63030..578acf379 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -1291,6 +1291,15 @@ When a user namespace is not in use, the UID and GID used within the container a
Set the user namespace mode for the container. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled unless an explicit mapping is set with the **--uidmap** and **--gidmap** options.
+Rootless user --userns=Key mappings:
+
+Key | Host User | Container User
+----------|---------------|---------------------
+"" |$UID |0 (Default User account mapped to root user in container.)
+keep-id |$UID |$UID (Map user account to same UID within container.)
+auto |$UID | nil (Host User UID is not mapped into container.)
+nomap |$UID | nil (Host User UID is not mapped into container.)
+
Valid _mode_ values are:
**auto**[:_OPTIONS,..._]: automatically create a unique user namespace.
@@ -1300,6 +1309,7 @@ The `--userns=auto` flag, requires that the user name `containers` and a range o
Example: `containers:2147483647:2147483648`.
Podman allocates unique ranges of UIDs and GIDs from the `containers` subordinate user ids. The size of the ranges is based on the number of UIDs required in the image. The number of UIDs and GIDs can be overridden with the `size` option.
+
The rootless option `--userns=keep-id` uses all the subuids and subgids of the user. Using `--userns=auto` when starting new containers will not work as long as any containers exist that were started with `--userns=keep-id`.
Valid `auto` options:
@@ -1314,10 +1324,11 @@ The rootless option `--userns=keep-id` uses all the subuids and subgids of the u
**keep-id**: creates a user namespace where the current rootless user's UID:GID are mapped to the same values in the container. This option is ignored for containers created by the root user.
+**nomap**: creates a user namespace where the current rootless user's UID:GID are not mapped into the container. This option is ignored for containers created by the root user.
+
**ns:**_namespace_: run the container in the given existing user namespace.
**private**: create a new namespace for the container.
-
This option is incompatible with **--gidmap**, **--uidmap**, **--subuidname** and **--subgidname**.
#### **--uts**=*mode*
diff --git a/go.mod b/go.mod
index 4bcf8f76b..141f59525 100644
--- a/go.mod
+++ b/go.mod
@@ -68,6 +68,7 @@ require (
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
+ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/text v0.3.7
google.golang.org/protobuf v1.28.0
gopkg.in/inf.v0 v0.9.1
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 735790411..76e0e9e13 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -845,7 +845,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
// Do not include if privileged - assumed that all devices will be
// included.
var err error
- hostConfig.Devices, err = c.GetDevices(*&hostConfig.Privileged, *ctrSpec, deviceNodes)
+ hostConfig.Devices, err = c.GetDevices(hostConfig.Privileged, *ctrSpec, deviceNodes)
if err != nil {
return nil, err
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index d409f7a04..9d0c8ff8c 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -401,6 +401,9 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(c.config.Spec)
// If network namespace was requested, add it now
@@ -1522,6 +1525,10 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO
func (c *Container) generateContainerSpec() error {
// Make sure the newly created config.json exists on disk
+
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(c.config.Spec)
if err := c.saveSpec(g.Config); err != nil {
diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go
index 51def1927..45b3a0e41 100644
--- a/libpod/healthcheck_linux.go
+++ b/libpod/healthcheck_linux.go
@@ -56,7 +56,7 @@ func (c *Container) startTimer() error {
return errors.Wrapf(err, "unable to get systemd connection to start healthchecks")
}
defer conn.Close()
- _, err = conn.StartUnit(fmt.Sprintf("%s.service", c.ID()), "fail", nil)
+ _, err = conn.StartUnitContext(context.Background(), fmt.Sprintf("%s.service", c.ID()), "fail", nil)
return err
}
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 4a0ef0b3a..4b1203dc3 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -210,7 +210,7 @@ func createBasicSlirp4netnsCmdArgs(options *slirp4netnsNetworkOptions, features
return cmdArgs, nil
}
-// setupSlirp4netns can be called in rootful as well as in rootless
+// setupSlirp4netns can be called in rootfull as well as in rootless
func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
path := r.config.Engine.NetworkCmdPath
if path == "" {
diff --git a/libpod/options.go b/libpod/options.go
index ffd0e6037..4e597201a 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -936,6 +936,9 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption {
if err := JSONDeepCopy(nsCtr.IDMappings(), &ctr.config.IDMappings); err != nil {
return err
}
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(ctr.config.Spec)
g.ClearLinuxUIDMappings()
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 7edd49fd1..a62c2b607 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -397,6 +397,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if ctr.restoreFromCheckpoint {
// Remove information about bind mount
// for new container from imported checkpoint
+
+ // NewFromSpec() is deprecated according to its comment
+ // however the recommended replace just causes a nil map panic
+ //nolint:staticcheck
g := generate.NewFromSpec(ctr.config.Spec)
g.RemoveMount("/dev/shm")
ctr.config.ShmDir = ""
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/README.md b/pkg/bindings/README.md
index ebc8a13d1..713adb104 100644
--- a/pkg/bindings/README.md
+++ b/pkg/bindings/README.md
@@ -9,7 +9,7 @@ The bindings require that the Podman system service is running for the specified
by calling the service directly.
### Starting the service with system
-The command to start the Podman service differs slightly depending on the user that is running the service. For a rootful service,
+The command to start the Podman service differs slightly depending on the user that is running the service. For a rootfull service,
start the service like this:
```
# systemctl start podman.socket
@@ -26,7 +26,7 @@ It can be handy to run the system service manually. Doing so allows you to enab
$ podman --log-level=debug system service -t0
```
If you do not provide a specific path for the socket, a default is provided. The location of that socket for
-rootful connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
+rootfull connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
information about the Podman system service, see `man podman-system-service`.
### Creating a connection
@@ -35,7 +35,7 @@ as they will be required to compile a Go program making use of the bindings.
The first step for using the bindings is to create a connection to the socket. As mentioned earlier, the destination
-of the socket depends on the user who owns it. In this case, a rootful connection is made.
+of the socket depends on the user who owns it. In this case, a rootfull connection is made.
```
import (
@@ -59,7 +59,7 @@ The `conn` variable returned from the `bindings.NewConnection` function can then
to interact with containers.
### Examples
-The following examples build upon the connection example from above. They are all rootful connections as well.
+The following examples build upon the connection example from above. They are all rootfull connections as well.
Note: Optional arguments to the bindings methods are set using With*() methods on *Option structures.
Composite types are not duplicated rather the address is used. As such, you should not change an underlying
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/images.go b/pkg/domain/infra/abi/images.go
index 74478b26d..43440b594 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -367,7 +367,7 @@ func (ir *ImageEngine) Transfer(ctx context.Context, source entities.ImageScpOpt
if rootless.IsRootless() && (len(dest.User) == 0 || dest.User == "root") { // if we are rootless and do not have a destination user we can just use sudo
return transferRootless(source, dest, podman, parentFlags)
}
- return transferRootful(source, dest, podman, parentFlags)
+ return transferRootfull(source, dest, podman, parentFlags)
}
func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
@@ -785,8 +785,8 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
return cmdLoad.Run()
}
-// TransferRootful creates new podman processes using exec.Command and a new uid/gid alongside a cleared environment
-func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
+// transferRootfull creates new podman processes using exec.Command and a new uid/gid alongside a cleared environment
+func transferRootfull(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
basicCommand := []string{podman}
basicCommand = append(basicCommand, parentFlags...)
saveCommand := append(basicCommand, "save")
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/config.go b/pkg/machine/config.go
index 6c2fab0e5..5dc5f6105 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -28,7 +28,7 @@ type InitOptions struct {
URI url.URL
Username string
ReExec bool
- Rootful bool
+ Rootfull bool
// The numerical userid of the user that called machine
UID string
}
@@ -95,7 +95,7 @@ type ListResponse struct {
}
type SetOptions struct {
- Rootful bool
+ Rootfull bool
}
type SSHOptions struct {
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/machine/qemu/config.go b/pkg/machine/qemu/config.go
index 4d4e3a6c1..6ab25b951 100644
--- a/pkg/machine/qemu/config.go
+++ b/pkg/machine/qemu/config.go
@@ -57,8 +57,8 @@ type MachineVMV1 struct {
QMPMonitor Monitorv1
// RemoteUsername of the vm user
RemoteUsername string
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
// UID is the numerical id of the user that called machine
UID int
}
@@ -99,8 +99,8 @@ type ImageConfig struct {
// HostUser describes the host user
type HostUser struct {
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
// UID is the numerical id of the user that called machine
UID int
}
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index a3dedeedb..4cfd4e8b0 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -204,7 +204,7 @@ func migrateVM(configPath string, config []byte, vm *MachineVM) error {
vm.QMPMonitor = qmpMonitor
vm.ReadySocket = readySocket
vm.RemoteUsername = old.RemoteUsername
- vm.Rootful = old.Rootful
+ vm.Rootfull = old.Rootfull
vm.UID = old.UID
// Backup the original config file
@@ -258,7 +258,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
)
sshDir := filepath.Join(homedir.Get(), ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
switch opts.ImagePath {
case Testing, Next, Stable, "":
@@ -356,8 +356,8 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
names := []string{v.Name, v.Name + "-root"}
// The first connection defined when connections is empty will become the default
- // regardless of IsDefault, so order according to rootful
- if opts.Rootful {
+ // regardless of IsDefault, so order according to rootfull
+ if opts.Rootfull {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -435,7 +435,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
}
func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
+ if v.Rootfull == opts.Rootfull {
return nil
}
@@ -459,7 +459,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootful {
+ if opts.Rootfull {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -467,7 +467,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
}
}
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
return v.writeConfig()
}
@@ -1117,7 +1117,7 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID)
forwardUser := "core"
- if v.Rootful {
+ if v.Rootfull {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
@@ -1323,11 +1323,11 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
}
waitAndPingAPI(forwardSock)
- if !v.Rootful {
+ if !v.Rootfull {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
}
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index dff7bfef9..dc3f33fa7 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -165,8 +165,8 @@ type MachineVM struct {
Port int
// RemoteUsername of the vm user
RemoteUsername string
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
}
type ExitCodeError struct {
@@ -232,7 +232,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
homeDir := homedir.Get()
sshDir := filepath.Join(homeDir, ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
if err := downloadDistro(v, opts); err != nil {
return false, err
@@ -316,8 +316,8 @@ func setupConnections(v *MachineVM, opts machine.InitOptions, sshDir string) err
names := []string{v.Name, v.Name + "-root"}
// The first connection defined when connections is empty will become the default
- // regardless of IsDefault, so order according to rootful
- if opts.Rootful {
+ // regardless of IsDefault, so order according to rootfull
+ if opts.Rootfull {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -733,7 +733,7 @@ func pipeCmdPassThrough(name string, input string, arg ...string) error {
}
func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
+ if v.Rootfull == opts.Rootfull {
return nil
}
@@ -744,7 +744,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootful {
+ if opts.Rootfull {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -752,7 +752,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
}
}
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
return v.writeConfig()
}
@@ -768,7 +768,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return errors.Wrap(err, "WSL bootstrap script failed")
}
- if !v.Rootful {
+ if !v.Rootfull {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
@@ -777,7 +777,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if name != machine.DefaultMachineName {
suffix = " " + name
}
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
}
globalName, pipeName, err := launchWinProxy(v)
@@ -833,7 +833,7 @@ func launchWinProxy(v *MachineVM) (bool, string, error) {
destSock := "/run/user/1000/podman/podman.sock"
forwardUser := v.RemoteUsername
- if v.Rootful {
+ if v.Rootfull {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
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/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/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index aa07de0af..95ce420f8 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -1,6 +1,7 @@
package specgenutil
import (
+ "encoding/csv"
"fmt"
"path/filepath"
"strings"
@@ -152,7 +153,15 @@ func findMountType(input string) (mountType string, tokens []string, err error)
// Split by comma, iterate over the slice and look for
// "type=$mountType". Everything else is appended to tokens.
found := false
- for _, s := range strings.Split(input, ",") {
+ csvReader := csv.NewReader(strings.NewReader(input))
+ records, err := csvReader.ReadAll()
+ if err != nil {
+ return "", nil, err
+ }
+ if len(records) != 1 {
+ return "", nil, errInvalidSyntax
+ }
+ for _, s := range records[0] {
kv := strings.Split(s, "=")
if found || !(len(kv) == 2 && kv[0] == "type") {
tokens = append(tokens, s)
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
diff --git a/rootless.md b/rootless.md
index 39c961d2a..d485290f2 100644
--- a/rootless.md
+++ b/rootless.md
@@ -18,7 +18,7 @@ can easily fail
* Some system unit configuration options do not work in the rootless container
* systemd fails to apply several options and failures are silently ignored (e.g. CPUShares, MemoryLimit). Should work on cgroup V2.
* Use of certain options will cause service startup failures (e.g. PrivateNetwork). The systemd services requiring `PrivateNetwork` can be made to work by passing `--cap-add SYS_ADMIN`, but the security implications should be carefully evaluated. In most cases, it's better to create an override.conf drop-in that sets `PrivateNetwork=no`. This also applies to containers run by root.
-* Can not share container images with CRI-O or other rootful users
+* Can not share container images with CRI-O or other rootfull users
* Difficult to use additional stores for sharing content
* Does not work on NFS or parallel filesystem homedirs (e.g. [GPFS](https://www.ibm.com/support/knowledgecenter/en/SSFKCN/gpfs_welcome.html))
* NFS and parallel filesystems enforce file creation on different UIDs on the server side and does not understand User Namespace.
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index 7b2dd89c9..2dc99bdc9 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -1061,7 +1061,7 @@ var _ = Describe("Podman checkpoint", func() {
// Open a network connection to the redis server via initial port mapping
// This should fail
- conn, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second)
+ _, err = net.DialTimeout("tcp4", fmt.Sprintf("localhost:%d", randomPort), time.Duration(3)*time.Second)
Expect(err).ToNot(BeNil())
Expect(err.Error()).To(ContainSubstring("connection refused"))
// Open a network connection to the redis server via new port mapping
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 2f4146bba..f808eb2b6 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -880,11 +880,11 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
func writeConf(conf []byte, confPath string) {
if _, err := os.Stat(filepath.Dir(confPath)); os.IsNotExist(err) {
- if err := os.MkdirAll(filepath.Dir(confPath), 777); err != nil {
+ if err := os.MkdirAll(filepath.Dir(confPath), 0o777); err != nil {
fmt.Println(err)
}
}
- if err := ioutil.WriteFile(confPath, conf, 777); err != nil {
+ if err := ioutil.WriteFile(confPath, conf, 0o777); err != nil {
fmt.Println(err)
}
}
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 3987746d0..4cfaa9a2e 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -123,7 +123,7 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec in keep-id container drops privileges", func() {
- SkipIfNotRootless("This function is not enabled for rootful podman")
+ SkipIfNotRootless("This function is not enabled for rootfull podman")
ctrName := "testctr1"
testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"})
testCtr.WaitWithDefaultTimeout()
diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go
index 77549a9a8..001779cdf 100644
--- a/test/e2e/login_logout_test.go
+++ b/test/e2e/login_logout_test.go
@@ -188,6 +188,8 @@ var _ = Describe("Podman login and logout", func() {
Expect(session).To(ExitWithError())
session = podmanTest.Podman([]string{"logout", "--authfile", authFile, server})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
})
It("podman login and logout with --tls-verify", func() {
diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go
index 30d7ce8a9..830c2dcda 100644
--- a/test/e2e/mount_rootless_test.go
+++ b/test/e2e/mount_rootless_test.go
@@ -17,7 +17,7 @@ var _ = Describe("Podman mount", func() {
)
BeforeEach(func() {
- SkipIfNotRootless("This function is not enabled for rootful podman")
+ SkipIfNotRootless("This function is not enabled for rootfull podman")
SkipIfRemote("Podman mount not supported for remote connections")
tempdir, err = CreateTempDirInTempDir()
if err != nil {
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index 89a9005f5..a7981a4d8 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -254,7 +254,7 @@ var _ = Describe("Podman network", func() {
expectedNetworks := []string{name}
if !rootless.IsRootless() {
- // rootful image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
+ // rootfull image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
expectedNetworks = append(expectedNetworks, "podman")
}
session := podmanTest.Podman(append([]string{"network", "inspect"}, expectedNetworks...))
diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go
index a8a98fc07..3b571ab20 100644
--- a/test/e2e/push_test.go
+++ b/test/e2e/push_test.go
@@ -220,6 +220,7 @@ var _ = Describe("Podman push", func() {
if setup.LineInOutputContains("Active: inactive") {
setup = SystemExec("systemctl", []string{"start", "docker"})
+ Expect(setup).Should(Exit(0))
defer func() {
stop := SystemExec("systemctl", []string{"stop", "docker"})
Expect(stop).Should(Exit(0))
diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go
index 5a046b0a4..092621c27 100644
--- a/test/e2e/run_userns_test.go
+++ b/test/e2e/run_userns_test.go
@@ -78,12 +78,18 @@ var _ = Describe("Podman UserNS support", func() {
It("podman --userns=keep-id", func() {
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-u"})
session.WaitWithDefaultTimeout()
+ if os.Geteuid() == 0 {
+ Expect(session).Should(Exit(125))
+ return
+ }
+
Expect(session).Should(Exit(0))
uid := fmt.Sprintf("%d", os.Geteuid())
Expect(session.OutputToString()).To(ContainSubstring(uid))
})
It("podman --userns=keep-id check passwd", func() {
+ SkipIfNotRootless("keep-id only works in rootless mode")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-un"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -93,6 +99,7 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman --userns=keep-id root owns /usr", func() {
+ SkipIfNotRootless("keep-id only works in rootless mode")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "stat", "-c%u", "/usr"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -100,6 +107,7 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman --userns=keep-id --user root:root", func() {
+ SkipIfNotRootless("keep-id only works in rootless mode")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "alpine", "id", "-u"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -107,10 +115,7 @@ var _ = Describe("Podman UserNS support", func() {
})
It("podman run --userns=keep-id can add users", func() {
- if os.Geteuid() == 0 {
- Skip("Test only runs without root")
- }
-
+ SkipIfNotRootless("keep-id only works in rootless mode")
userName := os.Getenv("USER")
if userName == "" {
Skip("Can't complete test if no username available")
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index 4887197f6..0be84e11b 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -120,6 +120,11 @@ var _ = Describe("Podman run with volumes", func() {
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
+ // test csv escaping
+ session = podmanTest.Podman([]string{"run", "--rm", "--mount=type=tmpfs,tmpfs-size=512M,\"destination=/test,\"", ALPINE, "ls", "/test,"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=bind,src=/tmp,target=/tmp,tmpcopyup", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
diff --git a/test/e2e/systemd_activate_test.go b/test/e2e/systemd_activate_test.go
index d5434868d..04acafe1b 100644
--- a/test/e2e/systemd_activate_test.go
+++ b/test/e2e/systemd_activate_test.go
@@ -97,7 +97,7 @@ var _ = Describe("Systemd activate", func() {
// Emulate 'systemd stop podman.service'
activateSession.Signal(syscall.SIGTERM)
- time.Sleep(2)
+ time.Sleep(100 * time.Millisecond)
Eventually(activateSession).Should(Exit(0))
abiSession := podman("inspect", "--format={{.State.Running}}", containerName)
diff --git a/test/e2e/toolbox_test.go b/test/e2e/toolbox_test.go
index b34fd299c..1fc28a06d 100644
--- a/test/e2e/toolbox_test.go
+++ b/test/e2e/toolbox_test.go
@@ -160,6 +160,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman create --userns=keep-id --user root:root - entrypoint - entrypoint is executed as root", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", ALPINE,
"id"})
session.WaitWithDefaultTimeout()
@@ -168,6 +169,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman create --userns=keep-id + podman exec - correct names of user and group", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
var err error
@@ -199,6 +201,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman create --userns=keep-id - entrypoint - adding user with useradd and then removing their password", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
var username string = "testuser"
@@ -238,6 +241,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman create --userns=keep-id + podman exec - adding group with groupadd", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
var groupName string = "testgroup"
@@ -268,6 +272,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman create --userns=keep-id - entrypoint - modifying existing user with usermod - add to new group, change home/shell/uid", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
var badHomeDir string = "/home/badtestuser"
var badShell string = "/bin/sh"
@@ -315,6 +320,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman run --privileged --userns=keep-id --user root:root - entrypoint - (bind)mounting", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE,
@@ -329,6 +335,7 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman create + start - with all needed switches for create - sleep as entry-point", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
// These should be most of the switches that Toolbox uses to create a "toolbox" container
@@ -365,8 +372,8 @@ var _ = Describe("Toolbox-specific testing", func() {
})
It("podman run --userns=keep-id check $HOME", func() {
+ SkipIfNotRootless("only meaningful when run rootless")
var session *PodmanSessionIntegration
-
currentUser, err := user.Current()
Expect(err).To(BeNil())
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 31db5f1c4..283c3aea9 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -272,9 +272,11 @@ echo $rand | 0 | $rand
# symptom only manifests on a fedora container image -- we have no
# reproducer on alpine. Checking directory ownership is good enough.
@test "podman run : user namespace preserved root ownership" {
+ keep="--userns=keep-id"
+ is_rootless || keep=""
for priv in "" "--privileged"; do
for user in "--user=0" "--user=100"; do
- for keepid in "" "--userns=keep-id"; do
+ for keepid in "" ${keep}; do
opts="$priv $user $keepid"
for dir in /etc /usr;do
@@ -289,6 +291,7 @@ echo $rand | 0 | $rand
# #6829 : add username to /etc/passwd inside container if --userns=keep-id
@test "podman run : add username to /etc/passwd if --userns=keep-id" {
+ skip_if_not_rootless "--userns=keep-id only works in rootless mode"
# Default: always run as root
run_podman run --rm $IMAGE id -un
is "$output" "root" "id -un on regular container"
@@ -339,6 +342,7 @@ echo $rand | 0 | $rand
# #6991 : /etc/passwd is modifiable
@test "podman run : --userns=keep-id: passwd file is modifiable" {
+ skip_if_not_rootless "--userns=keep-id only works in rootless mode"
run_podman run -d --userns=keep-id --cap-add=dac_override $IMAGE sh -c 'while ! test -e /tmp/stop; do sleep 0.1; done'
cid="$output"
@@ -827,6 +831,9 @@ EOF
# CVE-2022-1227 : podman top joins container mount NS and uses nsenter from image
@test "podman top does not use nsenter from image" {
+ keepid="--userns=keep-id"
+ is_rootless || keepid=""
+
tmpdir=$PODMAN_TMPDIR/build-test
mkdir -p $tmpdir
tmpbuilddir=$tmpdir/build
@@ -841,7 +848,7 @@ EOF
test_image="cve_2022_1227_test"
run_podman build -t $test_image $tmpbuilddir
- run_podman run -d --userns=keep-id $test_image top
+ run_podman run -d ${keepid} $test_image top
ctr="$output"
run_podman top $ctr huser,user
run_podman rm -f -t0 $ctr
diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats
index fe9292fd0..cfbeff3ae 100644
--- a/test/system/065-cp.bats
+++ b/test/system/065-cp.bats
@@ -119,7 +119,9 @@ load helpers
echo "content" > $srcdir/hostfile
userid=$(id -u)
- run_podman run --user=$userid --userns=keep-id -d --name cpcontainer $IMAGE sleep infinity
+ keepid="--userns=keep-id"
+ is_rootless || keepid=""
+ run_podman run --user=$userid ${keepid} -d --name cpcontainer $IMAGE sleep infinity
run_podman cp $srcdir/hostfile cpcontainer:/tmp/hostfile
run_podman exec cpcontainer stat -c "%u" /tmp/hostfile
is "$output" "$userid" "copied file is chowned to the container user"
@@ -138,7 +140,9 @@ load helpers
userid=$(id -u)
- run_podman run --user="$userid" --userns=keep-id -d --name cpcontainer $IMAGE sleep infinity
+ keepid="--userns=keep-id"
+ is_rootless || keepid=""
+ run_podman run --user=$userid ${keepid} -d --name cpcontainer $IMAGE sleep infinity
run_podman cp -a=false - cpcontainer:/tmp/ < "${tmpdir}/a.tar"
run_podman exec cpcontainer stat -c "%u:%g" /tmp/a.txt
is "$output" "1042:1043" "copied file retains uid/gid from the tar"
diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats
index 42954e5ec..0a6048b7e 100644
--- a/test/system/075-exec.bats
+++ b/test/system/075-exec.bats
@@ -87,6 +87,7 @@ load helpers
# #6829 : add username to /etc/passwd inside container if --userns=keep-id
@test "podman exec - with keep-id" {
+ skip_if_not_rootless "--userns=keep-id only works in rootless mode"
# Multiple --userns options confirm command-line override (last one wins)
run_podman run -d --userns=private --userns=keep-id $IMAGE sh -c \
"echo READY;while [ ! -f /tmp/stop ]; do sleep 1; done"
diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats
index 571d8767e..5b0460723 100644
--- a/test/system/160-volumes.bats
+++ b/test/system/160-volumes.bats
@@ -182,13 +182,14 @@ EOF
run_podman volume rm $myvol
- # Autocreated volumes should also work with keep-id
- # All we do here is check status; podman 1.9.1 would fail with EPERM
- myvol=myvol$(random_string)
- run_podman run --rm -v $myvol:/myvol:z --userns=keep-id $IMAGE \
+ if is_rootless; then
+ # Autocreated volumes should also work with keep-id
+ # All we do here is check status; podman 1.9.1 would fail with EPERM
+ myvol=myvol$(random_string)
+ run_podman run --rm -v $myvol:/myvol:z --userns=keep-id $IMAGE \
touch /myvol/myfile
-
- run_podman volume rm $myvol
+ run_podman volume rm $myvol
+ fi
}
diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats
index c020a73ab..d754306b2 100644
--- a/test/system/170-run-userns.bats
+++ b/test/system/170-run-userns.bats
@@ -94,3 +94,17 @@ EOF
is ${output} ${secret_content} "Secrets should work with user namespace"
run_podman secret rm ${test_name}
}
+
+@test "podman userns=nomap" {
+ skip_if_not_rootless "--userns=nomap only works in rootless mode"
+ ns_user=$(id -un)
+ baseuid=$(egrep "${ns_user}:" /etc/subuid | cut -f2 -d:)
+ test ! -z ${baseuid} || skip "no IDs allocated for user ${ns_user}"
+
+ test_name="test_$(random_string 12)"
+ run_podman run -d --userns=nomap $IMAGE sleep 100
+ cid=${output}
+ run_podman top ${cid} huser
+ is "${output}" "HUSER.*${baseuid}" "Container should start with baseuid from /etc/subuid not user UID"
+ run_podman rm -t 0 --force ${cid}
+}
diff --git a/test/system/270-socket-activation.bats b/test/system/270-socket-activation.bats
index 6d582be18..19f68abdd 100644
--- a/test/system/270-socket-activation.bats
+++ b/test/system/270-socket-activation.bats
@@ -90,7 +90,7 @@ function teardown() {
@test "podman system service - socket activation - kill rootless pause" {
if ! is_rootless; then
- skip "there is no pause process when running rootful"
+ skip "there is no pause process when running rootfull"
fi
run_podman run -d $IMAGE sleep 90
cid="$output"
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 880bf63ac..0c3062a7e 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -84,6 +84,7 @@ load helpers
# Issue #5466 - port-forwarding doesn't work with this option and -d
@test "podman networking: port with --userns=keep-id" {
+ skip_if_not_rootless "--userns=keep-id only works in rootless mode"
for cidr in "" "$(random_rfc1918_subnet).0/24"; do
myport=$(random_free_port 52000-52999)
if [[ -z $cidr ]]; then
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index b41be53bc..1a1dc0df9 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -483,7 +483,7 @@ function skip_if_root_ubuntu {
if is_ubuntu; then
if ! is_remote; then
if ! is_rootless; then
- skip "Cannot run this test on rootful ubuntu, usually due to user errors"
+ skip "Cannot run this test on rootfull ubuntu, usually due to user errors"
fi
fi
fi
diff --git a/test/utils/common_function_test.go b/test/utils/common_function_test.go
index 6323b44eb..a73d75490 100644
--- a/test/utils/common_function_test.go
+++ b/test/utils/common_function_test.go
@@ -110,9 +110,8 @@ var _ = Describe("Common functions test", func() {
Expect(err).To(BeNil(), "Failed to write JSON to file.")
read, err := os.Open("/tmp/testJSON")
- defer read.Close()
-
Expect(err).To(BeNil(), "Can not find the JSON file after we write it.")
+ defer read.Close()
bytes, _ := ioutil.ReadAll(read)
json.Unmarshal(bytes, compareData)
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 39a0ac875..9695835e5 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -439,10 +439,10 @@ func tagOutputToMap(imagesOutput []string) map[string]map[string]bool {
// GetHostDistributionInfo returns a struct with its distribution Name and version
func GetHostDistributionInfo() HostOS {
f, err := os.Open(OSReleasePath)
- defer f.Close()
if err != nil {
return HostOS{}
}
+ defer f.Close()
l := bufio.NewScanner(f)
host := HostOS{}
diff --git a/test/version/main.go b/test/version/main.go
index 8f2904405..2a68aa5fc 100644
--- a/test/version/main.go
+++ b/test/version/main.go
@@ -7,5 +7,5 @@ import (
)
func main() {
- fmt.Printf(version.Version.String())
+ fmt.Print(version.Version.String())
}
diff --git a/utils/utils_supported.go b/utils/utils_supported.go
index ab2de2ce1..493ea61ce 100644
--- a/utils/utils_supported.go
+++ b/utils/utils_supported.go
@@ -6,6 +6,7 @@ package utils
import (
"bufio"
"bytes"
+ "context"
"fmt"
"io/ioutil"
"os"
@@ -32,7 +33,7 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error {
return err
}
} else {
- conn, err = systemdDbus.New()
+ conn, err = systemdDbus.NewWithContext(context.Background())
if err != nil {
return err
}
@@ -43,10 +44,10 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error {
properties = append(properties, newProp("Delegate", true))
properties = append(properties, newProp("DefaultDependencies", false))
ch := make(chan string)
- _, err = conn.StartTransientUnit(unitName, "replace", properties, ch)
+ _, err = conn.StartTransientUnitContext(context.Background(), unitName, "replace", properties, ch)
if err != nil {
// On errors check if the cgroup already exists, if it does move the process there
- if props, err := conn.GetUnitTypeProperties(unitName, "Scope"); err == nil {
+ if props, err := conn.GetUnitTypePropertiesContext(context.Background(), unitName, "Scope"); err == nil {
if cgroup, ok := props["ControlGroup"].(string); ok && cgroup != "" {
if err := moveUnderCgroup(cgroup, "", []uint32{uint32(pid)}); err == nil {
return nil
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
deleted file mode 100644
index a4d1919a9..000000000
--- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Deprecated: this package moved to golang.org/x/term.
-package terminal
-
-import (
- "io"
-
- "golang.org/x/term"
-)
-
-// EscapeCodes contains escape sequences that can be written to the terminal in
-// order to achieve different styles of text.
-type EscapeCodes = term.EscapeCodes
-
-// Terminal contains the state for running a VT100 terminal that is capable of
-// reading lines of input.
-type Terminal = term.Terminal
-
-// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
-// a local terminal, that terminal must first have been put into raw mode.
-// prompt is a string that is written at the start of each input line (i.e.
-// "> ").
-func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
- return term.NewTerminal(c, prompt)
-}
-
-// ErrPasteIndicator may be returned from ReadLine as the error, in addition
-// to valid line data. It indicates that bracketed paste mode is enabled and
-// that the returned line consists only of pasted data. Programs may wish to
-// interpret pasted data more literally than typed data.
-var ErrPasteIndicator = term.ErrPasteIndicator
-
-// State contains the state of a terminal.
-type State = term.State
-
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
- return term.IsTerminal(fd)
-}
-
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
- return term.ReadPassword(fd)
-}
-
-// MakeRaw puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
- return term.MakeRaw(fd)
-}
-
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, oldState *State) error {
- return term.Restore(fd, oldState)
-}
-
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
- return term.GetState(fd)
-}
-
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
- return term.GetSize(fd)
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f86a8bc26..137975ced 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -719,7 +719,6 @@ golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
golang.org/x/crypto/ssh/knownhosts
-golang.org/x/crypto/ssh/terminal
# golang.org/x/net v0.0.0-20220225172249-27dd8689420f
golang.org/x/net/context
golang.org/x/net/html
@@ -745,6 +744,7 @@ golang.org/x/sys/unix
golang.org/x/sys/windows
golang.org/x/sys/windows/registry
# golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
+## explicit
golang.org/x/term
# golang.org/x/text v0.3.7
## explicit