github.com/AbhinandanKurakure/podman/v3@v3.4.10/libpod/container_validate.go (about) 1 package libpod 2 3 import ( 4 "github.com/containers/podman/v3/libpod/define" 5 spec "github.com/opencontainers/runtime-spec/specs-go" 6 "github.com/pkg/errors" 7 ) 8 9 // Validate that the configuration of a container is valid. 10 func (c *Container) validate() error { 11 imageIDSet := c.config.RootfsImageID != "" 12 imageNameSet := c.config.RootfsImageName != "" 13 rootfsSet := c.config.Rootfs != "" 14 15 // If one of RootfsImageIDor RootfsImageName are set, both must be set. 16 if (imageIDSet || imageNameSet) && !(imageIDSet && imageNameSet) { 17 return errors.Wrapf(define.ErrInvalidArg, "both RootfsImageName and RootfsImageID must be set if either is set") 18 } 19 20 // Cannot set RootfsImageID and Rootfs at the same time 21 if imageIDSet && rootfsSet { 22 return errors.Wrapf(define.ErrInvalidArg, "cannot set both an image ID and rootfs for a container") 23 } 24 25 // Must set at least one of RootfsImageID or Rootfs 26 if !(imageIDSet || rootfsSet) { 27 return errors.Wrapf(define.ErrInvalidArg, "must set root filesystem source to either image or rootfs") 28 } 29 30 // Cannot make a network namespace if we are joining another container's 31 // network namespace 32 if c.config.CreateNetNS && c.config.NetNsCtr != "" { 33 return errors.Wrapf(define.ErrInvalidArg, "cannot both create a network namespace and join another container's network namespace") 34 } 35 36 if c.config.CgroupsMode == cgroupSplit && c.config.CgroupParent != "" { 37 return errors.Wrapf(define.ErrInvalidArg, "cannot specify --cgroup-mode=split with a cgroup-parent") 38 } 39 40 // Not creating cgroups has a number of requirements, mostly related to 41 // the PID namespace. 42 if c.config.NoCgroups || c.config.CgroupsMode == "disabled" { 43 if c.config.PIDNsCtr != "" { 44 return errors.Wrapf(define.ErrInvalidArg, "cannot join another container's PID namespace if not creating cgroups") 45 } 46 47 if c.config.CgroupParent != "" { 48 return errors.Wrapf(define.ErrInvalidArg, "cannot set cgroup parent if not creating cgroups") 49 } 50 51 // Ensure we have a PID namespace 52 if c.config.Spec.Linux == nil { 53 return errors.Wrapf(define.ErrInvalidArg, "must provide Linux namespace configuration in OCI spec when using NoCgroups") 54 } 55 foundPid := false 56 for _, ns := range c.config.Spec.Linux.Namespaces { 57 if ns.Type == spec.PIDNamespace { 58 foundPid = true 59 if ns.Path != "" { 60 return errors.Wrapf(define.ErrInvalidArg, "containers not creating CGroups must create a private PID namespace - cannot use another") 61 } 62 break 63 } 64 } 65 if !foundPid { 66 return errors.Wrapf(define.ErrInvalidArg, "containers not creating CGroups must create a private PID namespace") 67 } 68 } 69 70 // Can only set static IP or MAC is creating a network namespace. 71 if !c.config.CreateNetNS && (c.config.StaticIP != nil || c.config.StaticMAC != nil) { 72 return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if not creating a network namespace") 73 } 74 75 // Cannot set static IP or MAC if joining >1 CNI network. 76 if len(c.config.Networks) > 1 && (c.config.StaticIP != nil || c.config.StaticMAC != nil) { 77 return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP or MAC address if joining more than one CNI network") 78 } 79 80 // Using image resolv.conf conflicts with various DNS settings. 81 if c.config.UseImageResolvConf && 82 (len(c.config.DNSSearch) > 0 || len(c.config.DNSServer) > 0 || 83 len(c.config.DNSOption) > 0) { 84 return errors.Wrapf(define.ErrInvalidArg, "cannot configure DNS options if using image's resolv.conf") 85 } 86 87 if c.config.UseImageHosts && len(c.config.HostAdd) > 0 { 88 return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if using image's /etc/hosts") 89 } 90 91 // Check named volume, overlay volume and image volume destination conflist 92 destinations := make(map[string]bool) 93 for _, vol := range c.config.NamedVolumes { 94 // Don't check if they already exist. 95 // If they don't we will automatically create them. 96 if _, ok := destinations[vol.Dest]; ok { 97 return errors.Wrapf(define.ErrInvalidArg, "two volumes found with destination %s", vol.Dest) 98 } 99 destinations[vol.Dest] = true 100 } 101 for _, vol := range c.config.OverlayVolumes { 102 // Don't check if they already exist. 103 // If they don't we will automatically create them. 104 if _, ok := destinations[vol.Dest]; ok { 105 return errors.Wrapf(define.ErrInvalidArg, "two volumes found with destination %s", vol.Dest) 106 } 107 destinations[vol.Dest] = true 108 } 109 for _, vol := range c.config.ImageVolumes { 110 // Don't check if they already exist. 111 // If they don't we will automatically create them. 112 if _, ok := destinations[vol.Dest]; ok { 113 return errors.Wrapf(define.ErrInvalidArg, "two volumes found with destination %s", vol.Dest) 114 } 115 destinations[vol.Dest] = true 116 } 117 118 // Check that networks and network aliases match up. 119 ctrNets := make(map[string]bool) 120 for _, net := range c.config.Networks { 121 ctrNets[net] = true 122 } 123 for net := range c.config.NetworkAliases { 124 if _, ok := ctrNets[net]; !ok { 125 return errors.Wrapf(define.ErrNoSuchNetwork, "container tried to set network aliases for network %s but is not connected to the network", net) 126 } 127 } 128 129 // If User in the OCI spec is set, require that c.config.User is set for 130 // security reasons (a lot of our code relies on c.config.User). 131 if c.config.User == "" && (c.config.Spec.Process.User.UID != 0 || c.config.Spec.Process.User.GID != 0) { 132 return errors.Wrapf(define.ErrInvalidArg, "please set User explicitly via WithUser() instead of in OCI spec directly") 133 } 134 135 // Init-ctrs must be used inside a Pod. Check if a init container type is 136 // passed and if no pod is passed 137 if len(c.config.InitContainerType) > 0 && len(c.config.Pod) < 1 { 138 return errors.Wrap(define.ErrInvalidArg, "init containers must be created in a pod") 139 } 140 return nil 141 }