diff --git a/cmd/oci-runtime-tool/generate.go b/cmd/oci-runtime-tool/generate.go index 3509a88f9..83a7087f9 100644 --- a/cmd/oci-runtime-tool/generate.go +++ b/cmd/oci-runtime-tool/generate.go @@ -131,18 +131,18 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { g.HostSpecific = true } - spec := g.Spec() + g.InitConfigLinuxResources() - if len(spec.Version) == 0 { - g.SetVersion(rspec.Version) + if len(g.Config.Version) == 0 { + g.Config.Version = rspec.Version } if context.IsSet("hostname") { - g.SetHostname(context.String("hostname")) + g.Config.Hostname = context.String("hostname") } - g.SetPlatformOS(context.String("os")) - g.SetPlatformArch(context.String("arch")) + g.Config.Platform.OS = context.String("os") + g.Config.Platform.Arch = context.String("arch") if context.IsSet("label") { annotations := context.StringSlice("label") @@ -151,51 +151,48 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { if len(pair) != 2 { return fmt.Errorf("incorrectly specified annotation: %s", s) } - g.AddAnnotation(pair[0], pair[1]) + g.Config.Annotations[pair[0]] = pair[1] } } - g.SetRootPath(context.String("rootfs")) + g.Config.Root.Path = context.String("rootfs") if context.IsSet("read-only") { - g.SetRootReadonly(context.Bool("read-only")) + g.Config.Root.Readonly = context.Bool("read-only") } if context.IsSet("uid") { - g.SetProcessUID(uint32(context.Int("uid"))) + g.Config.Process.User.UID = uint32(context.Int("uid")) } if context.IsSet("gid") { - g.SetProcessGID(uint32(context.Int("gid"))) + g.Config.Process.User.GID = uint32(context.Int("gid")) } if context.IsSet("selinux-label") { - g.SetProcessSelinuxLabel(context.String("selinux-label")) + g.Config.Process.SelinuxLabel = context.String("selinux-label") } - g.SetProcessCwd(context.String("cwd")) + g.Config.Process.Cwd = context.String("cwd") if context.IsSet("apparmor") { - g.SetProcessApparmorProfile(context.String("apparmor")) + g.Config.Process.ApparmorProfile = context.String("apparmor") } if context.IsSet("no-new-privileges") { - g.SetProcessNoNewPrivileges(context.Bool("no-new-privileges")) + g.Config.Process.NoNewPrivileges = context.Bool("no-new-privileges") } if context.IsSet("tty") { - g.SetProcessTerminal(context.Bool("tty")) + g.Config.Process.Terminal = context.Bool("tty") } if context.IsSet("args") { - g.SetProcessArgs(context.StringSlice("args")) + g.Config.Process.Args = context.StringSlice("args") } if context.IsSet("env") { - envs := context.StringSlice("env") - for _, env := range envs { - g.AddProcessEnv(env) - } + g.Config.Process.Env = append(g.Config.Process.Env, context.StringSlice("env")...) } if context.IsSet("groups") { @@ -210,25 +207,19 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { } if context.IsSet("cgroups-path") { - g.SetLinuxCgroupsPath(context.String("cgroups-path")) + g.Config.Linux.CgroupsPath = generate.StrPtr(context.String("cgroups-path")) } if context.IsSet("masked-paths") { - paths := context.StringSlice("masked-paths") - for _, path := range paths { - g.AddLinuxMaskedPaths(path) - } + g.Config.Linux.MaskedPaths = append(g.Config.Linux.MaskedPaths, context.StringSlice("masked-paths")...) } if context.IsSet("readonly-paths") { - paths := context.StringSlice("readonly-paths") - for _, path := range paths { - g.AddLinuxReadonlyPaths(path) - } + g.Config.Linux.ReadonlyPaths = append(g.Config.Linux.ReadonlyPaths, context.StringSlice("readonly-paths")...) } if context.IsSet("mount-label") { - g.SetLinuxMountLabel(context.String("mount-label")) + g.Config.Linux.MountLabel = context.String("mount-label") } if context.IsSet("sysctl") { @@ -238,15 +229,13 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { if len(pair) != 2 { return fmt.Errorf("incorrectly specified sysctl: %s", s) } - g.AddLinuxSysctl(pair[0], pair[1]) + g.Config.Linux.Sysctl[pair[0]] = pair[1] } } - privileged := false - if context.IsSet("privileged") { - privileged = context.Bool("privileged") + if context.IsSet("privileged") && context.Bool("privileged") { + g.SetupPrivileged() } - g.SetupPrivileged(privileged) if context.IsSet("cap-add") { addCaps := context.StringSlice("cap-add") @@ -287,137 +276,133 @@ func setupSpec(g *generate.Generator, context *cli.Context) error { if context.IsSet("tmpfs") { tmpfsSlice := context.StringSlice("tmpfs") for _, s := range tmpfsSlice { - dest, options, err := parseTmpfsMount(s) + mnt, err := parseTmpfsMount(s) if err != nil { return err } - g.AddTmpfsMount(dest, options) + g.Config.Mounts = append(g.Config.Mounts, mnt) } } - mountCgroupOption := context.String("mount-cgroups") - if err := g.AddCgroupsMount(mountCgroupOption); err != nil { - return err + if context.IsSet("mount-cgroups") && context.String("mount-cgroups") != "no" { + g.Config.Mounts = append(g.Config.Mounts, rspec.Mount{ + Destination: "/sys/fs/cgroup", + Type: "cgroup", + Source: "cgroup", + Options: []string{"nosuid", "noexec", "nodev", "relatime", context.String("mount-cgroups")}, + }) } if context.IsSet("bind") { binds := context.StringSlice("bind") for _, bind := range binds { - source, dest, options, err := parseBindMount(bind) + mnt, err := parseBindMount(bind) if err != nil { return err } - g.AddBindMount(source, dest, options) + g.Config.Mounts = append(g.Config.Mounts, mnt) } } if context.IsSet("prestart") { preStartHooks := context.StringSlice("prestart") for _, hook := range preStartHooks { - path, args := parseHook(hook) - g.AddPreStartHook(path, args) + g.Config.Hooks.Prestart = append(g.Config.Hooks.Prestart, parseHook(hook)) } } if context.IsSet("poststop") { postStopHooks := context.StringSlice("poststop") for _, hook := range postStopHooks { - path, args := parseHook(hook) - g.AddPostStopHook(path, args) + g.Config.Hooks.Poststop = append(g.Config.Hooks.Poststop, parseHook(hook)) } } if context.IsSet("poststart") { postStartHooks := context.StringSlice("poststart") for _, hook := range postStartHooks { - path, args := parseHook(hook) - g.AddPostStartHook(path, args) + g.Config.Hooks.Poststart = append(g.Config.Hooks.Poststart, parseHook(hook)) } } if context.IsSet("root-propagation") { - rp := context.String("root-propagation") - if err := g.SetLinuxRootPropagation(rp); err != nil { - return err - } + g.Config.Linux.RootfsPropagation = context.String("root-propagation") } for _, uidMap := range uidMaps { - hid, cid, size, err := parseIDMapping(uidMap) + mapping, err := parseIDMapping(uidMap) if err != nil { return err } - - g.AddLinuxUIDMapping(hid, cid, size) + g.Config.Linux.UIDMappings = append(g.Config.Linux.UIDMappings, mapping) } for _, gidMap := range gidMaps { - hid, cid, size, err := parseIDMapping(gidMap) + mapping, err := parseIDMapping(gidMap) if err != nil { return err } - - g.AddLinuxGIDMapping(hid, cid, size) + g.Config.Linux.GIDMappings = append(g.Config.Linux.GIDMappings, mapping) } if context.IsSet("disable-oom-kill") { - g.SetLinuxResourcesDisableOOMKiller(context.Bool("disable-oom-kill")) + g.Config.Linux.Resources.DisableOOMKiller = generate.BoolPtr(context.Bool("disable-oom-kill")) } if context.IsSet("oom-score-adj") { - g.SetLinuxResourcesOOMScoreAdj(context.Int("oom-score-adj")) + g.Config.Linux.Resources.OOMScoreAdj = generate.IntPtr(context.Int("oom-score-adj")) } if context.IsSet("linux-cpu-shares") { - g.SetLinuxResourcesCPUShares(context.Uint64("linux-cpu-shares")) + g.Config.Linux.Resources.CPU.Shares = generate.Uint64Ptr(context.Uint64("linux-cpu-shares")) } if context.IsSet("linux-cpu-period") { - g.SetLinuxResourcesCPUPeriod(context.Uint64("linux-cpu-period")) + g.Config.Linux.Resources.CPU.Period = generate.Uint64Ptr(context.Uint64("linux-cpu-period")) } if context.IsSet("linux-cpu-quota") { - g.SetLinuxResourcesCPUQuota(context.Uint64("linux-cpu-quota")) + g.Config.Linux.Resources.CPU.Quota = generate.Uint64Ptr(context.Uint64("linux-cpu-quota")) } if context.IsSet("linux-realtime-runtime") { - g.SetLinuxResourcesCPURealtimeRuntime(context.Uint64("linux-realtime-runtime")) + g.Config.Linux.Resources.CPU.RealtimeRuntime = generate.Uint64Ptr(context.Uint64("linux-realtime-runtime")) } if context.IsSet("linux-realtime-period") { - g.SetLinuxResourcesCPURealtimePeriod(context.Uint64("linux-realtime-period")) + g.Config.Linux.Resources.CPU.RealtimePeriod = generate.Uint64Ptr(context.Uint64("linux-realtime-period")) } if context.IsSet("linux-cpus") { - g.SetLinuxResourcesCPUCpus(context.String("linux-cpus")) + g.Config.Linux.Resources.CPU.Cpus = generate.StrPtr(context.String("linux-cpus")) } if context.IsSet("linux-mems") { - g.SetLinuxResourcesCPUMems(context.String("linux-mems")) + g.Config.Linux.Resources.CPU.Mems = generate.StrPtr(context.String("linux-mems")) } if context.IsSet("linux-mem-limit") { - g.SetLinuxResourcesMemoryLimit(context.Uint64("linux-mem-limit")) + g.Config.Linux.Resources.Memory.Limit = generate.Uint64Ptr(context.Uint64("linux-mem-limit")) } if context.IsSet("linux-mem-reservation") { - g.SetLinuxResourcesMemoryReservation(context.Uint64("linux-mem-reservation")) + g.Config.Linux.Resources.Memory.Reservation = generate.Uint64Ptr(context.Uint64("linux-mem-reservation")) } if context.IsSet("linux-mem-swap") { - g.SetLinuxResourcesMemorySwap(context.Uint64("linux-mem-swap")) + g.Config.Linux.Resources.Memory.Swap = generate.Uint64Ptr(context.Uint64("linux-mem-swap")) } if context.IsSet("linux-mem-kernel-limit") { - g.SetLinuxResourcesMemoryKernel(context.Uint64("linux-mem-kernel-limit")) + g.Config.Linux.Resources.Memory.Kernel = generate.Uint64Ptr(context.Uint64("linux-mem-kernel-limit")) } if context.IsSet("linux-mem-kernel-tcp") { - g.SetLinuxResourcesMemoryKernelTCP(context.Uint64("linux-mem-kernel-tcp")) + g.Config.Linux.Resources.Memory.KernelTCP = generate.Uint64Ptr(context.Uint64("linux-mem-kernel-tcp")) } if context.IsSet("linux-mem-swappiness") { - g.SetLinuxResourcesMemorySwappiness(context.Uint64("linux-mem-swappiness")) + g.Config.Linux.Resources.Memory.Swappiness = generate.Uint64Ptr(context.Uint64("linux-mem-swappiness")) } err := addSeccomp(context, g) @@ -438,74 +423,72 @@ func setupLinuxNamespaces(context *cli.Context, g *generate.Generator, needsNewU } } -func parseIDMapping(idms string) (uint32, uint32, uint32, error) { +func parseIDMapping(idms string) (mapping rspec.IDMapping, err error) { idm := strings.Split(idms, ":") if len(idm) != 3 { - return 0, 0, 0, fmt.Errorf("idmappings error: %s", idms) + return mapping, fmt.Errorf("idmappings error: %s", idms) } hid, err := strconv.Atoi(idm[0]) if err != nil { - return 0, 0, 0, err + return mapping, err } cid, err := strconv.Atoi(idm[1]) if err != nil { - return 0, 0, 0, err + return mapping, err } size, err := strconv.Atoi(idm[2]) if err != nil { - return 0, 0, 0, err + return mapping, err } - return uint32(hid), uint32(cid), uint32(size), nil + mapping.HostID = uint32(hid) + mapping.ContainerID = uint32(cid) + mapping.Size = uint32(size) + return mapping, nil } -func parseHook(s string) (string, []string) { +func parseHook(s string) (hook rspec.Hook) { parts := strings.Split(s, ":") - args := []string{} - path := parts[0] - if len(parts) > 1 { - args = parts[1:] - } - return path, args + hook.Path = parts[0] + hook.Args = parts[1:] + return hook } -func parseTmpfsMount(s string) (string, []string, error) { - var dest string - var options []string - var err error - +func parseTmpfsMount(s string) (mnt rspec.Mount, err error) { parts := strings.Split(s, ":") if len(parts) == 2 { - dest = parts[0] - options = strings.Split(parts[1], ",") + mnt.Destination = parts[0] + mnt.Options = strings.Split(parts[1], ",") } else if len(parts) == 1 { - dest = parts[0] - options = []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"} + mnt.Destination = parts[0] + mnt.Options = []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"} } else { - err = fmt.Errorf("invalid value for --tmpfs") + return mnt, fmt.Errorf("invalid value for --tmpfs") } - - return dest, options, err + mnt.Type = "tmpfs" + mnt.Source = "tmpfs" + return mnt, err } -func parseBindMount(s string) (string, string, string, error) { - var source, dest string - options := "ro" - +func parseBindMount(s string) (mnt rspec.Mount, err error) { bparts := strings.SplitN(s, ":", 3) switch len(bparts) { case 2: - source, dest = bparts[0], bparts[1] + mnt.Source = bparts[0] + mnt.Destination = bparts[1] + mnt.Options = []string{"ro"} case 3: - source, dest, options = bparts[0], bparts[1], bparts[2] + mnt.Source = bparts[0] + mnt.Destination = bparts[1] + mnt.Options = strings.Split(bparts[2], ",") default: - return source, dest, options, fmt.Errorf("--bind should have format src:dest:[options]") + return mnt, fmt.Errorf("--bind should have format src:dest:[options]") } - return source, dest, options, nil + return mnt, nil } func addSeccomp(context *cli.Context, g *generate.Generator) error { diff --git a/generate/config.go b/generate/config.go new file mode 100644 index 000000000..b5fe532e5 --- /dev/null +++ b/generate/config.go @@ -0,0 +1,60 @@ +package generate + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +func (g *Generator) InitConfig() { + if g.Config == nil { + g.Config = &rspec.Spec{} + } +} + +func (g *Generator) InitConfigAnnotations() { + g.InitConfig() + if g.Config.Annotations == nil { + g.Config.Annotations = make(map[string]string) + } +} + +func (g *Generator) InitConfigLinux() { + g.InitConfig() + if g.Config.Linux == nil { + g.Config.Linux = &rspec.Linux{} + } +} + +func (g *Generator) InitConfigLinuxSeccomp() { + g.InitConfigLinux() + if g.Config.Linux.Seccomp == nil { + g.Config.Linux.Seccomp = &rspec.Seccomp{} + } +} + +func (g *Generator) InitConfigLinuxResources() { + g.InitConfigLinux() + if g.Config.Linux.Resources == nil { + g.Config.Linux.Resources = &rspec.Resources{} + } +} + +func (g *Generator) InitConfigLinuxResourcesCPU() { + g.InitConfigLinuxResources() + if g.Config.Linux.Resources.CPU == nil { + g.Config.Linux.Resources.CPU = &rspec.CPU{} + } +} + +func (g *Generator) InitConfigLinuxResourcesMemory() { + g.InitConfigLinuxResources() + if g.Config.Linux.Resources.Memory == nil { + g.Config.Linux.Resources.Memory = &rspec.Memory{} + } +} + +func (g *Generator) InitConfigLinuxResourcesPids() { + g.InitConfigLinuxResources() + if g.Config.Linux.Resources.Pids == nil { + g.Config.Linux.Resources.Pids = &rspec.Pids{} + } +} diff --git a/generate/generate.go b/generate/generate.go index bd8e4908b..18791d907 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -19,9 +19,9 @@ var ( Namespaces = []string{"network", "pid", "mount", "ipc", "uts", "user", "cgroup"} ) -// Generator represents a generator for a container spec. +// Generator represents a generator for a container config. type Generator struct { - spec *rspec.Spec + Config *rspec.Spec HostSpecific bool } @@ -30,9 +30,9 @@ type ExportOptions struct { Seccomp bool // seccomp toggles if only seccomp should be exported } -// New creates a spec Generator with the default spec. +// New creates a config Generator with the default config. func New() Generator { - spec := rspec.Spec{ + config := rspec.Spec{ Version: rspec.Version, Platform: rspec.Platform{ OS: runtime.GOOS, @@ -121,7 +121,7 @@ func New() Generator { Devices: []rspec.DeviceCgroup{ { Allow: false, - Access: strPtr("rwm"), + Access: StrPtr("rwm"), }, }, }, @@ -145,20 +145,13 @@ func New() Generator { Devices: []rspec.Device{}, }, } - spec.Linux.Seccomp = seccomp.DefaultProfile(&spec) + config.Linux.Seccomp = seccomp.DefaultProfile(&config) return Generator{ - spec: &spec, + Config: &config, } } -// NewFromSpec creates a spec Generator from a given spec. -func NewFromSpec(spec *rspec.Spec) Generator { - return Generator{ - spec: spec, - } -} - -// NewFromFile loads the template specifed in a file into a spec Generator. +// NewFromFile loads the template specifed in a file into a config Generator. func NewFromFile(path string) (Generator, error) { cf, err := os.Open(path) if err != nil { @@ -171,35 +164,25 @@ func NewFromFile(path string) (Generator, error) { return NewFromTemplate(cf) } -// NewFromTemplate loads the template from io.Reader into a spec Generator. +// NewFromTemplate loads the template from io.Reader into a config Generator. func NewFromTemplate(r io.Reader) (Generator, error) { - var spec rspec.Spec - if err := json.NewDecoder(r).Decode(&spec); err != nil { + var config rspec.Spec + if err := json.NewDecoder(r).Decode(&config); err != nil { return Generator{}, err } return Generator{ - spec: &spec, + Config: &config, }, 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. +// Save writes the config into w. func (g *Generator) Save(w io.Writer, exportOpts ExportOptions) (err error) { var data []byte if exportOpts.Seccomp { - data, err = json.MarshalIndent(g.spec.Linux.Seccomp, "", "\t") + data, err = json.MarshalIndent(g.Config.Linux.Seccomp, "", "\t") } else { - data, err = json.MarshalIndent(g.spec, "", "\t") + data, err = json.MarshalIndent(g.Config, "", "\t") } if err != nil { return err @@ -213,7 +196,7 @@ func (g *Generator) Save(w io.Writer, exportOpts ExportOptions) (err error) { return nil } -// SaveToFile writes the spec into a file. +// SaveToFile writes the config into a file. func (g *Generator) SaveToFile(path string, exportOpts ExportOptions) error { f, err := os.Create(path) if err != nil { @@ -223,450 +206,32 @@ func (g *Generator) SaveToFile(path string, exportOpts ExportOptions) error { 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.initSpec() - g.spec.Root.Path = path -} - -// SetRootReadonly sets g.spec.Root.Readonly. -func (g *Generator) SetRootReadonly(b bool) { - g.initSpec() - 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) -} - -// SetPlatformOS sets g.spec.Process.OS. -func (g *Generator) SetPlatformOS(os string) { - g.initSpec() - g.spec.Platform.OS = os -} - -// SetPlatformArch sets g.spec.Platform.Arch. -func (g *Generator) SetPlatformArch(arch string) { - g.initSpec() - g.spec.Platform.Arch = arch -} - -// SetProcessUID sets g.spec.Process.User.UID. -func (g *Generator) SetProcessUID(uid uint32) { - g.initSpec() - g.spec.Process.User.UID = uid -} - -// SetProcessGID sets g.spec.Process.User.GID. -func (g *Generator) SetProcessGID(gid uint32) { - g.initSpec() - g.spec.Process.User.GID = gid -} - -// SetProcessCwd sets g.spec.Process.Cwd. -func (g *Generator) SetProcessCwd(cwd string) { - g.initSpec() - g.spec.Process.Cwd = cwd -} - -// SetProcessNoNewPrivileges sets g.spec.Process.NoNewPrivileges. -func (g *Generator) SetProcessNoNewPrivileges(b bool) { - g.initSpec() - g.spec.Process.NoNewPrivileges = b -} - -// SetProcessTerminal sets g.spec.Process.Terminal. -func (g *Generator) SetProcessTerminal(b bool) { - g.initSpec() - g.spec.Process.Terminal = b -} - -// SetProcessApparmorProfile sets g.spec.Process.ApparmorProfile. -func (g *Generator) SetProcessApparmorProfile(prof string) { - g.initSpec() - g.spec.Process.ApparmorProfile = prof -} - -// SetProcessArgs sets g.spec.Process.Args. -func (g *Generator) SetProcessArgs(args []string) { - g.initSpec() - 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 env into g.spec.Process.Env. -func (g *Generator) AddProcessEnv(env string) { - g.initSpec() - g.spec.Process.Env = append(g.spec.Process.Env, env) -} - -// 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. +// AddProcessAdditionalGid adds an additional gid into g.Config.Process.AdditionalGids. func (g *Generator) AddProcessAdditionalGid(gid uint32) { - g.initSpec() - for _, group := range g.spec.Process.User.AdditionalGids { + g.InitConfig() + for _, group := range g.Config.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.initSpec() - g.spec.Process.SelinuxLabel = label -} - -// SetLinuxCgroupsPath sets g.spec.Linux.CgroupsPath. -func (g *Generator) SetLinuxCgroupsPath(path string) { - g.initSpecLinux() - g.spec.Linux.CgroupsPath = strPtr(path) -} - -// SetLinuxMountLabel sets g.spec.Linux.MountLabel. -func (g *Generator) SetLinuxMountLabel(label string) { - g.initSpecLinux() - g.spec.Linux.MountLabel = label -} - -// SetLinuxResourcesDisableOOMKiller sets g.spec.Linux.Resources.DisableOOMKiller. -func (g *Generator) SetLinuxResourcesDisableOOMKiller(disable bool) { - g.initSpecLinuxResources() - g.spec.Linux.Resources.DisableOOMKiller = &disable -} - -// SetLinuxResourcesOOMScoreAdj sets g.spec.Linux.Resources.OOMScoreAdj. -func (g *Generator) SetLinuxResourcesOOMScoreAdj(adj int) { - g.initSpecLinuxResources() - g.spec.Linux.Resources.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 uint64) { - 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 uint64) { - 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 -} - -// SetLinuxResourcesMemoryLimit sets g.spec.Linux.Resources.Memory.Limit. -func (g *Generator) SetLinuxResourcesMemoryLimit(limit uint64) { - g.initSpecLinuxResourcesMemory() - g.spec.Linux.Resources.Memory.Limit = &limit -} - -// SetLinuxResourcesMemoryReservation sets g.spec.Linux.Resources.Memory.Reservation. -func (g *Generator) SetLinuxResourcesMemoryReservation(reservation uint64) { - g.initSpecLinuxResourcesMemory() - g.spec.Linux.Resources.Memory.Reservation = &reservation -} - -// SetLinuxResourcesMemorySwap sets g.spec.Linux.Resources.Memory.Swap. -func (g *Generator) SetLinuxResourcesMemorySwap(swap uint64) { - g.initSpecLinuxResourcesMemory() - g.spec.Linux.Resources.Memory.Swap = &swap -} - -// SetLinuxResourcesMemoryKernel sets g.spec.Linux.Resources.Memory.Kernel. -func (g *Generator) SetLinuxResourcesMemoryKernel(kernel uint64) { - g.initSpecLinuxResourcesMemory() - g.spec.Linux.Resources.Memory.Kernel = &kernel -} - -// SetLinuxResourcesMemoryKernelTCP sets g.spec.Linux.Resources.Memory.KernelTCP. -func (g *Generator) SetLinuxResourcesMemoryKernelTCP(kernelTCP uint64) { - 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 -} - -// 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.IDMapping{} -} - -// AddLinuxUIDMapping adds uidMap into g.spec.Linux.UIDMappings. -func (g *Generator) AddLinuxUIDMapping(hid, cid, size uint32) { - idMapping := rspec.IDMapping{ - 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.IDMapping{} -} - -// AddLinuxGIDMapping adds gidMap into g.spec.Linux.GIDMappings. -func (g *Generator) AddLinuxGIDMapping(hid, cid, size uint32) { - idMapping := rspec.IDMapping{ - 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 - } - 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.initSpec() - hook := rspec.Hook{Path: path, Args: args} - 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 - } - g.spec.Hooks.Poststop = []rspec.Hook{} + g.Config.Process.User.AdditionalGids = append(g.Config.Process.User.AdditionalGids, gid) } -// AddPostStopHook adds a poststop hook into g.spec.Hooks.Poststop. -func (g *Generator) AddPostStopHook(path string, args []string) { - g.initSpec() - hook := rspec.Hook{Path: path, Args: args} - 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 - } - 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.initSpec() - hook := rspec.Hook{Path: path, Args: args} - 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": - break - 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, options string) { - if options == "" { - options = "ro" - } - - defaultOptions := []string{"bind"} - - mnt := rspec.Mount{ - Destination: dest, - Type: "bind", - Source: source, - Options: append(defaultOptions, options), - } - g.initSpec() - g.spec.Mounts = append(g.spec.Mounts, mnt) -} - -// SetupPrivileged sets up the priviledge-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 > lastCap() { - continue - } - finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))) +// SetupPrivileged sets up the priviledge-related fields inside g.Config. +func (g *Generator) SetupPrivileged() { + // Add all capabilities in privileged mode. + var finalCapList []string + for _, cap := range capability.List() { + if g.HostSpecific && cap > lastCap() { + continue } - g.initSpecLinux() - g.spec.Process.Capabilities = finalCapList - g.spec.Process.SelinuxLabel = "" - g.spec.Process.ApparmorProfile = "" - g.spec.Linux.Seccomp = nil + finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))) } + g.InitConfigLinux() + g.Config.Process.Capabilities = finalCapList + g.Config.Process.SelinuxLabel = "" + g.Config.Process.ApparmorProfile = "" + g.Config.Linux.Seccomp = nil } func lastCap() capability.Cap { @@ -699,15 +264,7 @@ func checkCap(c string, hostSpecific bool) error { return nil } -// ClearProcessCapabilities clear g.spec.Process.Capabilities. -func (g *Generator) ClearProcessCapabilities() { - if g.spec == nil { - return - } - g.spec.Process.Capabilities = []string{} -} - -// AddProcessCapability adds a process capability into g.spec.Process.Capabilities. +// AddProcessCapability adds a process capability into g.Config.Process.Capabilities. func (g *Generator) AddProcessCapability(c string) error { if err := checkCap(c, g.HostSpecific); err != nil { return err @@ -715,18 +272,18 @@ func (g *Generator) AddProcessCapability(c string) error { cp := fmt.Sprintf("CAP_%s", strings.ToUpper(c)) - g.initSpec() - for _, cap := range g.spec.Process.Capabilities { + g.InitConfig() + for _, cap := range g.Config.Process.Capabilities { if strings.ToUpper(cap) == cp { return nil } } - g.spec.Process.Capabilities = append(g.spec.Process.Capabilities, cp) + g.Config.Process.Capabilities = append(g.Config.Process.Capabilities, cp) return nil } -// DropProcessCapability drops a process capability from g.spec.Process.Capabilities. +// DropProcessCapability drops a process capability from g.Config.Process.Capabilities. func (g *Generator) DropProcessCapability(c string) error { if err := checkCap(c, g.HostSpecific); err != nil { return err @@ -734,10 +291,10 @@ func (g *Generator) DropProcessCapability(c string) error { cp := fmt.Sprintf("CAP_%s", strings.ToUpper(c)) - g.initSpec() - for i, cap := range g.spec.Process.Capabilities { + g.InitConfig() + for i, cap := range g.Config.Process.Capabilities { if strings.ToUpper(cap) == cp { - g.spec.Process.Capabilities = append(g.spec.Process.Capabilities[:i], g.spec.Process.Capabilities[i+1:]...) + g.Config.Process.Capabilities = append(g.Config.Process.Capabilities[:i], g.Config.Process.Capabilities[i+1:]...) return nil } } @@ -766,100 +323,89 @@ func mapStrToNamespace(ns string, path string) (rspec.Namespace, error) { } } -// ClearLinuxNamespaces clear g.spec.Linux.Namespaces. -func (g *Generator) ClearLinuxNamespaces() { - if g.spec == nil || g.spec.Linux == nil { - return - } - g.spec.Linux.Namespaces = []rspec.Namespace{} -} - // AddOrReplaceLinuxNamespace adds or replaces a namespace inside -// g.spec.Linux.Namespaces. +// g.Config.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 { + g.InitConfigLinux() + for i, ns := range g.Config.Linux.Namespaces { if ns.Type == namespace.Type { - g.spec.Linux.Namespaces[i] = namespace + g.Config.Linux.Namespaces[i] = namespace return nil } } - g.spec.Linux.Namespaces = append(g.spec.Linux.Namespaces, namespace) + g.Config.Linux.Namespaces = append(g.Config.Linux.Namespaces, namespace) return nil } -// RemoveLinuxNamespace removes a namespace from g.spec.Linux.Namespaces. +// RemoveLinuxNamespace removes a namespace from g.Config.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 { + if g.Config == nil || g.Config.Linux == nil { return nil } - for i, ns := range g.spec.Linux.Namespaces { + for i, ns := range g.Config.Linux.Namespaces { if ns.Type == namespace.Type { - g.spec.Linux.Namespaces = append(g.spec.Linux.Namespaces[:i], g.spec.Linux.Namespaces[i+1:]...) + g.Config.Linux.Namespaces = append(g.Config.Linux.Namespaces[:i], g.Config.Linux.Namespaces[i+1:]...) return nil } } return nil } -// strPtr returns the pointer pointing to the string s. -func strPtr(s string) *string { return &s } +// BoolPtr returns the pointer pointing to the boolean b. +func BoolPtr(b bool) *bool { return &b } + +// IntPtr returns the pointer pointing to the int i. +func IntPtr(i int) *int { return &i } + +// StrPtr returns the pointer pointing to the string s. +func StrPtr(s string) *string { return &s } + +// Uint64Ptr returns the pointer pointing to the uint64 i. +func Uint64Ptr(i uint64) *uint64 { return &i } // 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) + g.InitConfigLinuxSeccomp() + return seccomp.ParseSyscallFlag(arguments, g.Config.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) + g.InitConfigLinuxSeccomp() + return seccomp.ParseDefaultAction(action, g.Config.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) + g.InitConfigLinuxSeccomp() + return seccomp.ParseDefaultActionForce(action, g.Config.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) + g.InitConfigLinuxSeccomp() + return seccomp.ParseArchitectureFlag(architecture, g.Config.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) + g.InitConfigLinuxSeccomp() + return seccomp.RemoveAction(arguments, g.Config.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) + g.InitConfigLinuxSeccomp() + return seccomp.RemoveAllSeccompRules(g.Config.Linux.Seccomp) } diff --git a/generate/spec.go b/generate/spec.go deleted file mode 100644 index 5711699c5..000000000 --- a/generate/spec.go +++ /dev/null @@ -1,67 +0,0 @@ -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) initSpecAnnotations() { - g.initSpec() - if g.spec.Annotations == nil { - g.spec.Annotations = make(map[string]string) - } -} - -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.Seccomp{} - } -} - -func (g *Generator) initSpecLinuxResources() { - g.initSpecLinux() - if g.spec.Linux.Resources == nil { - g.spec.Linux.Resources = &rspec.Resources{} - } -} - -func (g *Generator) initSpecLinuxResourcesCPU() { - g.initSpecLinuxResources() - if g.spec.Linux.Resources.CPU == nil { - g.spec.Linux.Resources.CPU = &rspec.CPU{} - } -} - -func (g *Generator) initSpecLinuxResourcesMemory() { - g.initSpecLinuxResources() - if g.spec.Linux.Resources.Memory == nil { - g.spec.Linux.Resources.Memory = &rspec.Memory{} - } -} - -func (g *Generator) initSpecLinuxResourcesPids() { - g.initSpecLinuxResources() - if g.spec.Linux.Resources.Pids == nil { - g.spec.Linux.Resources.Pids = &rspec.Pids{} - } -}