aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--cmd/podman/containers/rm.go9
-rw-r--r--docs/play_kube_support.md152
-rw-r--r--docs/source/markdown/podman-kill.1.md2
-rw-r--r--libpod/container.go3
-rw-r--r--libpod/container_api.go3
-rw-r--r--libpod/container_config.go1
-rw-r--r--libpod/container_exec.go2
-rw-r--r--libpod/container_internal_linux.go7
-rw-r--r--libpod/plugin/volume_api.go7
-rw-r--r--libpod/pod_api.go9
-rw-r--r--libpod/runtime.go3
-rw-r--r--test/e2e/kill_test.go20
13 files changed, 188 insertions, 32 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e9f40dffe..271c130c9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -150,7 +150,7 @@ Regardless of the type of PR, all PRs should include:
* additional testcases. Ideally, they should fail w/o your code change applied.
(With a few exceptions, CI hooks will block your PR unless your change
includes files named `*_test.go` or under the `test/` subdirectory. To
- bypass this block, include the string `[NO TESTS NEEDED]` in your
+ bypass this block, include the string `[NO NEW TESTS NEEDED]` in your
commit message).
* documentation changes.
diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go
index 420e3c38d..62143bbec 100644
--- a/cmd/podman/containers/rm.go
+++ b/cmd/podman/containers/rm.go
@@ -123,9 +123,7 @@ func rm(cmd *cobra.Command, args []string) error {
// removeContainers will set the exit code according to the `podman-rm` man
// page.
func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit bool) error {
- var (
- errs utils.OutputErrors
- )
+ var errs utils.OutputErrors
responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions)
if err != nil {
if setExit {
@@ -135,8 +133,9 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
}
for _, r := range responses {
if r.Err != nil {
- // TODO this will not work with the remote client
- if errors.Cause(err) == define.ErrWillDeadlock {
+ // When using the API, errors.Cause(err) will never equal constant define.ErrWillDeadLock
+ if errors.Cause(r.Err) == define.ErrWillDeadlock ||
+ errors.Cause(r.Err).Error() == define.ErrWillDeadlock.Error() {
logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve")
}
if setExit {
diff --git a/docs/play_kube_support.md b/docs/play_kube_support.md
new file mode 100644
index 000000000..cf983bc04
--- /dev/null
+++ b/docs/play_kube_support.md
@@ -0,0 +1,152 @@
+# Podman Play Kube Support
+
+This document outlines the kube yaml fields that are currently supported by the **podman play kube** command.
+
+Note: **N/A** means that the option cannot be supported in a single-node Podman environment.
+
+## Pod Fields
+
+| Field | Support |
+|---------------------------------------------------|---------|
+| containers | ✅ |
+| initContainers | ✅ |
+| imagePullSecrets | |
+| enableServiceLinks | |
+| os<nolink>.name | |
+| volumes | |
+| nodeSelector | N/A |
+| nodeName | N/A |
+| affinity.nodeAffinity | N/A |
+| affinity.podAffinity | N/A |
+| affinity.podAntiAffinity | N/A |
+| tolerations.key | N/A |
+| tolerations.operator | N/A |
+| tolerations.effect | N/A |
+| tolerations.tolerationSeconds | N/A |
+| schedulerName | N/A |
+| runtimeClassName | |
+| priorityClassName | |
+| priority | |
+| topologySpreadConstraints.maxSkew | N/A |
+| topologySpreadConstraints.topologyKey | N/A |
+| topologySpreadConstraints.whenUnsatisfiable | N/A |
+| topologySpreadConstraints.labelSelector | N/A |
+| topologySpreadConstraints.minDomains | N/A |
+| restartPolicy | ✅ |
+| terminationGracePeriod | |
+| activeDeadlineSeconds | |
+| readinessGates.conditionType | |
+| hostname | ✅ |
+| setHostnameAsFQDN | |
+| subdomain | |
+| hostAliases.hostnames | ✅ |
+| hostAliases.ip | ✅ |
+| dnsConfig.nameservers | ✅ |
+| dnsConfig<nolink>.options.name | ✅ |
+| dnsConfig.options.value | ✅ |
+| dnsConfig.searches | ✅ |
+| dnsPolicy | |
+| hostNetwork | ✅ |
+| hostPID | |
+| hostIPC | |
+| shareProcessNamespace | ✅ |
+| serviceAccountName | |
+| automountServiceAccountToken | |
+| securityContext.runAsUser | |
+| securityContext.runAsNonRoot | |
+| securityContext.runAsGroup | |
+| securityContext.supplementalGroups | |
+| securityContext.fsGroup | |
+| securityContext.fsGroupChangePolicy | |
+| securityContext.seccompProfile.type | |
+| securityContext.seccompProfile.localhostProfile | |
+| securityContext.seLinuxOptions.level | |
+| securityContext.seLinuxOptions.role | |
+| securityContext.seLinuxOptions.type | |
+| securityContext.seLinuxOptions.user | |
+| securityContext<nolink>.sysctls.name | |
+| securityContext.sysctls.value | |
+| securityContext.windowsOptions.gmsaCredentialSpec | |
+| securityContext.windowsOptions.hostProcess | |
+| securityContext.windowsOptions.runAsUserName | |
+
+## Container Fields
+
+| Field | Support |
+|---------------------------------------------------|---------|
+| name | ✅ |
+| image | ✅ |
+| imagePullPolicy | ✅ |
+| command | ✅ |
+| args | ✅ |
+| workingDir | ✅ |
+| ports.containerPort | ✅ |
+| ports.hostIP | ✅ |
+| ports.hostPort | ✅ |
+| ports<nolink>.name | ✅ |
+| ports.protocol | ✅ |
+| env<nolink>.name | ✅ |
+| env.value | ✅ |
+| env.valueFrom.configMapKeyRef.key | ✅ |
+| env<nolink>.valueFrom.configMapKeyRef.name | ✅ |
+| env.valueFrom.configMapKeyRef.optional | ✅ |
+| env.valueFrom.fieldRef | ✅ |
+| env.valueFrom.resourceFieldRef | ✅ |
+| env.valueFrom.secretKeyRef.key | ✅ |
+| env<nolink>.valueFrom.secretKeyRef.name | ✅ |
+| env.valueFrom.secretKeyRef.optional | ✅ |
+| envFrom<nolink>.configMapRef.name | ✅ |
+| envFrom.configMapRef.optional | ✅ |
+| envFrom.prefix | |
+| envFrom<nolink>.secretRef.name | ✅ |
+| envFrom.secretRef.optional | ✅ |
+| volumeMounts.mountPath | ✅ |
+| volumeMounts<nolink>.name | ✅ |
+| volumeMounts.mountPropagation | |
+| volumeMounts.readOnly | ✅ |
+| volumeMounts.subPath | |
+| volumeMounts.subPathExpr | |
+| volumeDevices.devicePath | |
+| volumeDevices<nolink>.name | |
+| resources.limits | ✅ |
+| resources.requests | ✅ |
+| lifecycle.postStart | |
+| lifecycle.preStop | |
+| terminationMessagePath | |
+| terminationMessagePolicy | |
+| livenessProbe | ✅ |
+| readinessProbe | |
+| startupProbe | |
+| securityContext.runAsUser | ✅ |
+| securityContext.runAsNonRoot | |
+| securityContext.runAsGroup | ✅ |
+| securityContext.readOnlyRootFilesystem | ✅ |
+| securityContext.procMount | |
+| securityContext.privileged | ✅ |
+| securityContext.allowPrivilegeEscalation | ✅ |
+| securityContext.capabilities.add | ✅ |
+| securityContext.capabilities.drop | ✅ |
+| securityContext.seccompProfile.type | |
+| securityContext.seccompProfile.localhostProfile | |
+| securityContext.seLinuxOptions.level | ✅ |
+| securityContext.seLinuxOptions.role | ✅ |
+| securityContext.seLinuxOptions.type | ✅ |
+| securityContext.seLinuxOptions.user | ✅ |
+| securityContext.windowsOptions.gmsaCredentialSpec | |
+| securityContext.windowsOptions.hostProcess | |
+| securityContext.windowsOptions.runAsUserName | |
+| stdin | |
+| stdinOnce | |
+| tty | |
+
+## PersistentVolumeClaim Fields
+
+| Field | Support |
+|--------------------|---------|
+| volumeName | |
+| storageClassName | ✅ |
+| volumeMode | |
+| accessModes | ✅ |
+| selector | |
+| resources.limits | |
+| resources.requests | ✅ |
diff --git a/docs/source/markdown/podman-kill.1.md b/docs/source/markdown/podman-kill.1.md
index 35ca9f74f..a4f80ac81 100644
--- a/docs/source/markdown/podman-kill.1.md
+++ b/docs/source/markdown/podman-kill.1.md
@@ -14,7 +14,7 @@ The main process inside each container specified will be sent SIGKILL, or any si
## OPTIONS
#### **--all**, **-a**
-Signal all running containers. This does not include paused containers.
+Signal all running and paused containers.
#### **--cidfile**
diff --git a/libpod/container.go b/libpod/container.go
index 64b4453fb..04a4ae64a 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -1331,8 +1331,7 @@ func (c *Container) getNetworkStatus() map[string]types.StatusBlock {
}
c.state.NetworkStatus = result
_ = c.save()
- // TODO remove debug for final version
- logrus.Debugf("converted old network result to new result %v", result)
+
return result
}
return nil
diff --git a/libpod/container_api.go b/libpod/container_api.go
index a6fcf709d..0fab36bdc 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -202,9 +202,8 @@ func (c *Container) Kill(signal uint) error {
}
}
- // TODO: Is killing a paused container OK?
switch c.state.State {
- case define.ContainerStateRunning, define.ContainerStateStopping:
+ case define.ContainerStateRunning, define.ContainerStateStopping, define.ContainerStatePaused:
// Note that killing containers in "stopping" state is okay.
// In that state, the Podman is waiting for the runtime to
// stop the container and if that is taking too long, a user
diff --git a/libpod/container_config.go b/libpod/container_config.go
index 3e85ad4d5..ae3bc5865 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -372,7 +372,6 @@ type ContainerMiscConfig struct {
// restart the container. Used only if RestartPolicy is set to
// "on-failure".
RestartRetries uint `json:"restart_retries,omitempty"`
- // TODO log options for log drivers
// PostConfigureNetNS needed when a user namespace is created by an OCI runtime
// if the network namespace is created before the user namespace it will be
// owned by the wrong user namespace.
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index c05e7fd94..1e8fce4da 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -279,8 +279,6 @@ func (c *Container) ExecStart(sessionID string) error {
// ExecStartAndAttach starts and attaches to an exec session in a container.
// newSize resizes the tty to this size before the process is started, must be nil if the exec session has no tty
-// TODO: Should we include detach keys in the signature to allow override?
-// TODO: How do we handle AttachStdin/AttachStdout/AttachStderr?
func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachStreams, newSize *define.TerminalSize) error {
if !c.batched {
c.lock.Lock()
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 298eb1947..e19d75deb 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1091,7 +1091,6 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr
g.AddProcessEnv("HOSTNAME", hostname)
}
- // TODO need unlocked version of this for use in pods
nsPath, err := nsCtr.NamespacePath(ns)
if err != nil {
return err
@@ -3230,10 +3229,8 @@ func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error {
return err
}
- // TODO: For now, I've disabled chowning volumes owned by non-Podman
- // drivers. This may be safe, but it's really going to be a case-by-case
- // thing, I think - safest to leave disabled now and re-enable later if
- // there is a demand.
+ // Volumes owned by a volume driver are not chowned - we don't want to
+ // mess with a mount not managed by us.
if vol.state.NeedsChown && !vol.UsesVolumeDriver() {
vol.state.NeedsChown = false
diff --git a/libpod/plugin/volume_api.go b/libpod/plugin/volume_api.go
index a6d66a034..2818e70c1 100644
--- a/libpod/plugin/volume_api.go
+++ b/libpod/plugin/volume_api.go
@@ -22,9 +22,6 @@ import (
var json = jsoniter.ConfigCompatibleWithStandardLibrary
-// TODO: We should add syntax for specifying plugins to containers.conf, and
-// support for loading based on that.
-
// Copied from docker/go-plugins-helpers/volume/api.go - not exported, so we
// need to do this to get at them.
// These are well-established paths that should not change unless the plugin API
@@ -185,8 +182,7 @@ func (p *VolumePlugin) getURI() string {
}
// Verify the plugin is still available.
-// TODO: Do we want to ping with an HTTP request? There's no ping endpoint so
-// we'd need to hit Activate or Capabilities?
+// Does not actually ping the API, just verifies that the socket still exists.
func (p *VolumePlugin) verifyReachable() error {
if _, err := os.Stat(p.SocketPath); err != nil {
if os.IsNotExist(err) {
@@ -307,7 +303,6 @@ func (p *VolumePlugin) ListVolumes() ([]*volume.Volume, error) {
return nil, err
}
- // TODO: Can probably unify response reading under a helper
volumeRespBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrapf(err, "error reading response body from volume plugin %s", p.Name)
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index eede896a9..1c1e15984 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -152,8 +152,8 @@ func (p *Pod) stopWithTimeout(ctx context.Context, cleanup bool, timeout int) (m
return nil, err
}
- // TODO: There may be cases where it makes sense to order stops based on
- // dependencies. Should we bother with this?
+ // Stopping pods is not ordered by dependency. We haven't seen any case
+ // where this would actually matter.
ctrErrChan := make(map[string]<-chan error)
@@ -162,8 +162,9 @@ func (p *Pod) stopWithTimeout(ctx context.Context, cleanup bool, timeout int) (m
c := ctr
logrus.Debugf("Adding parallel job to stop container %s", c.ID())
retChan := parallel.Enqueue(ctx, func() error {
- // TODO: Might be better to batch stop and cleanup
- // together?
+ // Can't batch these without forcing Stop() to hold the
+ // lock for the full duration of the timeout.
+ // We probably don't want to do that.
if timeout > -1 {
if err := c.StopWithTimeout(uint(timeout)); err != nil {
return err
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 00fa2fe88..e268c2d17 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -412,7 +412,6 @@ func makeRuntime(runtime *Runtime) (retErr error) {
return err
}
runtime.eventer = eventer
- // TODO: events for libimage
// Set up containers/image
if runtime.imageContext == nil {
@@ -517,8 +516,6 @@ func makeRuntime(runtime *Runtime) (retErr error) {
}
// Acquire the lock and hold it until we return
// This ensures that no two processes will be in runtime.refresh at once
- // TODO: we can't close the FD in this lock, so we should keep it around
- // and use it to lock important operations
aliveLock.Lock()
doRefresh := false
defer func() {
diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go
index 552a7c15d..2a9a86729 100644
--- a/test/e2e/kill_test.go
+++ b/test/e2e/kill_test.go
@@ -128,6 +128,26 @@ var _ = Describe("Podman kill", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
+ It("podman kill paused container", func() {
+ ctrName := "testctr"
+ session := podmanTest.RunTopContainer(ctrName)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ pause := podmanTest.Podman([]string{"pause", ctrName})
+ pause.WaitWithDefaultTimeout()
+ Expect(pause).Should(Exit(0))
+
+ kill := podmanTest.Podman([]string{"kill", ctrName})
+ kill.WaitWithDefaultTimeout()
+ Expect(kill).Should(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", "-f", "{{.State.Status}}", ctrName})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ Expect(inspect.OutputToString()).To(Or(Equal("stopped"), Equal("exited")))
+ })
+
It("podman kill --cidfile", func() {
tmpDir, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())