diff options
Diffstat (limited to 'pkg/spec')
-rw-r--r-- | pkg/spec/config_linux_cgo.go | 12 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 67 | ||||
-rw-r--r-- | pkg/spec/namespaces.go | 42 | ||||
-rw-r--r-- | pkg/spec/storage.go | 7 |
4 files changed, 96 insertions, 32 deletions
diff --git a/pkg/spec/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go index c47156456..ae83c9d52 100644 --- a/pkg/spec/config_linux_cgo.go +++ b/pkg/spec/config_linux_cgo.go @@ -8,13 +8,24 @@ import ( spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" seccomp "github.com/seccomp/containers-golang" + "github.com/sirupsen/logrus" ) func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) { var seccompConfig *spec.LinuxSeccomp var err error + if config.SeccompPolicy == SeccompPolicyImage && config.SeccompProfileFromImage != "" { + logrus.Debug("Loading seccomp profile from the security config") + seccompConfig, err = seccomp.LoadProfile(config.SeccompProfileFromImage, configSpec) + if err != nil { + return nil, errors.Wrap(err, "loading seccomp profile failed") + } + return seccompConfig, nil + } + if config.SeccompProfilePath != "" { + logrus.Debugf("Loading seccomp profile from %q", config.SeccompProfilePath) seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath) if err != nil { return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath) @@ -24,6 +35,7 @@ func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.Linu return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) } } else { + logrus.Debug("Loading default seccomp profile") seccompConfig, err = seccomp.GetDefaultProfile(configSpec) if err != nil { return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go index 6d058229b..fb222083b 100644 --- a/pkg/spec/createconfig.go +++ b/pkg/spec/createconfig.go @@ -2,6 +2,7 @@ package createconfig import ( "os" + "sort" "strconv" "strings" "syscall" @@ -106,19 +107,63 @@ type NetworkConfig struct { PublishAll bool //publish-all } +// SeccompPolicy determines which seccomp profile gets applied to the container. +type SeccompPolicy int + +const ( + // SeccompPolicyDefault - if set use SecurityConfig.SeccompProfilePath, + // otherwise use the default profile. The SeccompProfilePath might be + // explicitly set by the user. + SeccompPolicyDefault SeccompPolicy = iota + // SeccompPolicyImage - if set use SecurityConfig.SeccompProfileFromImage, + // otherwise follow SeccompPolicyDefault. + SeccompPolicyImage +) + +// Map for easy lookups of supported policies. +var supportedSeccompPolicies = map[string]SeccompPolicy{ + "": SeccompPolicyDefault, + "default": SeccompPolicyDefault, + "image": SeccompPolicyImage, +} + +// LookupSeccompPolicy looksup the corresponding SeccompPolicy for the specified +// string. If none is found, an errors is returned including the list of +// supported policies. +// Note that an empty string resolved to SeccompPolicyDefault. +func LookupSeccompPolicy(s string) (SeccompPolicy, error) { + policy, exists := supportedSeccompPolicies[s] + if exists { + return policy, nil + } + + // Sort the keys first as maps are non-deterministic. + keys := []string{} + for k := range supportedSeccompPolicies { + if k != "" { + keys = append(keys, k) + } + } + sort.Strings(keys) + + return -1, errors.Errorf("invalid seccomp policy %q: valid policies are %+q", s, keys) +} + // SecurityConfig configures the security features for the container type SecurityConfig struct { - CapAdd []string // cap-add - CapDrop []string // cap-drop - LabelOpts []string //SecurityOpts - NoNewPrivs bool //SecurityOpts - ApparmorProfile string //SecurityOpts - SeccompProfilePath string //SecurityOpts - SecurityOpts []string - Privileged bool //privileged - ReadOnlyRootfs bool //read-only - ReadOnlyTmpfs bool //read-only-tmpfs - Sysctl map[string]string //sysctl + CapAdd []string // cap-add + CapDrop []string // cap-drop + LabelOpts []string //SecurityOpts + NoNewPrivs bool //SecurityOpts + ApparmorProfile string //SecurityOpts + SeccompProfilePath string //SecurityOpts + SeccompProfileFromImage string // seccomp profile from the container image + SeccompPolicy SeccompPolicy + SecurityOpts []string + Privileged bool //privileged + ReadOnlyRootfs bool //read-only + ReadOnlyTmpfs bool //read-only-tmpfs + Sysctl map[string]string //sysctl } // CreateConfig is a pre OCI spec structure. It represents user input from varlink or the CLI diff --git a/pkg/spec/namespaces.go b/pkg/spec/namespaces.go index 8e95a3ca0..e62d4ed0a 100644 --- a/pkg/spec/namespaces.go +++ b/pkg/spec/namespaces.go @@ -44,7 +44,8 @@ func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserCon } } - if c.NetMode.IsNS() { + switch { + case c.NetMode.IsNS(): ns := c.NetMode.NS() if ns == "" { return nil, errors.Errorf("invalid empty user-defined network namespace") @@ -53,13 +54,13 @@ func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserCon if err != nil { return nil, err } - } else if c.NetMode.IsContainer() { + 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)) - } else if !c.NetMode.IsHost() && !c.NetMode.IsNone() { + case !c.NetMode.IsHost() && !c.NetMode.IsNone(): postConfigureNetNS := userns.getPostConfigureNetNS() options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS, string(c.NetMode), networks)) } @@ -102,29 +103,31 @@ func (c *NetworkConfig) ToCreateOptions(runtime *libpod.Runtime, userns *UserCon // state of the NetworkConfig. func (c *NetworkConfig) ConfigureGenerator(g *generate.Generator) error { netMode := c.NetMode - if netMode.IsHost() { + netCtr := netMode.Container() + switch { + case netMode.IsHost(): logrus.Debug("Using host netmode") if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil { return err } - } else if netMode.IsNone() { + case netMode.IsNone(): logrus.Debug("Using none netmode") - } else if netMode.IsBridge() { + case netMode.IsBridge(): logrus.Debug("Using bridge netmode") - } else if netCtr := netMode.Container(); netCtr != "" { + case netCtr != "": logrus.Debugf("using container %s netmode", netCtr) - } else if IsNS(string(netMode)) { + case IsNS(string(netMode)): logrus.Debug("Using ns netmode") if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), NS(string(netMode))); err != nil { return err } - } else if IsPod(string(netMode)) { + case IsPod(string(netMode)): logrus.Debug("Using pod netmode, unless pod is not sharing") - } else if netMode.IsSlirp4netns() { + case netMode.IsSlirp4netns(): logrus.Debug("Using slirp4netns netmode") - } else if netMode.IsUserDefined() { + case netMode.IsUserDefined(): logrus.Debug("Using user defined netmode") - } else { + default: return errors.Errorf("unknown network mode") } @@ -220,7 +223,8 @@ func (c *CgroupConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCre // ToCreateOptions converts the input to container create options. func (c *UserConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreateOption, error) { options := make([]libpod.CtrCreateOption, 0) - if c.UsernsMode.IsNS() { + switch { + case c.UsernsMode.IsNS(): ns := c.UsernsMode.NS() if ns == "" { return nil, errors.Errorf("invalid empty user-defined user namespace") @@ -230,13 +234,13 @@ func (c *UserConfig) ToCreateOptions(runtime *libpod.Runtime) ([]libpod.CtrCreat return nil, err } options = append(options, libpod.WithIDMappings(*c.IDMappings)) - } else if c.UsernsMode.IsContainer() { + 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)) - } else { + default: options = append(options, libpod.WithIDMappings(*c.IDMappings)) } @@ -413,20 +417,22 @@ func (c *UtsConfig) ToCreateOptions(runtime *libpod.Runtime, pod *libpod.Pod) ([ // 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 == "" { - if utsCtrID := c.UtsMode.Container(); utsCtrID != "" { + switch { + case utsCtrID != "": utsCtr, err := runtime.GetContainer(utsCtrID) if err != nil { return errors.Wrapf(err, "unable to retrieve hostname from dependency container %s", utsCtrID) } hostname = utsCtr.Hostname() - } else if net.NetMode.IsHost() || c.UtsMode.IsHost() { + 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") } - } else { + default: logrus.Debug("No hostname set; container's hostname will default to runtime default") } } diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index dbdab0030..0e2098c1d 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -409,9 +409,10 @@ func getBindMount(args []string) (spec.Mount, error) { // ro=[true|false] // rw // rw=[true|false] - if len(kv) == 1 { + switch len(kv) { + case 1: newMount.Options = append(newMount.Options, kv[0]) - } else if len(kv) == 2 { + case 2: switch strings.ToLower(kv[1]) { case "true": newMount.Options = append(newMount.Options, kv[0]) @@ -424,7 +425,7 @@ func getBindMount(args []string) (spec.Mount, error) { default: return newMount, errors.Wrapf(optionArgError, "%s must be set to true or false, instead received %q", kv[0], kv[1]) } - } else { + default: return newMount, errors.Wrapf(optionArgError, "badly formatted option %q", val) } case "nosuid", "suid": |