diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2017-11-30 09:37:57 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-12-02 15:32:56 +0000 |
commit | adf8809521733283c364ec7de27c783e324185e8 (patch) | |
tree | 427ed0c858ee54e760d0b3691e61765cd7429098 /cmd/kpod | |
parent | 1f01faf4375b2dc667b2794e4decdf360d6e32b8 (diff) | |
download | podman-adf8809521733283c364ec7de27c783e324185e8.tar.gz podman-adf8809521733283c364ec7de27c783e324185e8.tar.bz2 podman-adf8809521733283c364ec7de27c783e324185e8.zip |
Add NetMode, UTSMode and IPCMode
Allow kpod create/run to create contianers in different network namespaces, uts namespaces and
IPC Namespaces.
This patch just handles the simple join the host, or another containers namespaces.
Lots more work needed to full integrate --net
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Closes: #64
Approved by: mheon
Diffstat (limited to 'cmd/kpod')
-rw-r--r-- | cmd/kpod/create.go | 81 | ||||
-rw-r--r-- | cmd/kpod/run.go | 10 | ||||
-rw-r--r-- | cmd/kpod/spec.go | 72 |
3 files changed, 140 insertions, 23 deletions
diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go index 57dce6fbf..9a4539c14 100644 --- a/cmd/kpod/create.go +++ b/cmd/kpod/create.go @@ -81,20 +81,20 @@ type createConfig struct { groupAdd []uint32 // group-add hostname string //hostname image string - interactive bool //interactive - ip6Address string //ipv6 - ipAddress string //ip - labels map[string]string //label - linkLocalIP []string // link-local-ip - logDriver string // log-driver - logDriverOpt []string // log-opt - macAddress string //mac-address - name string //name - network string //network - networkAlias []string //network-alias - nsIPC string // ipc - nsNET string //net - pidMode container.PidMode //pid + interactive bool //interactive + ipcMode container.IpcMode //ipc + ip6Address string //ipv6 + ipAddress string //ip + labels map[string]string //label + linkLocalIP []string // link-local-ip + logDriver string // log-driver + logDriverOpt []string // log-opt + macAddress string //mac-address + name string //name + netMode container.NetworkMode //net + network string //network + networkAlias []string //network-alias + pidMode container.PidMode //pid nsUser string pod string //pod privileged bool //privileged @@ -102,7 +102,8 @@ type createConfig struct { publishAll bool //publish-all readOnlyRootfs bool //read-only resources createResourceConfig - rm bool //rm + rm bool //rm + shmDir string sigProxy bool //sig-proxy stopSignal string // stop-signal stopTimeout int64 // stop-timeout @@ -112,6 +113,7 @@ type createConfig struct { tty bool //tty user uint32 //user group uint32 // group + utsMode container.UTSMode //uts volumes []string //volume volumesFrom []string //volumes-from workDir string //workdir @@ -201,7 +203,8 @@ func createCmd(c *cli.Context) error { } // Gather up the options for NewContainer which consist of With... funcs options = append(options, libpod.WithRootFSFromImage(imageID, imageName, false)) - options = append(options, libpod.WithSELinuxMountLabel(createConfig.mountLabel)) + options = append(options, libpod.WithSELinuxLabels(createConfig.processLabel, createConfig.mountLabel)) + options = append(options, libpod.WithShmDir(createConfig.shmDir)) ctr, err := runtime.NewContainer(runtimeSpec, options...) if err != nil { return err @@ -230,6 +233,26 @@ func parseSecurityOpt(config *createConfig, securityOpts []string) error { err error ) + if config.pidMode.IsHost() { + labelOpts = append(labelOpts, label.DisableSecOpt()...) + } else if config.pidMode.IsContainer() { + ctr, err := config.runtime.LookupContainer(config.pidMode.Container()) + if err != nil { + return errors.Wrapf(err, "container %q not found", config.pidMode.Container()) + } + labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...) + } + + if config.ipcMode.IsHost() { + labelOpts = append(labelOpts, label.DisableSecOpt()...) + } else if config.ipcMode.IsContainer() { + ctr, err := config.runtime.LookupContainer(config.ipcMode.Container()) + if err != nil { + return errors.Wrapf(err, "container %q not found", config.ipcMode.Container()) + } + labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...) + } + for _, opt := range securityOpts { if opt == "no-new-privileges" { config.noNewPrivileges = true @@ -354,6 +377,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er if !c.Bool("detach") && !tty { tty = true } + pidMode := container.PidMode(c.String("pid")) if !pidMode.Valid() { return nil, errors.Errorf("--pid %q is not valid", c.String("pid")) @@ -363,6 +387,25 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er return nil, errors.Errorf("--rm and --detach can not be specified together") } + utsMode := container.UTSMode(c.String("uts")) + if !utsMode.Valid() { + return nil, errors.Errorf("--uts %q is not valid", c.String("uts")) + } + ipcMode := container.IpcMode(c.String("ipc")) + if !ipcMode.Valid() { + return nil, errors.Errorf("--ipc %q is not valid", ipcMode) + } + shmDir := "" + if ipcMode.IsHost() { + shmDir = "/dev/shm" + } else if ipcMode.IsContainer() { + ctr, err := runtime.LookupContainer(ipcMode.Container()) + if err != nil { + return nil, errors.Wrapf(err, "container %q not found", ipcMode.Container()) + } + shmDir = ctr.ShmDir() + } + config := &createConfig{ runtime: runtime, capAdd: c.StringSlice("cap-add"), @@ -390,8 +433,9 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er name: c.String("name"), network: c.String("network"), networkAlias: c.StringSlice("network-alias"), - nsIPC: c.String("ipc"), - nsNET: c.String("net"), + ipcMode: ipcMode, + netMode: container.NetworkMode(c.String("network")), + utsMode: utsMode, pidMode: pidMode, pod: c.String("pod"), privileged: c.Bool("privileged"), @@ -426,6 +470,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er ulimit: c.StringSlice("ulimit"), }, rm: c.Bool("rm"), + shmDir: shmDir, sigProxy: c.Bool("sig-proxy"), stopSignal: c.String("stop-signal"), stopTimeout: c.Int64("stop-timeout"), diff --git a/cmd/kpod/run.go b/cmd/kpod/run.go index ec68d8b97..eb3dee88c 100644 --- a/cmd/kpod/run.go +++ b/cmd/kpod/run.go @@ -85,9 +85,11 @@ func runCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "unable to parse new container options") } + // Gather up the options for NewContainer which consist of With... funcs options = append(options, libpod.WithRootFSFromImage(imageID, imageName, false)) - options = append(options, libpod.WithSELinuxMountLabel(createConfig.mountLabel)) + options = append(options, libpod.WithSELinuxLabels(createConfig.processLabel, createConfig.mountLabel)) + options = append(options, libpod.WithShmDir(createConfig.shmDir)) ctr, err := runtime.NewContainer(runtimeSpec, options...) if err != nil { return err @@ -130,14 +132,14 @@ func runCmd(c *cli.Context) error { if err := ctr.Start(); err != nil { return errors.Wrapf(err, "unable to start container %q", ctr.ID()) } - logrus.Debug("started container ", ctr.ID()) - if createConfig.detach { fmt.Printf("%s\n", ctr.ID()) + return nil } wg.Wait() + if createConfig.rm { return runtime.RemoveContainer(ctr, true) } - return nil + return ctr.CleanupStorage() } diff --git a/cmd/kpod/spec.go b/cmd/kpod/spec.go index 8d9189a0d..b2a439a9b 100644 --- a/cmd/kpod/spec.go +++ b/cmd/kpod/spec.go @@ -49,7 +49,7 @@ func blockAccessToKernelFilesystems(config *createConfig, g *generate.Generator) func addPidNS(config *createConfig, g *generate.Generator) error { pidMode := config.pidMode if pidMode.IsHost() { - return g.RemoveLinuxNamespace("pid") + return g.RemoveLinuxNamespace(libpod.PIDNamespace) } if pidMode.IsContainer() { ctr, err := config.runtime.LookupContainer(pidMode.Container()) @@ -68,6 +68,65 @@ func addPidNS(config *createConfig, g *generate.Generator) error { return nil } +func addNetNS(config *createConfig, g *generate.Generator) error { + netMode := config.netMode + if netMode.IsHost() { + return g.RemoveLinuxNamespace(libpod.NetNamespace) + } + if netMode.IsNone() { + return libpod.ErrNotImplemented + } + if netMode.IsBridge() { + return libpod.ErrNotImplemented + } + if netMode.IsContainer() { + ctr, err := config.runtime.LookupContainer(netMode.ConnectedContainer()) + if err != nil { + return errors.Wrapf(err, "container %q not found", netMode.ConnectedContainer()) + } + pid, err := ctr.PID() + if err != nil { + return errors.Wrapf(err, "Failed to get pid of container %q", netMode.ConnectedContainer()) + } + nsPath := fmt.Sprintf("/proc/%d/ns/net", pid) + if err := g.AddOrReplaceLinuxNamespace(libpod.NetNamespace, nsPath); err != nil { + return err + } + } + return nil +} + +func addUTSNS(config *createConfig, g *generate.Generator) error { + utsMode := config.utsMode + if utsMode.IsHost() { + return g.RemoveLinuxNamespace(libpod.UTSNamespace) + } + return nil +} + +func addIpcNS(config *createConfig, g *generate.Generator) error { + ipcMode := config.ipcMode + if ipcMode.IsHost() { + return g.RemoveLinuxNamespace(libpod.IPCNamespace) + } + if ipcMode.IsContainer() { + ctr, err := config.runtime.LookupContainer(ipcMode.Container()) + if err != nil { + return errors.Wrapf(err, "container %q not found", ipcMode.Container()) + } + pid, err := ctr.PID() + if err != nil { + return errors.Wrapf(err, "Failed to get pid of container %q", ipcMode.Container()) + } + nsPath := fmt.Sprintf("/proc/%d/ns/ipc", pid) + if err := g.AddOrReplaceLinuxNamespace(libpod.IPCNamespace, nsPath); err != nil { + return err + } + } + + return nil +} + func addRlimits(config *createConfig, g *generate.Generator) error { var ( ul *units.Ulimit @@ -210,6 +269,17 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { return nil, err } + if err := addNetNS(config, &g); err != nil { + return nil, err + } + + if err := addUTSNS(config, &g); err != nil { + return nil, err + } + + if err := addIpcNS(config, &g); err != nil { + return nil, err + } configSpec := g.Spec() if config.seccompProfilePath != "" && config.seccompProfilePath != "unconfined" { |