diff options
23 files changed, 169 insertions, 55 deletions
diff --git a/docs/source/markdown/options/device-read-bps.md b/docs/source/markdown/options/device-read-bps.md index e0c610061..f6617ab77 100644 --- a/docs/source/markdown/options/device-read-bps.md +++ b/docs/source/markdown/options/device-read-bps.md @@ -2,4 +2,8 @@ Limit read rate (in bytes per second) from a device (e.g. **--device-read-bps=/dev/sda:1mb**). +On some systems, changing the resource limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error + This option is not supported on cgroups V1 rootless systems. diff --git a/docs/source/markdown/options/device-read-iops.md b/docs/source/markdown/options/device-read-iops.md index 9cd0f9030..944c66441 100644 --- a/docs/source/markdown/options/device-read-iops.md +++ b/docs/source/markdown/options/device-read-iops.md @@ -2,4 +2,8 @@ Limit read rate (in IO operations per second) from a device (e.g. **--device-read-iops=/dev/sda:1000**). +On some systems, changing the resource limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error + This option is not supported on cgroups V1 rootless systems. diff --git a/docs/source/markdown/options/device-write-bps.md b/docs/source/markdown/options/device-write-bps.md index 3dacc4515..ebcda0181 100644 --- a/docs/source/markdown/options/device-write-bps.md +++ b/docs/source/markdown/options/device-write-bps.md @@ -2,4 +2,8 @@ Limit write rate (in bytes per second) to a device (e.g. **--device-write-bps=/dev/sda:1mb**). +On some systems, changing the resource limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error + This option is not supported on cgroups V1 rootless systems. diff --git a/docs/source/markdown/options/device-write-iops.md b/docs/source/markdown/options/device-write-iops.md index cf5ce3859..6de273d18 100644 --- a/docs/source/markdown/options/device-write-iops.md +++ b/docs/source/markdown/options/device-write-iops.md @@ -2,4 +2,8 @@ Limit write rate (in IO operations per second) to a device (e.g. **--device-write-iops=/dev/sda:1000**). +On some systems, changing the resource limits may not be allowed for non-root +users. For more details, see +https://github.com/containers/podman/blob/main/troubleshooting.md#26-running-containers-with-resource-limits-fails-with-a-permissions-error + This option is not supported on cgroups V1 rootless systems. diff --git a/docs/source/markdown/podman-create.1.md.in b/docs/source/markdown/podman-create.1.md.in index 987f10181..4fe50caed 100644 --- a/docs/source/markdown/podman-create.1.md.in +++ b/docs/source/markdown/podman-create.1.md.in @@ -144,7 +144,7 @@ device. The devices that podman will load modules when necessary are: @@option device-cgroup-rule -#### **--device-read-bps**=*path* +@@option device-read-bps @@option device-read-iops diff --git a/libpod/define/config.go b/libpod/define/config.go index 34c1a675d..1fad5cc9a 100644 --- a/libpod/define/config.go +++ b/libpod/define/config.go @@ -85,4 +85,4 @@ const PassthroughLogging = "passthrough" const RLimitDefaultValue = uint64(1048576) // BindMountPrefix distinguishes its annotations from others -const BindMountPrefix = "bind-mount-options:" +const BindMountPrefix = "bind-mount-options" diff --git a/libpod/kube.go b/libpod/kube.go index a70782d69..d4414aabd 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -385,7 +385,7 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po return nil, err } for k, v := range annotations { - podAnnotations[define.BindMountPrefix+k] = TruncateKubeAnnotation(v) + podAnnotations[define.BindMountPrefix] = TruncateKubeAnnotation(k + ":" + v) } // Since port bindings for the pod are handled by the // infra container, wipe them here only if we are sharing the net namespace @@ -529,7 +529,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, return nil, err } for k, v := range annotations { - kubeAnnotations[define.BindMountPrefix+k] = TruncateKubeAnnotation(v) + kubeAnnotations[define.BindMountPrefix] = TruncateKubeAnnotation(k + ":" + v) } if isInit { kubeInitCtrs = append(kubeInitCtrs, kubeCtr) diff --git a/libpod/runtime.go b/libpod/runtime.go index 9b97fd724..1503b2344 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -5,6 +5,7 @@ import ( "context" "errors" "fmt" + "math/rand" "os" "path/filepath" "strings" @@ -112,6 +113,13 @@ type Runtime struct { secretsManager *secrets.SecretsManager } +func init() { + // generateName calls namesgenerator.GetRandomName which the + // global RNG from math/rand. Seed it here to make sure we + // don't get the same name every time. + rand.Seed(time.Now().UnixNano()) +} + // SetXdgDirs ensures the XDG_RUNTIME_DIR env and XDG_CONFIG_HOME variables are set. // containers/image uses XDG_RUNTIME_DIR to locate the auth file, XDG_CONFIG_HOME is // use for the containers.conf configuration file. diff --git a/libpod/runtime_test.go b/libpod/runtime_test.go new file mode 100644 index 000000000..2e16c7fcd --- /dev/null +++ b/libpod/runtime_test.go @@ -0,0 +1,28 @@ +package libpod + +import ( + "math/rand" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_generateName(t *testing.T) { + state, path, _, err := getEmptyBoltState() + assert.NoError(t, err) + defer os.RemoveAll(path) + defer state.Close() + + r := &Runtime{ + state: state, + } + + // Test that (*Runtime).generateName returns different names + // if called twice, even if the global RNG has the default + // seed. + n1, _ := r.generateName() + rand.Seed(1) + n2, _ := r.generateName() + assert.NotEqual(t, n1, n2) +} diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 41baf5418..7e9c02816 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -212,7 +212,6 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // - in: query // name: signal // type: string - // default: TERM // description: signal to be sent to container // default: SIGKILL // produces: @@ -723,6 +722,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // type: boolean // description: Include namespace information // default: false + // - in: query // name: pod // type: boolean // default: false diff --git a/pkg/api/server/register_secrets.go b/pkg/api/server/register_secrets.go index f4608baa6..8918ad238 100644 --- a/pkg/api/server/register_secrets.go +++ b/pkg/api/server/register_secrets.go @@ -54,7 +54,6 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - `id=[id]` Matches for full or partial ID. // produces: // - application/json - // parameters: // responses: // '200': // "$ref": "#/responses/SecretListResponse" @@ -128,7 +127,6 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - `id=[id]` Matches for full or partial ID. // produces: // - application/json - // parameters: // responses: // '200': // "$ref": "#/responses/SecretListCompatResponse" diff --git a/pkg/machine/machine_windows.go b/pkg/machine/machine_windows.go new file mode 100644 index 000000000..c414986cf --- /dev/null +++ b/pkg/machine/machine_windows.go @@ -0,0 +1,20 @@ +//go:build windows +// +build windows + +package machine + +import ( + "syscall" +) + +func GetProcessState(pid int) (active bool, exitCode int) { + const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE + handle, err := syscall.OpenProcess(da, false, uint32(pid)) + if err != nil { + return false, int(syscall.ERROR_PROC_NOT_FOUND) + } + + var code uint32 + syscall.GetExitCodeProcess(handle, &code) + return code == 259, int(code) +} diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index e97b68e31..b59f07876 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -1,5 +1,5 @@ -//go:build (amd64 && !windows) || (arm64 && !windows) -// +build amd64,!windows arm64,!windows +//go:build amd64 || arm64 +// +build amd64 arm64 package qemu @@ -33,7 +33,6 @@ import ( "github.com/digitalocean/go-qemu/qmp" "github.com/docker/go-units" "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" ) var ( @@ -125,7 +124,7 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) { return nil, err } vm.QMPMonitor = monitor - cmd = append(cmd, []string{"-qmp", monitor.Network + ":/" + monitor.Address.GetPath() + ",server=on,wait=off"}...) + cmd = append(cmd, []string{"-qmp", monitor.Network + ":" + monitor.Address.GetPath() + ",server=on,wait=off"}...) // Add network // Right now the mac address is hardcoded so that the host networking gives it a specific IP address. This is @@ -629,14 +628,9 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { break } // check if qemu is still alive - var status syscall.WaitStatus - pid, err := syscall.Wait4(cmd.Process.Pid, &status, syscall.WNOHANG, nil) + err := checkProcessStatus("qemu", cmd.Process.Pid, stderrBuf) if err != nil { - return fmt.Errorf("failed to read qemu process status: %w", err) - } - if pid > 0 { - // child exited - return fmt.Errorf("qemu exited unexpectedly with exit code %d, stderr: %s", status.ExitStatus(), stderrBuf.String()) + return err } time.Sleep(wait) wait++ @@ -1724,14 +1718,6 @@ func (p *Provider) RemoveAndCleanMachines() error { return prevErr } -func isProcessAlive(pid int) bool { - err := unix.Kill(pid, syscall.Signal(0)) - if err == nil || err == unix.EPERM { - return true - } - return false -} - func (p *Provider) VMType() string { return vmtype } diff --git a/pkg/machine/qemu/machine_unix.go b/pkg/machine/qemu/machine_unix.go new file mode 100644 index 000000000..84ee191d1 --- /dev/null +++ b/pkg/machine/qemu/machine_unix.go @@ -0,0 +1,33 @@ +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd +// +build darwin dragonfly freebsd linux netbsd openbsd + +package qemu + +import ( + "bytes" + "fmt" + "syscall" + + "golang.org/x/sys/unix" +) + +func isProcessAlive(pid int) bool { + err := unix.Kill(pid, syscall.Signal(0)) + if err == nil || err == unix.EPERM { + return true + } + return false +} + +func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) error { + var status syscall.WaitStatus + pid, err := syscall.Wait4(pid, &status, syscall.WNOHANG, nil) + if err != nil { + return fmt.Errorf("failed to read qem%su process status: %w", processHint, err) + } + if pid > 0 { + // child exited + return fmt.Errorf("%s exited unexpectedly with exit code %d, stderr: %s", processHint, status.ExitStatus(), stderrBuf.String()) + } + return nil +} diff --git a/pkg/machine/qemu/machine_unsupported.go b/pkg/machine/qemu/machine_unsupported.go index 794e710f9..7a9a2531d 100644 --- a/pkg/machine/qemu/machine_unsupported.go +++ b/pkg/machine/qemu/machine_unsupported.go @@ -1,4 +1,4 @@ -//go:build (!amd64 && !arm64) || windows -// +build !amd64,!arm64 windows +//go:build (!amd64 && !arm64) +// +build !amd64,!arm64 package qemu diff --git a/pkg/machine/qemu/machine_windows.go b/pkg/machine/qemu/machine_windows.go new file mode 100644 index 000000000..6c63faf50 --- /dev/null +++ b/pkg/machine/qemu/machine_windows.go @@ -0,0 +1,27 @@ +package qemu + +import ( + "bytes" + "fmt" + + "github.com/containers/podman/v4/pkg/machine" +) + +func isProcessAlive(pid int) bool { + if checkProcessStatus("process", pid, nil) == nil { + return true + } + return false +} + +func checkProcessStatus(processHint string, pid int, stderrBuf *bytes.Buffer) error { + active, exitCode := machine.GetProcessState(pid) + if !active { + if stderrBuf != nil { + return fmt.Errorf("%s exited unexpectedly, exit code: %d stderr: %s", processHint, exitCode, stderrBuf.String()) + } else { + return fmt.Errorf("%s exited unexpectedly, exit code: %d", processHint, exitCode) + } + } + return nil +} diff --git a/pkg/machine/qemu/options_windows.go b/pkg/machine/qemu/options_windows.go new file mode 100644 index 000000000..69652ee39 --- /dev/null +++ b/pkg/machine/qemu/options_windows.go @@ -0,0 +1,13 @@ +package qemu + +import ( + "os" +) + +func getRuntimeDir() (string, error) { + tmpDir, ok := os.LookupEnv("TEMP") + if !ok { + tmpDir = os.Getenv("LOCALAPPDATA") + "\\Temp" + } + return tmpDir, nil +} diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 8f6ef7a43..b89e2f720 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -1063,7 +1063,7 @@ func launchWinProxy(v *MachineVM) (bool, string, error) { } return globalName, pipePrefix + waitPipe, waitPipeExists(waitPipe, 30, func() error { - active, exitCode := getProcessState(cmd.Process.Pid) + active, exitCode := machine.GetProcessState(cmd.Process.Pid) if !active { return fmt.Errorf("win-sshproxy.exe failed to start, exit code: %d (see windows event logs)", exitCode) } diff --git a/pkg/machine/wsl/util_windows.go b/pkg/machine/wsl/util_windows.go index 43f54fdd4..6c74e5652 100644 --- a/pkg/machine/wsl/util_windows.go +++ b/pkg/machine/wsl/util_windows.go @@ -280,18 +280,6 @@ func obtainShutdownPrivilege() error { return nil } -func getProcessState(pid int) (active bool, exitCode int) { - const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE - handle, err := syscall.OpenProcess(da, false, uint32(pid)) - if err != nil { - return false, int(syscall.ERROR_PROC_NOT_FOUND) - } - - var code uint32 - syscall.GetExitCodeProcess(handle, &code) - return code == 259, int(code) -} - func addRunOnceRegistryEntry(command string) error { k, _, err := registry.CreateKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\RunOnce`, registry.WRITE) if err != nil { diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 375b719d3..5862d3f1c 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -357,8 +357,11 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener // a selinux mount option exists for it for k, v := range opts.Annotations { // Make sure the z/Z option is not already there (from editing the YAML) - if strings.Replace(k, define.BindMountPrefix, "", 1) == volumeSource.Source && !cutil.StringInSlice("z", options) && !cutil.StringInSlice("Z", options) { - options = append(options, v) + if k == define.BindMountPrefix { + lastIndex := strings.LastIndex(v, ":") + if v[:lastIndex] == volumeSource.Source && !cutil.StringInSlice("z", options) && !cutil.StringInSlice("Z", options) { + options = append(options, v[lastIndex+1:]) + } } } mount := spec.Mount{ diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index 6a73d8ab6..960837ebe 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -719,7 +719,7 @@ var _ = Describe("Podman generate kube", func() { pod := new(v1.Pod) err = yaml.Unmarshal(b, pod) Expect(err).To(BeNil()) - Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix+vol1, HaveSuffix("z"))) + Expect(pod.Annotations).To(HaveKeyWithValue(define.BindMountPrefix, vol1+":"+"z")) rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", "test1"}) rm.WaitWithDefaultTimeout() diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 9a91501dd..8f4471f91 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -73,6 +73,11 @@ function service_cleanup() { # These tests can fail in dev. environment because of SELinux. # quick fix: chcon -t container_runtime_exec_t ./bin/podman @test "podman generate - systemd - basic" { + # Flakes with "ActiveState=failed (expected =inactive)" + if is_ubuntu; then + skip "FIXME: 2022-09-01: requires conmon-2.1.4, ubuntu has 2.1.3" + fi + cname=$(random_string) # See #7407 for --pull=always. run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE \ diff --git a/test/system/710-kube.bats b/test/system/710-kube.bats index 58e42148a..c446ff65f 100644 --- a/test/system/710-kube.bats +++ b/test/system/710-kube.bats @@ -78,11 +78,6 @@ status | = | null assert "$actual" $op "$expect" ".$key" done < <(parse_table "$expect") - if ! is_remote; then - count=$(egrep -c "$kubernetes_63" <<<"$output") - assert "$count" = 1 "1 instance of the Kubernetes-63-char warning" - fi - run_podman rm $cname } @@ -157,12 +152,6 @@ status | = | {} assert "$actual" $op "$expect" ".$key" done < <(parse_table "$expect") - # Why 4? Maybe two for each container? - if ! is_remote; then - count=$(egrep -c "$kubernetes_63" <<<"$output") - assert "$count" = 4 "instances of the Kubernetes-63-char warning" - fi - run_podman rm $cname1 $cname2 run_podman pod rm $pname run_podman rmi $(pause_image) |