summaryrefslogtreecommitdiff
path: root/pkg/specgen
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/specgen')
-rw-r--r--pkg/specgen/container_validate.go13
-rw-r--r--pkg/specgen/generate/config_linux.go1
-rw-r--r--pkg/specgen/generate/container_create.go16
-rw-r--r--pkg/specgen/generate/oci.go30
-rw-r--r--pkg/specgen/generate/pod_create.go4
-rw-r--r--pkg/specgen/generate/ports.go1
-rw-r--r--pkg/specgen/generate/security.go30
-rw-r--r--pkg/specgen/pod_validate.go11
-rw-r--r--pkg/specgen/podspecgen.go6
-rw-r--r--pkg/specgen/specgen.go17
10 files changed, 98 insertions, 31 deletions
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index 8063bee38..57dd2aba7 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -25,6 +25,15 @@ func exclusiveOptions(opt1, opt2 string) error {
// input for creating a container.
func (s *SpecGenerator) Validate() error {
+ if rootless.IsRootless() {
+ if s.StaticIP != nil || s.StaticIPv6 != nil {
+ return ErrNoStaticIPRootless
+ }
+ if s.StaticMAC != nil {
+ return ErrNoStaticMACRootless
+ }
+ }
+
//
// ContainerBasicConfig
//
@@ -65,10 +74,6 @@ func (s *SpecGenerator) Validate() error {
if len(s.CapAdd) > 0 && s.Privileged {
return exclusiveOptions("CapAdd", "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")
diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go
index 5d928cc5d..e445e6f0c 100644
--- a/pkg/specgen/generate/config_linux.go
+++ b/pkg/specgen/generate/config_linux.go
@@ -161,6 +161,7 @@ func BlockAccessToKernelFilesystems(privileged, pidModeIsHost bool, g *generate.
"/proc/scsi",
"/sys/firmware",
"/sys/fs/selinux",
+ "/sys/dev",
} {
g.AddLinuxMaskedPaths(mp)
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 57eaff355..be1e3b48e 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -78,7 +78,9 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
}
options := []libpod.CtrCreateOption{}
- options = append(options, libpod.WithCreateCommand())
+ if s.ContainerCreateCommand != nil {
+ options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
+ }
var newImage *image.Image
if s.Rootfs != "" {
@@ -104,7 +106,12 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
return nil, err
}
- opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, newImage)
+ command, err := makeCommand(ctx, s, newImage, rtc)
+ if err != nil {
+ return nil, err
+ }
+
+ opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, newImage, command)
if err != nil {
return nil, err
}
@@ -116,14 +123,14 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
}
options = append(options, libpod.WithExitCommand(exitCommandArgs))
- runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod)
+ runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command)
if err != nil {
return nil, err
}
return rt.NewContainer(ctx, runtimeSpec, options...)
}
-func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, img *image.Image) ([]libpod.CtrCreateOption, error) {
+func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, img *image.Image, command []string) ([]libpod.CtrCreateOption, error) {
var options []libpod.CtrCreateOption
var err error
@@ -138,7 +145,6 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
case "false":
break
case "", "true":
- command := s.Command
if len(command) == 0 {
command, err = img.Cmd(ctx)
if err != nil {
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index 0a485e7cd..f279aac1c 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -20,10 +20,9 @@ import (
func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
var (
- kernelMax uint64 = 1048576
- isRootless = rootless.IsRootless()
- nofileSet = false
- nprocSet = false
+ isRootless = rootless.IsRootless()
+ nofileSet = false
+ nprocSet = false
)
if s.Rlimits == nil {
@@ -45,8 +44,8 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
// files and number of processes to the maximum they can be set to
// (without overriding a sysctl)
if !nofileSet {
- max := kernelMax
- current := kernelMax
+ max := define.RLimitDefaultValue
+ current := define.RLimitDefaultValue
if isRootless {
var rlimit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err != nil {
@@ -62,8 +61,8 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
g.AddProcessRlimits("RLIMIT_NOFILE", max, current)
}
if !nprocSet {
- max := kernelMax
- current := kernelMax
+ max := define.RLimitDefaultValue
+ current := define.RLimitDefaultValue
if isRootless {
var rlimit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err != nil {
@@ -87,7 +86,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
finalCommand := []string{}
entrypoint := s.Entrypoint
- if len(entrypoint) == 0 && img != nil {
+ if entrypoint == nil && img != nil {
newEntry, err := img.Entrypoint(ctx)
if err != nil {
return nil, err
@@ -126,7 +125,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
return finalCommand, nil
}
-func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount, pod *libpod.Pod) (*spec.Spec, error) {
+func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount, pod *libpod.Pod, finalCmd []string) (*spec.Spec, error) {
var (
inUserNS bool
)
@@ -252,10 +251,6 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
}
g.SetProcessCwd(s.WorkDir)
- finalCmd, err := makeCommand(ctx, s, newImage, rtc)
- if err != nil {
- return nil, err
- }
g.SetProcessArgs(finalCmd)
g.SetProcessTerminal(s.Terminal)
@@ -290,13 +285,6 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
}
}
- // SECURITY OPTS
- g.SetProcessNoNewPrivileges(s.NoNewPrivileges)
-
- if !s.Privileged {
- g.SetProcessApparmorProfile(s.ApparmorProfile)
- }
-
BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), &g)
for name, val := range s.Env {
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 690651a23..4fe1b6435 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -93,7 +93,9 @@ func createPodOptions(p *specgen.PodSpecGenerator) ([]libpod.PodCreateOption, er
options = append(options, libpod.WithInfraContainerPorts(ports))
}
options = append(options, libpod.WithPodCgroups())
- options = append(options, libpod.WithPodCreateCommand())
+ if p.PodCreateCommand != nil {
+ options = append(options, libpod.WithPodCreateCommand(p.PodCreateCommand))
+ }
if len(p.InfraConmonPidFile) > 0 {
options = append(options, libpod.WithInfraConmonPidFile(p.InfraConmonPidFile))
}
diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go
index 9412ecfbf..c8d1c27c5 100644
--- a/pkg/specgen/generate/ports.go
+++ b/pkg/specgen/generate/ports.go
@@ -356,6 +356,7 @@ func checkProtocol(protocol string, allowSCTP bool) ([]string, error) {
splitProto := strings.Split(protocol, ",")
// Don't error on duplicates - just deduplicate
for _, p := range splitProto {
+ p = strings.ToLower(p)
switch p {
case protoTCP, "":
protocols[protoTCP] = struct{}{}
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index 70493cd5f..fcd1622f9 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -3,6 +3,7 @@ package generate
import (
"strings"
+ "github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/config"
"github.com/containers/libpod/v2/libpod"
@@ -56,6 +57,28 @@ func setLabelOpts(s *specgen.SpecGenerator, runtime *libpod.Runtime, pidConfig s
return nil
}
+func setupApparmor(s *specgen.SpecGenerator, rtc *config.Config, g *generate.Generator) error {
+ hasProfile := len(s.ApparmorProfile) > 0
+ if !apparmor.IsEnabled() {
+ if hasProfile {
+ return errors.Errorf("Apparmor profile %q specified, but Apparmor is not enabled on this system", s.ApparmorProfile)
+ }
+ return nil
+ }
+ // If privileged and caller did not specify apparmor profiles return
+ if s.Privileged && !hasProfile {
+ return nil
+ }
+ if !hasProfile {
+ s.ApparmorProfile = rtc.Containers.ApparmorProfile
+ }
+ if len(s.ApparmorProfile) > 0 {
+ g.SetProcessApparmorProfile(s.ApparmorProfile)
+ }
+
+ return nil
+}
+
func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, newImage *image.Image, rtc *config.Config) error {
var (
caplist []string
@@ -105,6 +128,13 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
}
}
}
+
+ g.SetProcessNoNewPrivileges(s.NoNewPrivileges)
+
+ if err := setupApparmor(s, rtc, g); err != nil {
+ return err
+ }
+
configSpec := g.Config
configSpec.Process.Capabilities.Bounding = caplist
diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go
index 070bb1e41..69c3b58ed 100644
--- a/pkg/specgen/pod_validate.go
+++ b/pkg/specgen/pod_validate.go
@@ -1,6 +1,7 @@
package specgen
import (
+ "github.com/containers/libpod/v2/pkg/rootless"
"github.com/containers/libpod/v2/pkg/util"
"github.com/pkg/errors"
)
@@ -18,6 +19,16 @@ func exclusivePodOptions(opt1, opt2 string) error {
// Validate verifies the input is valid
func (p *PodSpecGenerator) Validate() error {
+
+ if rootless.IsRootless() {
+ if p.StaticIP != nil {
+ return ErrNoStaticIPRootless
+ }
+ if p.StaticMAC != nil {
+ return ErrNoStaticMACRootless
+ }
+ }
+
// PodBasicConfig
if p.NoInfra {
if len(p.InfraCommand) > 0 {
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 600d27004..3c32ec365 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -49,6 +49,12 @@ type PodBasicConfig struct {
// Conflicts with NoInfra=true.
// Optional.
SharedNamespaces []string `json:"shared_namespaces,omitempty"`
+ // PodCreateCommand is the command used to create this pod.
+ // This will be shown in the output of Inspect() on the pod, and may
+ // also be used by some tools that wish to recreate the pod
+ // (e.g. `podman generate systemd --new`).
+ // Optional.
+ PodCreateCommand []string `json:"pod_create_command,omitempty"`
}
// PodNetworkConfig contains networking configuration for a pod.
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 327c15c5a..bd738f5a7 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -1,6 +1,7 @@
package specgen
import (
+ "errors"
"net"
"syscall"
@@ -130,6 +131,13 @@ type ContainerBasicConfig struct {
// Remove indicates if the container should be removed once it has been started
// and exits
Remove bool `json:"remove,omitempty"`
+ // ContainerCreateCommand is the command that was used to create this
+ // container.
+ // This will be shown in the output of Inspect() on the container, and
+ // may also be used by some tools that wish to recreate the container
+ // (e.g. `podman generate systemd --new`).
+ // Optional.
+ ContainerCreateCommand []string `json:"containerCreateCommand,omitempty"`
}
// ContainerStorageConfig contains information on the storage configuration of a
@@ -449,6 +457,15 @@ type PortMapping struct {
Protocol string `json:"protocol,omitempty"`
}
+var (
+ // ErrNoStaticIPRootless is used when a rootless user requests to assign a static IP address
+ // to a pod or container
+ ErrNoStaticIPRootless error = errors.New("rootless containers and pods cannot be assigned static IP addresses")
+ // ErrNoStaticMACRootless is used when a rootless user requests to assign a static MAC address
+ // to a pod or container
+ ErrNoStaticMACRootless error = errors.New("rootless containers and pods cannot be assigned static MAC addresses")
+)
+
// NewSpecGenerator returns a SpecGenerator struct given one of two mandatory inputs
func NewSpecGenerator(arg string, rootfs bool) *SpecGenerator {
csc := ContainerStorageConfig{}