diff options
Diffstat (limited to 'vendor/github.com/opencontainers/runtime-tools/generate')
9 files changed, 2409 insertions, 0 deletions
diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go new file mode 100644 index 000000000..fce88f5e2 --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go @@ -0,0 +1,1256 @@ +// Package generate implements functions generating container config files. +package generate + +import ( + "encoding/json" + "fmt" + "io" + "os" + "strings" + + rspec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runtime-tools/generate/seccomp" + "github.com/opencontainers/runtime-tools/validate" + "github.com/syndtr/gocapability/capability" +) + +var ( + // Namespaces include the names of supported namespaces. + Namespaces = []string{"network", "pid", "mount", "ipc", "uts", "user", "cgroup"} +) + +// Generator represents a generator for a container spec. +type Generator struct { + spec *rspec.Spec + HostSpecific bool +} + +// ExportOptions have toggles for exporting only certain parts of the specification +type ExportOptions struct { + Seccomp bool // seccomp toggles if only seccomp should be exported +} + +// New creates a spec Generator with the default spec. +func New() Generator { + spec := rspec.Spec{ + Version: rspec.Version, + Root: &rspec.Root{ + Path: "", + Readonly: false, + }, + Process: &rspec.Process{ + Terminal: false, + User: rspec.User{}, + Args: []string{ + "sh", + }, + Env: []string{ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "TERM=xterm", + }, + Cwd: "/", + Capabilities: &rspec.LinuxCapabilities{ + Bounding: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Permitted: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Inheritable: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Effective: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + Ambient: []string{ + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FSETID", + "CAP_FOWNER", + "CAP_MKNOD", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETUID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_NET_BIND_SERVICE", + "CAP_SYS_CHROOT", + "CAP_KILL", + "CAP_AUDIT_WRITE", + }, + }, + Rlimits: []rspec.POSIXRlimit{ + { + Type: "RLIMIT_NOFILE", + Hard: uint64(1024), + Soft: uint64(1024), + }, + }, + }, + Hostname: "mrsdalloway", + Mounts: []rspec.Mount{ + { + Destination: "/proc", + Type: "proc", + Source: "proc", + Options: nil, + }, + { + Destination: "/dev", + Type: "tmpfs", + Source: "tmpfs", + Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, + }, + { + Destination: "/dev/pts", + Type: "devpts", + Source: "devpts", + Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"}, + }, + { + Destination: "/dev/shm", + Type: "tmpfs", + Source: "shm", + Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"}, + }, + { + Destination: "/dev/mqueue", + Type: "mqueue", + Source: "mqueue", + Options: []string{"nosuid", "noexec", "nodev"}, + }, + { + Destination: "/sys", + Type: "sysfs", + Source: "sysfs", + Options: []string{"nosuid", "noexec", "nodev", "ro"}, + }, + }, + Linux: &rspec.Linux{ + Resources: &rspec.LinuxResources{ + Devices: []rspec.LinuxDeviceCgroup{ + { + Allow: false, + Access: "rwm", + }, + }, + }, + Namespaces: []rspec.LinuxNamespace{ + { + Type: "pid", + }, + { + Type: "network", + }, + { + Type: "ipc", + }, + { + Type: "uts", + }, + { + Type: "mount", + }, + }, + Devices: []rspec.LinuxDevice{}, + }, + } + spec.Linux.Seccomp = seccomp.DefaultProfile(&spec) + return Generator{ + spec: &spec, + } +} + +// NewFromSpec creates a spec Generator from a given spec. +func NewFromSpec(spec *rspec.Spec) Generator { + return Generator{ + spec: spec, + } +} + +// NewFromFile loads the template specified in a file into a spec Generator. +func NewFromFile(path string) (Generator, error) { + cf, err := os.Open(path) + if err != nil { + if os.IsNotExist(err) { + return Generator{}, fmt.Errorf("template configuration at %s not found", path) + } + } + defer cf.Close() + + return NewFromTemplate(cf) +} + +// NewFromTemplate loads the template from io.Reader into a spec Generator. +func NewFromTemplate(r io.Reader) (Generator, error) { + var spec rspec.Spec + if err := json.NewDecoder(r).Decode(&spec); err != nil { + return Generator{}, err + } + return Generator{ + spec: &spec, + }, nil +} + +// SetSpec sets the spec in the Generator g. +func (g *Generator) SetSpec(spec *rspec.Spec) { + g.spec = spec +} + +// Spec gets the spec in the Generator g. +func (g *Generator) Spec() *rspec.Spec { + return g.spec +} + +// Save writes the spec into w. +func (g *Generator) Save(w io.Writer, exportOpts ExportOptions) (err error) { + var data []byte + + if g.spec.Linux != nil { + buf, err := json.Marshal(g.spec.Linux) + if err != nil { + return err + } + if string(buf) == "{}" { + g.spec.Linux = nil + } + } + + if exportOpts.Seccomp { + data, err = json.MarshalIndent(g.spec.Linux.Seccomp, "", "\t") + } else { + data, err = json.MarshalIndent(g.spec, "", "\t") + } + if err != nil { + return err + } + + _, err = w.Write(data) + if err != nil { + return err + } + + return nil +} + +// SaveToFile writes the spec into a file. +func (g *Generator) SaveToFile(path string, exportOpts ExportOptions) error { + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + return g.Save(f, exportOpts) +} + +// SetVersion sets g.spec.Version. +func (g *Generator) SetVersion(version string) { + g.initSpec() + g.spec.Version = version +} + +// SetRootPath sets g.spec.Root.Path. +func (g *Generator) SetRootPath(path string) { + g.initSpecRoot() + g.spec.Root.Path = path +} + +// SetRootReadonly sets g.spec.Root.Readonly. +func (g *Generator) SetRootReadonly(b bool) { + g.initSpecRoot() + g.spec.Root.Readonly = b +} + +// SetHostname sets g.spec.Hostname. +func (g *Generator) SetHostname(s string) { + g.initSpec() + g.spec.Hostname = s +} + +// ClearAnnotations clears g.spec.Annotations. +func (g *Generator) ClearAnnotations() { + if g.spec == nil { + return + } + g.spec.Annotations = make(map[string]string) +} + +// AddAnnotation adds an annotation into g.spec.Annotations. +func (g *Generator) AddAnnotation(key, value string) { + g.initSpecAnnotations() + g.spec.Annotations[key] = value +} + +// RemoveAnnotation remove an annotation from g.spec.Annotations. +func (g *Generator) RemoveAnnotation(key string) { + if g.spec == nil || g.spec.Annotations == nil { + return + } + delete(g.spec.Annotations, key) +} + +// SetProcessConsoleSize sets g.spec.Process.ConsoleSize. +func (g *Generator) SetProcessConsoleSize(width, height uint) { + g.initSpecProcessConsoleSize() + g.spec.Process.ConsoleSize.Width = width + g.spec.Process.ConsoleSize.Height = height +} + +// SetProcessUID sets g.spec.Process.User.UID. +func (g *Generator) SetProcessUID(uid uint32) { + g.initSpecProcess() + g.spec.Process.User.UID = uid +} + +// SetProcessGID sets g.spec.Process.User.GID. +func (g *Generator) SetProcessGID(gid uint32) { + g.initSpecProcess() + g.spec.Process.User.GID = gid +} + +// SetProcessCwd sets g.spec.Process.Cwd. +func (g *Generator) SetProcessCwd(cwd string) { + g.initSpecProcess() + g.spec.Process.Cwd = cwd +} + +// SetProcessNoNewPrivileges sets g.spec.Process.NoNewPrivileges. +func (g *Generator) SetProcessNoNewPrivileges(b bool) { + g.initSpecProcess() + g.spec.Process.NoNewPrivileges = b +} + +// SetProcessTerminal sets g.spec.Process.Terminal. +func (g *Generator) SetProcessTerminal(b bool) { + g.initSpecProcess() + g.spec.Process.Terminal = b +} + +// SetProcessApparmorProfile sets g.spec.Process.ApparmorProfile. +func (g *Generator) SetProcessApparmorProfile(prof string) { + g.initSpecProcess() + g.spec.Process.ApparmorProfile = prof +} + +// SetProcessArgs sets g.spec.Process.Args. +func (g *Generator) SetProcessArgs(args []string) { + g.initSpecProcess() + g.spec.Process.Args = args +} + +// ClearProcessEnv clears g.spec.Process.Env. +func (g *Generator) ClearProcessEnv() { + if g.spec == nil { + return + } + g.spec.Process.Env = []string{} +} + +// AddProcessEnv adds name=value into g.spec.Process.Env, or replaces an +// existing entry with the given name. +func (g *Generator) AddProcessEnv(name, value string) { + g.initSpecProcess() + + env := fmt.Sprintf("%s=%s", name, value) + for idx := range g.spec.Process.Env { + if strings.HasPrefix(g.spec.Process.Env[idx], name+"=") { + g.spec.Process.Env[idx] = env + return + } + } + g.spec.Process.Env = append(g.spec.Process.Env, env) +} + +// AddProcessRlimits adds rlimit into g.spec.Process.Rlimits. +func (g *Generator) AddProcessRlimits(rType string, rHard uint64, rSoft uint64) { + g.initSpecProcess() + for i, rlimit := range g.spec.Process.Rlimits { + if rlimit.Type == rType { + g.spec.Process.Rlimits[i].Hard = rHard + g.spec.Process.Rlimits[i].Soft = rSoft + return + } + } + + newRlimit := rspec.POSIXRlimit{ + Type: rType, + Hard: rHard, + Soft: rSoft, + } + g.spec.Process.Rlimits = append(g.spec.Process.Rlimits, newRlimit) +} + +// RemoveProcessRlimits removes a rlimit from g.spec.Process.Rlimits. +func (g *Generator) RemoveProcessRlimits(rType string) error { + if g.spec == nil { + return nil + } + for i, rlimit := range g.spec.Process.Rlimits { + if rlimit.Type == rType { + g.spec.Process.Rlimits = append(g.spec.Process.Rlimits[:i], g.spec.Process.Rlimits[i+1:]...) + return nil + } + } + return nil +} + +// ClearProcessRlimits clear g.spec.Process.Rlimits. +func (g *Generator) ClearProcessRlimits() { + if g.spec == nil { + return + } + g.spec.Process.Rlimits = []rspec.POSIXRlimit{} +} + +// ClearProcessAdditionalGids clear g.spec.Process.AdditionalGids. +func (g *Generator) ClearProcessAdditionalGids() { + if g.spec == nil { + return + } + g.spec.Process.User.AdditionalGids = []uint32{} +} + +// AddProcessAdditionalGid adds an additional gid into g.spec.Process.AdditionalGids. +func (g *Generator) AddProcessAdditionalGid(gid uint32) { + g.initSpecProcess() + for _, group := range g.spec.Process.User.AdditionalGids { + if group == gid { + return + } + } + g.spec.Process.User.AdditionalGids = append(g.spec.Process.User.AdditionalGids, gid) +} + +// SetProcessSelinuxLabel sets g.spec.Process.SelinuxLabel. +func (g *Generator) SetProcessSelinuxLabel(label string) { + g.initSpecProcess() + g.spec.Process.SelinuxLabel = label +} + +// SetLinuxCgroupsPath sets g.spec.Linux.CgroupsPath. +func (g *Generator) SetLinuxCgroupsPath(path string) { + g.initSpecLinux() + g.spec.Linux.CgroupsPath = path +} + +// SetLinuxMountLabel sets g.spec.Linux.MountLabel. +func (g *Generator) SetLinuxMountLabel(label string) { + g.initSpecLinux() + g.spec.Linux.MountLabel = label +} + +// SetProcessOOMScoreAdj sets g.spec.Process.OOMScoreAdj. +func (g *Generator) SetProcessOOMScoreAdj(adj int) { + g.initSpecProcess() + g.spec.Process.OOMScoreAdj = &adj +} + +// SetLinuxResourcesCPUShares sets g.spec.Linux.Resources.CPU.Shares. +func (g *Generator) SetLinuxResourcesCPUShares(shares uint64) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.Shares = &shares +} + +// SetLinuxResourcesCPUQuota sets g.spec.Linux.Resources.CPU.Quota. +func (g *Generator) SetLinuxResourcesCPUQuota(quota int64) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.Quota = "a +} + +// SetLinuxResourcesCPUPeriod sets g.spec.Linux.Resources.CPU.Period. +func (g *Generator) SetLinuxResourcesCPUPeriod(period uint64) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.Period = &period +} + +// SetLinuxResourcesCPURealtimeRuntime sets g.spec.Linux.Resources.CPU.RealtimeRuntime. +func (g *Generator) SetLinuxResourcesCPURealtimeRuntime(time int64) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.RealtimeRuntime = &time +} + +// SetLinuxResourcesCPURealtimePeriod sets g.spec.Linux.Resources.CPU.RealtimePeriod. +func (g *Generator) SetLinuxResourcesCPURealtimePeriod(period uint64) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.RealtimePeriod = &period +} + +// SetLinuxResourcesCPUCpus sets g.spec.Linux.Resources.CPU.Cpus. +func (g *Generator) SetLinuxResourcesCPUCpus(cpus string) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.Cpus = cpus +} + +// SetLinuxResourcesCPUMems sets g.spec.Linux.Resources.CPU.Mems. +func (g *Generator) SetLinuxResourcesCPUMems(mems string) { + g.initSpecLinuxResourcesCPU() + g.spec.Linux.Resources.CPU.Mems = mems +} + +// AddLinuxResourcesHugepageLimit adds or sets g.spec.Linux.Resources.HugepageLimits. +func (g *Generator) AddLinuxResourcesHugepageLimit(pageSize string, limit uint64) { + hugepageLimit := rspec.LinuxHugepageLimit{ + Pagesize: pageSize, + Limit: limit, + } + + g.initSpecLinuxResources() + for i, pageLimit := range g.spec.Linux.Resources.HugepageLimits { + if pageLimit.Pagesize == pageSize { + g.spec.Linux.Resources.HugepageLimits[i].Limit = limit + return + } + } + g.spec.Linux.Resources.HugepageLimits = append(g.spec.Linux.Resources.HugepageLimits, hugepageLimit) +} + +// DropLinuxResourcesHugepageLimit drops a hugepage limit from g.spec.Linux.Resources.HugepageLimits. +func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) error { + g.initSpecLinuxResources() + for i, pageLimit := range g.spec.Linux.Resources.HugepageLimits { + if pageLimit.Pagesize == pageSize { + g.spec.Linux.Resources.HugepageLimits = append(g.spec.Linux.Resources.HugepageLimits[:i], g.spec.Linux.Resources.HugepageLimits[i+1:]...) + return nil + } + } + + return nil +} + +// SetLinuxResourcesMemoryLimit sets g.spec.Linux.Resources.Memory.Limit. +func (g *Generator) SetLinuxResourcesMemoryLimit(limit int64) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.Limit = &limit +} + +// SetLinuxResourcesMemoryReservation sets g.spec.Linux.Resources.Memory.Reservation. +func (g *Generator) SetLinuxResourcesMemoryReservation(reservation int64) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.Reservation = &reservation +} + +// SetLinuxResourcesMemorySwap sets g.spec.Linux.Resources.Memory.Swap. +func (g *Generator) SetLinuxResourcesMemorySwap(swap int64) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.Swap = &swap +} + +// SetLinuxResourcesMemoryKernel sets g.spec.Linux.Resources.Memory.Kernel. +func (g *Generator) SetLinuxResourcesMemoryKernel(kernel int64) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.Kernel = &kernel +} + +// SetLinuxResourcesMemoryKernelTCP sets g.spec.Linux.Resources.Memory.KernelTCP. +func (g *Generator) SetLinuxResourcesMemoryKernelTCP(kernelTCP int64) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.KernelTCP = &kernelTCP +} + +// SetLinuxResourcesMemorySwappiness sets g.spec.Linux.Resources.Memory.Swappiness. +func (g *Generator) SetLinuxResourcesMemorySwappiness(swappiness uint64) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.Swappiness = &swappiness +} + +// SetLinuxResourcesMemoryDisableOOMKiller sets g.spec.Linux.Resources.Memory.DisableOOMKiller. +func (g *Generator) SetLinuxResourcesMemoryDisableOOMKiller(disable bool) { + g.initSpecLinuxResourcesMemory() + g.spec.Linux.Resources.Memory.DisableOOMKiller = &disable +} + +// SetLinuxResourcesNetworkClassID sets g.spec.Linux.Resources.Network.ClassID. +func (g *Generator) SetLinuxResourcesNetworkClassID(classid uint32) { + g.initSpecLinuxResourcesNetwork() + g.spec.Linux.Resources.Network.ClassID = &classid +} + +// AddLinuxResourcesNetworkPriorities adds or sets g.spec.Linux.Resources.Network.Priorities. +func (g *Generator) AddLinuxResourcesNetworkPriorities(name string, prio uint32) { + g.initSpecLinuxResourcesNetwork() + for i, netPriority := range g.spec.Linux.Resources.Network.Priorities { + if netPriority.Name == name { + g.spec.Linux.Resources.Network.Priorities[i].Priority = prio + return + } + } + interfacePrio := new(rspec.LinuxInterfacePriority) + interfacePrio.Name = name + interfacePrio.Priority = prio + g.spec.Linux.Resources.Network.Priorities = append(g.spec.Linux.Resources.Network.Priorities, *interfacePrio) +} + +// DropLinuxResourcesNetworkPriorities drops one item from g.spec.Linux.Resources.Network.Priorities. +func (g *Generator) DropLinuxResourcesNetworkPriorities(name string) { + g.initSpecLinuxResourcesNetwork() + for i, netPriority := range g.spec.Linux.Resources.Network.Priorities { + if netPriority.Name == name { + g.spec.Linux.Resources.Network.Priorities = append(g.spec.Linux.Resources.Network.Priorities[:i], g.spec.Linux.Resources.Network.Priorities[i+1:]...) + return + } + } +} + +// SetLinuxResourcesPidsLimit sets g.spec.Linux.Resources.Pids.Limit. +func (g *Generator) SetLinuxResourcesPidsLimit(limit int64) { + g.initSpecLinuxResourcesPids() + g.spec.Linux.Resources.Pids.Limit = limit +} + +// ClearLinuxSysctl clears g.spec.Linux.Sysctl. +func (g *Generator) ClearLinuxSysctl() { + if g.spec == nil || g.spec.Linux == nil { + return + } + g.spec.Linux.Sysctl = make(map[string]string) +} + +// AddLinuxSysctl adds a new sysctl config into g.spec.Linux.Sysctl. +func (g *Generator) AddLinuxSysctl(key, value string) { + g.initSpecLinuxSysctl() + g.spec.Linux.Sysctl[key] = value +} + +// RemoveLinuxSysctl removes a sysctl config from g.spec.Linux.Sysctl. +func (g *Generator) RemoveLinuxSysctl(key string) { + if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Sysctl == nil { + return + } + delete(g.spec.Linux.Sysctl, key) +} + +// ClearLinuxUIDMappings clear g.spec.Linux.UIDMappings. +func (g *Generator) ClearLinuxUIDMappings() { + if g.spec == nil || g.spec.Linux == nil { + return + } + g.spec.Linux.UIDMappings = []rspec.LinuxIDMapping{} +} + +// AddLinuxUIDMapping adds uidMap into g.spec.Linux.UIDMappings. +func (g *Generator) AddLinuxUIDMapping(hid, cid, size uint32) { + idMapping := rspec.LinuxIDMapping{ + HostID: hid, + ContainerID: cid, + Size: size, + } + + g.initSpecLinux() + g.spec.Linux.UIDMappings = append(g.spec.Linux.UIDMappings, idMapping) +} + +// ClearLinuxGIDMappings clear g.spec.Linux.GIDMappings. +func (g *Generator) ClearLinuxGIDMappings() { + if g.spec == nil || g.spec.Linux == nil { + return + } + g.spec.Linux.GIDMappings = []rspec.LinuxIDMapping{} +} + +// AddLinuxGIDMapping adds gidMap into g.spec.Linux.GIDMappings. +func (g *Generator) AddLinuxGIDMapping(hid, cid, size uint32) { + idMapping := rspec.LinuxIDMapping{ + HostID: hid, + ContainerID: cid, + Size: size, + } + + g.initSpecLinux() + g.spec.Linux.GIDMappings = append(g.spec.Linux.GIDMappings, idMapping) +} + +// SetLinuxRootPropagation sets g.spec.Linux.RootfsPropagation. +func (g *Generator) SetLinuxRootPropagation(rp string) error { + switch rp { + case "": + case "private": + case "rprivate": + case "slave": + case "rslave": + case "shared": + case "rshared": + default: + return fmt.Errorf("rootfs-propagation must be empty or one of private|rprivate|slave|rslave|shared|rshared") + } + g.initSpecLinux() + g.spec.Linux.RootfsPropagation = rp + return nil +} + +// ClearPreStartHooks clear g.spec.Hooks.Prestart. +func (g *Generator) ClearPreStartHooks() { + if g.spec == nil { + return + } + if g.spec.Hooks == nil { + return + } + g.spec.Hooks.Prestart = []rspec.Hook{} +} + +// AddPreStartHook add a prestart hook into g.spec.Hooks.Prestart. +func (g *Generator) AddPreStartHook(path string, args []string) { + g.initSpecHooks() + hook := rspec.Hook{Path: path, Args: args} + for i, hook := range g.spec.Hooks.Prestart { + if hook.Path == path { + g.spec.Hooks.Prestart[i] = hook + return + } + } + g.spec.Hooks.Prestart = append(g.spec.Hooks.Prestart, hook) +} + +// AddPreStartHookEnv adds envs of a prestart hook into g.spec.Hooks.Prestart. +func (g *Generator) AddPreStartHookEnv(path string, envs []string) { + g.initSpecHooks() + for i, hook := range g.spec.Hooks.Prestart { + if hook.Path == path { + g.spec.Hooks.Prestart[i].Env = envs + return + } + } + hook := rspec.Hook{Path: path, Env: envs} + g.spec.Hooks.Prestart = append(g.spec.Hooks.Prestart, hook) +} + +// AddPreStartHookTimeout adds timeout of a prestart hook into g.spec.Hooks.Prestart. +func (g *Generator) AddPreStartHookTimeout(path string, timeout int) { + g.initSpecHooks() + for i, hook := range g.spec.Hooks.Prestart { + if hook.Path == path { + g.spec.Hooks.Prestart[i].Timeout = &timeout + return + } + } + hook := rspec.Hook{Path: path, Timeout: &timeout} + g.spec.Hooks.Prestart = append(g.spec.Hooks.Prestart, hook) +} + +// ClearPostStopHooks clear g.spec.Hooks.Poststop. +func (g *Generator) ClearPostStopHooks() { + if g.spec == nil { + return + } + if g.spec.Hooks == nil { + return + } + g.spec.Hooks.Poststop = []rspec.Hook{} +} + +// AddPostStopHook adds a poststop hook into g.spec.Hooks.Poststop. +func (g *Generator) AddPostStopHook(path string, args []string) { + g.initSpecHooks() + hook := rspec.Hook{Path: path, Args: args} + for i, hook := range g.spec.Hooks.Poststop { + if hook.Path == path { + g.spec.Hooks.Poststop[i] = hook + return + } + } + g.spec.Hooks.Poststop = append(g.spec.Hooks.Poststop, hook) +} + +// AddPostStopHookEnv adds envs of a poststop hook into g.spec.Hooks.Poststop. +func (g *Generator) AddPostStopHookEnv(path string, envs []string) { + g.initSpecHooks() + for i, hook := range g.spec.Hooks.Poststop { + if hook.Path == path { + g.spec.Hooks.Poststop[i].Env = envs + return + } + } + hook := rspec.Hook{Path: path, Env: envs} + g.spec.Hooks.Poststop = append(g.spec.Hooks.Poststop, hook) +} + +// AddPostStopHookTimeout adds timeout of a poststop hook into g.spec.Hooks.Poststop. +func (g *Generator) AddPostStopHookTimeout(path string, timeout int) { + g.initSpecHooks() + for i, hook := range g.spec.Hooks.Poststop { + if hook.Path == path { + g.spec.Hooks.Poststop[i].Timeout = &timeout + return + } + } + hook := rspec.Hook{Path: path, Timeout: &timeout} + g.spec.Hooks.Poststop = append(g.spec.Hooks.Poststop, hook) +} + +// ClearPostStartHooks clear g.spec.Hooks.Poststart. +func (g *Generator) ClearPostStartHooks() { + if g.spec == nil { + return + } + if g.spec.Hooks == nil { + return + } + g.spec.Hooks.Poststart = []rspec.Hook{} +} + +// AddPostStartHook adds a poststart hook into g.spec.Hooks.Poststart. +func (g *Generator) AddPostStartHook(path string, args []string) { + g.initSpecHooks() + hook := rspec.Hook{Path: path, Args: args} + for i, hook := range g.spec.Hooks.Poststart { + if hook.Path == path { + g.spec.Hooks.Poststart[i] = hook + return + } + } + g.spec.Hooks.Poststart = append(g.spec.Hooks.Poststart, hook) +} + +// AddPostStartHookEnv adds envs of a poststart hook into g.spec.Hooks.Poststart. +func (g *Generator) AddPostStartHookEnv(path string, envs []string) { + g.initSpecHooks() + for i, hook := range g.spec.Hooks.Poststart { + if hook.Path == path { + g.spec.Hooks.Poststart[i].Env = envs + return + } + } + hook := rspec.Hook{Path: path, Env: envs} + g.spec.Hooks.Poststart = append(g.spec.Hooks.Poststart, hook) +} + +// AddPostStartHookTimeout adds timeout of a poststart hook into g.spec.Hooks.Poststart. +func (g *Generator) AddPostStartHookTimeout(path string, timeout int) { + g.initSpecHooks() + for i, hook := range g.spec.Hooks.Poststart { + if hook.Path == path { + g.spec.Hooks.Poststart[i].Timeout = &timeout + return + } + } + hook := rspec.Hook{Path: path, Timeout: &timeout} + g.spec.Hooks.Poststart = append(g.spec.Hooks.Poststart, hook) +} + +// AddTmpfsMount adds a tmpfs mount into g.spec.Mounts. +func (g *Generator) AddTmpfsMount(dest string, options []string) { + mnt := rspec.Mount{ + Destination: dest, + Type: "tmpfs", + Source: "tmpfs", + Options: options, + } + + g.initSpec() + g.spec.Mounts = append(g.spec.Mounts, mnt) +} + +// AddCgroupsMount adds a cgroup mount into g.spec.Mounts. +func (g *Generator) AddCgroupsMount(mountCgroupOption string) error { + switch mountCgroupOption { + case "ro": + case "rw": + case "no": + return nil + default: + return fmt.Errorf("--mount-cgroups should be one of (ro,rw,no)") + } + + mnt := rspec.Mount{ + Destination: "/sys/fs/cgroup", + Type: "cgroup", + Source: "cgroup", + Options: []string{"nosuid", "noexec", "nodev", "relatime", mountCgroupOption}, + } + g.initSpec() + g.spec.Mounts = append(g.spec.Mounts, mnt) + + return nil +} + +// AddBindMount adds a bind mount into g.spec.Mounts. +func (g *Generator) AddBindMount(source, dest string, options []string) { + if len(options) == 0 { + options = []string{"rw"} + } + + // We have to make sure that there is a bind option set, otherwise it won't + // be an actual bindmount. + foundBindOption := false + for _, opt := range options { + if opt == "bind" || opt == "rbind" { + foundBindOption = true + break + } + } + if !foundBindOption { + options = append(options, "bind") + } + + mnt := rspec.Mount{ + Destination: dest, + Type: "bind", + Source: source, + Options: options, + } + g.initSpec() + g.spec.Mounts = append(g.spec.Mounts, mnt) +} + +// SetupPrivileged sets up the privilege-related fields inside g.spec. +func (g *Generator) SetupPrivileged(privileged bool) { + if privileged { // Add all capabilities in privileged mode. + var finalCapList []string + for _, cap := range capability.List() { + if g.HostSpecific && cap > validate.LastCap() { + continue + } + finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))) + } + g.initSpecLinux() + g.initSpecProcessCapabilities() + g.ClearProcessCapabilities() + g.spec.Process.Capabilities.Bounding = append(g.spec.Process.Capabilities.Bounding, finalCapList...) + g.spec.Process.Capabilities.Effective = append(g.spec.Process.Capabilities.Effective, finalCapList...) + g.spec.Process.Capabilities.Inheritable = append(g.spec.Process.Capabilities.Inheritable, finalCapList...) + g.spec.Process.Capabilities.Permitted = append(g.spec.Process.Capabilities.Permitted, finalCapList...) + g.spec.Process.Capabilities.Ambient = append(g.spec.Process.Capabilities.Ambient, finalCapList...) + g.spec.Process.SelinuxLabel = "" + g.spec.Process.ApparmorProfile = "" + g.spec.Linux.Seccomp = nil + } +} + +// ClearProcessCapabilities clear g.spec.Process.Capabilities. +func (g *Generator) ClearProcessCapabilities() { + if g.spec == nil { + return + } + g.spec.Process.Capabilities.Bounding = []string{} + g.spec.Process.Capabilities.Effective = []string{} + g.spec.Process.Capabilities.Inheritable = []string{} + g.spec.Process.Capabilities.Permitted = []string{} + g.spec.Process.Capabilities.Ambient = []string{} +} + +// AddProcessCapability adds a process capability into g.spec.Process.Capabilities. +func (g *Generator) AddProcessCapability(c string) error { + cp := strings.ToUpper(c) + if err := validate.CapValid(cp, g.HostSpecific); err != nil { + return err + } + + g.initSpecProcessCapabilities() + + var foundBounding bool + for _, cap := range g.spec.Process.Capabilities.Bounding { + if strings.ToUpper(cap) == cp { + foundBounding = true + break + } + } + if !foundBounding { + g.spec.Process.Capabilities.Bounding = append(g.spec.Process.Capabilities.Bounding, cp) + } + + var foundEffective bool + for _, cap := range g.spec.Process.Capabilities.Effective { + if strings.ToUpper(cap) == cp { + foundEffective = true + break + } + } + if !foundEffective { + g.spec.Process.Capabilities.Effective = append(g.spec.Process.Capabilities.Effective, cp) + } + + var foundInheritable bool + for _, cap := range g.spec.Process.Capabilities.Inheritable { + if strings.ToUpper(cap) == cp { + foundInheritable = true + break + } + } + if !foundInheritable { + g.spec.Process.Capabilities.Inheritable = append(g.spec.Process.Capabilities.Inheritable, cp) + } + + var foundPermitted bool + for _, cap := range g.spec.Process.Capabilities.Permitted { + if strings.ToUpper(cap) == cp { + foundPermitted = true + break + } + } + if !foundPermitted { + g.spec.Process.Capabilities.Permitted = append(g.spec.Process.Capabilities.Permitted, cp) + } + + var foundAmbient bool + for _, cap := range g.spec.Process.Capabilities.Ambient { + if strings.ToUpper(cap) == cp { + foundAmbient = true + break + } + } + if !foundAmbient { + g.spec.Process.Capabilities.Ambient = append(g.spec.Process.Capabilities.Ambient, cp) + } + + return nil +} + +// DropProcessCapability drops a process capability from g.spec.Process.Capabilities. +func (g *Generator) DropProcessCapability(c string) error { + cp := strings.ToUpper(c) + if err := validate.CapValid(cp, g.HostSpecific); err != nil { + return err + } + + g.initSpecProcessCapabilities() + + // we don't care about order...and this is way faster... + removeFunc := func(s []string, i int) []string { + s[i] = s[len(s)-1] + return s[:len(s)-1] + } + + for i, cap := range g.spec.Process.Capabilities.Bounding { + if strings.ToUpper(cap) == cp { + g.spec.Process.Capabilities.Bounding = removeFunc(g.spec.Process.Capabilities.Bounding, i) + } + } + + for i, cap := range g.spec.Process.Capabilities.Effective { + if strings.ToUpper(cap) == cp { + g.spec.Process.Capabilities.Effective = removeFunc(g.spec.Process.Capabilities.Effective, i) + } + } + + for i, cap := range g.spec.Process.Capabilities.Inheritable { + if strings.ToUpper(cap) == cp { + g.spec.Process.Capabilities.Inheritable = removeFunc(g.spec.Process.Capabilities.Inheritable, i) + } + } + + for i, cap := range g.spec.Process.Capabilities.Permitted { + if strings.ToUpper(cap) == cp { + g.spec.Process.Capabilities.Permitted = removeFunc(g.spec.Process.Capabilities.Permitted, i) + } + } + + for i, cap := range g.spec.Process.Capabilities.Ambient { + if strings.ToUpper(cap) == cp { + g.spec.Process.Capabilities.Ambient = removeFunc(g.spec.Process.Capabilities.Ambient, i) + } + } + + return nil +} + +func mapStrToNamespace(ns string, path string) (rspec.LinuxNamespace, error) { + switch ns { + case "network": + return rspec.LinuxNamespace{Type: rspec.NetworkNamespace, Path: path}, nil + case "pid": + return rspec.LinuxNamespace{Type: rspec.PIDNamespace, Path: path}, nil + case "mount": + return rspec.LinuxNamespace{Type: rspec.MountNamespace, Path: path}, nil + case "ipc": + return rspec.LinuxNamespace{Type: rspec.IPCNamespace, Path: path}, nil + case "uts": + return rspec.LinuxNamespace{Type: rspec.UTSNamespace, Path: path}, nil + case "user": + return rspec.LinuxNamespace{Type: rspec.UserNamespace, Path: path}, nil + case "cgroup": + return rspec.LinuxNamespace{Type: rspec.CgroupNamespace, Path: path}, nil + default: + return rspec.LinuxNamespace{}, fmt.Errorf("unrecognized namespace %q", ns) + } +} + +// ClearLinuxNamespaces clear g.spec.Linux.Namespaces. +func (g *Generator) ClearLinuxNamespaces() { + if g.spec == nil || g.spec.Linux == nil { + return + } + g.spec.Linux.Namespaces = []rspec.LinuxNamespace{} +} + +// AddOrReplaceLinuxNamespace adds or replaces a namespace inside +// g.spec.Linux.Namespaces. +func (g *Generator) AddOrReplaceLinuxNamespace(ns string, path string) error { + namespace, err := mapStrToNamespace(ns, path) + if err != nil { + return err + } + + g.initSpecLinux() + for i, ns := range g.spec.Linux.Namespaces { + if ns.Type == namespace.Type { + g.spec.Linux.Namespaces[i] = namespace + return nil + } + } + g.spec.Linux.Namespaces = append(g.spec.Linux.Namespaces, namespace) + return nil +} + +// RemoveLinuxNamespace removes a namespace from g.spec.Linux.Namespaces. +func (g *Generator) RemoveLinuxNamespace(ns string) error { + namespace, err := mapStrToNamespace(ns, "") + if err != nil { + return err + } + + if g.spec == nil || g.spec.Linux == nil { + return nil + } + for i, ns := range g.spec.Linux.Namespaces { + if ns.Type == namespace.Type { + g.spec.Linux.Namespaces = append(g.spec.Linux.Namespaces[:i], g.spec.Linux.Namespaces[i+1:]...) + return nil + } + } + return nil +} + +// AddDevice - add a device into g.spec.Linux.Devices +func (g *Generator) AddDevice(device rspec.LinuxDevice) { + g.initSpecLinux() + + for i, dev := range g.spec.Linux.Devices { + if dev.Path == device.Path { + g.spec.Linux.Devices[i] = device + return + } + if dev.Type == device.Type && dev.Major == device.Major && dev.Minor == device.Minor { + fmt.Fprintln(os.Stderr, "WARNING: The same type, major and minor should not be used for multiple devices.") + } + } + + g.spec.Linux.Devices = append(g.spec.Linux.Devices, device) +} + +// RemoveDevice remove a device from g.spec.Linux.Devices +func (g *Generator) RemoveDevice(path string) error { + if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Devices == nil { + return nil + } + + for i, device := range g.spec.Linux.Devices { + if device.Path == path { + g.spec.Linux.Devices = append(g.spec.Linux.Devices[:i], g.spec.Linux.Devices[i+1:]...) + return nil + } + } + return nil +} + +// ClearLinuxDevices clears g.spec.Linux.Devices +func (g *Generator) ClearLinuxDevices() { + if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Devices == nil { + return + } + + g.spec.Linux.Devices = []rspec.LinuxDevice{} +} + +// strPtr returns the pointer pointing to the string s. +func strPtr(s string) *string { return &s } + +// SetSyscallAction adds rules for syscalls with the specified action +func (g *Generator) SetSyscallAction(arguments seccomp.SyscallOpts) error { + g.initSpecLinuxSeccomp() + return seccomp.ParseSyscallFlag(arguments, g.spec.Linux.Seccomp) +} + +// SetDefaultSeccompAction sets the default action for all syscalls not defined +// and then removes any syscall rules with this action already specified. +func (g *Generator) SetDefaultSeccompAction(action string) error { + g.initSpecLinuxSeccomp() + return seccomp.ParseDefaultAction(action, g.spec.Linux.Seccomp) +} + +// SetDefaultSeccompActionForce only sets the default action for all syscalls not defined +func (g *Generator) SetDefaultSeccompActionForce(action string) error { + g.initSpecLinuxSeccomp() + return seccomp.ParseDefaultActionForce(action, g.spec.Linux.Seccomp) +} + +// SetSeccompArchitecture sets the supported seccomp architectures +func (g *Generator) SetSeccompArchitecture(architecture string) error { + g.initSpecLinuxSeccomp() + return seccomp.ParseArchitectureFlag(architecture, g.spec.Linux.Seccomp) +} + +// RemoveSeccompRule removes rules for any specified syscalls +func (g *Generator) RemoveSeccompRule(arguments string) error { + g.initSpecLinuxSeccomp() + return seccomp.RemoveAction(arguments, g.spec.Linux.Seccomp) +} + +// RemoveAllSeccompRules removes all syscall rules +func (g *Generator) RemoveAllSeccompRules() error { + g.initSpecLinuxSeccomp() + return seccomp.RemoveAllSeccompRules(g.spec.Linux.Seccomp) +} + +// AddLinuxMaskedPaths adds masked paths into g.spec.Linux.MaskedPaths. +func (g *Generator) AddLinuxMaskedPaths(path string) { + g.initSpecLinux() + g.spec.Linux.MaskedPaths = append(g.spec.Linux.MaskedPaths, path) +} + +// AddLinuxReadonlyPaths adds readonly paths into g.spec.Linux.MaskedPaths. +func (g *Generator) AddLinuxReadonlyPaths(path string) { + g.initSpecLinux() + g.spec.Linux.ReadonlyPaths = append(g.spec.Linux.ReadonlyPaths, path) +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go new file mode 100644 index 000000000..eade5718e --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go @@ -0,0 +1,12 @@ +package seccomp + +const ( + seccompOverwrite = "overwrite" + seccompAppend = "append" + nothing = "nothing" + kill = "kill" + trap = "trap" + trace = "trace" + allow = "allow" + errno = "errno" +) diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go new file mode 100644 index 000000000..25daf0752 --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go @@ -0,0 +1,135 @@ +package seccomp + +import ( + "fmt" + "strconv" + "strings" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// SyscallOpts contain options for parsing syscall rules +type SyscallOpts struct { + Action string + Syscall string + Index string + Value string + ValueTwo string + Operator string +} + +// ParseSyscallFlag takes a SyscallOpts struct and the seccomp configuration +// and sets the new syscall rule accordingly +func ParseSyscallFlag(args SyscallOpts, config *rspec.LinuxSeccomp) error { + var arguments []string + if args.Index != "" && args.Value != "" && args.ValueTwo != "" && args.Operator != "" { + arguments = []string{args.Action, args.Syscall, args.Index, args.Value, + args.ValueTwo, args.Operator} + } else { + arguments = []string{args.Action, args.Syscall} + } + + action, _ := parseAction(arguments[0]) + if action == config.DefaultAction && args.argsAreEmpty() { + // default already set, no need to make changes + return nil + } + + var newSyscall rspec.LinuxSyscall + numOfArgs := len(arguments) + if numOfArgs == 6 || numOfArgs == 2 { + argStruct, err := parseArguments(arguments[1:]) + if err != nil { + return err + } + newSyscall = newSyscallStruct(arguments[1], action, argStruct) + } else { + return fmt.Errorf("incorrect number of arguments to ParseSyscall: %d", numOfArgs) + } + + descison, err := decideCourseOfAction(&newSyscall, config.Syscalls) + if err != nil { + return err + } + delimDescison := strings.Split(descison, ":") + + if delimDescison[0] == seccompAppend { + config.Syscalls = append(config.Syscalls, newSyscall) + } + + if delimDescison[0] == seccompOverwrite { + indexForOverwrite, err := strconv.ParseInt(delimDescison[1], 10, 32) + if err != nil { + return err + } + config.Syscalls[indexForOverwrite] = newSyscall + } + + return nil +} + +var actions = map[string]rspec.LinuxSeccompAction{ + "allow": rspec.ActAllow, + "errno": rspec.ActErrno, + "kill": rspec.ActKill, + "trace": rspec.ActTrace, + "trap": rspec.ActTrap, +} + +// Take passed action, return the SCMP_ACT_<ACTION> version of it +func parseAction(action string) (rspec.LinuxSeccompAction, error) { + a, ok := actions[action] + if !ok { + return "", fmt.Errorf("unrecognized action: %s", action) + } + return a, nil +} + +// ParseDefaultAction sets the default action of the seccomp configuration +// and then removes any rules that were already specified with this action +func ParseDefaultAction(action string, config *rspec.LinuxSeccomp) error { + if action == "" { + return nil + } + + defaultAction, err := parseAction(action) + if err != nil { + return err + } + config.DefaultAction = defaultAction + err = RemoveAllMatchingRules(config, defaultAction) + if err != nil { + return err + } + return nil +} + +// ParseDefaultActionForce simply sets the default action of the seccomp configuration +func ParseDefaultActionForce(action string, config *rspec.LinuxSeccomp) error { + if action == "" { + return nil + } + + defaultAction, err := parseAction(action) + if err != nil { + return err + } + config.DefaultAction = defaultAction + return nil +} + +func newSyscallStruct(name string, action rspec.LinuxSeccompAction, args []rspec.LinuxSeccompArg) rspec.LinuxSyscall { + syscallStruct := rspec.LinuxSyscall{ + Names: []string{name}, + Action: action, + Args: args, + } + return syscallStruct +} + +func (s SyscallOpts) argsAreEmpty() bool { + return (s.Index == "" && + s.Value == "" && + s.ValueTwo == "" && + s.Operator == "") +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go new file mode 100644 index 000000000..9b2bdfd2f --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go @@ -0,0 +1,55 @@ +package seccomp + +import ( + "fmt" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// ParseArchitectureFlag takes the raw string passed with the --arch flag, parses it +// and updates the Seccomp config accordingly +func ParseArchitectureFlag(architectureArg string, config *rspec.LinuxSeccomp) error { + correctedArch, err := parseArch(architectureArg) + if err != nil { + return err + } + + shouldAppend := true + for _, alreadySpecified := range config.Architectures { + if correctedArch == alreadySpecified { + shouldAppend = false + } + } + if shouldAppend { + config.Architectures = append(config.Architectures, correctedArch) + } + return nil +} + +func parseArch(arch string) (rspec.Arch, error) { + arches := map[string]rspec.Arch{ + "x86": rspec.ArchX86, + "amd64": rspec.ArchX86_64, + "x32": rspec.ArchX32, + "arm": rspec.ArchARM, + "arm64": rspec.ArchAARCH64, + "mips": rspec.ArchMIPS, + "mips64": rspec.ArchMIPS64, + "mips64n32": rspec.ArchMIPS64N32, + "mipsel": rspec.ArchMIPSEL, + "mipsel64": rspec.ArchMIPSEL64, + "mipsel64n32": rspec.ArchMIPSEL64N32, + "parisc": rspec.ArchPARISC, + "parisc64": rspec.ArchPARISC64, + "ppc": rspec.ArchPPC, + "ppc64": rspec.ArchPPC64, + "ppc64le": rspec.ArchPPC64LE, + "s390": rspec.ArchS390, + "s390x": rspec.ArchS390X, + } + a, ok := arches[arch] + if !ok { + return "", fmt.Errorf("unrecognized architecture: %s", arch) + } + return a, nil +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go new file mode 100644 index 000000000..2b4c394e6 --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go @@ -0,0 +1,73 @@ +package seccomp + +import ( + "fmt" + "strconv" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// parseArguments takes a list of arguments (delimArgs). It parses and fills out +// the argument information and returns a slice of arg structs +func parseArguments(delimArgs []string) ([]rspec.LinuxSeccompArg, error) { + nilArgSlice := []rspec.LinuxSeccompArg{} + numberOfArgs := len(delimArgs) + + // No parameters passed with syscall + if numberOfArgs == 1 { + return nilArgSlice, nil + } + + // Correct number of parameters passed with syscall + if numberOfArgs == 5 { + syscallIndex, err := strconv.ParseUint(delimArgs[1], 10, 0) + if err != nil { + return nilArgSlice, err + } + + syscallValue, err := strconv.ParseUint(delimArgs[2], 10, 64) + if err != nil { + return nilArgSlice, err + } + + syscallValueTwo, err := strconv.ParseUint(delimArgs[3], 10, 64) + if err != nil { + return nilArgSlice, err + } + + syscallOp, err := parseOperator(delimArgs[4]) + if err != nil { + return nilArgSlice, err + } + + argStruct := rspec.LinuxSeccompArg{ + Index: uint(syscallIndex), + Value: syscallValue, + ValueTwo: syscallValueTwo, + Op: syscallOp, + } + + argSlice := []rspec.LinuxSeccompArg{} + argSlice = append(argSlice, argStruct) + return argSlice, nil + } + + return nilArgSlice, fmt.Errorf("incorrect number of arguments passed with syscall: %d", numberOfArgs) +} + +func parseOperator(operator string) (rspec.LinuxSeccompOperator, error) { + operators := map[string]rspec.LinuxSeccompOperator{ + "NE": rspec.OpNotEqual, + "LT": rspec.OpLessThan, + "LE": rspec.OpLessEqual, + "EQ": rspec.OpEqualTo, + "GE": rspec.OpGreaterEqual, + "GT": rspec.OpGreaterThan, + "ME": rspec.OpMaskedEqual, + } + o, ok := operators[operator] + if !ok { + return "", fmt.Errorf("unrecognized operator: %s", operator) + } + return o, nil +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go new file mode 100644 index 000000000..59537d49c --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go @@ -0,0 +1,52 @@ +package seccomp + +import ( + "fmt" + "reflect" + "strings" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// RemoveAction takes the argument string that was passed with the --remove flag, +// parses it, and updates the Seccomp config accordingly +func RemoveAction(arguments string, config *rspec.LinuxSeccomp) error { + if config == nil { + return fmt.Errorf("Cannot remove action from nil Seccomp pointer") + } + + syscallsToRemove := strings.Split(arguments, ",") + + for counter, syscallStruct := range config.Syscalls { + if reflect.DeepEqual(syscallsToRemove, syscallStruct.Names) { + config.Syscalls = append(config.Syscalls[:counter], config.Syscalls[counter+1:]...) + } + } + + return nil +} + +// RemoveAllSeccompRules removes all seccomp syscall rules +func RemoveAllSeccompRules(config *rspec.LinuxSeccomp) error { + if config == nil { + return fmt.Errorf("Cannot remove action from nil Seccomp pointer") + } + newSyscallSlice := []rspec.LinuxSyscall{} + config.Syscalls = newSyscallSlice + return nil +} + +// RemoveAllMatchingRules will remove any syscall rules that match the specified action +func RemoveAllMatchingRules(config *rspec.LinuxSeccomp, seccompAction rspec.LinuxSeccompAction) error { + if config == nil { + return fmt.Errorf("Cannot remove action from nil Seccomp pointer") + } + + for _, syscall := range config.Syscalls { + if reflect.DeepEqual(syscall.Action, seccompAction) { + RemoveAction(strings.Join(syscall.Names, ","), config) + } + } + + return nil +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go new file mode 100644 index 000000000..35b12cd65 --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go @@ -0,0 +1,577 @@ +package seccomp + +import ( + "runtime" + "syscall" + + "github.com/opencontainers/runtime-spec/specs-go" + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +func arches() []rspec.Arch { + native := runtime.GOARCH + + switch native { + case "amd64": + return []rspec.Arch{rspec.ArchX86_64, rspec.ArchX86, rspec.ArchX32} + case "arm64": + return []rspec.Arch{rspec.ArchARM, rspec.ArchAARCH64} + case "mips64": + return []rspec.Arch{rspec.ArchMIPS, rspec.ArchMIPS64, rspec.ArchMIPS64N32} + case "mips64n32": + return []rspec.Arch{rspec.ArchMIPS, rspec.ArchMIPS64, rspec.ArchMIPS64N32} + case "mipsel64": + return []rspec.Arch{rspec.ArchMIPSEL, rspec.ArchMIPSEL64, rspec.ArchMIPSEL64N32} + case "mipsel64n32": + return []rspec.Arch{rspec.ArchMIPSEL, rspec.ArchMIPSEL64, rspec.ArchMIPSEL64N32} + case "s390x": + return []rspec.Arch{rspec.ArchS390, rspec.ArchS390X} + default: + return []rspec.Arch{} + } +} + +// DefaultProfile defines the whitelist for the default seccomp profile. +func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp { + + syscalls := []rspec.LinuxSyscall{ + { + Names: []string{ + "accept", + "accept4", + "access", + "alarm", + "bind", + "brk", + "capget", + "capset", + "chdir", + "chmod", + "chown", + "chown32", + "clock_getres", + "clock_gettime", + "clock_nanosleep", + "close", + "connect", + "copy_file_range", + "creat", + "dup", + "dup2", + "dup3", + "epoll_create", + "epoll_create1", + "epoll_ctl", + "epoll_ctl_old", + "epoll_pwait", + "epoll_wait", + "epoll_wait_old", + "eventfd", + "eventfd2", + "execve", + "execveat", + "exit", + "exit_group", + "faccessat", + "fadvise64", + "fadvise64_64", + "fallocate", + "fanotify_mark", + "fchdir", + "fchmod", + "fchmodat", + "fchown", + "fchown32", + "fchownat", + "fcntl", + "fcntl64", + "fdatasync", + "fgetxattr", + "flistxattr", + "flock", + "fork", + "fremovexattr", + "fsetxattr", + "fstat", + "fstat64", + "fstatat64", + "fstatfs", + "fstatfs64", + "fsync", + "ftruncate", + "ftruncate64", + "futex", + "futimesat", + "getcpu", + "getcwd", + "getdents", + "getdents64", + "getegid", + "getegid32", + "geteuid", + "geteuid32", + "getgid", + "getgid32", + "getgroups", + "getgroups32", + "getitimer", + "getpeername", + "getpgid", + "getpgrp", + "getpid", + "getppid", + "getpriority", + "getrandom", + "getresgid", + "getresgid32", + "getresuid", + "getresuid32", + "getrlimit", + "get_robust_list", + "getrusage", + "getsid", + "getsockname", + "getsockopt", + "get_thread_area", + "gettid", + "gettimeofday", + "getuid", + "getuid32", + "getxattr", + "inotify_add_watch", + "inotify_init", + "inotify_init1", + "inotify_rm_watch", + "io_cancel", + "ioctl", + "io_destroy", + "io_getevents", + "ioprio_get", + "ioprio_set", + "io_setup", + "io_submit", + "ipc", + "kill", + "lchown", + "lchown32", + "lgetxattr", + "link", + "linkat", + "listen", + "listxattr", + "llistxattr", + "_llseek", + "lremovexattr", + "lseek", + "lsetxattr", + "lstat", + "lstat64", + "madvise", + "memfd_create", + "mincore", + "mkdir", + "mkdirat", + "mknod", + "mknodat", + "mlock", + "mlock2", + "mlockall", + "mmap", + "mmap2", + "mprotect", + "mq_getsetattr", + "mq_notify", + "mq_open", + "mq_timedreceive", + "mq_timedsend", + "mq_unlink", + "mremap", + "msgctl", + "msgget", + "msgrcv", + "msgsnd", + "msync", + "munlock", + "munlockall", + "munmap", + "nanosleep", + "newfstatat", + "_newselect", + "open", + "openat", + "pause", + "pipe", + "pipe2", + "poll", + "ppoll", + "prctl", + "pread64", + "preadv", + "prlimit64", + "pselect6", + "pwrite64", + "pwritev", + "read", + "readahead", + "readlink", + "readlinkat", + "readv", + "recv", + "recvfrom", + "recvmmsg", + "recvmsg", + "remap_file_pages", + "removexattr", + "rename", + "renameat", + "renameat2", + "restart_syscall", + "rmdir", + "rt_sigaction", + "rt_sigpending", + "rt_sigprocmask", + "rt_sigqueueinfo", + "rt_sigreturn", + "rt_sigsuspend", + "rt_sigtimedwait", + "rt_tgsigqueueinfo", + "sched_getaffinity", + "sched_getattr", + "sched_getparam", + "sched_get_priority_max", + "sched_get_priority_min", + "sched_getscheduler", + "sched_rr_get_interval", + "sched_setaffinity", + "sched_setattr", + "sched_setparam", + "sched_setscheduler", + "sched_yield", + "seccomp", + "select", + "semctl", + "semget", + "semop", + "semtimedop", + "send", + "sendfile", + "sendfile64", + "sendmmsg", + "sendmsg", + "sendto", + "setfsgid", + "setfsgid32", + "setfsuid", + "setfsuid32", + "setgid", + "setgid32", + "setgroups", + "setgroups32", + "setitimer", + "setpgid", + "setpriority", + "setregid", + "setregid32", + "setresgid", + "setresgid32", + "setresuid", + "setresuid32", + "setreuid", + "setreuid32", + "setrlimit", + "set_robust_list", + "setsid", + "setsockopt", + "set_thread_area", + "set_tid_address", + "setuid", + "setuid32", + "setxattr", + "shmat", + "shmctl", + "shmdt", + "shmget", + "shutdown", + "sigaltstack", + "signalfd", + "signalfd4", + "sigreturn", + "socket", + "socketcall", + "socketpair", + "splice", + "stat", + "stat64", + "statfs", + "statfs64", + "symlink", + "symlinkat", + "sync", + "sync_file_range", + "syncfs", + "sysinfo", + "syslog", + "tee", + "tgkill", + "time", + "timer_create", + "timer_delete", + "timerfd_create", + "timerfd_gettime", + "timerfd_settime", + "timer_getoverrun", + "timer_gettime", + "timer_settime", + "times", + "tkill", + "truncate", + "truncate64", + "ugetrlimit", + "umask", + "uname", + "unlink", + "unlinkat", + "utime", + "utimensat", + "utimes", + "vfork", + "vmsplice", + "wait4", + "waitid", + "waitpid", + "write", + "writev", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + { + Names: []string{"personality"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{ + { + Index: 0, + Value: 0x0, + Op: rspec.OpEqualTo, + }, + { + Index: 0, + Value: 0x0008, + Op: rspec.OpEqualTo, + }, + { + Index: 0, + Value: 0xffffffff, + Op: rspec.OpEqualTo, + }, + }, + }, + } + var sysCloneFlagsIndex uint + + capSysAdmin := false + caps := make(map[string]bool) + + for _, cap := range rs.Process.Capabilities.Bounding { + caps[cap] = true + } + for _, cap := range rs.Process.Capabilities.Effective { + caps[cap] = true + } + for _, cap := range rs.Process.Capabilities.Inheritable { + caps[cap] = true + } + for _, cap := range rs.Process.Capabilities.Permitted { + caps[cap] = true + } + for _, cap := range rs.Process.Capabilities.Ambient { + caps[cap] = true + } + + for cap := range caps { + switch cap { + case "CAP_DAC_READ_SEARCH": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"open_by_handle_at"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_ADMIN": + capSysAdmin = true + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "bpf", + "clone", + "fanotify_init", + "lookup_dcookie", + "mount", + "name_to_handle_at", + "perf_event_open", + "setdomainname", + "sethostname", + "setns", + "umount", + "umount2", + "unshare", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_BOOT": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"reboot"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_CHROOT": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"chroot"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_MODULE": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "delete_module", + "init_module", + "finit_module", + "query_module", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_PACCT": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"acct"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_PTRACE": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "kcmp", + "process_vm_readv", + "process_vm_writev", + "ptrace", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_RAWIO": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "iopl", + "ioperm", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_TIME": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "settimeofday", + "stime", + "adjtimex", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "CAP_SYS_TTY_CONFIG": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"vhangup"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + } + } + + if !capSysAdmin { + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"clone"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{ + { + Index: sysCloneFlagsIndex, + Value: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET, + ValueTwo: 0, + Op: rspec.OpMaskedEqual, + }, + }, + }, + }...) + + } + + arch := runtime.GOARCH + switch arch { + case "arm", "arm64": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "breakpoint", + "cacheflush", + "set_tls", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "amd64", "x32": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"arch_prctl"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + fallthrough + case "x86": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"modify_ldt"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + case "s390", "s390x": + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{ + "s390_pci_mmio_read", + "s390_pci_mmio_write", + "s390_runtime_instr", + }, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{}, + }, + }...) + /* Flags parameter of the clone syscall is the 2nd on s390 */ + } + + return &rspec.LinuxSeccomp{ + DefaultAction: rspec.ActErrno, + Architectures: arches(), + Syscalls: syscalls, + } +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go new file mode 100644 index 000000000..dbf2aec1c --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go @@ -0,0 +1,140 @@ +package seccomp + +import ( + "fmt" + "reflect" + "strconv" + "strings" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// Determine if a new syscall rule should be appended, overwrite an existing rule +// or if no action should be taken at all +func decideCourseOfAction(newSyscall *rspec.LinuxSyscall, syscalls []rspec.LinuxSyscall) (string, error) { + ruleForSyscallAlreadyExists := false + + var sliceOfDeterminedActions []string + for i, syscall := range syscalls { + if sameName(&syscall, newSyscall) { + ruleForSyscallAlreadyExists = true + + if identical(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing) + } + + if sameAction(newSyscall, &syscall) { + if bothHaveArgs(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) + } + if onlyOneHasArgs(newSyscall, &syscall) { + if firstParamOnlyHasArgs(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i)) + } else { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing) + } + } + } + + if !sameAction(newSyscall, &syscall) { + if bothHaveArgs(newSyscall, &syscall) { + if sameArgs(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i)) + } + if !sameArgs(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) + } + } + if onlyOneHasArgs(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) + } + if neitherHasArgs(newSyscall, &syscall) { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i)) + } + } + } + } + + if !ruleForSyscallAlreadyExists { + sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) + } + + // Nothing has highest priority + for _, determinedAction := range sliceOfDeterminedActions { + if determinedAction == nothing { + return determinedAction, nil + } + } + + // Overwrite has second highest priority + for _, determinedAction := range sliceOfDeterminedActions { + if strings.Contains(determinedAction, seccompOverwrite) { + return determinedAction, nil + } + } + + // Append has the lowest priority + for _, determinedAction := range sliceOfDeterminedActions { + if determinedAction == seccompAppend { + return determinedAction, nil + } + } + + return "", fmt.Errorf("Trouble determining action: %s", sliceOfDeterminedActions) +} + +func hasArguments(config *rspec.LinuxSyscall) bool { + nilSyscall := new(rspec.LinuxSyscall) + return !sameArgs(nilSyscall, config) +} + +func identical(config1, config2 *rspec.LinuxSyscall) bool { + return reflect.DeepEqual(config1, config2) +} + +func identicalExceptAction(config1, config2 *rspec.LinuxSyscall) bool { + samename := sameName(config1, config2) + sameAction := sameAction(config1, config2) + sameArgs := sameArgs(config1, config2) + + return samename && !sameAction && sameArgs +} + +func identicalExceptArgs(config1, config2 *rspec.LinuxSyscall) bool { + samename := sameName(config1, config2) + sameAction := sameAction(config1, config2) + sameArgs := sameArgs(config1, config2) + + return samename && sameAction && !sameArgs +} + +func sameName(config1, config2 *rspec.LinuxSyscall) bool { + return reflect.DeepEqual(config1.Names, config2.Names) +} + +func sameAction(config1, config2 *rspec.LinuxSyscall) bool { + return config1.Action == config2.Action +} + +func sameArgs(config1, config2 *rspec.LinuxSyscall) bool { + return reflect.DeepEqual(config1.Args, config2.Args) +} + +func bothHaveArgs(config1, config2 *rspec.LinuxSyscall) bool { + return hasArguments(config1) && hasArguments(config2) +} + +func onlyOneHasArgs(config1, config2 *rspec.LinuxSyscall) bool { + conf1 := hasArguments(config1) + conf2 := hasArguments(config2) + + return (conf1 && !conf2) || (!conf1 && conf2) +} + +func neitherHasArgs(config1, config2 *rspec.LinuxSyscall) bool { + return !hasArguments(config1) && !hasArguments(config2) +} + +func firstParamOnlyHasArgs(config1, config2 *rspec.LinuxSyscall) bool { + return !hasArguments(config1) && hasArguments(config2) +} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/spec.go b/vendor/github.com/opencontainers/runtime-tools/generate/spec.go new file mode 100644 index 000000000..519d25448 --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/generate/spec.go @@ -0,0 +1,109 @@ +package generate + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +func (g *Generator) initSpec() { + if g.spec == nil { + g.spec = &rspec.Spec{} + } +} + +func (g *Generator) initSpecProcess() { + g.initSpec() + if g.spec.Process == nil { + g.spec.Process = &rspec.Process{} + } +} + +func (g *Generator) initSpecProcessConsoleSize() { + g.initSpecProcess() + if g.spec.Process.ConsoleSize == nil { + g.spec.Process.ConsoleSize = &rspec.Box{} + } +} + +func (g *Generator) initSpecProcessCapabilities() { + g.initSpecProcess() + if g.spec.Process.Capabilities == nil { + g.spec.Process.Capabilities = &rspec.LinuxCapabilities{} + } +} + +func (g *Generator) initSpecRoot() { + g.initSpec() + if g.spec.Root == nil { + g.spec.Root = &rspec.Root{} + } +} + +func (g *Generator) initSpecAnnotations() { + g.initSpec() + if g.spec.Annotations == nil { + g.spec.Annotations = make(map[string]string) + } +} + +func (g *Generator) initSpecHooks() { + g.initSpec() + if g.spec.Hooks == nil { + g.spec.Hooks = &rspec.Hooks{} + } +} + +func (g *Generator) initSpecLinux() { + g.initSpec() + if g.spec.Linux == nil { + g.spec.Linux = &rspec.Linux{} + } +} + +func (g *Generator) initSpecLinuxSysctl() { + g.initSpecLinux() + if g.spec.Linux.Sysctl == nil { + g.spec.Linux.Sysctl = make(map[string]string) + } +} + +func (g *Generator) initSpecLinuxSeccomp() { + g.initSpecLinux() + if g.spec.Linux.Seccomp == nil { + g.spec.Linux.Seccomp = &rspec.LinuxSeccomp{} + } +} + +func (g *Generator) initSpecLinuxResources() { + g.initSpecLinux() + if g.spec.Linux.Resources == nil { + g.spec.Linux.Resources = &rspec.LinuxResources{} + } +} + +func (g *Generator) initSpecLinuxResourcesCPU() { + g.initSpecLinuxResources() + if g.spec.Linux.Resources.CPU == nil { + g.spec.Linux.Resources.CPU = &rspec.LinuxCPU{} + } +} + +func (g *Generator) initSpecLinuxResourcesMemory() { + g.initSpecLinuxResources() + if g.spec.Linux.Resources.Memory == nil { + g.spec.Linux.Resources.Memory = &rspec.LinuxMemory{} + } +} + +func (g *Generator) initSpecLinuxResourcesNetwork() { + g.initSpecLinuxResources() + if g.spec.Linux.Resources.Network == nil { + g.spec.Linux.Resources.Network = &rspec.LinuxNetwork{} + } +} + +func (g *Generator) initSpecLinuxResourcesPids() { + g.initSpecLinuxResources() + if g.spec.Linux.Resources.Pids == nil { + g.spec.Linux.Resources.Pids = &rspec.LinuxPids{} + } +} |