summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml26
-rw-r--r--README.md12
-rw-r--r--cmd/podman/images/scp.go28
-rw-r--r--docs/source/markdown/podman-image-scp.1.md16
-rw-r--r--pkg/api/handlers/compat/containers_create.go2
-rw-r--r--pkg/domain/infra/abi/play.go30
-rw-r--r--pkg/specgen/generate/container_create.go3
-rw-r--r--pkg/specgen/generate/pod_create.go11
-rw-r--r--pkg/specgen/specgen.go4
-rw-r--r--test/e2e/config/containers-netns2.conf3
-rw-r--r--test/e2e/image_scp_test.go4
-rw-r--r--test/e2e/play_kube_test.go28
-rw-r--r--test/python/docker/compat/test_containers.py14
-rw-r--r--test/system/700-play.bats6
14 files changed, 124 insertions, 63 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 9897a9f7f..091b37627 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -26,10 +26,10 @@ env:
####
FEDORA_NAME: "fedora-34"
PRIOR_FEDORA_NAME: "fedora-33"
- UBUNTU_NAME: "ubuntu-2104"
+ UBUNTU_NAME: "ubuntu-2110"
# Google-cloud VM Images
- IMAGE_SUFFIX: "c6431352024203264"
+ IMAGE_SUFFIX: "c4955591916388352"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
@@ -148,11 +148,11 @@ build_task:
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
# ID for re-use of build output
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- - env: &priorfedora_envvars
- DISTRO_NV: ${PRIOR_FEDORA_NAME}
- VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
- _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ # - env: &priorfedora_envvars
+ # DISTRO_NV: ${PRIOR_FEDORA_NAME}
+ # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
+ # _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- env: &ubuntu_envvars
DISTRO_NV: ${UBUNTU_NAME}
VM_IMAGE_NAME: ${UBUNTU_CACHE_IMAGE_NAME}
@@ -402,7 +402,7 @@ unit_test_task:
- validate
matrix:
- env: *stdenvars
- - env: *priorfedora_envvars
+ #- env: *priorfedora_envvars
- env: *ubuntu_envvars
# Special-case: Rootless on latest Fedora (standard) VM
- name: "Rootless unit on $DISTRO_NV"
@@ -522,11 +522,11 @@ container_integration_test_task:
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
- - env:
- DISTRO_NV: ${PRIOR_FEDORA_NAME}
- _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
+ # - env:
+ # DISTRO_NV: ${PRIOR_FEDORA_NAME}
+ # _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
gce_instance: *standardvm
timeout_in: 90m
env:
diff --git a/README.md b/README.md
index 3697943ec..2b384239f 100644
--- a/README.md
+++ b/README.md
@@ -168,7 +168,11 @@ was replaced by the REST API. Varlink support has been removed as of the 3.0 rel
For more details, you can see [this blog](https://podman.io/blogs/2020/01/17/podman-new-api.html).
## Static Binary Builds
-The Cirrus CI integration within this repository contains a `static_build` job
-which produces a static Podman binary for testing purposes. Please note that
-this binary is not officially supported with respect to feature-completeness
-and functionality and should be only used for testing.
+The Cirrus CI integration within this repository contains a `Static_Build` job
+which produces static Podman binaries for testing purposes. Please note that
+these binaries are not officially supported with respect to feature-completeness
+and functionality and should be only used for testing. To download these binaries,
+load the build link with the commit SHA at
+[main](https://cirrus-ci.com/github/containers/podman/main) or
+`https://cirrus-ci.com/github/containers/podman/pull/<selected PR>`
+and open the artifacts folder within `Static Build`.
diff --git a/cmd/podman/images/scp.go b/cmd/podman/images/scp.go
index 67a531e6b..5c9cadc7a 100644
--- a/cmd/podman/images/scp.go
+++ b/cmd/podman/images/scp.go
@@ -137,9 +137,15 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
scpOpts.Save.Format = "oci-archive"
abiErr := abiEng.Save(context.Background(), scpOpts.SourceImageName, []string{}, scpOpts.Save) // save the image locally before loading it on remote, local, or ssh
if abiErr != nil {
- errors.Wrapf(abiErr, "could not save image as specified")
+ return errors.Wrapf(abiErr, "could not save image as specified")
}
if !rootless.IsRootless() && scpOpts.Rootless {
+ if scpOpts.User == "" {
+ scpOpts.User = os.Getenv("SUDO_USER")
+ if scpOpts.User == "" {
+ return errors.New("could not obtain root user, make sure the environmental variable SUDO_USER is set, and that this command is being run as root")
+ }
+ }
err := abiEng.Transfer(context.Background(), scpOpts)
if err != nil {
return err
@@ -270,7 +276,13 @@ func parseArgs(args []string, cfg *config.Config) (map[string]config.Destination
cliConnections := []string{}
switch len(args) {
case 1:
- if strings.Contains(args[0], "::") {
+ if strings.Contains(args[0], "localhost") {
+ if strings.Split(args[0], "@")[0] != "root" {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "cannot transfer images from any user besides root using sudo")
+ }
+ scpOpts.Rootless = true
+ scpOpts.SourceImageName = strings.Split(args[0], "::")[1]
+ } else if strings.Contains(args[0], "::") {
scpOpts.FromRemote = true
cliConnections = append(cliConnections, args[0])
} else {
@@ -282,11 +294,15 @@ func parseArgs(args []string, cfg *config.Config) (map[string]config.Destination
}
case 2:
if strings.Contains(args[0], "localhost") || strings.Contains(args[1], "localhost") { // only supporting root to local using sudo at the moment
- scpOpts.Rootless = true
- scpOpts.User = strings.Split(args[1], "@")[0]
- scpOpts.SourceImageName = strings.Split(args[0], "::")[1]
if strings.Split(args[0], "@")[0] != "root" {
- return nil, errors.Wrapf(define.ErrInvalidArg, "cannot transfer images from any user besides root using sudo")
+ return nil, errors.Wrapf(define.ErrInvalidArg, "currently, transferring images to a user account is not supported")
+ }
+ if len(strings.Split(args[0], "::")) > 1 {
+ scpOpts.Rootless = true
+ scpOpts.User = strings.Split(args[1], "@")[0]
+ scpOpts.SourceImageName = strings.Split(args[0], "::")[1]
+ } else {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "currently, you cannot rename images during the transfer or transfer them to a user account")
}
} else if strings.Contains(args[0], "::") {
if !(strings.Contains(args[1], "::")) && remoteArgLength(args[0], 1) == 0 { // if an image is specified, this mean we are loading to our client
diff --git a/docs/source/markdown/podman-image-scp.1.md b/docs/source/markdown/podman-image-scp.1.md
index b4caf353a..d39882417 100644
--- a/docs/source/markdown/podman-image-scp.1.md
+++ b/docs/source/markdown/podman-image-scp.1.md
@@ -68,8 +68,6 @@ Copying blob e2eb06d8af82 done
Copying config 696d33ca15 done
Writing manifest to image destination
Storing signatures
-Run Directory Obtained: /run/user/1000/
-[Run Root: /var/tmp/containers-user-1000/containers Graph Root: /root/.local/share/containers/storage DB Path: /root/.local/share/containers/storage/libpod/bolt_state.db]
Getting image source signatures
Copying blob 5eb901baf107 skipped: already exists
Copying config 696d33ca15 done
@@ -78,6 +76,20 @@ Storing signatures
Loaded image(s): docker.io/library/alpine:latest
```
+```
+$ sudo podman image scp root@localhost::alpine
+Copying blob e2eb06d8af82 done
+Copying config 696d33ca15 done
+Writing manifest to image destination
+Storing signatures
+Getting image source signatures
+Copying blob 5eb901baf107
+Copying config 696d33ca15 done
+Writing manifest to image destination
+Storing signatures
+Loaded image(s): docker.io/library/alpine:latest
+```
+
## SEE ALSO
**[podman(1)](podman.1.md)**, **[podman-load(1)](podman-load.1.md)**, **[podman-save(1)](podman-save.1.md)**, **[podman-remote(1)](podman-remote.1.md)**, **[podman-system-connection-add(1)](podman-system-connection-add.1.md)**, **[containers.conf(5)](https://github.com/containers/common/blob/main/docs/containers.conf.5.md)**, **[containers-transports(5)](https://github.com/containers/image/blob/main/docs/containers-transports.5.md)**
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 94d20a04a..1e175d664 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -86,6 +86,8 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
return
}
+ // moby always create the working directory
+ sg.CreateWorkingDir = true
ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.ContainerCreate(r.Context(), sg)
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 4d21751d1..3fdb3f286 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -269,17 +269,11 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
if podOpt.Infra {
- containerConfig := util.DefaultContainerConfig()
-
- pulledImages, err := pullImage(ic, writer, containerConfig.Engine.InfraImage, options, config.PullPolicyNewer)
- if err != nil {
- return nil, err
- }
+ infraImage := util.DefaultContainerConfig().Engine.InfraImage
infraOptions := entities.ContainerCreateOptions{ImageVolume: "bind"}
-
- podSpec.PodSpecGen.InfraImage = pulledImages[0].Names()[0]
+ podSpec.PodSpecGen.InfraImage = infraImage
podSpec.PodSpecGen.NoInfra = false
- podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(pulledImages[0].Names()[0], false)
+ podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(infraImage, false)
podSpec.PodSpecGen.InfraContainerSpec.NetworkOptions = p.NetworkOptions
err = specgenutil.FillOutSpecGen(podSpec.PodSpecGen.InfraContainerSpec, &infraOptions, []string{})
@@ -758,21 +752,3 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ enti
}
return reports, nil
}
-
-// pullImage is a helper function to set up the proper pull options and pull the image for certain containers
-func pullImage(ic *ContainerEngine, writer io.Writer, imagePull string, options entities.PlayKubeOptions, pullPolicy config.PullPolicy) ([]*libimage.Image, error) {
- // This ensures the image is the image store
- pullOptions := &libimage.PullOptions{}
- pullOptions.AuthFilePath = options.Authfile
- pullOptions.CertDirPath = options.CertDir
- pullOptions.SignaturePolicyPath = options.SignaturePolicy
- pullOptions.Writer = writer
- pullOptions.Username = options.Username
- pullOptions.Password = options.Password
- pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
- pulledImages, err := ic.Libpod.LibimageRuntime().Pull(context.Background(), imagePull, pullPolicy, pullOptions)
- if err != nil {
- return nil, err
- }
- return pulledImages, nil
-}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 9f398a0ed..f3dc28b01 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -378,6 +378,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.WorkDir == "" {
s.WorkDir = "/"
}
+ if s.CreateWorkingDir {
+ options = append(options, libpod.WithCreateWorkingDir())
+ }
if s.StopSignal != nil {
options = append(options, libpod.WithStopSignal(*s.StopSignal))
}
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 501bce05d..bfd81739a 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -12,7 +12,6 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -216,15 +215,6 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
logrus.Debugf("No networking because the infra container is missing")
break
}
- if rootless.IsRootless() {
- logrus.Debugf("Pod will use slirp4netns")
- if p.InfraContainerSpec.NetNS.NSMode != "host" {
- p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
- p.InfraContainerSpec.NetNS.NSMode = specgen.NamespaceMode("slirp4netns")
- }
- } else {
- logrus.Debugf("Pod using bridge network mode")
- }
case specgen.Bridge:
p.InfraContainerSpec.NetNS.NSMode = specgen.Bridge
logrus.Debugf("Pod using bridge network mode")
@@ -258,7 +248,6 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
}
- libpod.WithPodCgroups()
if len(p.InfraCommand) > 0 {
p.InfraContainerSpec.Entrypoint = p.InfraCommand
}
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 8a4497130..d777287d7 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -272,6 +272,10 @@ type ContainerStorageConfig struct {
// If unset, the default, /, will be used.
// Optional.
WorkDir string `json:"work_dir,omitempty"`
+ // Create the working directory if it doesn't exist.
+ // If unset, it doesn't create it.
+ // Optional.
+ CreateWorkingDir bool `json:"create_working_dir,omitempty"`
// StorageOpts is the container's storage options
// Optional.
StorageOpts map[string]string `json:"storage_opts,omitempty"`
diff --git a/test/e2e/config/containers-netns2.conf b/test/e2e/config/containers-netns2.conf
new file mode 100644
index 000000000..1ffd100f5
--- /dev/null
+++ b/test/e2e/config/containers-netns2.conf
@@ -0,0 +1,3 @@
+[containers]
+
+netns = "bridge"
diff --git a/test/e2e/image_scp_test.go b/test/e2e/image_scp_test.go
index acea2993d..3e7e8da48 100644
--- a/test/e2e/image_scp_test.go
+++ b/test/e2e/image_scp_test.go
@@ -78,6 +78,10 @@ var _ = Describe("podman image scp", func() {
list.WaitWithDefaultTimeout()
Expect(list).To(Exit(0))
Expect(list.LineInOutputStartsWith("quay.io/libpod/alpine")).To(BeTrue())
+
+ scp = podmanTest.PodmanAsUser([]string{"image", "scp", "root@localhost::" + ALPINE}, 0, 0, "", env) //transfer from root to rootless (us)
+ scp.WaitWithDefaultTimeout()
+ Expect(scp).To(Exit(0))
})
It("podman image scp bogus image", func() {
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index b0b927445..64b46756f 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -2786,6 +2786,34 @@ invalid kube kind
Expect(exists).To(Exit(0))
})
+ It("podman play kube use network mode from config", func() {
+ confPath, err := filepath.Abs("config/containers-netns2.conf")
+ Expect(err).ToNot(HaveOccurred())
+ os.Setenv("CONTAINERS_CONF", confPath)
+ defer os.Unsetenv("CONTAINERS_CONF")
+ if IsRemote() {
+ podmanTest.RestartRemoteService()
+ }
+
+ pod := getPod()
+ err = generateKubeYaml("pod", pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ podInspect := podmanTest.Podman([]string{"pod", "inspect", pod.Name, "--format", "{{.InfraContainerID}}"})
+ podInspect.WaitWithDefaultTimeout()
+ Expect(podInspect).To(Exit(0))
+ infraID := podInspect.OutputToString()
+
+ inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.HostConfig.NetworkMode}}", infraID})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).To(Exit(0))
+ Expect(inspect.OutputToString()).To(Equal("bridge"))
+ })
+
It("podman play kube replace", func() {
pod := getPod()
err := generateKubeYaml("pod", pod, kubeYaml)
diff --git a/test/python/docker/compat/test_containers.py b/test/python/docker/compat/test_containers.py
index 1ad1e7f15..e6f7d992d 100644
--- a/test/python/docker/compat/test_containers.py
+++ b/test/python/docker/compat/test_containers.py
@@ -251,3 +251,17 @@ class TestContainers(unittest.TestCase):
ctr.start()
ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/workspace"])
self.assertEqual(out.rstrip(), b'1042:1043', "UID/GID set in dockerfile")
+
+
+ def test_non_existant_workdir(self):
+ dockerfile = (B'FROM quay.io/libpod/alpine:latest\n'
+ B'USER root\n'
+ B'WORKDIR /workspace/scratch\n'
+ B'RUN touch test')
+ img: Image
+ img, out = self.client.images.build(fileobj=io.BytesIO(dockerfile))
+ ctr: Container = self.client.containers.create(image=img.id, detach=True, command="top",
+ volumes=["test_non_existant_workdir:/workspace"])
+ ctr.start()
+ ret, out = ctr.exec_run(["stat", "/workspace/scratch/test"])
+ self.assertEqual(ret, 0, "Working directory created if it doesn't exist")
diff --git a/test/system/700-play.bats b/test/system/700-play.bats
index 8cf279ada..c3e5e9354 100644
--- a/test/system/700-play.bats
+++ b/test/system/700-play.bats
@@ -76,6 +76,12 @@ RELABEL="system_u:object_r:container_file_t:s0"
is "$output" "${RELABEL} $TESTDIR" "selinux relabel should have happened"
fi
+ # Make sure that the K8s pause image isn't pulled but the local podman-pause is built.
+ run_podman images
+ run_podman 1 image exists k8s.gcr.io/pause
+ run_podman version --format "{{.Server.Version}}-{{.Server.Built}}"
+ run_podman image exists localhost/podman-pause:$output
+
run_podman stop -a -t 0
run_podman pod rm -t 0 -f test_pod
}