Skip to content

Commit

Permalink
kube-play: add support for HostIPC in pod.Spec
Browse files Browse the repository at this point in the history
* play_kube_test: add tests

Signed-off-by: danishprakash <[email protected]>
  • Loading branch information
danishprakash committed Jan 23, 2023
1 parent 8252dcc commit 08186d7
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/kubernetes_support.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Note: **N/A** means that the option cannot be supported in a single-node Podman
| dnsPolicy | |
| hostNetwork ||
| hostPID ||
| hostIPC | |
| hostIPC | |
| shareProcessNamespace ||
| serviceAccountName | |
| automountServiceAccountToken | |
Expand Down
7 changes: 7 additions & 0 deletions pkg/domain/entities/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ type PodCreateOptions struct {
InfraName string `json:"container_name,omitempty"`
InfraCommand *string `json:"container_command,omitempty"`
InfraConmonPidFile string `json:"container_conmon_pidfile,omitempty"`
Ipc string `json:"ipc,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Name string `json:"name,omitempty"`
Net *NetOptions `json:"net,omitempty"`
Expand Down Expand Up @@ -349,6 +350,12 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
return nil, err
}
s.Pid = out

out, err = specgen.ParseNamespace(p.Ipc)
if err != nil {
return nil, err
}
s.Ipc = out
s.Hostname = p.Hostname
s.ExitPolicy = p.ExitPolicy
s.Labels = p.Labels
Expand Down
3 changes: 2 additions & 1 deletion pkg/domain/infra/abi/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -710,10 +710,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
ConfigMaps: configMaps,
Container: container,
Image: pulledImage,
IpcNSIsHost: p.Ipc.IsHost(),
Labels: labels,
LogDriver: options.LogDriver,
LogOptions: options.LogOptions,
NetNSIsHost: p.NetNS.IsHost(),
PidNSIsHost: p.Pid.IsHost(),
PodID: pod.ID(),
PodInfraID: podInfraID,
PodName: podName,
Expand All @@ -722,7 +724,6 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
RestartPolicy: ctrRestartPolicy,
SeccompPaths: seccompPaths,
SecretsManager: secretsManager,
PidNSIsHost: p.Pid.IsHost(),
UserNSIsHost: p.Userns.IsHost(),
Volumes: volumes,
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/specgen/generate/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions,
if podYAML.Spec.HostPID {
p.Pid = "host"
}
if podYAML.Spec.HostIPC {
p.Ipc = "host"
}
p.Hostname = podYAML.Spec.Hostname
if p.Hostname == "" {
p.Hostname = podName
Expand Down Expand Up @@ -114,6 +117,8 @@ type CtrSpecGenOptions struct {
Container v1.Container
// Image available to use (pulled or found local)
Image *libimage.Image
// IPCNSIsHost tells the container to use the host ipcns
IpcNSIsHost bool
// Volumes for all containers
Volumes map[string]*KubeVolume
// PodID of the parent pod
Expand Down Expand Up @@ -470,6 +475,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
if opts.PidNSIsHost {
s.PidNS.NSMode = specgen.Host
}
if opts.IpcNSIsHost {
s.IpcNS.NSMode = specgen.Host
}

// Add labels that come from kube
if len(s.Labels) == 0 {
Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/podspecgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type PodBasicConfig struct {
// Conflicts with NoInfra=true.
// Optional.
InfraName string `json:"infra_name,omitempty"`
// Ipc sets the IPC namespace of the pod, set to private by default.
// This configuration will then be shared with the entire pod if PID namespace sharing is enabled via --share
Ipc Namespace `json:"ipcns,omitempty"`
// SharedNamespaces instructs the pod to share a set of namespaces.
// Shared namespaces will be joined (by default) by every container
// which joins the pod.
Expand Down
42 changes: 42 additions & 0 deletions test/e2e/play_kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"net/url"
"os"
"os/exec"
"os/user"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -953,6 +954,19 @@ spec:
command: ['sh', '-c', 'echo $$']
`

var podWithHostIPCDefined = `
apiVersion: v1
kind: Pod
metadata:
name: test-hostipc
spec:
hostIPC: true
containers:
- name: alpine
image: quay.io/libpod/alpine:latest
command: ['sh', '-c', 'ls -l /proc/self/ns/ipc']
`

var (
defaultCtrName = "testCtr"
defaultCtrCmd = []string{"top"}
Expand Down Expand Up @@ -4964,4 +4978,32 @@ spec:
Expect(inspect.OutputToString()).To(Equal("host"))
})

It("podman play kube test with hostIPC", func() {
err := writeYaml(podWithHostIPCDefined, kubeYaml)
Expect(err).ToNot(HaveOccurred())

kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

inspect := podmanTest.Podman([]string{"inspect", "test-hostipc-alpine", "--format", "{{ .HostConfig.IpcMode }}"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(Equal("shareable"))

cmd := exec.Command("ls", "-l", "/proc/self/ns/ipc")
res, err := cmd.Output()
Expect(err).ToNot(HaveOccurred())
fields := strings.Split(string(res), " ")
hostIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n")

logs := podmanTest.Podman([]string{"pod", "logs", "-c", "test-hostipc-alpine", "test-hostipc"})
logs.WaitWithDefaultTimeout()
Expect(logs).Should(Exit(0))
fields = strings.Split(logs.OutputToString(), " ")
ctrIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n")

Expect(hostIpcNS).To(Equal(ctrIpcNS))
})

})

0 comments on commit 08186d7

Please sign in to comment.