summaryrefslogtreecommitdiff
path: root/pkg/specgen/container_validate.go
diff options
context:
space:
mode:
authorBrent Baude <bbaude@redhat.com>2020-03-24 07:28:36 -0500
committerBrent Baude <bbaude@redhat.com>2020-03-27 09:04:10 -0500
commite56d5295614b745115abf0198f7b67ae157aae1e (patch)
tree4b18581f6656f2bd6455e797f69ab7d45535ec6a /pkg/specgen/container_validate.go
parent7007680bfdee8c36b855a97ee45d268b24bde7d3 (diff)
downloadpodman-e56d5295614b745115abf0198f7b67ae157aae1e.tar.gz
podman-e56d5295614b745115abf0198f7b67ae157aae1e.tar.bz2
podman-e56d5295614b745115abf0198f7b67ae157aae1e.zip
podmanv2 pod create using podspecgen
using the factory approach similar to container, we now create pods based on a pod spec generator. wired up the podmanv2 pod create command, podcreatewithspec binding, simple binding test, and apiv2 endpoint. also included some code refactoring as it introduced as easy circular import. Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/specgen/container_validate.go')
-rw-r--r--pkg/specgen/container_validate.go167
1 files changed, 167 insertions, 0 deletions
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
new file mode 100644
index 000000000..b27659f5f
--- /dev/null
+++ b/pkg/specgen/container_validate.go
@@ -0,0 +1,167 @@
+package specgen
+
+import (
+ "strings"
+
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/util"
+ "github.com/pkg/errors"
+)
+
+var (
+ // ErrInvalidSpecConfig describes an error that the given SpecGenerator is invalid
+ ErrInvalidSpecConfig error = errors.New("invalid configuration")
+ // SystemDValues describes the only values that SystemD can be
+ SystemDValues = []string{"true", "false", "always"}
+ // ImageVolumeModeValues describes the only values that ImageVolumeMode can be
+ ImageVolumeModeValues = []string{"ignore", "tmpfs", "anonymous"}
+)
+
+func exclusiveOptions(opt1, opt2 string) error {
+ return errors.Errorf("%s and %s are mutually exclusive options", opt1, opt2)
+}
+
+// Validate verifies that the given SpecGenerator is valid and satisfies required
+// input for creating a container.
+func (s *SpecGenerator) validate() error {
+
+ //
+ // ContainerBasicConfig
+ //
+ // Rootfs and Image cannot both populated
+ if len(s.ContainerStorageConfig.Image) > 0 && len(s.ContainerStorageConfig.Rootfs) > 0 {
+ return errors.Wrap(ErrInvalidSpecConfig, "both image and rootfs cannot be simultaneously")
+ }
+ // Cannot set hostname and utsns
+ if len(s.ContainerBasicConfig.Hostname) > 0 && !s.ContainerBasicConfig.UtsNS.IsPrivate() {
+ return errors.Wrap(ErrInvalidSpecConfig, "cannot set hostname when creating an UTS namespace")
+ }
+ // systemd values must be true, false, or always
+ if len(s.ContainerBasicConfig.Systemd) > 0 && !util.StringInSlice(strings.ToLower(s.ContainerBasicConfig.Systemd), SystemDValues) {
+ return errors.Wrapf(ErrInvalidSpecConfig, "SystemD values must be one of %s", strings.Join(SystemDValues, ","))
+ }
+
+ //
+ // ContainerStorageConfig
+ //
+ // rootfs and image cannot both be set
+ if len(s.ContainerStorageConfig.Image) > 0 && len(s.ContainerStorageConfig.Rootfs) > 0 {
+ return exclusiveOptions("rootfs", "image")
+ }
+ // imagevolumemode must be one of ignore, tmpfs, or anonymous if given
+ if len(s.ContainerStorageConfig.ImageVolumeMode) > 0 && !util.StringInSlice(strings.ToLower(s.ContainerStorageConfig.ImageVolumeMode), ImageVolumeModeValues) {
+ return errors.Errorf("ImageVolumeMode values must be one of %s", strings.Join(ImageVolumeModeValues, ","))
+ }
+ // shmsize conflicts with IPC namespace
+ if s.ContainerStorageConfig.ShmSize != nil && !s.ContainerStorageConfig.IpcNS.IsPrivate() {
+ return errors.New("cannot set shmsize when creating an IPC namespace")
+ }
+
+ //
+ // ContainerSecurityConfig
+ //
+ // groups and privileged are exclusive
+ if len(s.Groups) > 0 && s.Privileged {
+ return exclusiveOptions("Groups", "privileged")
+ }
+ // capadd and privileged are exclusive
+ if len(s.CapAdd) > 0 && s.Privileged {
+ return exclusiveOptions("CapAdd", "privileged")
+ }
+ // selinuxprocesslabel and privileged are exclusive
+ if len(s.SelinuxProcessLabel) > 0 && s.Privileged {
+ return exclusiveOptions("SelinuxProcessLabel", "privileged")
+ }
+ // selinuxmounmtlabel and privileged are exclusive
+ if len(s.SelinuxMountLabel) > 0 && s.Privileged {
+ return exclusiveOptions("SelinuxMountLabel", "privileged")
+ }
+ // selinuxopts and privileged are exclusive
+ if len(s.SelinuxOpts) > 0 && s.Privileged {
+ return exclusiveOptions("SelinuxOpts", "privileged")
+ }
+ // apparmor and privileged are exclusive
+ if len(s.ApparmorProfile) > 0 && s.Privileged {
+ return exclusiveOptions("AppArmorProfile", "privileged")
+ }
+ // userns and idmappings conflict
+ if s.UserNS.IsPrivate() && s.IDMappings == nil {
+ return errors.Wrap(ErrInvalidSpecConfig, "IDMappings are required when not creating a User namespace")
+ }
+
+ //
+ // ContainerCgroupConfig
+ //
+ //
+ // None for now
+
+ //
+ // ContainerNetworkConfig
+ //
+ if !s.NetNS.IsPrivate() && s.ConfigureNetNS {
+ return errors.New("can only configure network namespace when creating a network a network namespace")
+ }
+ // useimageresolveconf conflicts with dnsserver, dnssearch, dnsoption
+ if s.UseImageResolvConf {
+ if len(s.DNSServer) > 0 {
+ return exclusiveOptions("UseImageResolvConf", "DNSServer")
+ }
+ if len(s.DNSSearch) > 0 {
+ return exclusiveOptions("UseImageResolvConf", "DNSSearch")
+ }
+ if len(s.DNSOption) > 0 {
+ return exclusiveOptions("UseImageResolvConf", "DNSOption")
+ }
+ }
+ // UseImageHosts and HostAdd are exclusive
+ if s.UseImageHosts && len(s.HostAdd) > 0 {
+ return exclusiveOptions("UseImageHosts", "HostAdd")
+ }
+
+ // TODO the specgen does not appear to handle this? Should it
+ //switch config.Cgroup.Cgroups {
+ //case "disabled":
+ // if addedResources {
+ // return errors.New("cannot specify resource limits when cgroups are disabled is specified")
+ // }
+ // configSpec.Linux.Resources = &spec.LinuxResources{}
+ //case "enabled", "no-conmon", "":
+ // // Do nothing
+ //default:
+ // return errors.New("unrecognized option for cgroups; supported are 'default', 'disabled', 'no-conmon'")
+ //}
+
+ // Namespaces
+ if err := s.UtsNS.validate(); err != nil {
+ return err
+ }
+ if err := s.IpcNS.validate(); err != nil {
+ return err
+ }
+ if err := s.PidNS.validate(); err != nil {
+ return err
+ }
+ if err := s.CgroupNS.validate(); err != nil {
+ return err
+ }
+ if err := s.UserNS.validate(); err != nil {
+ return err
+ }
+
+ // The following are defaults as needed by container creation
+ if len(s.WorkDir) < 1 {
+ s.WorkDir = "/"
+ }
+
+ // Set defaults if network info is not provided
+ if s.NetNS.NSMode == "" {
+ s.NetNS.NSMode = Bridge
+ if rootless.IsRootless() {
+ s.NetNS.NSMode = Slirp
+ }
+ }
+ if err := validateNetNS(&s.NetNS); err != nil {
+ return err
+ }
+ return nil
+}