diff options
Diffstat (limited to 'pkg/spec/namespaces.go')
-rw-r--r-- | pkg/spec/namespaces.go | 463 |
1 files changed, 0 insertions, 463 deletions
diff --git a/pkg/spec/namespaces.go b/pkg/spec/namespaces.go deleted file mode 100644 index 8f98a9786..000000000 --- a/pkg/spec/namespaces.go +++ /dev/null @@ -1,463 +0,0 @@ -package createconfig - -import ( - "net" - "os" - "strconv" - "strings" - - "github.com/containers/podman/v2/libpod" - "github.com/containers/podman/v2/libpod/define" - "github.com/containers/podman/v2/pkg/cgroups" - "github.com/cri-o/ocicni/pkg/ocicni" - "github.com/docker/go-connections/nat" - spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/runtime-tools/generate" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -) - -// DefaultKernelNamespaces is a comma-separated list of default kernel -// namespaces. -const DefaultKernelNamespaces = "cgroup,ipc,net,uts" - -// ToCreateOptions converts the input to a slice of container create options. -func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserConfig) ([]libpod.CtrCreateOption, error) { - var portBindings []ocicni.PortMapping - var err error - if len(c.PortBindings) > 0 { - portBindings, err = NatToOCIPortBindings(c.PortBindings) - if err != nil { - return nil, errors.Wrapf(err, "unable to create port bindings") - } - } - - options := make([]libpod.CtrCreateOption, 0) - userNetworks := c.NetMode.UserDefined() - networks := make([]string, 0) - - if IsPod(userNetworks) { - userNetworks = "" - } - if userNetworks != "" { - for _, netName := range strings.Split(userNetworks, ",") { - if netName == "" { - return nil, errors.Errorf("container networks %q invalid", userNetworks) - } - networks = append(networks, netName) - } - } - - switch { - case c.NetMode.IsNS(): - ns := c.NetMode.NS() - if ns == "" { - return nil, errors.Errorf("invalid empty user-defined network namespace") - } - _, err := os.Stat(ns) - if err != nil { - return nil, err - } - case c.NetMode.IsContainer(): - connectedCtr, err := runtime.LookupContainer(c.NetMode.Container()) - if err != nil { - return nil, errors.Wrapf(err, "container %q not found", c.NetMode.Container()) - } - options = append(options, libpod.WithNetNSFrom(connectedCtr)) - case !c.NetMode.IsHost() && !c.NetMode.IsNone(): - postConfigureNetNS := userns.getPostConfigureNetNS() - options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, string(c.NetMode), networks)) - } - - if len(c.DNSSearch) > 0 { - options = append(options, libpod.WithDNSSearch(c.DNSSearch)) - } - if len(c.DNSServers) > 0 { - if len(c.DNSServers) == 1 && strings.ToLower(c.DNSServers[0]) == "none" { - options = append(options, libpod.WithUseImageResolvConf()) - } else { - options = append(options, libpod.WithDNS(c.DNSServers)) - } - } - if len(c.DNSOpt) > 0 { - options = append(options, libpod.WithDNSOption(c.DNSOpt)) - } - if c.IPAddress != "" { - ip := net.ParseIP(c.IPAddress) - if ip == nil { - return nil, errors.Wrapf(define.ErrInvalidArg, "cannot parse %s as IP address", c.IPAddress) - } else if ip.To4() == nil { - return nil, errors.Wrapf(define.ErrInvalidArg, "%s is not an IPv4 address", c.IPAddress) - } - options = append(options, libpod.WithStaticIP(ip)) - } - - if c.MacAddress != "" { - mac, err := net.ParseMAC(c.MacAddress) - if err != nil { - return nil, errors.Wrapf(define.ErrInvalidArg, "cannot parse %s as MAC address: %v", c.MacAddress, err) - } - options = append(options, libpod.WithStaticMAC(mac)) - } - - return options, nil -} - -// ConfigureGenerator configures the generator based according to the current -// state of the NetworkConfig. -func (c *NetworkConfig) ConfigureGenerator(g *generate.Generator) error { - netMode := c.NetMode - netCtr := netMode.Container() - switch { - case netMode.IsHost(): - logrus.Debug("Using host netmode") - if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil { - return err - } - case netMode.IsNone(): - logrus.Debug("Using none netmode") - case netMode.IsBridge(): - logrus.Debug("Using bridge netmode") - case netCtr != "": - logrus.Debugf("using container %s netmode", netCtr) - case IsNS(string(netMode)): - logrus.Debug("Using ns netmode") - if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), NS(string(netMode))); err != nil { - return err - } - case IsPod(string(netMode)): - logrus.Debug("Using pod netmode, unless pod is not sharing") - case netMode.IsSlirp4netns(): - logrus.Debug("Using slirp4netns netmode") - case netMode.IsUserDefined(): - logrus.Debug("Using user defined netmode") - default: - return errors.Errorf("unknown network mode") - } - - if c.HTTPProxy { - for _, envSpec := range []string{ - "http_proxy", - "HTTP_PROXY", - "https_proxy", - "HTTPS_PROXY", - "ftp_proxy", - "FTP_PROXY", - "no_proxy", - "NO_PROXY", - } { - envVal := os.Getenv(envSpec) - if envVal != "" { - g.AddProcessEnv(envSpec, envVal) - } - } - } - - if g.Config.Annotations == nil { - g.Config.Annotations = make(map[string]string) - } - - if c.PublishAll { - g.Config.Annotations[define.InspectAnnotationPublishAll] = define.InspectResponseTrue - } else { - g.Config.Annotations[define.InspectAnnotationPublishAll] = define.InspectResponseFalse - } - - return nil -} - -// NatToOCIPortBindings iterates a nat.portmap slice and creates []ocicni portmapping slice -func NatToOCIPortBindings(ports nat.PortMap) ([]ocicni.PortMapping, error) { - var portBindings []ocicni.PortMapping - for containerPb, hostPb := range ports { - var pm ocicni.PortMapping - pm.ContainerPort = int32(containerPb.Int()) - for _, i := range hostPb { - var hostPort int - var err error - pm.HostIP = i.HostIP - if i.HostPort == "" { - hostPort = containerPb.Int() - } else { - hostPort, err = strconv.Atoi(i.HostPort) - if err != nil { - return nil, errors.Wrapf(err, "unable to convert host port to integer") - } - } - - pm.HostPort = int32(hostPort) - pm.Protocol = containerPb.Proto() - portBindings = append(portBindings, pm) - } - } - return portBindings, nil -} - -// ToCreateOptions converts the input to container create options. -func (c *CgroupConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreateOption, error) { - options := make([]libpod.CtrCreateOption, 0) - if c.CgroupMode.IsNS() { - ns := c.CgroupMode.NS() - if ns == "" { - return nil, errors.Errorf("invalid empty user-defined network namespace") - } - _, err := os.Stat(ns) - if err != nil { - return nil, err - } - } else if c.CgroupMode.IsContainer() { - connectedCtr, err := runtime.LookupContainer(c.CgroupMode.Container()) - if err != nil { - return nil, errors.Wrapf(err, "container %q not found", c.CgroupMode.Container()) - } - options = append(options, libpod.WithCgroupNSFrom(connectedCtr)) - } - - if c.CgroupParent != "" { - options = append(options, libpod.WithCgroupParent(c.CgroupParent)) - } - - if c.Cgroups != "" { - options = append(options, libpod.WithCgroupsMode(c.Cgroups)) - } - - return options, nil -} - -// ToCreateOptions converts the input to container create options. -func (c *UserConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreateOption, error) { - options := make([]libpod.CtrCreateOption, 0) - switch { - case c.UsernsMode.IsNS(): - ns := c.UsernsMode.NS() - if ns == "" { - return nil, errors.Errorf("invalid empty user-defined user namespace") - } - _, err := os.Stat(ns) - if err != nil { - return nil, err - } - options = append(options, libpod.WithIDMappings(*c.IDMappings)) - case c.UsernsMode.IsContainer(): - connectedCtr, err := runtime.LookupContainer(c.UsernsMode.Container()) - if err != nil { - return nil, errors.Wrapf(err, "container %q not found", c.UsernsMode.Container()) - } - options = append(options, libpod.WithUserNSFrom(connectedCtr)) - default: - options = append(options, libpod.WithIDMappings(*c.IDMappings)) - } - - options = append(options, libpod.WithUser(c.User)) - options = append(options, libpod.WithGroups(c.GroupAdd)) - - return options, nil -} - -// ConfigureGenerator configures the generator according to the current state -// of the UserConfig. -func (c *UserConfig) ConfigureGenerator(g *generate.Generator) error { - if IsNS(string(c.UsernsMode)) { - if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), NS(string(c.UsernsMode))); err != nil { - return err - } - // runc complains if no mapping is specified, even if we join another ns. So provide a dummy mapping - g.AddLinuxUIDMapping(uint32(0), uint32(0), uint32(1)) - g.AddLinuxGIDMapping(uint32(0), uint32(0), uint32(1)) - } - - if (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost() { - if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil { - return err - } - } - for _, uidmap := range c.IDMappings.UIDMap { - g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size)) - } - for _, gidmap := range c.IDMappings.GIDMap { - g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size)) - } - return nil -} - -func (c *UserConfig) getPostConfigureNetNS() bool { - hasUserns := c.UsernsMode.IsContainer() || c.UsernsMode.IsNS() || c.UsernsMode.IsAuto() || len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0 - postConfigureNetNS := hasUserns && !c.UsernsMode.IsHost() - return postConfigureNetNS -} - -// InNS returns true if the UserConfig indicates to be in a dedicated user -// namespace. -func (c *UserConfig) InNS(isRootless bool) bool { - hasUserns := c.UsernsMode.IsContainer() || c.UsernsMode.IsNS() || c.UsernsMode.IsAuto() || len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0 - return isRootless || (hasUserns && !c.UsernsMode.IsHost()) -} - -// ToCreateOptions converts the input to container create options. -func (c *IpcConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreateOption, error) { - options := make([]libpod.CtrCreateOption, 0) - if c.IpcMode.IsHost() { - options = append(options, libpod.WithShmDir("/dev/shm")) - } else if c.IpcMode.IsContainer() { - connectedCtr, err := runtime.LookupContainer(c.IpcMode.Container()) - if err != nil { - return nil, errors.Wrapf(err, "container %q not found", c.IpcMode.Container()) - } - - options = append(options, libpod.WithIPCNSFrom(connectedCtr)) - options = append(options, libpod.WithShmDir(connectedCtr.ShmDir())) - } - - return options, nil -} - -// ConfigureGenerator configures the generator according to the current state -// of the IpcConfig. -func (c *IpcConfig) ConfigureGenerator(g *generate.Generator) error { - ipcMode := c.IpcMode - if IsNS(string(ipcMode)) { - return g.AddOrReplaceLinuxNamespace(string(spec.IPCNamespace), NS(string(ipcMode))) - } - if ipcMode.IsHost() { - return g.RemoveLinuxNamespace(string(spec.IPCNamespace)) - } - if ipcCtr := ipcMode.Container(); ipcCtr != "" { - logrus.Debugf("Using container %s ipcmode", ipcCtr) - } - - return nil -} - -// ConfigureGenerator configures the generator according to the current state -// of the CgroupConfig. -func (c *CgroupConfig) ConfigureGenerator(g *generate.Generator) error { - cgroupMode := c.CgroupMode - if cgroupMode.IsDefaultValue() { - // If the value is not specified, default to "private" on cgroups v2 and "host" on cgroups v1. - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return err - } - if unified { - cgroupMode = "private" - } else { - cgroupMode = "host" - } - } - if cgroupMode.IsNS() { - return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), NS(string(cgroupMode))) - } - if cgroupMode.IsHost() { - return g.RemoveLinuxNamespace(string(spec.CgroupNamespace)) - } - if cgroupMode.IsPrivate() { - return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), "") - } - if cgCtr := cgroupMode.Container(); cgCtr != "" { - logrus.Debugf("Using container %s cgroup mode", cgCtr) - } - return nil -} - -// ToCreateOptions converts the input to container create options. -func (c *PidConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreateOption, error) { - options := make([]libpod.CtrCreateOption, 0) - if c.PidMode.IsContainer() { - connectedCtr, err := runtime.LookupContainer(c.PidMode.Container()) - if err != nil { - return nil, errors.Wrapf(err, "container %q not found", c.PidMode.Container()) - } - - options = append(options, libpod.WithPIDNSFrom(connectedCtr)) - } - - return options, nil -} - -// ConfigureGenerator configures the generator according to the current state -// of the PidConfig. -func (c *PidConfig) ConfigureGenerator(g *generate.Generator) error { - pidMode := c.PidMode - if IsNS(string(pidMode)) { - return g.AddOrReplaceLinuxNamespace(string(spec.PIDNamespace), NS(string(pidMode))) - } - if pidMode.IsHost() { - return g.RemoveLinuxNamespace(string(spec.PIDNamespace)) - } - if pidCtr := pidMode.Container(); pidCtr != "" { - logrus.Debugf("using container %s pidmode", pidCtr) - } - if IsPod(string(pidMode)) { - logrus.Debug("using pod pidmode") - } - return nil -} - -// ToCreateOptions converts the input to container create options. -func (c *UtsConfig) ToCreateOptions(runtime *libpod.Runtime, pod *libpod.Pod) ([]libpod.CtrCreateOption, error) { - options := make([]libpod.CtrCreateOption, 0) - if IsPod(string(c.UtsMode)) { - options = append(options, libpod.WithUTSNSFromPod(pod)) - } - if c.UtsMode.IsContainer() { - connectedCtr, err := runtime.LookupContainer(c.UtsMode.Container()) - if err != nil { - return nil, errors.Wrapf(err, "container %q not found", c.UtsMode.Container()) - } - - options = append(options, libpod.WithUTSNSFrom(connectedCtr)) - } - if c.NoHosts { - options = append(options, libpod.WithUseImageHosts()) - } - if len(c.HostAdd) > 0 && !c.NoHosts { - options = append(options, libpod.WithHosts(c.HostAdd)) - } - - return options, nil -} - -// ConfigureGenerator configures the generator according to the current state -// of the UtsConfig. -func (c *UtsConfig) ConfigureGenerator(g *generate.Generator, net *NetworkConfig, runtime *libpod.Runtime) error { - hostname := c.Hostname - utsCtrID := c.UtsMode.Container() - var err error - if hostname == "" { - switch { - case utsCtrID != "": - utsCtr, err := runtime.LookupContainer(utsCtrID) - if err != nil { - return errors.Wrapf(err, "unable to retrieve hostname from dependency container %s", utsCtrID) - } - hostname = utsCtr.Hostname() - case net.NetMode.IsHost() || c.UtsMode.IsHost(): - hostname, err = os.Hostname() - if err != nil { - return errors.Wrap(err, "unable to retrieve hostname of the host") - } - default: - logrus.Debug("No hostname set; container's hostname will default to runtime default") - } - } - g.RemoveHostname() - if c.Hostname != "" || !c.UtsMode.IsHost() { - // Set the hostname in the OCI configuration only - // if specified by the user or if we are creating - // a new UTS namespace. - g.SetHostname(hostname) - } - g.AddProcessEnv("HOSTNAME", hostname) - - utsMode := c.UtsMode - if IsNS(string(utsMode)) { - return g.AddOrReplaceLinuxNamespace(string(spec.UTSNamespace), NS(string(utsMode))) - } - if utsMode.IsHost() { - return g.RemoveLinuxNamespace(string(spec.UTSNamespace)) - } - if utsCtr := utsMode.Container(); utsCtr != "" { - logrus.Debugf("using container %s utsmode", utsCtr) - } - return nil -} |