summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.golangci.yml1
-rw-r--r--Makefile2
-rw-r--r--cmd/podman/common/create_opts.go2
-rw-r--r--cmd/podman/containers/create.go19
-rw-r--r--cmd/podman/containers/ps.go5
-rw-r--r--cmd/podman/containers/run.go2
-rw-r--r--cmd/podman/machine/init.go17
-rw-r--r--cmd/podman/machine/set.go7
-rw-r--r--cmd/podman/root.go4
-rw-r--r--cmd/podman/system/connection/add.go4
-rwxr-xr-xcontrib/cirrus/logformatter2
-rwxr-xr-xcontrib/cirrus/setup_environment.sh2
-rw-r--r--contrib/podmanimage/README.md2
-rw-r--r--contrib/remote/containers.conf2
-rw-r--r--docs/source/markdown/podman-build.1.md6
-rw-r--r--docs/source/markdown/podman-create.1.md8
-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-network-reload.1.md2
-rw-r--r--docs/source/markdown/podman-play-kube.1.md4
-rw-r--r--docs/source/markdown/podman-pod-create.1.md4
-rw-r--r--docs/source/markdown/podman-pull.1.md2
-rw-r--r--docs/source/markdown/podman-run.1.md8
-rw-r--r--docs/source/markdown/podman-system-service.1.md2
-rw-r--r--docs/source/markdown/podman.1.md4
-rw-r--r--docs/tutorials/basic_networking.md20
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rwxr-xr-xhack/golangci-lint.sh4
-rw-r--r--libpod/container_api.go6
-rw-r--r--libpod/container_copy_linux.go13
-rw-r--r--libpod/container_internal_linux.go32
-rw-r--r--libpod/container_internal_linux_test.go8
-rw-r--r--libpod/container_stat_linux.go13
-rw-r--r--libpod/kube.go4
-rw-r--r--libpod/networking_linux.go43
-rw-r--r--libpod/networking_linux_test.go11
-rw-r--r--libpod/networking_machine.go5
-rw-r--r--libpod/networking_slirp4netns.go2
-rw-r--r--libpod/oci_conmon_exec_linux.go2
-rw-r--r--libpod/oci_conmon_linux.go4
-rw-r--r--libpod/runtime.go12
-rw-r--r--libpod/runtime_ctr.go2
-rw-r--r--libpod/runtime_migrate.go3
-rw-r--r--libpod/runtime_volume_linux.go4
-rw-r--r--pkg/api/handlers/compat/images_build.go6
-rw-r--r--pkg/autoupdate/autoupdate.go4
-rw-r--r--pkg/bindings/README.md8
-rw-r--r--pkg/bindings/images/build.go13
-rw-r--r--pkg/domain/infra/abi/images.go6
-rw-r--r--pkg/domain/infra/abi/play.go4
-rw-r--r--pkg/domain/infra/runtime_libpod.go4
-rw-r--r--pkg/machine/config.go4
-rw-r--r--pkg/machine/e2e/basic_test.go50
-rw-r--r--pkg/machine/e2e/config.go174
-rw-r--r--pkg/machine/e2e/config_basic.go19
-rw-r--r--pkg/machine/e2e/config_init.go101
-rw-r--r--pkg/machine/e2e/config_inspect.go24
-rw-r--r--pkg/machine/e2e/config_list.go45
-rw-r--r--pkg/machine/e2e/config_rm.go56
-rw-r--r--pkg/machine/e2e/config_ssh.go33
-rw-r--r--pkg/machine/e2e/config_start.go16
-rw-r--r--pkg/machine/e2e/config_stop.go16
-rw-r--r--pkg/machine/e2e/init_test.go77
-rw-r--r--pkg/machine/e2e/inspect_test.go67
-rw-r--r--pkg/machine/e2e/list_test.go79
-rw-r--r--pkg/machine/e2e/machine_test.go129
-rw-r--r--pkg/machine/e2e/rm_test.go67
-rw-r--r--pkg/machine/e2e/ssh_test.go59
-rw-r--r--pkg/machine/e2e/start_test.go36
-rw-r--r--pkg/machine/e2e/stop_test.go46
-rw-r--r--pkg/machine/fcos.go14
-rw-r--r--pkg/machine/ignition.go20
-rw-r--r--pkg/machine/qemu/config.go8
-rw-r--r--pkg/machine/qemu/machine.go62
-rw-r--r--pkg/machine/wsl/machine.go26
-rw-r--r--pkg/signal/signal_common_test.go120
-rw-r--r--pkg/specgen/generate/container_create.go8
-rw-r--r--pkg/specgen/generate/namespaces.go7
-rw-r--r--pkg/specgen/generate/oci.go12
-rw-r--r--pkg/specgen/generate/pod_create.go6
-rw-r--r--pkg/specgen/generate/ports.go3
-rw-r--r--pkg/specgen/volumes.go27
-rw-r--r--pkg/specgen/winpath.go59
-rw-r--r--pkg/specgen/winpath_linux.go24
-rw-r--r--pkg/specgen/winpath_unsupported.go20
-rw-r--r--pkg/specgen/winpath_windows.go30
-rw-r--r--pkg/specgenutil/ports_test.go57
-rw-r--r--pkg/specgenutil/specgen.go4
-rw-r--r--pkg/specgenutil/specgenutil_test.go77
-rw-r--r--pkg/specgenutil/util.go1
-rw-r--r--pkg/specgenutil/util_test.go146
-rw-r--r--pkg/specgenutil/volumes.go21
-rw-r--r--pkg/specgenutil/volumes_test.go68
-rw-r--r--rootless.md2
-rw-r--r--test/e2e/common_test.go9
-rw-r--r--test/e2e/exec_test.go2
-rw-r--r--test/e2e/generate_kube_test.go2
-rw-r--r--test/e2e/mount_rootless_test.go2
-rw-r--r--test/e2e/network_test.go2
-rw-r--r--test/e2e/play_kube_test.go4
-rw-r--r--test/e2e/pod_infra_container_test.go6
-rw-r--r--test/e2e/run_aardvark_test.go30
-rw-r--r--test/e2e/run_staticip_test.go29
-rw-r--r--test/system/005-info.bats8
-rw-r--r--test/system/270-socket-activation.bats2
-rw-r--r--test/system/500-networking.bats2
-rw-r--r--test/system/helpers.bash4
-rw-r--r--test/testvol/main.go9
-rw-r--r--vendor/github.com/containers/common/libnetwork/etchosts/ip.go5
-rw-r--r--vendor/github.com/containers/common/libnetwork/netavark/network.go2
-rw-r--r--vendor/github.com/containers/common/libnetwork/network/interface.go3
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config_freebsd.go25
-rw-r--r--vendor/github.com/containers/common/pkg/config/containers.conf10
-rw-r--r--vendor/github.com/containers/common/pkg/machine/machine.go70
-rw-r--r--vendor/modules.txt3
118 files changed, 2192 insertions, 337 deletions
diff --git a/.golangci.yml b/.golangci.yml
index 4d60bc848..a3c9c4a8b 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -34,7 +34,6 @@ linters:
- ifshort
- forbidigo
- exhaustive
- - unparam
- gofumpt
- gci
- godot
diff --git a/Makefile b/Makefile
index 982d7b1e5..c14e58f66 100644
--- a/Makefile
+++ b/Makefile
@@ -537,7 +537,7 @@ localunit: test/goecho/goecho test/version/version
UNIT=1 $(GOBIN)/ginkgo \
-r \
$(TESTFLAGS) \
- --skipPackage test/e2e,pkg/apparmor,pkg/bindings,hack \
+ --skipPackage test/e2e,pkg/apparmor,pkg/bindings,hack,pkg/machine/e2e \
--cover \
--covermode atomic \
--coverprofile coverprofile \
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 7b7626040..16f193b03 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -347,7 +347,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
cliOpts.Volume = append(cliOpts.Volume, vol)
// Extract the destination so we don't add duplicate mounts in
// the volumes phase.
- splitVol := strings.SplitN(vol, ":", 3)
+ splitVol := specgen.SplitVolumeString(vol)
switch len(splitVol) {
case 1:
volDestinations[vol] = true
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index b202e404f..29e138e30 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -142,7 +142,7 @@ func create(cmd *cobra.Command, args []string) error {
}
s.RawImageName = rawImageName
- if _, err := createPodIfNecessary(cmd, s, cliVals.Net); err != nil {
+ if err := createPodIfNecessary(cmd, s, cliVals.Net); err != nil {
return err
}
@@ -345,13 +345,13 @@ func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (strin
// createPodIfNecessary automatically creates a pod when requested. if the pod name
// has the form new:ID, the pod ID is created and the name in the spec generator is replaced
// with ID.
-func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts *entities.NetOptions) (*entities.PodCreateReport, error) {
+func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts *entities.NetOptions) error {
if !strings.HasPrefix(s.Pod, "new:") {
- return nil, nil
+ return nil
}
podName := strings.Replace(s.Pod, "new:", "", 1)
if len(podName) < 1 {
- return nil, errors.Errorf("new pod name must be at least one character")
+ return errors.Errorf("new pod name must be at least one character")
}
var err error
@@ -359,7 +359,7 @@ func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts
if cliVals.UserNS != "" {
uns, err = specgen.ParseNamespace(cliVals.UserNS)
if err != nil {
- return nil, err
+ return err
}
}
createOptions := entities.PodCreateOptions{
@@ -383,7 +383,7 @@ func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts
podSpec.PodSpecGen = *podGen
podGen, err = entities.ToPodSpecGen(podSpec.PodSpecGen, &createOptions)
if err != nil {
- return nil, err
+ return err
}
infraOpts := entities.NewInfraContainerCreateOptions()
@@ -391,14 +391,15 @@ func createPodIfNecessary(cmd *cobra.Command, s *specgen.SpecGenerator, netOpts
infraOpts.Quiet = true
infraOpts.Hostname, err = cmd.Flags().GetString("hostname")
if err != nil {
- return nil, err
+ return err
}
podGen.InfraContainerSpec = specgen.NewSpecGenerator("", false)
podGen.InfraContainerSpec.NetworkOptions = podGen.NetworkOptions
err = specgenutil.FillOutSpecGen(podGen.InfraContainerSpec, &infraOpts, []string{})
if err != nil {
- return nil, err
+ return err
}
podSpec.PodSpecGen = *podGen
- return registry.ContainerEngine().PodCreate(context.Background(), podSpec)
+ _, err = registry.ContainerEngine().PodCreate(context.Background(), podSpec)
+ return err
}
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go
index 91bb9bdb7..4adae30c2 100644
--- a/cmd/podman/containers/ps.go
+++ b/cmd/podman/containers/ps.go
@@ -363,6 +363,11 @@ func (l psReporter) State() string {
state = fmt.Sprintf("Exited (%d) %s ago", l.ExitCode, t)
default:
// Need to capitalize the first letter to match Docker.
+
+ // strings.Title is deprecated since go 1.18
+ // However for our use case it is still fine. The recommended replacement
+ // is adding about 400kb binary size so lets keep using this for now.
+ //nolint:staticcheck
state = strings.Title(l.ListContainer.State)
}
return state
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 4ad8d3183..951981293 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -197,7 +197,7 @@ func run(cmd *cobra.Command, args []string) error {
s.Passwd = &runOpts.Passwd
runOpts.Spec = s
- if _, err := createPodIfNecessary(cmd, s, cliVals.Net); err != nil {
+ if err := createPodIfNecessary(cmd, s, cliVals.Net); err != nil {
return err
}
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
index 06c1f7248..4991c6aa3 100644
--- a/cmd/podman/machine/init.go
+++ b/cmd/podman/machine/init.go
@@ -12,7 +12,6 @@ import (
"github.com/containers/podman/v4/pkg/machine"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
)
var (
@@ -107,18 +106,8 @@ func init() {
flags.StringVar(&initOpts.IgnitionPath, IgnitionPathFlagName, "", "Path to ignition file")
_ = initCmd.RegisterFlagCompletionFunc(IgnitionPathFlagName, completion.AutocompleteDefault)
- 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)
+ rootfulFlagName := "rootful"
+ flags.BoolVar(&initOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
}
// TODO should we allow for a users to append to the qemu cmdline?
@@ -146,7 +135,6 @@ func initMachine(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
-
if finished, err := vm.Init(initOpts); err != nil || !finished {
// Finished = true, err = nil - Success! Log a message with further instructions
// Finished = false, err = nil - The installation is partially complete and podman should
@@ -155,7 +143,6 @@ func initMachine(cmd *cobra.Command, args []string) error {
// - a user has chosen to perform their own reboot
// - reexec for limited admin operations, returning to parent
// Finished = *, err != nil - Exit with an error message
-
return err
}
fmt.Println("Machine init complete")
diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go
index b1dfb51da..4c15f1de1 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 --rootfull=false`,
+ Example: `podman machine set --rootful=false`,
ValidArgsFunction: completion.AutocompleteNone,
}
)
@@ -33,9 +33,8 @@ func init() {
})
flags := setCmd.Flags()
- rootfullFlagName := "rootfull"
- flags.BoolVar(&setOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
- flags.SetNormalizeFunc(aliasFlags)
+ rootfulFlagName := "rootful"
+ flags.BoolVar(&setOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
}
func setMachine(cmd *cobra.Command, args []string) error {
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 500a475bd..9b1aa778b 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -429,6 +429,10 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
pFlags.BoolVar(&opts.Trace, "trace", false, "Enable opentracing output (default false)")
+ volumePathFlagName := "volumepath"
+ pFlags.StringVar(&opts.Engine.VolumePath, volumePathFlagName, "", "Path to the volume directory in which volume data is stored")
+ _ = cmd.RegisterFlagCompletionFunc(volumePathFlagName, completion.AutocompleteDefault)
+
// Hide these flags for both ABI and Tunneling
for _, f := range []string{
"cpu-profile",
diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go
index db575a689..387de3c58 100644
--- a/cmd/podman/system/connection/add.go
+++ b/cmd/podman/system/connection/add.go
@@ -112,7 +112,7 @@ func add(cmd *cobra.Command, args []string) error {
iden = cOpts.Identity
}
if uri.Path == "" || uri.Path == "/" {
- if uri.Path, err = getUDS(cmd, uri, iden); err != nil {
+ if uri.Path, err = getUDS(uri, iden); err != nil {
return err
}
}
@@ -204,7 +204,7 @@ func GetUserInfo(uri *url.URL) (*url.Userinfo, error) {
return url.User(usr.Username), nil
}
-func getUDS(cmd *cobra.Command, uri *url.URL, iden string) (string, error) {
+func getUDS(uri *url.URL, iden string) (string, error) {
cfg, err := ValidateAndConfigure(uri, iden)
if err != nil {
return "", errors.Wrapf(err, "failed to validate")
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 05f05dc0b..e45f03df9 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -207,7 +207,7 @@ END_HTML
print { $out_fh } "<pre> <!-- begin processed output -->\n";
- # Assume rootfull prompt, check for rootless (here and in log itself, below)
+ # Assume rootful prompt, check for rootless (here and in log itself, below)
my $Prompt = '#';
$Prompt = '$' if $test_name =~ /rootless/;
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index a7d0f7fa1..742289733 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -268,7 +268,7 @@ case "$TEST_FLAVOR" in
;;
docker-py)
remove_packaged_podman_files
- make install PREFIX=/usr ETCDIR=/etc
+ make && make install PREFIX=/usr ETCDIR=/etc
msg "Installing previously downloaded/cached packages"
dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm
diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md
index 58c14be72..4f184ca28 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 rootfull 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 rootful 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 45f58171a..9b0b62c42 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 rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
+# remote rootful 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 406dfcd89..bd1e673b8 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 rootfull 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 rootful users.
#### **--no-cache**
@@ -685,7 +685,7 @@ suitable group name to use as the default setting for this option.
**NOTE:** When this option is specified by a rootless user, the specified
mappings are relative to the rootless user namespace in the container, rather
-than being relative to the host as it would be when run rootfull.
+than being relative to the host as it would be when run rootful.
#### **--userns-uid-map**=*mapping*
@@ -721,7 +721,7 @@ suitable user name to use as the default setting for this option.
**NOTE:** When this option is specified by a rootless user, the specified
mappings are relative to the rootless user namespace in the container, rather
-than being relative to the host as it would be when run rootfull.
+than being relative to the host as it would be when run rootful.
#### **--uts**=*how*
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 15ae28dc3..c63e8814b 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -704,7 +704,7 @@ Set the network mode for the container. Invalid if using **--dns**, **--dns-opt*
Valid _mode_ values are:
-- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootfull containers. It is possible to specify these additional options:
+- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options:
- **alias=name**: Add network-scoped alias for the container.
- **ip=IPv4**: Specify a static ipv4 address for this container.
- **ip=IPv6**: Specify a static ipv6 address for this container.
@@ -717,7 +717,7 @@ Valid _mode_ values are:
- **container:**_id_: Reuse another container's network stack.
- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the 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. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
+- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones.
- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
@@ -1118,8 +1118,8 @@ option conflicts with the **--userns** and **--subuidname** options. This
option provides a way to map host UIDs to container UIDs. It can be passed
several times to map different ranges.
-The _from_uid_ value is based upon the user running the command, either rootfull or rootless users.
-* rootfull user: *container_uid*:*host_uid*:*amount*
+The _from_uid_ value is based upon the user running the command, either rootful or rootless users.
+* rootful user: *container_uid*:*host_uid*:*amount*
* rootless user: *container_uid*:*intermediate_uid*:*amount*
When **podman create** is called by a privileged user, the option **--uidmap**
diff --git a/docs/source/markdown/podman-image-scp.1.md b/docs/source/markdown/podman-image-scp.1.md
index 6d5a51298..1d902da91 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 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.
+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.
**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 e42c5025b..33947bbba 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.
-#### **--rootfull**=*true|false*
+#### **--rootful**=*true|false*
-Whether this machine should prefer rootfull (`true`) or rootless (`false`)
+Whether this machine should prefer rootful (`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 --rootfull
+$ podman machine init --rootful
$ 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 e69a7dc14..a4918eacf 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.
-#### **--rootfull**=*true|false*
+#### **--rootful**=*true|false*
-Whether this machine should prefer rootfull (`true`) or rootless (`false`)
+Whether this machine should prefer rootful (`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 rootfull/rootless
+this option will also make the API socket, if available, forward to the rootful/rootless
socket in the VM.
## EXAMPLES
-To switch the default VM `podman-machine-default` from rootless to rootfull:
+To switch the default VM `podman-machine-default` from rootless to rootful:
```
-$ podman machine set --rootfull
+$ podman machine set --rootful
```
or more explicitly:
```
-$ podman machine set --rootfull=true
+$ podman machine set --rootful=true
```
-To switch the default VM `podman-machine-default` from rootfull to rootless:
+To switch the default VM `podman-machine-default` from rootful to rootless:
```
-$ podman machine set --rootfull=false
+$ podman machine set --rootful=false
```
-To switch the VM `myvm` from rootless to rootfull:
+To switch the VM `myvm` from rootless to rootful:
```
-$ podman machine set --rootfull myvm
+$ podman machine set --rootful myvm
```
## SEE ALSO
diff --git a/docs/source/markdown/podman-network-reload.1.md b/docs/source/markdown/podman-network-reload.1.md
index 5cbe9b9bf..31d10829e 100644
--- a/docs/source/markdown/podman-network-reload.1.md
+++ b/docs/source/markdown/podman-network-reload.1.md
@@ -9,7 +9,7 @@ podman\-network\-reload - Reload network configuration for containers
## DESCRIPTION
Reload one or more container network configurations.
-Rootfull Podman relies on iptables rules in order to provide network connectivity. If the iptables rules are deleted,
+Rootful Podman relies on iptables rules in order to provide network connectivity. If the iptables rules are deleted,
this happens for example with `firewall-cmd --reload`, the container loses network connectivity. This command restores
the network connectivity.
diff --git a/docs/source/markdown/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md
index 8b56d109a..8ed71b734 100644
--- a/docs/source/markdown/podman-play-kube.1.md
+++ b/docs/source/markdown/podman-play-kube.1.md
@@ -188,7 +188,7 @@ Note: When joining multiple networks you should use the **--network name:mac=\<m
Change the network mode of the pod. The host network mode should be configured in the YAML file.
Valid _mode_ values are:
-- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootfull containers. It is possible to specify these additional options:
+- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options:
- **alias=name**: Add network-scoped alias for the container.
- **ip=IPv4**: Specify a static ipv4 address for this container.
- **ip=IPv6**: Specify a static ipv6 address for this container.
@@ -200,7 +200,7 @@ Valid _mode_ values are:
- **none**: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity.
- **container:**_id_: Reuse another container's network stack.
- **ns:**_path_: Path to a network namespace to join.
-- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
+- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones.
- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 403a317ea..714909b98 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -156,7 +156,7 @@ Set the network mode for the pod. Invalid if using **--dns**, **--dns-opt**, or
Valid _mode_ values are:
-- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootfull containers. It is possible to specify these additional options:
+- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options:
- **alias=name**: Add network-scoped alias for the container.
- **ip=IPv4**: Specify a static ipv4 address for this container.
- **ip=IPv6**: Specify a static ipv6 address for this container.
@@ -169,7 +169,7 @@ Valid _mode_ values are:
- **container:**_id_: Reuse another container's network stack.
- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the 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. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
+- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones.
- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md
index 00a86aa71..928bbc6fe 100644
--- a/docs/source/markdown/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -117,7 +117,7 @@ Using short names is subject to the risk of hitting squatted registry namespaces
While it is highly recommended to always use fully-qualified image references, existing deployments using short names may not be easily changed. To circumvent the aforementioned ambiguity, so called short-name aliases can be configured that point to a fully-qualified image reference. Distributions often ship a default shortnames.conf expansion file in /etc/containers/registries.conf.d/ directory. Administrators can use this directory to add their own local short-name expansion files.
When pulling an image, if the user does not specify the complete registry, container engines attempt to expand the short-name into a full name. If the command is executed with a tty, the user will be prompted to select a registry from the
-default list unqualified registries defined in registries.conf. The user's selection is then stored in a cache file to be used in all future short-name expansions. Rootfull short-names are stored in /var/cache/containers/short-name-aliases.conf. Rootless short-names are stored in the $HOME/.cache/containers/short-name-aliases.conf file.
+default list unqualified registries defined in registries.conf. The user's selection is then stored in a cache file to be used in all future short-name expansions. Rootful short-names are stored in /var/cache/containers/short-name-aliases.conf. Rootless short-names are stored in the $HOME/.cache/containers/short-name-aliases.conf file.
For more information on short-names, see `containers-registries.conf(5)`
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 578acf379..9d9394020 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -730,7 +730,7 @@ Set the network mode for the container. Invalid if using **--dns**, **--dns-opt*
Valid _mode_ values are:
-- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootfull containers. It is possible to specify these additional options:
+- **bridge[:OPTIONS,...]**: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options:
- **alias=name**: Add network-scoped alias for the container.
- **ip=IPv4**: Specify a static ipv4 address for this container.
- **ip=IPv6**: Specify a static ipv6 address for this container.
@@ -743,7 +743,7 @@ Valid _mode_ values are:
- **container:**_id_: Reuse another container's network stack.
- **host**: Do not create a network namespace, the container will use the host's network. Note: The host mode gives the 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. This will use the **bridge** mode for rootfull containers and **slirp4netns** for rootless ones.
+- **private**: Create a new namespace for the container. This will use the **bridge** mode for rootful containers and **slirp4netns** for rootless ones.
- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf:
- **allow_host_loopback=true|false**: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). Default is false.
- **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`).
@@ -1185,8 +1185,8 @@ option conflicts with the **--userns** and **--subuidname** options. This
option provides a way to map host UIDs to container UIDs. It can be passed
several times to map different ranges.
-The _from_uid_ value is based upon the user running the command, either rootfull or rootless users.
-* rootfull user: *container_uid*:*host_uid*:*amount*
+The _from_uid_ value is based upon the user running the command, either rootful or rootless users.
+* rootful user: *container_uid*:*host_uid*:*amount*
* rootless user: *container_uid*:*intermediate_uid*:*amount*
When **podman run** is called by a privileged user, the option **--uidmap**
diff --git a/docs/source/markdown/podman-system-service.1.md b/docs/source/markdown/podman-system-service.1.md
index 678f08a20..176d73eda 100644
--- a/docs/source/markdown/podman-system-service.1.md
+++ b/docs/source/markdown/podman-system-service.1.md
@@ -9,7 +9,7 @@ podman\-system\-service - Run an API service
## DESCRIPTION
The **podman system service** command creates a listening service that will answer API calls for Podman. You may
optionally provide an endpoint for the API in URI form. For example, *unix:///tmp/foobar.sock* or *tcp:localhost:8080*.
-If no endpoint is provided, defaults will be used. The default endpoint for a rootfull
+If no endpoint is provided, defaults will be used. The default endpoint for a rootful
service is *unix:///run/podman/podman.sock* and rootless is *unix://$XDG_RUNTIME_DIR/podman/podman.sock* (for
example *unix:///run/user/1000/podman/podman.sock*)
diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md
index aad12c584..3d1578ea1 100644
--- a/docs/source/markdown/podman.1.md
+++ b/docs/source/markdown/podman.1.md
@@ -193,6 +193,10 @@ Some example URL values in valid formats:
Print the version
+#### **--volumepath**=*value*
+
+Volume directory where builtin volume information is stored (default: "/var/lib/containers/storage/volumes" for UID 0, "$HOME/.local/share/containers/storage/volumes" for other users). Default volume path can be overridden in `containers.conf`.
+
## Environment Variables
Podman can set up environment variables from env of [engine] table in containers.conf. These variables can be overridden by passing environment variables before the `podman` commands.
diff --git a/docs/tutorials/basic_networking.md b/docs/tutorials/basic_networking.md
index e341df531..396994596 100644
--- a/docs/tutorials/basic_networking.md
+++ b/docs/tutorials/basic_networking.md
@@ -7,15 +7,15 @@
It seems once people master the basics of containers, networking is one of the first
aspects they begin experimenting with. And regarding networking, it takes very
little experimentation before ending up on the deep end of the pool. The following
-guide shows the most common network setups for Podman rootfull and rootless containers.
+guide shows the most common network setups for Podman rootful and rootless containers.
Each setup is supported with an example.
-## Differences between rootfull and rootless container networking
+## Differences between rootful and rootless container networking
One of the guiding factors on networking for containers with Podman is going to be
whether or not the container is run by a root user or not. This is because unprivileged
-users cannot create networking interfaces on the host. Therefore, with rootfull
+users cannot create networking interfaces on the host. Therefore, with rootful
containers, the default networking mode is to use netavark.
For rootless, the default network
mode is slirp4netns. Because of the limited privileges, slirp4netns lacks some of
@@ -32,13 +32,13 @@ ports being opened automatically due to running a container with a port mapping
example). If container traffic does not seem to work properly, check the firewall
and allow traffic on ports the container is using. A common problem is that
reloading the firewall deletes the cni iptables rules resulting in a loss of
-network connectivity for rootfull containers. Podman v3 provides the podman
+network connectivity for rootful containers. Podman v3 provides the podman
network reload command to restore this without having to restart the container.
## Basic Network Setups
Most containers and pods being run with Podman adhere to a couple of simple scenarios.
-By default, rootfull Podman will create a bridged network. This is the most straightforward
+By default, rootful Podman will create a bridged network. This is the most straightforward
and preferred network setup for Podman. Bridge networking creates an interface for
the container on an internal bridge network, which is then connected to the internet
via Network Address Translation(NAT). We also see users wanting to use `macvlan`
@@ -79,7 +79,7 @@ command. Containers can be joined to a network when they are created with the
As mentioned earlier, slirp4netns is the default network configuration for rootless
users. But as of Podman version 4.0, rootless users can also use netavark.
-The user experience of rootless netavark is very akin to a rootfull netavark, except that
+The user experience of rootless netavark is very akin to a rootful netavark, except that
there is no default network configuration provided. You simply need to create a
network, and the one will be created as a bridge network. If you would like to switch from
CNI networking to netvaark, you must issue the `podman system reset --force` command.
@@ -95,17 +95,17 @@ will be executed inside an extra network namespace. To join this namespace, use
#### Example
-By default, rootfull containers use the netavark for its default network if
+By default, rootful containers use the netavark for its default network if
you have not migrated from Podman v3.
In this case, no network name must be passed to Podman. However, you can create
additional bridged networks with the podman create command.
The following example shows how to set up a web server and expose it to the network
-outside the host as both rootfull and rootless. It will also show how an outside
+outside the host as both rootful and rootless. It will also show how an outside
client can connect to the container.
```
-(rootfull) $ sudo podman run -dt --name webserver -p 8080:80 quay.io/libpod/banner
+(rootful) $ sudo podman run -dt --name webserver -p 8080:80 quay.io/libpod/banner
00f3440c7576aae2d5b193c40513c29c7964e96bf797cf0cc352c2b68ccbe66a
```
@@ -120,7 +120,7 @@ how the host and container ports can be mapped for external access. The port co
very well have been 80 as well (except for rootless users).
To connect from an outside client to the webserver, simply point an HTTP client to
-the host’s IP address at port 8080 for rootfull and port 8081 for rootless.
+the host’s IP address at port 8080 for rootful and port 8081 for rootless.
```
(outside_host): $ curl 192.168.99.109:8080
___ __
diff --git a/go.mod b/go.mod
index 4fb9de397..f7f4d12a7 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.1.1
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057
- github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb
+ github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.21.1-0.20220421124950-8527e238867c
github.com/containers/ocicrypt v1.1.3
diff --git a/go.sum b/go.sum
index 47ff1ec36..a827cd687 100644
--- a/go.sum
+++ b/go.sum
@@ -357,8 +357,8 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057 h1:lKSxhMBpcHyyQrj2QJYzcm56uiSeibRdSL2KoppF6rg=
github.com/containers/buildah v1.25.2-0.20220406205807-5b8e79118057/go.mod h1:iSoopbYRb6K4b5c3hXgXNkGTI/T085t2+XiGjceud94=
github.com/containers/common v0.47.5-0.20220331143923-5f14ec785c18/go.mod h1:Vr2Fn6EdzD6JNAbz8L8bTv3uWLv2p31Ih2O3EAK6Hyc=
-github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb h1:TBrx1KcmWcesByqTb4Cq7F6bg7bDOjqCf6+6rbi8x4k=
-github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA=
+github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356 h1:eJ1ghvyswTLRywF4YYEWrzZyOFEzlD1FUPLzJSz+wKo=
+github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356/go.mod h1:r80nWTmJrG9EoLkuI6WfbWQDUNQVqkVuB8Oaj1VVjOA=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.19.2-0.20220224100137-1045fb70b094/go.mod h1:XoYK6kE0dpazFNcuS+a8lra+QfbC6s8tzv+cUuCrZpE=
diff --git a/hack/golangci-lint.sh b/hack/golangci-lint.sh
index bcb83a2fd..8b80bd9c9 100755
--- a/hack/golangci-lint.sh
+++ b/hack/golangci-lint.sh
@@ -10,9 +10,9 @@ BUILD_TAGS[abi]="${BUILD_TAGS[default]},!remoteclient"
BUILD_TAGS[tunnel]="${BUILD_TAGS[default]},remote,remoteclient"
declare -A SKIP_DIRS
-SKIP_DIRS[abi]=""
+SKIP_DIRS[abi]="pkg/machine/e2e"
# TODO: add "remote" build tag to pkg/api
-SKIP_DIRS[tunnel]="pkg/api"
+SKIP_DIRS[tunnel]="pkg/api,pkg/machine/e2e"
[[ $1 == run ]] && shift
diff --git a/libpod/container_api.go b/libpod/container_api.go
index ebefed600..fe41998c0 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -889,7 +889,7 @@ func (c *Container) CopyFromArchive(ctx context.Context, containerPath string, c
}
}
- return c.copyFromArchive(ctx, containerPath, chown, rename, tarStream)
+ return c.copyFromArchive(containerPath, chown, rename, tarStream)
}
// CopyToArchive copies the contents from the specified path *inside* the
@@ -904,7 +904,7 @@ func (c *Container) CopyToArchive(ctx context.Context, containerPath string, tar
}
}
- return c.copyToArchive(ctx, containerPath, tarStream)
+ return c.copyToArchive(containerPath, tarStream)
}
// Stat the specified path *inside* the container and return a file info.
@@ -934,6 +934,6 @@ func (c *Container) Stat(ctx context.Context, containerPath string) (*define.Fil
}()
}
- info, _, _, err := c.stat(ctx, mountPoint, containerPath)
+ info, _, _, err := c.stat(mountPoint, containerPath)
return info, err
}
diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go
index 38927d691..91e712c74 100644
--- a/libpod/container_copy_linux.go
+++ b/libpod/container_copy_linux.go
@@ -4,7 +4,6 @@
package libpod
import (
- "context"
"io"
"os"
"path/filepath"
@@ -24,7 +23,7 @@ import (
"golang.org/x/sys/unix"
)
-func (c *Container) copyFromArchive(ctx context.Context, path string, chown bool, rename map[string]string, reader io.Reader) (func() error, error) {
+func (c *Container) copyFromArchive(path string, chown bool, rename map[string]string, reader io.Reader) (func() error, error) {
var (
mountPoint string
resolvedRoot string
@@ -93,7 +92,7 @@ func (c *Container) copyFromArchive(ctx context.Context, path string, chown bool
Rename: rename,
}
- return c.joinMountAndExec(ctx,
+ return c.joinMountAndExec(
func() error {
return buildahCopiah.Put(resolvedRoot, resolvedPath, putOptions, decompressed)
},
@@ -101,7 +100,7 @@ func (c *Container) copyFromArchive(ctx context.Context, path string, chown bool
}, nil
}
-func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Writer) (func() error, error) {
+func (c *Container) copyToArchive(path string, writer io.Writer) (func() error, error) {
var (
mountPoint string
unmount func()
@@ -121,7 +120,7 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr
unmount = func() { c.unmount(false) }
}
- statInfo, resolvedRoot, resolvedPath, err := c.stat(ctx, mountPoint, path)
+ statInfo, resolvedRoot, resolvedPath, err := c.stat(mountPoint, path)
if err != nil {
unmount()
return nil, err
@@ -165,7 +164,7 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr
// container's user namespace.
IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning,
}
- return c.joinMountAndExec(ctx,
+ return c.joinMountAndExec(
func() error {
return buildahCopiah.Get(resolvedRoot, "", getOptions, []string{resolvedPath}, writer)
},
@@ -216,7 +215,7 @@ func idtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxI
// container's file system.
//
// Note, if the container is not running `f()` will be executed as is.
-func (c *Container) joinMountAndExec(ctx context.Context, f func() error) error {
+func (c *Container) joinMountAndExec(f func() error) error {
if c.state.State != define.ContainerStateRunning {
return f()
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index ead58b373..9f8b7c686 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2632,7 +2632,7 @@ func (c *Container) generateGroupEntry() (string, error) {
addedGID = gid
}
if c.config.User != "" {
- entry, _, err := c.generateUserGroupEntry(addedGID)
+ entry, err := c.generateUserGroupEntry(addedGID)
if err != nil {
return "", err
}
@@ -2685,9 +2685,9 @@ func (c *Container) generateCurrentUserGroupEntry() (string, int, error) {
// Make an entry in /etc/group for the group the container was specified to run
// as.
-func (c *Container) generateUserGroupEntry(addedGID int) (string, int, error) {
+func (c *Container) generateUserGroupEntry(addedGID int) (string, error) {
if c.config.User == "" {
- return "", 0, nil
+ return "", nil
}
splitUser := strings.SplitN(c.config.User, ":", 2)
@@ -2698,20 +2698,20 @@ func (c *Container) generateUserGroupEntry(addedGID int) (string, int, error) {
gid, err := strconv.ParseUint(group, 10, 32)
if err != nil {
- return "", 0, nil // nolint: nilerr
+ return "", nil // nolint: nilerr
}
if addedGID != 0 && addedGID == int(gid) {
- return "", 0, nil
+ return "", nil
}
// Check if the group already exists
_, err = lookup.GetGroup(c.state.Mountpoint, group)
if err != runcuser.ErrNoGroupEntries {
- return "", 0, err
+ return "", err
}
- return fmt.Sprintf("%d:x:%d:%s\n", gid, gid, splitUser[0]), int(gid), nil
+ return fmt.Sprintf("%d:x:%d:%s\n", gid, gid, splitUser[0]), nil
}
// generatePasswdEntry generates an entry or entries into /etc/passwd as
@@ -2751,7 +2751,7 @@ func (c *Container) generatePasswdEntry() (string, error) {
addedUID = uid
}
if c.config.User != "" {
- entry, _, _, err := c.generateUserPasswdEntry(addedUID)
+ entry, err := c.generateUserPasswdEntry(addedUID)
if err != nil {
return "", err
}
@@ -2838,13 +2838,13 @@ func (c *Container) userPasswdEntry(u *user.User) (string, error) {
// Accepts one argument, that being any UID that has already been added to the
// passwd file by other functions; if it matches the UID we were given, we don't
// need to do anything.
-func (c *Container) generateUserPasswdEntry(addedUID int) (string, int, int, error) {
+func (c *Container) generateUserPasswdEntry(addedUID int) (string, error) {
var (
groupspec string
gid int
)
if c.config.User == "" {
- return "", 0, 0, nil
+ return "", nil
}
splitSpec := strings.SplitN(c.config.User, ":", 2)
userspec := splitSpec[0]
@@ -2854,17 +2854,17 @@ func (c *Container) generateUserPasswdEntry(addedUID int) (string, int, int, err
// If a non numeric User, then don't generate passwd
uid, err := strconv.ParseUint(userspec, 10, 32)
if err != nil {
- return "", 0, 0, nil // nolint: nilerr
+ return "", nil // nolint: nilerr
}
if addedUID != 0 && int(uid) == addedUID {
- return "", 0, 0, nil
+ return "", nil
}
// Lookup the user to see if it exists in the container image
_, err = lookup.GetUser(c.state.Mountpoint, userspec)
if err != runcuser.ErrNoPasswdEntries {
- return "", 0, 0, err
+ return "", err
}
if groupspec != "" {
@@ -2874,7 +2874,7 @@ func (c *Container) generateUserPasswdEntry(addedUID int) (string, int, int, err
} else {
group, err := lookup.GetGroup(c.state.Mountpoint, groupspec)
if err != nil {
- return "", 0, 0, errors.Wrapf(err, "unable to get gid %s from group file", groupspec)
+ return "", errors.Wrapf(err, "unable to get gid %s from group file", groupspec)
}
gid = group.Gid
}
@@ -2882,10 +2882,10 @@ func (c *Container) generateUserPasswdEntry(addedUID int) (string, int, int, err
if c.config.PasswdEntry != "" {
entry := c.passwdEntry(fmt.Sprintf("%d", uid), fmt.Sprintf("%d", uid), fmt.Sprintf("%d", gid), "container user", c.WorkingDir())
- return entry, int(uid), gid, nil
+ return entry, nil
}
- return fmt.Sprintf("%d:*:%d:%d:container user:%s:/bin/sh\n", uid, uid, gid, c.WorkingDir()), int(uid), gid, nil
+ return fmt.Sprintf("%d:*:%d:%d:container user:%s:/bin/sh\n", uid, uid, gid, c.WorkingDir()), nil
}
func (c *Container) passwdEntry(username string, uid, gid, name, homeDir string) string {
diff --git a/libpod/container_internal_linux_test.go b/libpod/container_internal_linux_test.go
index 2c1193445..03095aa58 100644
--- a/libpod/container_internal_linux_test.go
+++ b/libpod/container_internal_linux_test.go
@@ -30,14 +30,14 @@ func TestGenerateUserPasswdEntry(t *testing.T) {
Mountpoint: "/does/not/exist/tmp/",
},
}
- user, _, _, err := c.generateUserPasswdEntry(0)
+ user, err := c.generateUserPasswdEntry(0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, user, "123:*:123:456:container user:/:/bin/sh\n")
c.config.User = "567"
- user, _, _, err = c.generateUserPasswdEntry(0)
+ user, err = c.generateUserPasswdEntry(0)
if err != nil {
t.Fatal(err)
}
@@ -56,14 +56,14 @@ func TestGenerateUserGroupEntry(t *testing.T) {
Mountpoint: "/does/not/exist/tmp/",
},
}
- group, _, err := c.generateUserGroupEntry(0)
+ group, err := c.generateUserGroupEntry(0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, group, "456:x:456:123\n")
c.config.User = "567"
- group, _, err = c.generateUserGroupEntry(0)
+ group, err = c.generateUserGroupEntry(0)
if err != nil {
t.Fatal(err)
}
diff --git a/libpod/container_stat_linux.go b/libpod/container_stat_linux.go
index 84ab984e0..9e225de2e 100644
--- a/libpod/container_stat_linux.go
+++ b/libpod/container_stat_linux.go
@@ -4,7 +4,6 @@
package libpod
import (
- "context"
"os"
"path/filepath"
"strings"
@@ -18,12 +17,12 @@ import (
// statInsideMount stats the specified path *inside* the container's mount and PID
// namespace. It returns the file info along with the resolved root ("/") and
// the resolved path (relative to the root).
-func (c *Container) statInsideMount(ctx context.Context, containerPath string) (*copier.StatForItem, string, string, error) {
+func (c *Container) statInsideMount(containerPath string) (*copier.StatForItem, string, string, error) {
resolvedRoot := "/"
resolvedPath := c.pathAbs(containerPath)
var statInfo *copier.StatForItem
- err := c.joinMountAndExec(ctx,
+ err := c.joinMountAndExec(
func() error {
var statErr error
statInfo, statErr = secureStat(resolvedRoot, resolvedPath)
@@ -38,7 +37,7 @@ func (c *Container) statInsideMount(ctx context.Context, containerPath string) (
// along with the resolved root and the resolved path. Both paths are absolute
// to the host's root. Note that the paths may resolved outside the
// container's mount point (e.g., to a volume or bind mount).
-func (c *Container) statOnHost(ctx context.Context, mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) {
+func (c *Container) statOnHost(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) {
// Now resolve the container's path. It may hit a volume, it may hit a
// bind mount, it may be relative.
resolvedRoot, resolvedPath, err := c.resolvePath(mountPoint, containerPath)
@@ -50,7 +49,7 @@ func (c *Container) statOnHost(ctx context.Context, mountPoint string, container
return statInfo, resolvedRoot, resolvedPath, err
}
-func (c *Container) stat(ctx context.Context, containerMountPoint string, containerPath string) (*define.FileInfo, string, string, error) {
+func (c *Container) stat(containerMountPoint string, containerPath string) (*define.FileInfo, string, string, error) {
var (
resolvedRoot string
resolvedPath string
@@ -75,11 +74,11 @@ func (c *Container) stat(ctx context.Context, containerMountPoint string, contai
if c.state.State == define.ContainerStateRunning {
// If the container is running, we need to join it's mount namespace
// and stat there.
- statInfo, resolvedRoot, resolvedPath, statErr = c.statInsideMount(ctx, containerPath)
+ statInfo, resolvedRoot, resolvedPath, statErr = c.statInsideMount(containerPath)
} else {
// If the container is NOT running, we need to resolve the path
// on the host.
- statInfo, resolvedRoot, resolvedPath, statErr = c.statOnHost(ctx, containerMountPoint, containerPath)
+ statInfo, resolvedRoot, resolvedPath, statErr = c.statOnHost(containerMountPoint, containerPath)
}
if statErr != nil {
diff --git a/libpod/kube.go b/libpod/kube.go
index 5e5260dd5..eb62643fe 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -525,9 +525,9 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
}
podName := strings.ReplaceAll(ctrs[0].Name(), "_", "")
// Check if the pod name and container name will end up conflicting
- // Append _pod if so
+ // Append -pod if so
if util.StringInSlice(podName, ctrNames) {
- podName = podName + "_pod"
+ podName = podName + "-pod"
}
return newPodObject(
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 0db0896cf..a312f5a0c 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -23,6 +23,7 @@ import (
"github.com/containers/common/libnetwork/etchosts"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/machine"
"github.com/containers/common/pkg/netns"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
@@ -62,7 +63,7 @@ const (
// This is need because a HostIP of 127.0.0.1 would now allow the gvproxy forwarder to reach to open ports.
// For machine the HostIP must only be used by gvproxy and never in the VM.
func (c *Container) convertPortMappings() []types.PortMapping {
- if !c.runtime.config.Engine.MachineEnabled || len(c.config.PortMappings) == 0 {
+ if !machine.IsGvProxyBased() || len(c.config.PortMappings) == 0 {
return c.config.PortMappings
}
// if we run in a machine VM we have to ignore the host IP part
@@ -74,7 +75,7 @@ func (c *Container) convertPortMappings() []types.PortMapping {
return newPorts
}
-func (c *Container) getNetworkOptions(networkOpts map[string]types.PerNetworkOptions) (types.NetworkOptions, error) {
+func (c *Container) getNetworkOptions(networkOpts map[string]types.PerNetworkOptions) types.NetworkOptions {
opts := types.NetworkOptions{
ContainerID: c.config.ID,
ContainerName: getCNIPodName(c),
@@ -88,7 +89,7 @@ func (c *Container) getNetworkOptions(networkOpts map[string]types.PerNetworkOpt
} else {
opts.Networks = networkOpts
}
- return opts, nil
+ return opts
}
type RootlessNetNS struct {
@@ -653,10 +654,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
return nil, nil
}
- netOpts, err := ctr.getNetworkOptions(networks)
- if err != nil {
- return nil, err
- }
+ netOpts := ctr.getNetworkOptions(networks)
netStatus, err := r.setUpNetwork(ctrNS.Path(), netOpts)
if err != nil {
return nil, err
@@ -814,10 +812,7 @@ func (r *Runtime) teardownCNI(ctr *Container) error {
}
if !ctr.config.NetMode.IsSlirp4netns() && len(networks) > 0 {
- netOpts, err := ctr.getNetworkOptions(networks)
- if err != nil {
- return err
- }
+ netOpts := ctr.getNetworkOptions(networks)
return r.teardownNetwork(ctr.state.NetNS.Path(), netOpts)
}
return nil
@@ -1000,11 +995,9 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
if c.state.NetNS == nil {
if networkNSPath := c.joinedNetworkNSPath(); networkNSPath != "" {
if result, err := c.inspectJoinedNetworkNS(networkNSPath); err == nil {
- if basicConfig, err := resultToBasicNetworkConfig(result); err == nil {
- // fallback to dummy configuration
- settings.InspectBasicNetworkConfig = basicConfig
- return settings, nil
- }
+ // fallback to dummy configuration
+ settings.InspectBasicNetworkConfig = resultToBasicNetworkConfig(result)
+ return settings, nil
}
// do not propagate error inspecting a joined network ns
logrus.Errorf("Inspecting network namespace: %s of container %s: %v", networkNSPath, c.ID(), err)
@@ -1047,14 +1040,8 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
result := netStatus[name]
addedNet := new(define.InspectAdditionalNetwork)
addedNet.NetworkID = name
-
- basicConfig, err := resultToBasicNetworkConfig(result)
- if err != nil {
- return nil, err
- }
addedNet.Aliases = opts.Aliases
-
- addedNet.InspectBasicNetworkConfig = basicConfig
+ addedNet.InspectBasicNetworkConfig = resultToBasicNetworkConfig(result)
settings.Networks[name] = addedNet
}
@@ -1074,11 +1061,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
if len(netStatus) == 1 {
for _, status := range netStatus {
- basicConfig, err := resultToBasicNetworkConfig(status)
- if err != nil {
- return nil, err
- }
- settings.InspectBasicNetworkConfig = basicConfig
+ settings.InspectBasicNetworkConfig = resultToBasicNetworkConfig(status)
}
}
return settings, nil
@@ -1152,7 +1135,7 @@ func (c *Container) inspectJoinedNetworkNS(networkns string) (q types.StatusBloc
// resultToBasicNetworkConfig produces an InspectBasicNetworkConfig from a CNI
// result
-func resultToBasicNetworkConfig(result types.StatusBlock) (define.InspectBasicNetworkConfig, error) {
+func resultToBasicNetworkConfig(result types.StatusBlock) define.InspectBasicNetworkConfig {
config := define.InspectBasicNetworkConfig{}
interfaceNames := make([]string, 0, len(result.Interfaces))
for interfaceName := range result.Interfaces {
@@ -1190,7 +1173,7 @@ func resultToBasicNetworkConfig(result types.StatusBlock) (define.InspectBasicNe
config.AdditionalMacAddresses = append(config.AdditionalMacAddresses, netInt.MacAddress.String())
}
}
- return config, nil
+ return config
}
type logrusDebugWriter struct {
diff --git a/libpod/networking_linux_test.go b/libpod/networking_linux_test.go
index a21494824..2aeb1a02c 100644
--- a/libpod/networking_linux_test.go
+++ b/libpod/networking_linux_test.go
@@ -241,7 +241,6 @@ func Test_ocicniPortsToNetTypesPorts(t *testing.T) {
func Test_resultToBasicNetworkConfig(t *testing.T) {
testCases := []struct {
description string
- expectError bool
inputResult types.StatusBlock
expectedNetworkConfig define.InspectBasicNetworkConfig
}{
@@ -431,15 +430,7 @@ func Test_resultToBasicNetworkConfig(t *testing.T) {
tc := tcl
t.Run(tc.description, func(t *testing.T) {
t.Parallel()
- actualNetworkConfig, err := resultToBasicNetworkConfig(tc.inputResult)
-
- if tc.expectError && err == nil {
- t.Fatalf("Expected error didn't happen")
- }
-
- if !tc.expectError && err != nil {
- t.Fatalf("Unexpected error happened: %v", err)
- }
+ actualNetworkConfig := resultToBasicNetworkConfig(tc.inputResult)
if !reflect.DeepEqual(tc.expectedNetworkConfig, actualNetworkConfig) {
t.Fatalf(
diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go
index d2a6b7cfa..73089c474 100644
--- a/libpod/networking_machine.go
+++ b/libpod/networking_machine.go
@@ -14,6 +14,7 @@ import (
"time"
"github.com/containers/common/libnetwork/types"
+ "github.com/containers/common/pkg/machine"
"github.com/sirupsen/logrus"
)
@@ -117,7 +118,7 @@ func annotateGvproxyResponseError(r io.Reader) error {
// exposeMachinePorts exposes the ports for podman machine via gvproxy
func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error {
- if !r.config.Engine.MachineEnabled {
+ if !machine.IsGvProxyBased() {
return nil
}
return requestMachinePorts(true, ports)
@@ -125,7 +126,7 @@ func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error {
// unexposeMachinePorts closes the ports for podman machine via gvproxy
func (r *Runtime) unexposeMachinePorts(ports []types.PortMapping) error {
- if !r.config.Engine.MachineEnabled {
+ if !machine.IsGvProxyBased() {
return nil
}
return requestMachinePorts(false, ports)
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 4b1203dc3..4a0ef0b3a 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 rootfull as well as in rootless
+// setupSlirp4netns can be called in rootful 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/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index 1005d18da..b8fd82591 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -439,7 +439,7 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex
// }
// }
- conmonEnv := r.configureConmonEnv(c, runtimeDir)
+ conmonEnv := r.configureConmonEnv(runtimeDir)
var filesToClose []*os.File
if options.PreserveFDs > 0 {
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 06ba8a03f..dc1c75cea 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1181,7 +1181,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
}
// 0, 1 and 2 are stdin, stdout and stderr
- conmonEnv := r.configureConmonEnv(ctr, runtimeDir)
+ conmonEnv := r.configureConmonEnv(runtimeDir)
var filesToClose []*os.File
if preserveFDs > 0 {
@@ -1312,7 +1312,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
// configureConmonEnv gets the environment values to add to conmon's exec struct
// TODO this may want to be less hardcoded/more configurable in the future
-func (r *ConmonOCIRuntime) configureConmonEnv(ctr *Container, runtimeDir string) []string {
+func (r *ConmonOCIRuntime) configureConmonEnv(runtimeDir string) []string {
var env []string
for _, e := range os.Environ() {
if strings.HasPrefix(e, "LC_") {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 07653217a..877e151a9 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -167,7 +167,7 @@ func NewRuntime(ctx context.Context, options ...RuntimeOption) (*Runtime, error)
if err != nil {
return nil, err
}
- return newRuntimeFromConfig(ctx, conf, options...)
+ return newRuntimeFromConfig(conf, options...)
}
// NewRuntimeFromConfig creates a new container runtime using the given
@@ -176,10 +176,10 @@ func NewRuntime(ctx context.Context, options ...RuntimeOption) (*Runtime, error)
// An error will be returned if the configuration file at the given path does
// not exist or cannot be loaded
func NewRuntimeFromConfig(ctx context.Context, userConfig *config.Config, options ...RuntimeOption) (*Runtime, error) {
- return newRuntimeFromConfig(ctx, userConfig, options...)
+ return newRuntimeFromConfig(userConfig, options...)
}
-func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...RuntimeOption) (*Runtime, error) {
+func newRuntimeFromConfig(conf *config.Config, options ...RuntimeOption) (*Runtime, error) {
runtime := new(Runtime)
if conf.Engine.OCIRuntime == "" {
@@ -224,7 +224,7 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
return nil, errors.Wrapf(err, "error starting shutdown signal handler")
}
- if err := makeRuntime(ctx, runtime); err != nil {
+ if err := makeRuntime(runtime); err != nil {
return nil, err
}
@@ -292,7 +292,7 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
// Make a new runtime based on the given configuration
// Sets up containers/storage, state store, OCI runtime
-func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
+func makeRuntime(runtime *Runtime) (retErr error) {
// Find a working conmon binary
cPath, err := findConmon(runtime.config.Engine.ConmonPath)
if err != nil {
@@ -598,7 +598,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
runtime.valid = true
if runtime.doMigrate {
- if err := runtime.migrate(ctx); err != nil {
+ if err := runtime.migrate(); err != nil {
return err
}
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index a62c2b607..fd3ffd199 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -501,7 +501,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
volOptions = append(volOptions, parsedOptions...)
}
}
- newVol, err := r.newVolume(ctx, volOptions...)
+ newVol, err := r.newVolume(volOptions...)
if err != nil {
return nil, errors.Wrapf(err, "error creating named volume %q", vol.Name)
}
diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go
index fccd5bdee..f56cb83a4 100644
--- a/libpod/runtime_migrate.go
+++ b/libpod/runtime_migrate.go
@@ -4,7 +4,6 @@
package libpod
import (
- "context"
"fmt"
"io/ioutil"
"os"
@@ -46,7 +45,7 @@ func (r *Runtime) stopPauseProcess() error {
return nil
}
-func (r *Runtime) migrate(ctx context.Context) error {
+func (r *Runtime) migrate() error {
runningContainers, err := r.GetRunningContainers()
if err != nil {
return err
diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go
index 3d585fa7a..241f6e2f2 100644
--- a/libpod/runtime_volume_linux.go
+++ b/libpod/runtime_volume_linux.go
@@ -25,11 +25,11 @@ func (r *Runtime) NewVolume(ctx context.Context, options ...VolumeCreateOption)
if !r.valid {
return nil, define.ErrRuntimeStopped
}
- return r.newVolume(ctx, options...)
+ return r.newVolume(options...)
}
// newVolume creates a new empty volume
-func (r *Runtime) newVolume(ctx context.Context, options ...VolumeCreateOption) (_ *Volume, deferredErr error) {
+func (r *Runtime) newVolume(options ...VolumeCreateOption) (_ *Volume, deferredErr error) {
volume := newVolume(r)
for _, option := range options {
if err := option(volume); err != nil {
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 08646202a..1a24f1ae3 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -123,6 +123,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
Tags []string `schema:"t"`
Target string `schema:"target"`
Timestamp int64 `schema:"timestamp"`
+ TLSVerify bool `schema:"tlsVerify"`
Ulimits string `schema:"ulimits"`
UnsetEnvs []string `schema:"unsetenv"`
Secrets string `schema:"secrets"`
@@ -491,6 +492,11 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
utils.PossiblyEnforceDockerHub(r, systemContext)
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ systemContext.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
+ systemContext.OCIInsecureSkipTLSVerify = !query.TLSVerify
+ systemContext.DockerDaemonInsecureSkipTLSVerify = !query.TLSVerify
+ }
// Channels all mux'ed in select{} below to follow API build protocol
stdout := channel.NewWriter(make(chan []byte))
defer stdout.Close()
diff --git a/pkg/autoupdate/autoupdate.go b/pkg/autoupdate/autoupdate.go
index 07962a965..ee530528e 100644
--- a/pkg/autoupdate/autoupdate.go
+++ b/pkg/autoupdate/autoupdate.go
@@ -209,7 +209,7 @@ func autoUpdateRegistry(ctx context.Context, image *libimage.Image, ctr *libpod.
}
authfile := getAuthfilePath(ctr, options)
- needsUpdate, err := newerRemoteImageAvailable(ctx, runtime, image, rawImageName, authfile)
+ needsUpdate, err := newerRemoteImageAvailable(ctx, image, rawImageName, authfile)
if err != nil {
return report, errors.Wrapf(err, "registry auto-updating container %q: image check for %q failed", cid, rawImageName)
}
@@ -399,7 +399,7 @@ func getAuthfilePath(ctr *libpod.Container, options *entities.AutoUpdateOptions)
// newerRemoteImageAvailable returns true if there corresponding image on the remote
// registry is newer.
-func newerRemoteImageAvailable(ctx context.Context, runtime *libpod.Runtime, img *libimage.Image, origName string, authfile string) (bool, error) {
+func newerRemoteImageAvailable(ctx context.Context, img *libimage.Image, origName string, authfile string) (bool, error) {
remoteRef, err := docker.ParseReference("//" + origName)
if err != nil {
return false, err
diff --git a/pkg/bindings/README.md b/pkg/bindings/README.md
index 713adb104..ebc8a13d1 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 rootfull service,
+The command to start the Podman service differs slightly depending on the user that is running the service. For a rootful 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
-rootfull connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
+rootful 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 rootfull connection is made.
+of the socket depends on the user who owns it. In this case, a rootful 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 rootfull connections as well.
+The following examples build upon the connection example from above. They are all rootful 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/images/build.go b/pkg/bindings/images/build.go
index 15900a2ed..1729bd922 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -312,10 +312,15 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
var (
headers http.Header
)
- if options.SystemContext != nil && options.SystemContext.DockerAuthConfig != nil {
- headers, err = auth.MakeXRegistryAuthHeader(options.SystemContext, options.SystemContext.DockerAuthConfig.Username, options.SystemContext.DockerAuthConfig.Password)
- } else {
- headers, err = auth.MakeXRegistryConfigHeader(options.SystemContext, "", "")
+ if options.SystemContext != nil {
+ if options.SystemContext.DockerAuthConfig != nil {
+ headers, err = auth.MakeXRegistryAuthHeader(options.SystemContext, options.SystemContext.DockerAuthConfig.Username, options.SystemContext.DockerAuthConfig.Password)
+ } else {
+ headers, err = auth.MakeXRegistryConfigHeader(options.SystemContext, "", "")
+ }
+ if options.SystemContext.DockerInsecureSkipTLSVerify == types.OptionalBoolTrue {
+ params.Set("tlsVerify", "false")
+ }
}
if err != nil {
return nil, err
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 43440b594..74478b26d 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 transferRootfull(source, dest, podman, parentFlags)
+ return transferRootful(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()
}
-// 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 {
+// 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 {
basicCommand := []string{podman}
basicCommand = append(basicCommand, parentFlags...)
saveCommand := append(basicCommand, "save")
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index c3f6bb17d..1d347ed8c 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -114,7 +114,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
return nil, errors.Wrap(err, "unable to read YAML as Kube PersistentVolumeClaim")
}
- r, err := ic.playKubePVC(ctx, &pvcYAML, options)
+ r, err := ic.playKubePVC(ctx, &pvcYAML)
if err != nil {
return nil, err
}
@@ -592,7 +592,7 @@ func (ic *ContainerEngine) getImageAndLabelInfo(ctx context.Context, cwd string,
}
// playKubePVC creates a podman volume from a kube persistent volume claim.
-func (ic *ContainerEngine) playKubePVC(ctx context.Context, pvcYAML *v1.PersistentVolumeClaim, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
+func (ic *ContainerEngine) playKubePVC(ctx context.Context, pvcYAML *v1.PersistentVolumeClaim) (*entities.PlayKubeReport, error) {
var report entities.PlayKubeReport
opts := make(map[string]string)
diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go
index 5fdc252e2..ac557e9de 100644
--- a/pkg/domain/infra/runtime_libpod.go
+++ b/pkg/domain/infra/runtime_libpod.go
@@ -209,6 +209,10 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo
options = append(options, libpod.WithEventsLogger(cfg.Engine.EventsLogger))
}
+ if fs.Changed("volumepath") {
+ options = append(options, libpod.WithVolumePath(cfg.Engine.VolumePath))
+ }
+
if fs.Changed("cgroup-manager") {
options = append(options, libpod.WithCgroupManager(cfg.Engine.CgroupManager))
} else {
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 505311264..1103933cd 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
- Rootfull bool
+ Rootful bool
// The numerical userid of the user that called machine
UID string
}
@@ -95,7 +95,7 @@ type ListResponse struct {
}
type SetOptions struct {
- Rootfull bool
+ Rootful bool
}
type SSHOptions struct {
diff --git a/pkg/machine/e2e/basic_test.go b/pkg/machine/e2e/basic_test.go
new file mode 100644
index 000000000..f67fb4c67
--- /dev/null
+++ b/pkg/machine/e2e/basic_test.go
@@ -0,0 +1,50 @@
+package e2e
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("run basic podman commands", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("Basic ops", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withNow()).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ bm := basicMachine{}
+ imgs, err := mb.setCmd(bm.withPodmanCommand([]string{"images", "-q"})).run()
+ Expect(err).To(BeNil())
+ Expect(imgs).To(Exit(0))
+ Expect(len(imgs.outputToStringSlice())).To(Equal(0))
+
+ newImgs, err := mb.setCmd(bm.withPodmanCommand([]string{"pull", "quay.io/libpod/alpine_nginx"})).run()
+ Expect(err).To(BeNil())
+ Expect(newImgs).To(Exit(0))
+ Expect(len(newImgs.outputToStringSlice())).To(Equal(1))
+
+ runAlp, err := mb.setCmd(bm.withPodmanCommand([]string{"run", "quay.io/libpod/alpine_nginx", "cat", "/etc/os-release"})).run()
+ Expect(err).To(BeNil())
+ Expect(runAlp).To(Exit(0))
+ Expect(runAlp.outputToString()).To(ContainSubstring("Alpine Linux"))
+
+ rmCon, err := mb.setCmd(bm.withPodmanCommand([]string{"rm", "-a"})).run()
+ Expect(err).To(BeNil())
+ Expect(rmCon).To(Exit(0))
+ })
+
+})
diff --git a/pkg/machine/e2e/config.go b/pkg/machine/e2e/config.go
new file mode 100644
index 000000000..7d75ca6bc
--- /dev/null
+++ b/pkg/machine/e2e/config.go
@@ -0,0 +1,174 @@
+package e2e
+
+import (
+ "encoding/json"
+ "fmt"
+ "math/rand"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/containers/podman/v4/pkg/machine"
+ "github.com/containers/podman/v4/pkg/machine/qemu"
+ "github.com/containers/podman/v4/pkg/util"
+ . "github.com/onsi/ginkgo" //nolint:golint,stylecheck
+ . "github.com/onsi/gomega"
+ "github.com/onsi/gomega/gexec"
+ . "github.com/onsi/gomega/gexec" //nolint:golint,stylecheck
+)
+
+var originalHomeDir = os.Getenv("HOME")
+
+const (
+ defaultTimeout time.Duration = 90 * time.Second
+)
+
+type machineCommand interface {
+ buildCmd(m *machineTestBuilder) []string
+}
+
+type MachineTestBuilder interface {
+ setName(string) *MachineTestBuilder
+ setCmd(mc machineCommand) *MachineTestBuilder
+ setTimeout(duration time.Duration) *MachineTestBuilder
+ run() (*machineSession, error)
+}
+type machineSession struct {
+ *gexec.Session
+}
+
+type machineTestBuilder struct {
+ cmd []string
+ imagePath string
+ name string
+ names []string
+ podmanBinary string
+ timeout time.Duration
+}
+type qemuMachineInspectInfo struct {
+ State machine.Status
+ VM qemu.MachineVM
+}
+
+// waitWithTimeout waits for a command to complete for a given
+// number of seconds
+func (ms *machineSession) waitWithTimeout(timeout time.Duration) {
+ Eventually(ms, timeout).Should(Exit())
+ os.Stdout.Sync()
+ os.Stderr.Sync()
+}
+
+func (ms *machineSession) Bytes() []byte {
+ return []byte(ms.outputToString())
+}
+
+func (ms *machineSession) outputToStringSlice() []string {
+ var results []string
+ output := string(ms.Out.Contents())
+ for _, line := range strings.Split(output, "\n") {
+ if line != "" {
+ results = append(results, line)
+ }
+ }
+ return results
+}
+
+// outputToString returns the output from a session in string form
+func (ms *machineSession) outputToString() string {
+ if ms == nil || ms.Out == nil || ms.Out.Contents() == nil {
+ return ""
+ }
+
+ fields := strings.Fields(string(ms.Out.Contents()))
+ return strings.Join(fields, " ")
+}
+
+// newMB constructor for machine test builders
+func newMB() (*machineTestBuilder, error) {
+ mb := machineTestBuilder{
+ timeout: defaultTimeout,
+ }
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+ mb.podmanBinary = filepath.Join(cwd, "../../../bin/podman-remote")
+ if os.Getenv("PODMAN_BINARY") != "" {
+ mb.podmanBinary = os.Getenv("PODMAN_BINARY")
+ }
+ return &mb, nil
+}
+
+// setName sets the name of the virtuaql machine for the command
+func (m *machineTestBuilder) setName(name string) *machineTestBuilder {
+ m.name = name
+ return m
+}
+
+// setCmd takes a machineCommand struct and assembles a cmd line
+// representation of the podman machine command
+func (m *machineTestBuilder) setCmd(mc machineCommand) *machineTestBuilder {
+ // If no name for the machine exists, we set a random name.
+ if !util.StringInSlice(m.name, m.names) {
+ if len(m.name) < 1 {
+ m.name = randomString(12)
+ }
+ m.names = append(m.names, m.name)
+ }
+ m.cmd = mc.buildCmd(m)
+ return m
+}
+
+func (m *machineTestBuilder) setTimeout(timeout time.Duration) *machineTestBuilder {
+ m.timeout = timeout
+ return m
+}
+
+// toQemuInspectInfo is only for inspecting qemu machines. Other providers will need
+// to make their own.
+func (mb *machineTestBuilder) toQemuInspectInfo() ([]qemuMachineInspectInfo, int, error) {
+ args := []string{"machine", "inspect"}
+ args = append(args, mb.names...)
+ session, err := runWrapper(mb.podmanBinary, args, defaultTimeout)
+ if err != nil {
+ return nil, -1, err
+ }
+ mii := []qemuMachineInspectInfo{}
+ err = json.Unmarshal(session.Bytes(), &mii)
+ return mii, session.ExitCode(), err
+}
+
+func (m *machineTestBuilder) run() (*machineSession, error) {
+ return runWrapper(m.podmanBinary, m.cmd, m.timeout)
+}
+
+func runWrapper(podmanBinary string, cmdArgs []string, timeout time.Duration) (*machineSession, error) {
+ if len(os.Getenv("DEBUG")) > 0 {
+ cmdArgs = append([]string{"--log-level=debug"}, cmdArgs...)
+ }
+ fmt.Println(podmanBinary + " " + strings.Join(cmdArgs, " "))
+ c := exec.Command(podmanBinary, cmdArgs...)
+ session, err := Start(c, GinkgoWriter, GinkgoWriter)
+ if err != nil {
+ Fail(fmt.Sprintf("Unable to start session: %q", err))
+ return nil, err
+ }
+ ms := machineSession{session}
+ ms.waitWithTimeout(timeout)
+ fmt.Println("output:", ms.outputToString())
+ return &ms, nil
+}
+
+func (m *machineTestBuilder) init() {}
+
+// randomString returns a string of given length composed of random characters
+func randomString(n int) string {
+ var randomLetters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ b := make([]rune, n)
+ for i := range b {
+ b[i] = randomLetters[rand.Intn(len(randomLetters))]
+ }
+ return string(b)
+}
diff --git a/pkg/machine/e2e/config_basic.go b/pkg/machine/e2e/config_basic.go
new file mode 100644
index 000000000..be0896156
--- /dev/null
+++ b/pkg/machine/e2e/config_basic.go
@@ -0,0 +1,19 @@
+package e2e
+
+type basicMachine struct {
+ args []string
+ cmd []string
+}
+
+func (s basicMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"-r"}
+ if len(s.args) > 0 {
+ cmd = append(cmd, s.args...)
+ }
+ return cmd
+}
+
+func (s *basicMachine) withPodmanCommand(args []string) *basicMachine {
+ s.args = args
+ return s
+}
diff --git a/pkg/machine/e2e/config_init.go b/pkg/machine/e2e/config_init.go
new file mode 100644
index 000000000..55218221d
--- /dev/null
+++ b/pkg/machine/e2e/config_init.go
@@ -0,0 +1,101 @@
+package e2e
+
+import (
+ "strconv"
+)
+
+type initMachine struct {
+ /*
+ --cpus uint Number of CPUs (default 1)
+ --disk-size uint Disk size in GB (default 100)
+ --ignition-path string Path to ignition file
+ --image-path string Path to qcow image (default "testing")
+ -m, --memory uint Memory in MB (default 2048)
+ --now Start machine now
+ --rootful Whether this machine should prefer rootful container exectution
+ --timezone string Set timezone (default "local")
+ -v, --volume stringArray Volumes to mount, source:target
+ --volume-driver string Optional volume driver
+
+ */
+ cpus *uint
+ diskSize *uint
+ ignitionPath string
+ imagePath string
+ memory *uint
+ now bool
+ timezone string
+ volumes []string
+
+ cmd []string
+}
+
+func (i *initMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "init"}
+ if i.cpus != nil {
+ cmd = append(cmd, "--cpus", strconv.Itoa(int(*i.cpus)))
+ }
+ if i.diskSize != nil {
+ cmd = append(cmd, "--disk-size", strconv.Itoa(int(*i.diskSize)))
+ }
+ if l := len(i.ignitionPath); l > 0 {
+ cmd = append(cmd, "--ignition-path", i.ignitionPath)
+ }
+ if l := len(i.imagePath); l > 0 {
+ cmd = append(cmd, "--image-path", i.imagePath)
+ }
+ if i.memory != nil {
+ cmd = append(cmd, "--memory", strconv.Itoa(int(*i.memory)))
+ }
+ if l := len(i.timezone); l > 0 {
+ cmd = append(cmd, "--timezone", i.timezone)
+ }
+ for _, v := range i.volumes {
+ cmd = append(cmd, "--volume", v)
+ }
+ if i.now {
+ cmd = append(cmd, "--now")
+ }
+ cmd = append(cmd, m.name)
+ i.cmd = cmd
+ return cmd
+}
+
+func (i *initMachine) withCPUs(num uint) *initMachine {
+ i.cpus = &num
+ return i
+}
+func (i *initMachine) withDiskSize(size uint) *initMachine {
+ i.diskSize = &size
+ return i
+}
+
+func (i *initMachine) withIgnitionPath(path string) *initMachine {
+ i.ignitionPath = path
+ return i
+}
+
+func (i *initMachine) withImagePath(path string) *initMachine {
+ i.imagePath = path
+ return i
+}
+
+func (i *initMachine) withMemory(num uint) *initMachine {
+ i.memory = &num
+ return i
+}
+
+func (i *initMachine) withNow() *initMachine {
+ i.now = true
+ return i
+}
+
+func (i *initMachine) withTimezone(tz string) *initMachine {
+ i.timezone = tz
+ return i
+}
+
+func (i *initMachine) withVolume(v string) *initMachine {
+ i.volumes = append(i.volumes, v)
+ return i
+}
diff --git a/pkg/machine/e2e/config_inspect.go b/pkg/machine/e2e/config_inspect.go
new file mode 100644
index 000000000..74c9a5d9c
--- /dev/null
+++ b/pkg/machine/e2e/config_inspect.go
@@ -0,0 +1,24 @@
+package e2e
+
+type inspectMachine struct {
+ /*
+ --format string Format volume output using JSON or a Go template
+ */
+ cmd []string
+ format string
+}
+
+func (i *inspectMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "inspect"}
+ if len(i.format) > 0 {
+ cmd = append(cmd, "--format", i.format)
+ }
+ cmd = append(cmd, m.names...)
+ i.cmd = cmd
+ return cmd
+}
+
+func (i *inspectMachine) withFormat(format string) *inspectMachine {
+ i.format = format
+ return i
+}
diff --git a/pkg/machine/e2e/config_list.go b/pkg/machine/e2e/config_list.go
new file mode 100644
index 000000000..150f984bc
--- /dev/null
+++ b/pkg/machine/e2e/config_list.go
@@ -0,0 +1,45 @@
+package e2e
+
+type listMachine struct {
+ /*
+ --format string Format volume output using JSON or a Go template (default "{{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\t{{.CPUs}}\t{{.Memory}}\t{{.DiskSize}}\n")
+ --noheading Do not print headers
+ -q, --quiet Show only machine names
+ */
+
+ format string
+ noHeading bool
+ quiet bool
+
+ cmd []string
+}
+
+func (i *listMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "list"}
+ if len(i.format) > 0 {
+ cmd = append(cmd, "--format", i.format)
+ }
+ if i.noHeading {
+ cmd = append(cmd, "--noheading")
+ }
+ if i.quiet {
+ cmd = append(cmd, "--quiet")
+ }
+ i.cmd = cmd
+ return cmd
+}
+
+func (i *listMachine) withNoHeading() *listMachine {
+ i.noHeading = true
+ return i
+}
+
+func (i *listMachine) withQuiet() *listMachine {
+ i.quiet = true
+ return i
+}
+
+func (i *listMachine) withFormat(format string) *listMachine {
+ i.format = format
+ return i
+}
diff --git a/pkg/machine/e2e/config_rm.go b/pkg/machine/e2e/config_rm.go
new file mode 100644
index 000000000..6cf262a22
--- /dev/null
+++ b/pkg/machine/e2e/config_rm.go
@@ -0,0 +1,56 @@
+package e2e
+
+type rmMachine struct {
+ /*
+ -f, --force Stop and do not prompt before rming
+ --save-ignition Do not delete ignition file
+ --save-image Do not delete the image file
+ --save-keys Do not delete SSH keys
+
+ */
+ force bool
+ saveIgnition bool
+ saveImage bool
+ saveKeys bool
+
+ cmd []string
+}
+
+func (i *rmMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "rm"}
+ if i.force {
+ cmd = append(cmd, "--force")
+ }
+ if i.saveIgnition {
+ cmd = append(cmd, "--save-ignition")
+ }
+ if i.saveImage {
+ cmd = append(cmd, "--save-image")
+ }
+ if i.saveKeys {
+ cmd = append(cmd, "--save-keys")
+ }
+ cmd = append(cmd, m.name)
+ i.cmd = cmd
+ return cmd
+}
+
+func (i *rmMachine) withForce() *rmMachine {
+ i.force = true
+ return i
+}
+
+func (i *rmMachine) withSaveIgnition() *rmMachine {
+ i.saveIgnition = true
+ return i
+}
+
+func (i *rmMachine) withSaveImage() *rmMachine {
+ i.saveImage = true
+ return i
+}
+
+func (i *rmMachine) withSaveKeys() *rmMachine {
+ i.saveKeys = true
+ return i
+}
diff --git a/pkg/machine/e2e/config_ssh.go b/pkg/machine/e2e/config_ssh.go
new file mode 100644
index 000000000..b09eed47d
--- /dev/null
+++ b/pkg/machine/e2e/config_ssh.go
@@ -0,0 +1,33 @@
+package e2e
+
+type sshMachine struct {
+ /*
+ --username string Username to use when ssh-ing into the VM.
+ */
+
+ username string
+ sshCommand []string
+
+ cmd []string
+}
+
+func (s sshMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "ssh"}
+ if len(m.name) > 0 {
+ cmd = append(cmd, m.name)
+ }
+ if len(s.sshCommand) > 0 {
+ cmd = append(cmd, s.sshCommand...)
+ }
+ return cmd
+}
+
+func (s *sshMachine) withUsername(name string) *sshMachine {
+ s.username = name
+ return s
+}
+
+func (s *sshMachine) withSSHComand(sshCommand []string) *sshMachine {
+ s.sshCommand = sshCommand
+ return s
+}
diff --git a/pkg/machine/e2e/config_start.go b/pkg/machine/e2e/config_start.go
new file mode 100644
index 000000000..86b1721f8
--- /dev/null
+++ b/pkg/machine/e2e/config_start.go
@@ -0,0 +1,16 @@
+package e2e
+
+type startMachine struct {
+ /*
+ No command line args other than a machine vm name (also not required)
+ */
+ cmd []string
+}
+
+func (s startMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "start"}
+ if len(m.name) > 0 {
+ cmd = append(cmd, m.name)
+ }
+ return cmd
+}
diff --git a/pkg/machine/e2e/config_stop.go b/pkg/machine/e2e/config_stop.go
new file mode 100644
index 000000000..04dcfb524
--- /dev/null
+++ b/pkg/machine/e2e/config_stop.go
@@ -0,0 +1,16 @@
+package e2e
+
+type stopMachine struct {
+ /*
+ No command line args other than a machine vm name (also not required)
+ */
+ cmd []string
+}
+
+func (s stopMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "stop"}
+ if len(m.name) > 0 {
+ cmd = append(cmd, m.name)
+ }
+ return cmd
+}
diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go
new file mode 100644
index 000000000..309d460a9
--- /dev/null
+++ b/pkg/machine/e2e/init_test.go
@@ -0,0 +1,77 @@
+package e2e
+
+import (
+ "time"
+
+ "github.com/containers/podman/v4/pkg/machine"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("podman machine init", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("bad init name", func() {
+ i := initMachine{}
+ reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ session, err := mb.setName(reallyLongName).setCmd(&i).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(125))
+ })
+ It("simple init", func() {
+ i := new(initMachine)
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspectBefore, ec, err := mb.toQemuInspectInfo()
+ Expect(err).To(BeNil())
+ Expect(ec).To(BeZero())
+
+ Expect(len(inspectBefore)).To(BeNumerically(">", 0))
+ testMachine := inspectBefore[0]
+ Expect(testMachine.VM.Name).To(Equal(mb.names[0]))
+ Expect(testMachine.VM.CPUs).To(Equal(uint64(1)))
+ Expect(testMachine.VM.Memory).To(Equal(uint64(2048)))
+
+ })
+
+ It("simple init with start", func() {
+ i := initMachine{}
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+
+ inspectBefore, ec, err := mb.toQemuInspectInfo()
+ Expect(ec).To(BeZero())
+ Expect(len(inspectBefore)).To(BeNumerically(">", 0))
+ Expect(err).To(BeNil())
+ Expect(len(inspectBefore)).To(BeNumerically(">", 0))
+ Expect(inspectBefore[0].VM.Name).To(Equal(mb.names[0]))
+
+ s := startMachine{}
+ ssession, err := mb.setCmd(s).setTimeout(time.Minute * 10).run()
+ Expect(err).To(BeNil())
+ Expect(ssession).Should(Exit(0))
+
+ inspectAfter, ec, err := mb.toQemuInspectInfo()
+ Expect(err).To(BeNil())
+ Expect(ec).To(BeZero())
+ Expect(len(inspectBefore)).To(BeNumerically(">", 0))
+ Expect(len(inspectAfter)).To(BeNumerically(">", 0))
+ Expect(inspectAfter[0].State).To(Equal(machine.Running))
+ })
+
+})
diff --git a/pkg/machine/e2e/inspect_test.go b/pkg/machine/e2e/inspect_test.go
new file mode 100644
index 000000000..30d810b8f
--- /dev/null
+++ b/pkg/machine/e2e/inspect_test.go
@@ -0,0 +1,67 @@
+package e2e
+
+import (
+ "encoding/json"
+
+ "github.com/containers/podman/v4/pkg/machine/qemu"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("podman machine stop", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("inspect bad name", func() {
+ i := inspectMachine{}
+ reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ session, err := mb.setName(reallyLongName).setCmd(&i).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(125))
+ })
+
+ It("inspect two machines", func() {
+ i := new(initMachine)
+ foo1, err := mb.setName("foo1").setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(foo1.ExitCode()).To(Equal(0))
+
+ ii := new(initMachine)
+ foo2, err := mb.setName("foo2").setCmd(ii.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(foo2.ExitCode()).To(Equal(0))
+
+ inspect := new(inspectMachine)
+ inspectSession, err := mb.setName("foo1").setCmd(inspect).run()
+ Expect(err).To(BeNil())
+ Expect(inspectSession.ExitCode()).To(Equal(0))
+
+ type fakeInfos struct {
+ Status string
+ VM qemu.MachineVM
+ }
+ infos := make([]fakeInfos, 0, 2)
+ err = json.Unmarshal(inspectSession.Bytes(), &infos)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(len(infos)).To(Equal(2))
+
+ //rm := new(rmMachine)
+ //// Must manually clean up due to multiple names
+ //for _, name := range []string{"foo1", "foo2"} {
+ // mb.setName(name).setCmd(rm.withForce()).run()
+ // mb.names = []string{}
+ //}
+ //mb.names = []string{}
+
+ })
+})
diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go
new file mode 100644
index 000000000..e7a439945
--- /dev/null
+++ b/pkg/machine/e2e/list_test.go
@@ -0,0 +1,79 @@
+package e2e
+
+import (
+ "strings"
+
+ "github.com/containers/buildah/util"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("podman machine list", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("list machine", func() {
+ list := new(listMachine)
+ firstList, err := mb.setCmd(list).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(firstList).Should(Exit(0))
+ Expect(len(firstList.outputToStringSlice())).To(Equal(1)) // just the header
+
+ i := new(initMachine)
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ secondList, err := mb.setCmd(list).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(secondList).To(Exit(0))
+ Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // one machine and the header
+ })
+
+ It("list machines with quiet", func() {
+ // Random names for machines to test list
+ name1 := randomString(12)
+ name2 := randomString(12)
+
+ list := new(listMachine)
+ firstList, err := mb.setCmd(list.withQuiet()).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(firstList).Should(Exit(0))
+ Expect(len(firstList.outputToStringSlice())).To(Equal(0)) // No header with quiet
+
+ i := new(initMachine)
+ session, err := mb.setName(name1).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ session2, err := mb.setName(name2).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session2).To(Exit(0))
+
+ secondList, err := mb.setCmd(list.withQuiet()).run()
+ Expect(err).NotTo(HaveOccurred())
+ Expect(secondList).To(Exit(0))
+ Expect(len(secondList.outputToStringSlice())).To(Equal(2)) // two machines, no header
+
+ listNames := secondList.outputToStringSlice()
+ stripAsterisk(listNames)
+ Expect(util.StringInSlice(name1, listNames)).To(BeTrue())
+ Expect(util.StringInSlice(name2, listNames)).To(BeTrue())
+ })
+})
+
+func stripAsterisk(sl []string) {
+ for idx, val := range sl {
+ sl[idx] = strings.TrimRight(val, "*")
+ }
+}
diff --git a/pkg/machine/e2e/machine_test.go b/pkg/machine/e2e/machine_test.go
new file mode 100644
index 000000000..46fe18069
--- /dev/null
+++ b/pkg/machine/e2e/machine_test.go
@@ -0,0 +1,129 @@
+package e2e
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ url2 "net/url"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/containers/podman/v4/pkg/machine"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestMain(m *testing.M) {
+ os.Exit(m.Run())
+}
+
+const (
+ defaultStream string = "podman-testing"
+ tmpDir string = "/var/tmp"
+)
+
+var (
+ fqImageName string
+ suiteImageName string
+)
+
+// TestLibpod ginkgo master function
+func TestMachine(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Podman Machine tests")
+}
+
+var _ = BeforeSuite(func() {
+ fcd, err := machine.GetFCOSDownload(defaultStream)
+ if err != nil {
+ Fail("unable to get virtual machine image")
+ }
+ suiteImageName = strings.TrimSuffix(path.Base(fcd.Location), ".xz")
+ fqImageName = filepath.Join(tmpDir, suiteImageName)
+ if _, err := os.Stat(fqImageName); err != nil {
+ if os.IsNotExist(err) {
+ getMe, err := url2.Parse(fcd.Location)
+ if err != nil {
+ Fail(fmt.Sprintf("unable to create url for download: %q", err))
+ }
+ now := time.Now()
+ if err := machine.DownloadVMImage(getMe, fqImageName+".xz"); err != nil {
+ Fail(fmt.Sprintf("unable to download machine image: %q", err))
+ }
+ fmt.Println("Download took: ", time.Since(now).String())
+ if err := machine.Decompress(fqImageName+".xz", fqImageName); err != nil {
+ Fail(fmt.Sprintf("unable to decompress image file: %q", err))
+ }
+ } else {
+ Fail(fmt.Sprintf("unable to check for cache image: %q", err))
+ }
+ }
+})
+
+var _ = SynchronizedAfterSuite(func() {},
+ func() {
+ fmt.Println("After")
+ })
+
+func setup() (string, *machineTestBuilder) {
+ homeDir, err := ioutil.TempDir("/var/tmp", "podman_test")
+ if err != nil {
+ Fail(fmt.Sprintf("failed to create home directory: %q", err))
+ }
+ if err := os.MkdirAll(filepath.Join(homeDir, ".ssh"), 0700); err != nil {
+ Fail(fmt.Sprintf("failed to create ssh dir: %q", err))
+ }
+ sshConfig, err := os.Create(filepath.Join(homeDir, ".ssh", "config"))
+ if err != nil {
+ Fail(fmt.Sprintf("failed to create ssh config: %q", err))
+ }
+ if _, err := sshConfig.WriteString("IdentitiesOnly=yes"); err != nil {
+ Fail(fmt.Sprintf("failed to write ssh config: %q", err))
+ }
+ if err := sshConfig.Close(); err != nil {
+ Fail(fmt.Sprintf("unable to close ssh config file descriptor: %q", err))
+ }
+ if err := os.Setenv("HOME", homeDir); err != nil {
+ Fail("failed to set home dir")
+ }
+ if err := os.Unsetenv("SSH_AUTH_SOCK"); err != nil {
+ Fail("unable to unset SSH_AUTH_SOCK")
+ }
+ mb, err := newMB()
+ if err != nil {
+ Fail(fmt.Sprintf("failed to create machine test: %q", err))
+ }
+ f, err := os.Open(fqImageName)
+ if err != nil {
+ Fail(fmt.Sprintf("failed to open file %s: %q", fqImageName, err))
+ }
+ mb.imagePath = filepath.Join(homeDir, suiteImageName)
+ n, err := os.Create(mb.imagePath)
+ if err != nil {
+ Fail(fmt.Sprintf("failed to create file %s: %q", mb.imagePath, err))
+ }
+ if _, err := io.Copy(n, f); err != nil {
+ Fail(fmt.Sprintf("failed to copy %ss to %s: %q", fqImageName, mb.imagePath, err))
+ }
+ return homeDir, mb
+}
+
+func teardown(origHomeDir string, testDir string, mb *machineTestBuilder) {
+ s := new(stopMachine)
+ for _, name := range mb.names {
+ if _, err := mb.setName(name).setCmd(s).run(); err != nil {
+ fmt.Printf("error occured rm'ing machine: %q\n", err)
+ }
+ }
+ if err := os.RemoveAll(testDir); err != nil {
+ Fail(fmt.Sprintf("failed to remove test dir: %q", err))
+ }
+ // this needs to be last in teardown
+ if err := os.Setenv("HOME", origHomeDir); err != nil {
+ Fail("failed to set home dir")
+ }
+}
diff --git a/pkg/machine/e2e/rm_test.go b/pkg/machine/e2e/rm_test.go
new file mode 100644
index 000000000..011da5dde
--- /dev/null
+++ b/pkg/machine/e2e/rm_test.go
@@ -0,0 +1,67 @@
+package e2e
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("podman machine rm", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("bad init name", func() {
+ i := rmMachine{}
+ reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ session, err := mb.setName(reallyLongName).setCmd(&i).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(125))
+ })
+
+ It("Remove machine", func() {
+ i := new(initMachine)
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+ rm := rmMachine{}
+ _, err = mb.setCmd(rm.withForce()).run()
+ Expect(err).To(BeNil())
+
+ // Inspecting a non-existent machine should fail
+ // which means it is gone
+ _, ec, err := mb.toQemuInspectInfo()
+ Expect(err).To(BeNil())
+ Expect(ec).To(Equal(125))
+ })
+
+ It("Remove running machine", func() {
+ i := new(initMachine)
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath).withNow()).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+ rm := new(rmMachine)
+
+ // Removing a running machine should fail
+ stop, err := mb.setCmd(rm).run()
+ Expect(err).To(BeNil())
+ Expect(stop.ExitCode()).To(Equal(125))
+
+ // Removing again with force
+ stopAgain, err := mb.setCmd(rm.withForce()).run()
+ Expect(err).To(BeNil())
+ Expect(stopAgain.ExitCode()).To(BeZero())
+
+ // Inspect to be dead sure
+ _, ec, err := mb.toQemuInspectInfo()
+ Expect(err).To(BeNil())
+ Expect(ec).To(Equal(125))
+ })
+})
diff --git a/pkg/machine/e2e/ssh_test.go b/pkg/machine/e2e/ssh_test.go
new file mode 100644
index 000000000..90296fa10
--- /dev/null
+++ b/pkg/machine/e2e/ssh_test.go
@@ -0,0 +1,59 @@
+package e2e
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("podman machine ssh", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("bad machine name", func() {
+ name := randomString(12)
+ ssh := sshMachine{}
+ session, err := mb.setName(name).setCmd(ssh).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(125))
+ // TODO seems like stderr is not being returned; re-enabled when fixed
+ //Expect(session.outputToString()).To(ContainSubstring("not exist"))
+ })
+
+ It("ssh to non-running machine", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+
+ ssh := sshMachine{}
+ sshSession, err := mb.setName(name).setCmd(ssh).run()
+ Expect(err).To(BeNil())
+ // TODO seems like stderr is not being returned; re-enabled when fixed
+ //Expect(sshSession.outputToString()).To(ContainSubstring("is not running"))
+ Expect(sshSession.ExitCode()).To(Equal(125))
+ })
+
+ It("ssh to running machine and check os-type", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withNow()).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+
+ ssh := sshMachine{}
+ sshSession, err := mb.setName(name).setCmd(ssh.withSSHComand([]string{"cat", "/etc/os-release"})).run()
+ Expect(err).To(BeNil())
+ Expect(sshSession.ExitCode()).To(Equal(0))
+ Expect(sshSession.outputToString()).To(ContainSubstring("Fedora CoreOS"))
+ })
+})
diff --git a/pkg/machine/e2e/start_test.go b/pkg/machine/e2e/start_test.go
new file mode 100644
index 000000000..1cda0e8f1
--- /dev/null
+++ b/pkg/machine/e2e/start_test.go
@@ -0,0 +1,36 @@
+package e2e
+
+import (
+ "github.com/containers/podman/v4/pkg/machine"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("podman machine start", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("start simple machine", func() {
+ i := new(initMachine)
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+ s := new(startMachine)
+ startSession, err := mb.setCmd(s).run()
+ Expect(err).To(BeNil())
+ Expect(startSession.ExitCode()).To(Equal(0))
+
+ info, ec, err := mb.toQemuInspectInfo()
+ Expect(err).To(BeNil())
+ Expect(ec).To(BeZero())
+ Expect(info[0].State).To(Equal(machine.Running))
+ })
+})
diff --git a/pkg/machine/e2e/stop_test.go b/pkg/machine/e2e/stop_test.go
new file mode 100644
index 000000000..5dee6a345
--- /dev/null
+++ b/pkg/machine/e2e/stop_test.go
@@ -0,0 +1,46 @@
+package e2e
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("podman machine stop", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("stop bad name", func() {
+ i := stopMachine{}
+ reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ session, err := mb.setName(reallyLongName).setCmd(&i).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(125))
+ })
+
+ It("Stop running machine", func() {
+ i := new(initMachine)
+ session, err := mb.setCmd(i.withImagePath(mb.imagePath).withNow()).run()
+ Expect(err).To(BeNil())
+ Expect(session.ExitCode()).To(Equal(0))
+
+ stop := new(stopMachine)
+ // Removing a running machine should fail
+ stopSession, err := mb.setCmd(stop).run()
+ Expect(err).To(BeNil())
+ Expect(stopSession.ExitCode()).To(Equal(0))
+
+ // Stopping it again should not result in an error
+ stopAgain, err := mb.setCmd(stop).run()
+ Expect(err).To(BeNil())
+ Expect(stopAgain.ExitCode()).To(BeZero())
+ })
+})
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index d8516dd59..df58b8a1e 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -43,7 +43,7 @@ type FcosDownload struct {
}
func NewFcosDownloader(vmType, vmName, imageStream string) (DistributionDownload, error) {
- info, err := getFCOSDownload(imageStream)
+ info, err := GetFCOSDownload(imageStream)
if err != nil {
return nil, err
}
@@ -79,7 +79,7 @@ func (f FcosDownload) Get() *Download {
return &f.Download
}
-type fcosDownloadInfo struct {
+type FcosDownloadInfo struct {
CompressionType string
Location string
Release string
@@ -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) { // nolint:staticcheck
+func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) { //nolint:staticcheck
var (
fcosstable stream.Stream
altMeta release.Release
@@ -150,8 +150,8 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { // nolint:
// 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"
+
+ imageStream = "podman-testing" //nolint:staticcheck
switch imageStream {
case "podman-testing":
@@ -194,7 +194,7 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { // nolint:
}
disk := qcow2.Disk
- return &fcosDownloadInfo{
+ return &FcosDownloadInfo{
Location: disk.Location,
Sha256Sum: disk.Sha256,
CompressionType: "xz",
@@ -228,7 +228,7 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) { // nolint:
if disk == nil {
return nil, fmt.Errorf("unable to pull VM image: no disk in stream")
}
- return &fcosDownloadInfo{
+ return &FcosDownloadInfo{
Location: disk.Location,
Release: qemu.Release,
Sha256Sum: disk.Sha256,
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index fe47437e3..35a9a30cb 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -304,6 +304,8 @@ ExecStart=/usr/bin/sleep infinity
containers := `[containers]
netns="bridge"
`
+ // Set deprecated machine_enabled until podman package on fcos is
+ // current enough to no longer require it
rootContainers := `[engine]
machine_enabled=true
`
@@ -392,7 +394,7 @@ Delegate=memory pids cpu io
FileEmbedded1: FileEmbedded1{Mode: intToPtr(0644)},
})
- // Set machine_enabled to true to indicate we're in a VM
+ // Set deprecated machine_enabled to true to indicate we're in a VM
files = append(files, File{
Node: Node{
Group: getNodeGrp("root"),
@@ -408,6 +410,22 @@ Delegate=memory pids cpu io
},
})
+ // Set machine marker file to indicate podman is in a qemu based machine
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: "/etc/containers/podman-machine",
+ User: getNodeUsr("root"),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr("qemu\n"),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
+
// Issue #11489: make sure that we can inject a custom registries.conf
// file on the system level to force a single search registry.
// The remote client does not yet support prompting for short-name
diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go
index 840bd5c59..9473eef6f 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 rootfull or rootless manner
- Rootfull bool
+ // Whether this machine should run in a rootful or rootless manner
+ Rootful bool
// UID is the numerical id of the user that called machine
UID int
}
@@ -105,8 +105,8 @@ type ImageConfig struct {
// HostUser describes the host user
type HostUser struct {
- // Whether this machine should run in a rootfull or rootless manner
- Rootfull bool
+ // Whether this machine should run in a rootful or rootless manner
+ Rootful 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 c54d18a4b..969acb760 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -76,7 +76,6 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) {
return nil, err
}
vm.IgnitionFilePath = *ignitionFile
-
imagePath, err := NewMachineFile(opts.ImagePath, nil)
if err != nil {
return nil, err
@@ -206,7 +205,7 @@ func migrateVM(configPath string, config []byte, vm *MachineVM) error {
vm.QMPMonitor = qmpMonitor
vm.ReadySocket = readySocket
vm.RemoteUsername = old.RemoteUsername
- vm.Rootfull = old.Rootfull
+ vm.Rootful = old.Rootful
vm.UID = old.UID
// Backup the original config file
@@ -260,7 +259,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
)
sshDir := filepath.Join(homedir.Get(), ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootfull = opts.Rootfull
+ v.Rootful = opts.Rootful
switch opts.ImagePath {
case Testing, Next, Stable, "":
@@ -358,8 +357,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 rootfull
- if opts.Rootfull {
+ // regardless of IsDefault, so order according to rootful
+ if opts.Rootful {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -375,7 +374,6 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
if err := v.writeConfig(); err != nil {
return false, fmt.Errorf("writing JSON file: %w", err)
}
-
// User has provided ignition file so keygen
// will be skipped.
if len(opts.IgnitionPath) < 1 {
@@ -389,7 +387,6 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
if err := v.prepare(); err != nil {
return false, err
}
-
originalDiskSize, err := getDiskSize(v.getImageFile())
if err != nil {
return false, err
@@ -437,7 +434,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
}
func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
- if v.Rootfull == opts.Rootfull {
+ if v.Rootful == opts.Rootful {
return nil
}
@@ -461,7 +458,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootfull {
+ if opts.Rootful {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -469,7 +466,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
}
}
- v.Rootfull = opts.Rootfull
+ v.Rootful = opts.Rootful
return v.writeConfig()
}
@@ -528,17 +525,28 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
time.Sleep(wait)
wait++
}
+ defer qemuSocketConn.Close()
if err != nil {
return err
}
-
fd, err := qemuSocketConn.(*net.UnixConn).File()
if err != nil {
return err
}
+ defer fd.Close()
+ dnr, err := os.OpenFile("/dev/null", os.O_RDONLY, 0755)
+ if err != nil {
+ return err
+ }
+ defer dnr.Close()
+ dnw, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755)
+ if err != nil {
+ return err
+ }
+ defer dnw.Close()
attr := new(os.ProcAttr)
- files := []*os.File{os.Stdin, os.Stdout, os.Stderr, fd}
+ files := []*os.File{dnr, dnw, dnw, fd}
attr.Files = files
logrus.Debug(v.CmdLine)
cmd := v.CmdLine
@@ -566,7 +574,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
_, err = os.StartProcess(cmd[0], cmd, attr)
if err != nil {
- return err
+ return errors.Wrapf(err, "unable to execute %q", cmd)
}
}
fmt.Println("Waiting for VM ...")
@@ -589,11 +597,11 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if err != nil {
return err
}
+ defer conn.Close()
_, err = bufio.NewReader(conn).ReadString('\n')
if err != nil {
return err
}
-
if len(v.Mounts) > 0 {
state, err := v.State(true)
if err != nil {
@@ -944,7 +952,7 @@ func (v *MachineVM) SSH(_ string, opts machine.SSHOptions) error {
sshDestination := username + "@localhost"
port := strconv.Itoa(v.Port)
- args := []string{"-i", v.IdentityPath, "-p", port, sshDestination, "-o", "UserKnownHostsFile /dev/null", "-o", "StrictHostKeyChecking no"}
+ args := []string{"-i", v.IdentityPath, "-p", port, sshDestination, "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no"}
if len(opts.Args) > 0 {
args = append(args, opts.Args...)
} else {
@@ -1120,9 +1128,19 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
}
attr := new(os.ProcAttr)
- // Pass on stdin, stdout, stderr
- files := []*os.File{os.Stdin, os.Stdout, os.Stderr}
- attr.Files = files
+ dnr, err := os.OpenFile("/dev/null", os.O_RDONLY, 0755)
+ if err != nil {
+ return "", noForwarding, err
+ }
+ dnw, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755)
+ if err != nil {
+ return "", noForwarding, err
+ }
+
+ defer dnr.Close()
+ defer dnw.Close()
+
+ attr.Files = []*os.File{dnr, dnw, dnw}
cmd := []string{binary}
cmd = append(cmd, []string{"-listen-qemu", fmt.Sprintf("unix://%s", v.QMPMonitor.Address.GetPath()), "-pid-file", v.PidFilePath.GetPath()}...)
// Add the ssh port
@@ -1139,7 +1157,7 @@ func (v *MachineVM) startHostNetworking() (string, apiForwardingState, error) {
fmt.Println(cmd)
}
_, err = os.StartProcess(cmd[0], cmd, attr)
- return forwardSock, state, err
+ return forwardSock, state, errors.Wrapf(err, "unable to execute: %q", cmd)
}
func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwardingState) {
@@ -1152,7 +1170,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.Rootfull {
+ if v.Rootful {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
@@ -1358,11 +1376,11 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
}
waitAndPingAPI(forwardSock)
- if !v.Rootfull {
+ if !v.Rootful {
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 --rootfull%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootful%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 6e0453f8f..f57dbd299 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 rootfull or rootless manner
- Rootfull bool
+ // Whether this machine should run in a rootful or rootless manner
+ Rootful 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.Rootfull = opts.Rootfull
+ v.Rootful = opts.Rootful
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 rootfull
- if opts.Rootfull {
+ // regardless of IsDefault, so order according to rootful
+ if opts.Rootful {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -448,6 +448,10 @@ func configureSystem(v *MachineVM, dist string) error {
return errors.Wrap(err, "could not create containers.conf for guest OS")
}
+ if err := runCmdPassThrough("wsl", "-d", dist, "sh", "-c", "echo wsl > /etc/containers/podman-machine"); err != nil {
+ return errors.Wrap(err, "could not create podman-machine file for guest OS")
+ }
+
return nil
}
@@ -733,7 +737,7 @@ func pipeCmdPassThrough(name string, input string, arg ...string) error {
}
func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
- if v.Rootfull == opts.Rootfull {
+ if v.Rootful == opts.Rootful {
return nil
}
@@ -744,7 +748,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootfull {
+ if opts.Rootful {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -752,7 +756,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
}
}
- v.Rootfull = opts.Rootfull
+ v.Rootful = opts.Rootful
return v.writeConfig()
}
@@ -768,7 +772,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return errors.Wrap(err, "WSL bootstrap script failed")
}
- if !v.Rootfull {
+ if !v.Rootful {
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 +781,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if name != machine.DefaultMachineName {
suffix = " " + name
}
- fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
}
globalName, pipeName, err := launchWinProxy(v)
@@ -833,7 +837,7 @@ func launchWinProxy(v *MachineVM) (bool, string, error) {
destSock := "/run/user/1000/podman/podman.sock"
forwardUser := v.RemoteUsername
- if v.Rootfull {
+ if v.Rootful {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
diff --git a/pkg/signal/signal_common_test.go b/pkg/signal/signal_common_test.go
new file mode 100644
index 000000000..c4ae6b389
--- /dev/null
+++ b/pkg/signal/signal_common_test.go
@@ -0,0 +1,120 @@
+package signal
+
+import (
+ "syscall"
+ "testing"
+)
+
+func TestParseSignal(t *testing.T) {
+ type args struct {
+ rawSignal string
+ }
+ tests := []struct {
+ name string
+ args args
+ want syscall.Signal
+ wantErr bool
+ }{
+ {
+ name: "KILL to SIGKILL",
+ args: args{
+ rawSignal: "KILL",
+ },
+ want: syscall.SIGKILL,
+ wantErr: false,
+ },
+ {
+ name: "Case doesnt matter",
+ args: args{
+ rawSignal: "kIlL",
+ },
+ want: syscall.SIGKILL,
+ wantErr: false,
+ },
+ {
+ name: "Garbage signal",
+ args: args{
+ rawSignal: "FOO",
+ },
+ want: -1,
+ wantErr: true,
+ },
+ {
+ name: "Signal with prepended SIG",
+ args: args{
+ rawSignal: "SIGKILL",
+ },
+ want: syscall.SIGKILL,
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := ParseSignal(tt.args.rawSignal)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("ParseSignal() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("ParseSignal() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestParseSignalNameOrNumber(t *testing.T) {
+ type args struct {
+ rawSignal string
+ }
+ tests := []struct {
+ name string
+ args args
+ want syscall.Signal
+ wantErr bool
+ }{
+ {
+ name: "Kill should work",
+ args: args{
+ rawSignal: "kill",
+ },
+ want: syscall.SIGKILL,
+ wantErr: false,
+ },
+ {
+ name: "9 for kill should work",
+ args: args{
+ rawSignal: "9",
+ },
+ want: syscall.SIGKILL,
+ wantErr: false,
+ },
+ {
+ name: "Non-defined signal number should work",
+ args: args{
+ rawSignal: "923",
+ },
+ want: 923,
+ wantErr: false,
+ },
+ {
+ name: "garbage should fail",
+ args: args{
+ rawSignal: "foo",
+ },
+ want: -1,
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := ParseSignalNameOrNumber(tt.args.rawSignal)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("ParseSignalNameOrNumber() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("ParseSignalNameOrNumber() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 021b88280..50454cbab 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -146,13 +146,13 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
options = append(options, libpod.WithHostUsers(s.HostUsers))
}
- command, err := makeCommand(ctx, s, imageData, rtc)
+ command, err := makeCommand(s, imageData, rtc)
if err != nil {
return nil, nil, nil, err
}
infraVol := (len(compatibleOptions.Mounts) > 0 || len(compatibleOptions.Volumes) > 0 || len(compatibleOptions.ImageVolumes) > 0 || len(compatibleOptions.OverlayVolumes) > 0)
- opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, finalOverlays, imageData, command, infraVol, *compatibleOptions)
+ opts, err := createContainerOptions(rt, s, pod, finalVolumes, finalOverlays, imageData, command, infraVol, *compatibleOptions)
if err != nil {
return nil, nil, nil, err
}
@@ -251,7 +251,7 @@ func isCDIDevice(device string) bool {
return cdi.IsQualifiedName(device)
}
-func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, overlays []*specgen.OverlayVolume, imageData *libimage.ImageData, command []string, infraVolumes bool, compatibleOptions libpod.InfraInherit) ([]libpod.CtrCreateOption, error) {
+func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, overlays []*specgen.OverlayVolume, imageData *libimage.ImageData, command []string, infraVolumes bool, compatibleOptions libpod.InfraInherit) ([]libpod.CtrCreateOption, error) {
var options []libpod.CtrCreateOption
var err error
@@ -453,7 +453,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
options = append(options, libpod.WithPrivileged(s.Privileged))
// Get namespace related options
- namespaceOpts, err := namespaceOptions(ctx, s, rt, pod, imageData)
+ namespaceOpts, err := namespaceOptions(s, rt, pod, imageData)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index d8d1ae652..2362f61c4 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -1,7 +1,6 @@
package generate
import (
- "context"
"fmt"
"os"
"strings"
@@ -80,7 +79,7 @@ func GetDefaultNamespaceMode(nsType string, cfg *config.Config, pod *libpod.Pod)
// joining a pod.
// TODO: Consider grouping options that are not directly attached to a namespace
// elsewhere.
-func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.Pod, imageData *libimage.ImageData) ([]libpod.CtrCreateOption, error) {
+func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod.Pod, imageData *libimage.ImageData) ([]libpod.CtrCreateOption, error) {
toReturn := []libpod.CtrCreateOption{}
// If pod is not nil, get infra container.
@@ -256,7 +255,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
}
toReturn = append(toReturn, libpod.WithNetNSFrom(netCtr))
case specgen.Slirp:
- portMappings, expose, err := createPortMappings(ctx, s, imageData)
+ portMappings, expose, err := createPortMappings(s, imageData)
if err != nil {
return nil, err
}
@@ -268,7 +267,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
case specgen.Private:
fallthrough
case specgen.Bridge:
- portMappings, expose, err := createPortMappings(ctx, s, imageData)
+ portMappings, expose, err := createPortMappings(s, imageData)
if err != nil {
return nil, err
}
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index 961cea933..95bcea8f0 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -32,7 +32,7 @@ func setProcOpts(s *specgen.SpecGenerator, g *generate.Generator) {
}
}
-func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
+func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) {
var (
isRootless = rootless.IsRootless()
nofileSet = false
@@ -41,7 +41,7 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
if s.Rlimits == nil {
g.Config.Process.Rlimits = nil
- return nil
+ return
}
for _, u := range s.Rlimits {
@@ -91,12 +91,10 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
}
g.AddProcessRlimits("RLIMIT_NPROC", max, current)
}
-
- return nil
}
// Produce the final command for the container.
-func makeCommand(ctx context.Context, s *specgen.SpecGenerator, imageData *libimage.ImageData, rtc *config.Config) ([]string, error) {
+func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData, rtc *config.Config) ([]string, error) {
finalCommand := []string{}
entrypoint := s.Entrypoint
@@ -388,9 +386,7 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
g.AddProcessEnv(name, val)
}
- if err := addRlimits(s, &g); err != nil {
- return nil, err
- }
+ addRlimits(s, &g)
// NAMESPACES
if err := specConfigureNamespaces(s, &g, rt, pod); err != nil {
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index ba823f3a8..a3408b402 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -119,7 +119,7 @@ func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
}
}
- options, err := createPodOptions(&p.PodSpecGen, rt, p.PodSpecGen.InfraContainerSpec)
+ options, err := createPodOptions(&p.PodSpecGen)
if err != nil {
return nil, err
}
@@ -161,11 +161,11 @@ func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
return pod, nil
}
-func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime, infraSpec *specgen.SpecGenerator) ([]libpod.PodCreateOption, error) {
+func createPodOptions(p *specgen.PodSpecGenerator) ([]libpod.PodCreateOption, error) {
var (
options []libpod.PodCreateOption
)
- if !p.NoInfra { //&& infraSpec != nil {
+ if !p.NoInfra {
options = append(options, libpod.WithInfraContainer())
if p.ShareParent == nil || (p.ShareParent != nil && *p.ShareParent) {
options = append(options, libpod.WithPodParent())
diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go
index c30c4e49d..bec548d3b 100644
--- a/pkg/specgen/generate/ports.go
+++ b/pkg/specgen/generate/ports.go
@@ -1,7 +1,6 @@
package generate
import (
- "context"
"fmt"
"net"
"sort"
@@ -338,7 +337,7 @@ func appendProtocolsNoDuplicates(slice []string, protocols []string) []string {
}
// Make final port mappings for the container
-func createPortMappings(ctx context.Context, s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]types.PortMapping, map[uint16][]string, error) {
+func createPortMappings(s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]types.PortMapping, map[uint16][]string, error) {
expose := make(map[uint16]string)
var err error
if imageData != nil {
diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go
index eca8c0c35..b26666df3 100644
--- a/pkg/specgen/volumes.go
+++ b/pkg/specgen/volumes.go
@@ -65,7 +65,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
err error
)
- splitVol := strings.Split(vol, ":")
+ splitVol := SplitVolumeString(vol)
if len(splitVol) > 3 {
return nil, nil, nil, errors.Wrapf(volumeFormatErr, vol)
}
@@ -93,7 +93,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
}
}
- if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") {
+ if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") || isHostWinPath(src) {
// This is not a named volume
overlayFlag := false
chownFlag := false
@@ -152,3 +152,26 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
return mounts, volumes, overlayVolumes, nil
}
+
+// Splits a volume string, accounting for Win drive paths
+// when running as a WSL linux guest or Windows client
+func SplitVolumeString(vol string) []string {
+ parts := strings.Split(vol, ":")
+ if !shouldResolveWinPaths() {
+ return parts
+ }
+
+ // Skip extended marker prefix if present
+ n := 0
+ if strings.HasPrefix(vol, `\\?\`) {
+ n = 4
+ }
+
+ if hasWinDriveScheme(vol, n) {
+ first := parts[0] + ":" + parts[1]
+ parts = parts[1:]
+ parts[0] = first
+ }
+
+ return parts
+}
diff --git a/pkg/specgen/winpath.go b/pkg/specgen/winpath.go
new file mode 100644
index 000000000..f4249fab1
--- /dev/null
+++ b/pkg/specgen/winpath.go
@@ -0,0 +1,59 @@
+package specgen
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+
+ "github.com/pkg/errors"
+)
+
+func isHostWinPath(path string) bool {
+ return shouldResolveWinPaths() && strings.HasPrefix(path, `\\`) || hasWinDriveScheme(path, 0) || winPathExists(path)
+}
+
+func hasWinDriveScheme(path string, start int) bool {
+ if len(path) < start+2 || path[start+1] != ':' {
+ return false
+ }
+
+ drive := rune(path[start])
+ return drive < unicode.MaxASCII && unicode.IsLetter(drive)
+}
+
+// Converts a Windows path to a WSL guest path if local env is a WSL linux guest or this is a Windows client.
+func ConvertWinMountPath(path string) (string, error) {
+ if !shouldResolveWinPaths() {
+ return path, nil
+ }
+
+ if strings.HasPrefix(path, "/") {
+ // Handle /[driveletter]/windows/path form (e.g. c:\Users\bar == /c/Users/bar)
+ if len(path) > 2 && path[2] == '/' && shouldResolveUnixWinVariant(path) {
+ drive := unicode.ToLower(rune(path[1]))
+ if unicode.IsLetter(drive) && drive <= unicode.MaxASCII {
+ return fmt.Sprintf("/mnt/%c/%s", drive, path[3:]), nil
+ }
+ }
+
+ // unix path - pass through
+ return path, nil
+ }
+
+ // Convert remote win client relative paths to absolute
+ path = resolveRelativeOnWindows(path)
+
+ // Strip extended marker prefix if present
+ path = strings.TrimPrefix(path, `\\?\`)
+
+ // Drive installed via wsl --mount
+ if strings.HasPrefix(path, `\\.\`) {
+ path = "/mnt/wsl/" + path[4:]
+ } else if len(path) > 1 && path[1] == ':' {
+ path = "/mnt/" + strings.ToLower(path[0:1]) + path[2:]
+ } else {
+ return path, errors.New("unsupported UNC path")
+ }
+
+ return strings.ReplaceAll(path, `\`, "/"), nil
+}
diff --git a/pkg/specgen/winpath_linux.go b/pkg/specgen/winpath_linux.go
new file mode 100644
index 000000000..f42ac7639
--- /dev/null
+++ b/pkg/specgen/winpath_linux.go
@@ -0,0 +1,24 @@
+package specgen
+
+import (
+ "os"
+
+ "github.com/containers/common/pkg/machine"
+)
+
+func shouldResolveWinPaths() bool {
+ return machine.MachineHostType() == "wsl"
+}
+
+func shouldResolveUnixWinVariant(path string) bool {
+ _, err := os.Stat(path)
+ return err != nil
+}
+
+func resolveRelativeOnWindows(path string) string {
+ return path
+}
+
+func winPathExists(path string) bool {
+ return false
+}
diff --git a/pkg/specgen/winpath_unsupported.go b/pkg/specgen/winpath_unsupported.go
new file mode 100644
index 000000000..4cd008fdd
--- /dev/null
+++ b/pkg/specgen/winpath_unsupported.go
@@ -0,0 +1,20 @@
+//go:build !linux && !windows
+// +build !linux,!windows
+
+package specgen
+
+func shouldResolveWinPaths() bool {
+ return false
+}
+
+func shouldResolveUnixWinVariant(path string) bool {
+ return false
+}
+
+func resolveRelativeOnWindows(path string) string {
+ return path
+}
+
+func winPathExists(path string) bool {
+ return false
+}
diff --git a/pkg/specgen/winpath_windows.go b/pkg/specgen/winpath_windows.go
new file mode 100644
index 000000000..c6aad314a
--- /dev/null
+++ b/pkg/specgen/winpath_windows.go
@@ -0,0 +1,30 @@
+package specgen
+
+import (
+ "github.com/sirupsen/logrus"
+ "os"
+ "path/filepath"
+)
+
+func shouldResolveUnixWinVariant(path string) bool {
+ return true
+}
+
+func shouldResolveWinPaths() bool {
+ return true
+}
+
+func resolveRelativeOnWindows(path string) string {
+ ret, err := filepath.Abs(path)
+ if err != nil {
+ logrus.Debugf("problem resolving possible relative path %q: %s", path, err.Error())
+ return path
+ }
+
+ return ret
+}
+
+func winPathExists(path string) bool {
+ _, err := os.Stat(path)
+ return err == nil
+}
diff --git a/pkg/specgenutil/ports_test.go b/pkg/specgenutil/ports_test.go
new file mode 100644
index 000000000..3f62c619c
--- /dev/null
+++ b/pkg/specgenutil/ports_test.go
@@ -0,0 +1,57 @@
+package specgenutil
+
+import "testing"
+
+func Test_verifyExpose(t *testing.T) {
+ type args struct {
+ expose []string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "single port with tcp",
+ args: args{
+ expose: []string{"53/tcp"},
+ },
+ wantErr: false,
+ },
+ {
+ name: "single port with udp",
+ args: args{
+ expose: []string{"53/udp"},
+ },
+ wantErr: false,
+ },
+ {
+ name: "good port range",
+ args: args{
+ expose: []string{"100-133"},
+ },
+ wantErr: false,
+ },
+ {
+ name: "high to low should fail",
+ args: args{
+ expose: []string{"100-99"},
+ },
+ wantErr: true,
+ },
+ {
+ name: "range with protocol",
+ args: args{
+ expose: []string{"53/tcp-55/tcp"},
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if err := verifyExpose(tt.args.expose); (err != nil) != tt.wantErr {
+ t.Errorf("verifyExpose() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 00de99817..f0dfcac1a 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -136,7 +136,7 @@ func LimitToSwap(memory *specs.LinuxMemory, swap string, ml int64) {
}
}
-func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) {
+func getMemoryLimits(c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) {
var err error
memory := &specs.LinuxMemory{}
hasLimits := false
@@ -497,7 +497,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
}
if s.ResourceLimits.Memory == nil || (len(c.Memory) != 0 || len(c.MemoryReservation) != 0 || len(c.MemorySwap) != 0 || c.MemorySwappiness != 0) {
- s.ResourceLimits.Memory, err = getMemoryLimits(s, c)
+ s.ResourceLimits.Memory, err = getMemoryLimits(c)
if err != nil {
return err
}
diff --git a/pkg/specgenutil/specgenutil_test.go b/pkg/specgenutil/specgenutil_test.go
new file mode 100644
index 000000000..5867b0ae0
--- /dev/null
+++ b/pkg/specgenutil/specgenutil_test.go
@@ -0,0 +1,77 @@
+//go:build linux
+// +build linux
+
+package specgenutil
+
+import (
+ "testing"
+
+ "github.com/containers/common/pkg/machine"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+ "github.com/containers/podman/v4/pkg/specgen"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestWinPath(t *testing.T) {
+ const (
+ fail = false
+ pass = true
+ )
+ tests := []struct {
+ vol string
+ source string
+ dest string
+ isN bool
+ outcome bool
+ mach string
+ }{
+ {`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"},
+ {`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, fail, ""},
+ {`\\?\C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"},
+ {`/c/bar:/blah`, "/mnt/c/bar", "/blah", false, pass, "wsl"},
+ {`/c/bar:/blah`, "/c/bar", "/blah", false, pass, ""},
+ {`/test/this:/blah`, "/test/this", "/blah", false, pass, "wsl"},
+ {`c:/bar/something:/other`, "/mnt/c/bar/something", "/other", false, pass, "wsl"},
+ {`c:/foo:ro`, "c", "/foo", true, pass, ""},
+ {`\\computer\loc:/dest`, "", "", false, fail, "wsl"},
+ {`\\.\drive\loc:/target`, "/mnt/wsl/drive/loc", "/target", false, pass, "wsl"},
+ }
+
+ f := func(vol string, mach string) (*specgen.SpecGenerator, error) {
+ machine := machine.GetMachineMarker()
+ oldEnable, oldType := machine.Enabled, machine.Type
+ machine.Enabled, machine.Type = len(mach) > 0, mach
+ sg := specgen.NewSpecGenerator("nothing", false)
+ err := FillOutSpecGen(sg, &entities.ContainerCreateOptions{
+ ImageVolume: "ignore",
+ Volume: []string{vol}}, []string{},
+ )
+ machine.Enabled, machine.Type = oldEnable, oldType
+ return sg, err
+ }
+
+ for _, test := range tests {
+ msg := "Checking: " + test.vol
+ sg, err := f(test.vol, test.mach)
+ if test.outcome == fail {
+ assert.NotNil(t, err, msg)
+ continue
+ }
+ if !assert.Nil(t, err, msg) {
+ continue
+ }
+ if test.isN {
+ if !assert.Equal(t, 1, len(sg.Volumes), msg) {
+ continue
+ }
+ assert.Equal(t, test.source, sg.Volumes[0].Name, msg)
+ assert.Equal(t, test.dest, sg.Volumes[0].Dest, msg)
+ } else {
+ if !assert.Equal(t, 1, len(sg.Mounts), msg) {
+ continue
+ }
+ assert.Equal(t, test.source, sg.Mounts[0].Source, msg)
+ assert.Equal(t, test.dest, sg.Mounts[0].Destination, msg)
+ }
+ }
+}
diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go
index 80d31398b..fa2e90457 100644
--- a/pkg/specgenutil/util.go
+++ b/pkg/specgenutil/util.go
@@ -281,6 +281,7 @@ func CreateExitCommandArgs(storageConfig storageTypes.StoreOptions, config *conf
"--tmpdir", config.Engine.TmpDir,
"--network-config-dir", config.Network.NetworkConfigDir,
"--network-backend", config.Network.NetworkBackend,
+ "--volumepath", config.Engine.VolumePath,
}
if config.Engine.OCIRuntime != "" {
command = append(command, []string{"--runtime", config.Engine.OCIRuntime}...)
diff --git a/pkg/specgenutil/util_test.go b/pkg/specgenutil/util_test.go
new file mode 100644
index 000000000..79d60d335
--- /dev/null
+++ b/pkg/specgenutil/util_test.go
@@ -0,0 +1,146 @@
+package specgenutil
+
+import (
+ "reflect"
+ "testing"
+)
+
+func TestCreateExpose(t *testing.T) {
+ single := make(map[uint16]string, 0)
+ single[99] = "tcp"
+
+ simpleRange := make(map[uint16]string, 0)
+ simpleRange[99] = "tcp"
+ simpleRange[100] = "tcp"
+
+ simpleRangeUDP := make(map[uint16]string, 0)
+ simpleRangeUDP[99] = "udp"
+ simpleRangeUDP[100] = "udp"
+ type args struct {
+ expose []string
+ }
+ tests := []struct {
+ name string
+ args args
+ want map[uint16]string
+ wantErr bool
+ }{
+ {
+ name: "single port",
+ args: args{
+ expose: []string{"99"},
+ },
+ want: single,
+ wantErr: false,
+ },
+ {
+ name: "simple range tcp",
+ args: args{
+ expose: []string{"99-100"},
+ },
+ want: simpleRange,
+ wantErr: false,
+ },
+ {
+ name: "simple range udp",
+ args: args{
+ expose: []string{"99-100/udp"},
+ },
+ want: simpleRangeUDP,
+ wantErr: false,
+ },
+ {
+ name: "range inverted should fail",
+ args: args{
+ expose: []string{"100-99"},
+ },
+ want: nil,
+ wantErr: true,
+ },
+ {
+ name: "specifying protocol twice should fail",
+ args: args{
+ expose: []string{"99/tcp-100/tcp"},
+ },
+ want: nil,
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := CreateExpose(tt.args.expose)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("CreateExpose() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("CreateExpose() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func Test_parseAndValidatePort(t *testing.T) {
+ type args struct {
+ port string
+ }
+ tests := []struct {
+ name string
+ args args
+ want uint16
+ wantErr bool
+ }{
+ {
+ name: "0 should fail",
+ args: args{
+ port: "0",
+ },
+ want: 0,
+ wantErr: true,
+ },
+ {
+ name: "over 65535 should fail",
+ args: args{
+ port: "66666",
+ },
+ want: 0,
+ wantErr: true,
+ },
+ {
+ name: "",
+ args: args{
+ port: "99",
+ },
+ want: 99,
+ wantErr: false,
+ },
+ {
+ name: "negative values should fail",
+ args: args{
+ port: "-1",
+ },
+ want: 0,
+ wantErr: true,
+ },
+ {
+ name: "protocol should fail",
+ args: args{
+ port: "99/tcp",
+ },
+ want: 0,
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := parseAndValidatePort(tt.args.port)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("parseAndValidatePort() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("parseAndValidatePort() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index 95ce420f8..50d745380 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -3,7 +3,7 @@ package specgenutil
import (
"encoding/csv"
"fmt"
- "path/filepath"
+ "path"
"strings"
"github.com/containers/common/pkg/parse"
@@ -123,7 +123,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
finalMounts := make([]spec.Mount, 0, len(unifiedMounts))
for _, mount := range unifiedMounts {
if mount.Type == define.TypeBind {
- absSrc, err := filepath.Abs(mount.Source)
+ absSrc, err := specgen.ConvertWinMountPath(mount.Source)
if err != nil {
return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source)
}
@@ -334,7 +334,7 @@ func getBindMount(args []string) (spec.Mount, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
}
- newMount.Destination = filepath.Clean(kv[1])
+ newMount.Destination = unixPathClean(kv[1])
setDest = true
case "relabel":
if setRelabel {
@@ -456,7 +456,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
}
- newMount.Destination = filepath.Clean(kv[1])
+ newMount.Destination = unixPathClean(kv[1])
setDest = true
case "U", "chown":
if setOwnership {
@@ -507,7 +507,7 @@ func getDevptsMount(args []string) (spec.Mount, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
}
- newMount.Destination = filepath.Clean(kv[1])
+ newMount.Destination = unixPathClean(kv[1])
setDest = true
default:
return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
@@ -572,7 +572,7 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return nil, err
}
- newVolume.Dest = filepath.Clean(kv[1])
+ newVolume.Dest = unixPathClean(kv[1])
setDest = true
case "U", "chown":
if setOwnership {
@@ -624,7 +624,7 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return nil, err
}
- newVolume.Destination = filepath.Clean(kv[1])
+ newVolume.Destination = unixPathClean(kv[1])
case "rw", "readwrite":
switch kv[1] {
case "true":
@@ -670,7 +670,7 @@ func getTmpfsMounts(tmpfsFlag []string) (map[string]spec.Mount, error) {
}
mount := spec.Mount{
- Destination: filepath.Clean(destPath),
+ Destination: unixPathClean(destPath),
Type: define.TypeTmpfs,
Options: options,
Source: define.TypeTmpfs,
@@ -700,3 +700,8 @@ func validChownFlag(flag string) (bool, error) {
return true, nil
}
+
+// Use path instead of filepath to preserve Unix style paths on Windows
+func unixPathClean(p string) string {
+ return path.Clean(p)
+}
diff --git a/pkg/specgenutil/volumes_test.go b/pkg/specgenutil/volumes_test.go
new file mode 100644
index 000000000..fc6caf83c
--- /dev/null
+++ b/pkg/specgenutil/volumes_test.go
@@ -0,0 +1,68 @@
+package specgenutil
+
+import "testing"
+
+func Test_validChownFlag(t *testing.T) {
+ type args struct {
+ flag string
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ wantErr bool
+ }{
+ {
+ name: "U true",
+ args: args{
+ flag: "U=true",
+ },
+ want: true,
+ wantErr: false,
+ },
+ {
+ name: "U true case doesnt matter",
+ args: args{
+ flag: "u=True",
+ },
+ want: true,
+ wantErr: false,
+ },
+ {
+ name: "U is false",
+ args: args{
+ flag: "U=false",
+ },
+ want: false,
+ wantErr: false,
+ },
+ {
+ name: "chown should also work",
+ args: args{
+ flag: "chown=true",
+ },
+ want: true,
+ wantErr: false,
+ },
+ {
+ name: "garbage value should fail",
+ args: args{
+ flag: "U=foobar",
+ },
+ want: false,
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := validChownFlag(tt.args.flag)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("validChownFlag() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("validChownFlag() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/rootless.md b/rootless.md
index d485290f2..39c961d2a 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 rootfull users
+* Can not share container images with CRI-O or other rootful 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/common_test.go b/test/e2e/common_test.go
index 5e0c6e837..6846a5677 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -462,7 +462,8 @@ func (p *PodmanTestIntegration) RunNginxWithHealthCheck(name string) (*PodmanSes
if name != "" {
podmanArgs = append(podmanArgs, "--name", name)
}
- podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl http://localhost/", nginx)
+ // curl without -f exits 0 even if http code >= 400!
+ podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl -f http://localhost/", nginx)
session := p.Podman(podmanArgs)
session.WaitWithDefaultTimeout()
return session, session.OutputToString()
@@ -1047,7 +1048,7 @@ var IPRegex = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01
// digShort execs into the given container and does a dig lookup with a timeout
// backoff. If it gets a response, it ensures that the output is in the correct
// format and iterates a string array for match
-func digShort(container, lookupName string, matchNames []string, p *PodmanTestIntegration) string {
+func digShort(container, lookupName string, matchNames []string, p *PodmanTestIntegration) {
digInterval := time.Millisecond * 250
for i := 0; i < 6; i++ {
time.Sleep(digInterval * time.Duration(i))
@@ -1059,9 +1060,9 @@ func digShort(container, lookupName string, matchNames []string, p *PodmanTestIn
for _, name := range matchNames {
Expect(output).To(Equal(name))
}
- return output
+ // success
+ return
}
}
Fail("dns is not responding")
- return ""
}
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 4cfaa9a2e..3987746d0 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 rootfull podman")
+ SkipIfNotRootless("This function is not enabled for rootful podman")
ctrName := "testctr1"
testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"})
testCtr.WaitWithDefaultTimeout()
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 44c906eed..9c99c3d93 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -71,7 +71,7 @@ var _ = Describe("Podman generate kube", func() {
Expect(pod.Spec.DNSConfig).To(BeNil())
Expect(pod.Spec.Containers[0].WorkingDir).To(Equal(""))
Expect(pod.Spec.Containers[0].Env).To(BeNil())
- Expect(pod.Name).To(Equal("top_pod"))
+ Expect(pod.Name).To(Equal("top-pod"))
numContainers := 0
for range pod.Spec.Containers {
diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go
index 830c2dcda..30d7ce8a9 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 rootfull podman")
+ SkipIfNotRootless("This function is not enabled for rootful 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 a7981a4d8..89a9005f5 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() {
- // rootfull image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
+ // rootful 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/play_kube_test.go b/test/e2e/play_kube_test.go
index f16180854..4dd05c755 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -680,7 +680,7 @@ func generateMultiDocKubeYaml(kubeObjects []string, pathname string) error {
return writeYaml(multiKube, pathname)
}
-func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte) {
+func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte) { //nolint:unparam
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
err := ioutil.WriteFile(secretFilePath, value, 0755)
Expect(err).To(BeNil())
@@ -1078,7 +1078,7 @@ func withVolumeMount(mountPath string, readonly bool) ctrOption {
}
}
-func withEnv(name, value, valueFrom, refName, refKey string, optional bool) ctrOption {
+func withEnv(name, value, valueFrom, refName, refKey string, optional bool) ctrOption { //nolint:unparam
return func(c *Ctr) {
e := Env{
Name: name,
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index 6373b949a..2b56502b0 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -119,11 +119,11 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "localhost:80"})
+ session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "-f", "localhost:80"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"run", fedoraMinimal, "curl", "localhost"})
+ session = podmanTest.Podman([]string{"run", fedoraMinimal, "curl", "-f", "localhost"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
})
@@ -219,7 +219,7 @@ var _ = Describe("Podman pod create", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", nginx, "curl", "localhost"})
+ session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", nginx, "curl", "-f", "localhost"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
})
diff --git a/test/e2e/run_aardvark_test.go b/test/e2e/run_aardvark_test.go
index c82f614a6..7b4598423 100644
--- a/test/e2e/run_aardvark_test.go
+++ b/test/e2e/run_aardvark_test.go
@@ -54,7 +54,7 @@ var _ = Describe("Podman run networking", func() {
cip := ctrIP.OutputToString()
Expect(cip).To(MatchRegexp(IPRegex))
- _ = digShort(cid, "aone", []string{cip}, podmanTest)
+ digShort(cid, "aone", []string{cip}, podmanTest)
reverseLookup := podmanTest.Podman([]string{"exec", cid, "dig", "+short", "-x", cip})
reverseLookup.WaitWithDefaultTimeout()
@@ -95,9 +95,9 @@ var _ = Describe("Podman run networking", func() {
cip2 := ctrIP2.OutputToString()
Expect(cip2).To(MatchRegexp(IPRegex))
- _ = digShort("aone", "atwo", []string{cip2}, podmanTest)
+ digShort("aone", "atwo", []string{cip2}, podmanTest)
- _ = digShort("atwo", "aone", []string{cip1}, podmanTest)
+ digShort("atwo", "aone", []string{cip1}, podmanTest)
reverseLookup12 := podmanTest.Podman([]string{"exec", cid1, "dig", "+short", "-x", cip2})
reverseLookup12.WaitWithDefaultTimeout()
@@ -144,17 +144,17 @@ var _ = Describe("Podman run networking", func() {
cip2 := ctrIP2.OutputToString()
Expect(cip2).To(MatchRegexp(IPRegex))
- _ = digShort("aone", "atwo", []string{cip2}, podmanTest)
+ digShort("aone", "atwo", []string{cip2}, podmanTest)
- _ = digShort("aone", "alias_a2", []string{cip2}, podmanTest)
+ digShort("aone", "alias_a2", []string{cip2}, podmanTest)
- _ = digShort("aone", "alias_2a", []string{cip2}, podmanTest)
+ digShort("aone", "alias_2a", []string{cip2}, podmanTest)
- _ = digShort("atwo", "aone", []string{cip1}, podmanTest)
+ digShort("atwo", "aone", []string{cip1}, podmanTest)
- _ = digShort("atwo", "alias_a1", []string{cip1}, podmanTest)
+ digShort("atwo", "alias_a1", []string{cip1}, podmanTest)
- _ = digShort("atwo", "alias_1a", []string{cip1}, podmanTest)
+ digShort("atwo", "alias_1a", []string{cip1}, podmanTest)
})
@@ -251,13 +251,13 @@ var _ = Describe("Podman run networking", func() {
cipA2B22 := ctrIPA2B22.OutputToString()
Expect(cipA2B22).To(MatchRegexp(IPRegex))
- _ = digShort("aone", "atwobtwo", []string{cipA2B21}, podmanTest)
+ digShort("aone", "atwobtwo", []string{cipA2B21}, podmanTest)
- _ = digShort("bone", "atwobtwo", []string{cipA2B22}, podmanTest)
+ digShort("bone", "atwobtwo", []string{cipA2B22}, podmanTest)
- _ = digShort("atwobtwo", "aone", []string{cipA1}, podmanTest)
+ digShort("atwobtwo", "aone", []string{cipA1}, podmanTest)
- _ = digShort("atwobtwo", "bone", []string{cipB1}, podmanTest)
+ digShort("atwobtwo", "bone", []string{cipB1}, podmanTest)
})
It("Aardvark Test 6: Three subnets, first container on 1/2 and second on 2/3, w/ network aliases", func() {
@@ -305,9 +305,9 @@ var _ = Describe("Podman run networking", func() {
Expect(ctrIPCB2).Should(Exit(0))
cipCB2 := ctrIPCB2.OutputToString()
- _ = digShort("aone", "testB2_nw", []string{cipCB2}, podmanTest)
+ digShort("aone", "testB2_nw", []string{cipCB2}, podmanTest)
- _ = digShort("cone", "testB1_nw", []string{cipAB1}, podmanTest)
+ digShort("cone", "testB1_nw", []string{cipAB1}, podmanTest)
})
diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go
index b78a37495..7e61e7c5e 100644
--- a/test/e2e/run_staticip_test.go
+++ b/test/e2e/run_staticip_test.go
@@ -102,22 +102,33 @@ var _ = Describe("Podman run with --ip flag", func() {
It("Podman run two containers with the same IP", func() {
ip := GetRandomIPAddress()
- result := podmanTest.Podman([]string{"run", "-dt", "--ip", ip, nginx})
+ result := podmanTest.Podman([]string{"run", "-d", "--name", "nginx", "--ip", ip, nginx})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
- for i := 0; i < 10; i++ {
- fmt.Println("Waiting for nginx", err)
- time.Sleep(1 * time.Second)
+
+ for retries := 20; retries > 0; retries-- {
response, err := http.Get(fmt.Sprintf("http://%s", ip))
- if err != nil {
- continue
- }
- if response.StatusCode == http.StatusOK {
+ if err == nil && response.StatusCode == http.StatusOK {
break
}
+ if retries == 1 {
+ logps := podmanTest.Podman([]string{"ps", "-a"})
+ logps.WaitWithDefaultTimeout()
+ logps = podmanTest.Podman([]string{"logs", "nginx"})
+ logps.WaitWithDefaultTimeout()
+ Fail("Timed out waiting for nginx container, see ps & log above.")
+ }
+
+ if err != nil {
+ fmt.Printf("nginx not ready yet; error=%v; %d retries left...\n", err, retries)
+ } else {
+ fmt.Printf("nginx not ready yet; response=%v; %d retries left...\n", response.StatusCode, retries)
+ }
+ time.Sleep(1 * time.Second)
}
- result = podmanTest.Podman([]string{"run", "-ti", "--ip", ip, ALPINE, "ip", "addr"})
+ result = podmanTest.Podman([]string{"run", "--ip", ip, ALPINE, "ip", "addr"})
result.WaitWithDefaultTimeout()
Expect(result).To(ExitWithError())
+ Expect(result.ErrorToString()).To(ContainSubstring(" address %s ", ip))
})
})
diff --git a/test/system/005-info.bats b/test/system/005-info.bats
index 1d84ede9b..333553b07 100644
--- a/test/system/005-info.bats
+++ b/test/system/005-info.bats
@@ -107,4 +107,12 @@ host.slirp4netns.executable | $expr_path
fi
}
+@test "podman --root PATH --volumepath info - basic output" {
+ volumePath=${PODMAN_TMPDIR}/volumesGoHere
+ if ! is_remote; then
+ run_podman --storage-driver=vfs --root ${PODMAN_TMPDIR}/nothing-here-move-along --volumepath ${volumePath} info --format '{{ .Store.VolumePath }}'
+ is "$output" "${volumePath}" "'podman --volumepath should reset VolumePath"
+ fi
+}
+
# vim: filetype=sh
diff --git a/test/system/270-socket-activation.bats b/test/system/270-socket-activation.bats
index 19f68abdd..6d582be18 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 rootfull"
+ skip "there is no pause process when running rootful"
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 958aa4493..01571d176 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -83,7 +83,7 @@ load helpers
}
# Issue #5466 - port-forwarding doesn't work with this option and -d
-@test "podman networking: port with --userns=keep-id for rootless or --uidmap=* for rootfull" {
+@test "podman networking: port with --userns=keep-id for rootless or --uidmap=* for rootful" {
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 1a1dc0df9..138d668f4 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -423,7 +423,7 @@ function skip_if_rootless() {
######################
function skip_if_not_rootless() {
if ! is_rootless; then
- local msg=$(_add_label_if_missing "$1" "rootfull")
+ local msg=$(_add_label_if_missing "$1" "rootful")
skip "${msg:-not applicable under rootlfull podman}"
fi
}
@@ -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 rootfull ubuntu, usually due to user errors"
+ skip "Cannot run this test on rootful ubuntu, usually due to user errors"
fi
fi
fi
diff --git a/test/testvol/main.go b/test/testvol/main.go
index 883f55f82..30ab365b3 100644
--- a/test/testvol/main.go
+++ b/test/testvol/main.go
@@ -86,10 +86,7 @@ func startServer(socketPath string) error {
}
}
- handle, err := makeDirDriver(config.path)
- if err != nil {
- return errors.Wrapf(err, "error making volume driver")
- }
+ handle := makeDirDriver(config.path)
logrus.Infof("Using %s for volume path", config.path)
server := volume.NewHandler(handle)
@@ -116,12 +113,12 @@ type dirVol struct {
}
// Make a new DirDriver.
-func makeDirDriver(path string) (volume.Driver, error) {
+func makeDirDriver(path string) volume.Driver {
drv := new(DirDriver)
drv.volumesPath = path
drv.volumes = make(map[string]*dirVol)
- return drv, nil
+ return drv
}
// Capabilities returns the capabilities of the driver.
diff --git a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go
index 3d14b7147..2b8186e72 100644
--- a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go
+++ b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/libnetwork/util"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/machine"
"github.com/containers/storage/pkg/unshare"
)
@@ -15,8 +16,8 @@ func GetHostContainersInternalIP(conf *config.Config, netStatus map[string]types
switch conf.Containers.HostContainersInternalIP {
case "":
// if empty (default) we will automatically choose one below
- // if machine we let the gvproxy dns server handle the dns name so do not add it
- if conf.Engine.MachineEnabled {
+ // if machine using gvproxy we let the gvproxy dns server handle the dns name so do not add it
+ if machine.IsGvProxyBased() {
return ""
}
case "none":
diff --git a/vendor/github.com/containers/common/libnetwork/netavark/network.go b/vendor/github.com/containers/common/libnetwork/netavark/network.go
index 9c8c4bfb4..8e7576a56 100644
--- a/vendor/github.com/containers/common/libnetwork/netavark/network.go
+++ b/vendor/github.com/containers/common/libnetwork/netavark/network.go
@@ -27,7 +27,7 @@ type netavarkNetwork struct {
// networkRunDir is where temporary files are stored, i.e.the ipam db, aardvark config etc
networkRunDir string
- // tells netavark whether this is rootless mode or rootfull, "true" or "false"
+ // tells netavark whether this is rootless mode or rootful, "true" or "false"
networkRootless bool
// netavarkBinary is the path to the netavark binary.
diff --git a/vendor/github.com/containers/common/libnetwork/network/interface.go b/vendor/github.com/containers/common/libnetwork/network/interface.go
index e452e6cd5..893bdea2e 100644
--- a/vendor/github.com/containers/common/libnetwork/network/interface.go
+++ b/vendor/github.com/containers/common/libnetwork/network/interface.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/common/libnetwork/netavark"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/machine"
"github.com/containers/storage"
"github.com/containers/storage/pkg/homedir"
"github.com/containers/storage/pkg/ioutils"
@@ -173,7 +174,7 @@ func getCniInterface(conf *config.Config) (types.ContainerNetwork, error) {
DefaultNetwork: conf.Network.DefaultNetwork,
DefaultSubnet: conf.Network.DefaultSubnet,
DefaultsubnetPools: conf.Network.DefaultSubnetPools,
- IsMachine: conf.Engine.MachineEnabled,
+ IsMachine: machine.IsGvProxyBased(),
})
}
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index 319b8d153..d362495e3 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -312,6 +312,8 @@ type EngineConfig struct {
LockType string `toml:"lock_type,omitempty"`
// MachineEnabled indicates if Podman is running in a podman-machine VM
+ //
+ // This method is soft deprecated, use machine.IsPodmanMachine instead
MachineEnabled bool `toml:"machine_enabled,omitempty"`
// MultiImageArchive - if true, the container engine allows for storing
diff --git a/vendor/github.com/containers/common/pkg/config/config_freebsd.go b/vendor/github.com/containers/common/pkg/config/config_freebsd.go
new file mode 100644
index 000000000..85404a48d
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/config/config_freebsd.go
@@ -0,0 +1,25 @@
+package config
+
+import (
+ "os"
+)
+
+// podman remote clients on freebsd cannot use unshare.isRootless() to determine the configuration file locations.
+func customConfigFile() (string, error) {
+ if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
+ return path, nil
+ }
+ return rootlessConfigPath()
+}
+
+func ifRootlessConfigPath() (string, error) {
+ return rootlessConfigPath()
+}
+
+var defaultHelperBinariesDir = []string{
+ "/usr/local/bin",
+ "/usr/local/libexec/podman",
+ "/usr/local/lib/podman",
+ "/usr/local/libexec/podman",
+ "/usr/local/lib/podman",
+}
diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf
index 429b254bc..2b250753e 100644
--- a/vendor/github.com/containers/common/pkg/config/containers.conf
+++ b/vendor/github.com/containers/common/pkg/config/containers.conf
@@ -455,12 +455,6 @@ default_sysctls = [
#
#lock_type** = "shm"
-# Indicates if Podman is running inside a VM via Podman Machine.
-# Podman uses this value to do extra setup around networking from the
-# container inside the VM to to host.
-#
-#machine_enabled = false
-
# MultiImageArchive - if true, the container engine allows for storing archives
# (e.g., of the docker-archive transport) with multiple images. By default,
# Podman creates single-image archives.
@@ -572,9 +566,9 @@ default_sysctls = [
# URI to access the Podman service
# Examples:
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
-# rootfull "unix://run/podman/podman.sock (Default)
+# rootful "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
-# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
+# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
#
# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
diff --git a/vendor/github.com/containers/common/pkg/machine/machine.go b/vendor/github.com/containers/common/pkg/machine/machine.go
new file mode 100644
index 000000000..465eeceaf
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/machine/machine.go
@@ -0,0 +1,70 @@
+package machine
+
+import (
+ "os"
+ "strings"
+ "sync"
+
+ "github.com/containers/common/pkg/config"
+ "github.com/sirupsen/logrus"
+)
+
+type MachineMarker struct {
+ Enabled bool
+ Type string
+}
+
+const (
+ markerFile = "/etc/containers/podman-machine"
+ Wsl = "wsl"
+ Qemu = "qemu"
+)
+
+var (
+ markerSync sync.Once
+ machineMarker *MachineMarker
+)
+
+func loadMachineMarker(file string) {
+ var kind string
+
+ // Support deprecated config value for compatibility
+ enabled := isLegacyConfigSet()
+
+ if content, err := os.ReadFile(file); err == nil {
+ enabled = true
+ kind = strings.TrimSpace(string(content))
+ }
+
+ machineMarker = &MachineMarker{enabled, kind}
+}
+
+func isLegacyConfigSet() bool {
+ config, err := config.Default()
+ if err != nil {
+ logrus.Warnf("could not obtain container configuration")
+ return false
+ }
+
+ //nolint:staticcheck //lint:ignore SA1019 deprecated call
+ return config.Engine.MachineEnabled
+}
+
+func IsPodmanMachine() bool {
+ return GetMachineMarker().Enabled
+}
+
+func MachineHostType() string {
+ return GetMachineMarker().Type
+}
+
+func IsGvProxyBased() bool {
+ return IsPodmanMachine() && MachineHostType() != Wsl
+}
+
+func GetMachineMarker() *MachineMarker {
+ markerSync.Do(func() {
+ loadMachineMarker(markerFile)
+ })
+ return machineMarker
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index b1e0e3a23..4b1f03471 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -109,7 +109,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.47.5-0.20220421111103-112a47964ddb
+# github.com/containers/common v0.47.5-0.20220425182415-4081e6be9356
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
@@ -132,6 +132,7 @@ github.com/containers/common/pkg/config
github.com/containers/common/pkg/download
github.com/containers/common/pkg/filters
github.com/containers/common/pkg/flag
+github.com/containers/common/pkg/machine
github.com/containers/common/pkg/manifests
github.com/containers/common/pkg/netns
github.com/containers/common/pkg/parse