Allow additional arguments to be passed into hooks

If a packager wants to be able to support addititional arguments on his
hook this will allow them to setup the configuration with these arguments.

For example this would allow a hook developer to add support for a --debug
flag to change the level of debugging in his hook.

In order to complete this task, I had to vendor in the latest
github.com://opencontainers/runtime-tools, which caused me to have to fix a
Mount and Capability interface calls

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh 2018-01-04 10:53:55 -05:00
parent 41aaf4e3d8
commit 23d20c9db5
45 changed files with 7145 additions and 672 deletions

View file

@ -17,6 +17,12 @@ import (
var (
// Namespaces include the names of supported namespaces.
Namespaces = []string{"network", "pid", "mount", "ipc", "uts", "user", "cgroup"}
// 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]
}
)
// Generator represents a generator for a container spec.
@ -35,7 +41,7 @@ func New() Generator {
spec := rspec.Spec{
Version: rspec.Version,
Root: &rspec.Root{
Path: "",
Path: "rootfs",
Readonly: false,
},
Process: &rspec.Process{
@ -227,6 +233,7 @@ func NewFromFile(path string) (Generator, error) {
if os.IsNotExist(err) {
return Generator{}, fmt.Errorf("template configuration at %s not found", path)
}
return Generator{}, err
}
defer cf.Close()
@ -392,7 +399,7 @@ func (g *Generator) SetProcessArgs(args []string) {
// ClearProcessEnv clears g.spec.Process.Env.
func (g *Generator) ClearProcessEnv() {
if g.spec == nil {
if g.spec == nil || g.spec.Process == nil {
return
}
g.spec.Process.Env = []string{}
@ -433,22 +440,21 @@ func (g *Generator) AddProcessRlimits(rType string, rHard uint64, rSoft uint64)
}
// RemoveProcessRlimits removes a rlimit from g.spec.Process.Rlimits.
func (g *Generator) RemoveProcessRlimits(rType string) error {
if g.spec == nil {
return nil
func (g *Generator) RemoveProcessRlimits(rType string) {
if g.spec == nil || g.spec.Process == nil {
return
}
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
}
}
return nil
}
// ClearProcessRlimits clear g.spec.Process.Rlimits.
func (g *Generator) ClearProcessRlimits() {
if g.spec == nil {
if g.spec == nil || g.spec.Process == nil {
return
}
g.spec.Process.Rlimits = []rspec.POSIXRlimit{}
@ -456,7 +462,7 @@ func (g *Generator) ClearProcessRlimits() {
// ClearProcessAdditionalGids clear g.spec.Process.AdditionalGids.
func (g *Generator) ClearProcessAdditionalGids() {
if g.spec == nil {
if g.spec == nil || g.spec.Process == nil {
return
}
g.spec.Process.User.AdditionalGids = []uint32{}
@ -485,6 +491,12 @@ func (g *Generator) SetLinuxCgroupsPath(path string) {
g.spec.Linux.CgroupsPath = path
}
// SetLinuxIntelRdtL3CacheSchema sets g.spec.Linux.IntelRdt.L3CacheSchema
func (g *Generator) SetLinuxIntelRdtL3CacheSchema(schema string) {
g.initSpecLinuxIntelRdt()
g.spec.Linux.IntelRdt.L3CacheSchema = schema
}
// SetLinuxMountLabel sets g.spec.Linux.MountLabel.
func (g *Generator) SetLinuxMountLabel(label string) {
g.initSpecLinux()
@ -497,6 +509,162 @@ func (g *Generator) SetProcessOOMScoreAdj(adj int) {
g.spec.Process.OOMScoreAdj = &adj
}
// SetLinuxResourcesBlockIOLeafWeight sets g.spec.Linux.Resources.BlockIO.LeafWeight.
func (g *Generator) SetLinuxResourcesBlockIOLeafWeight(weight uint16) {
g.initSpecLinuxResourcesBlockIO()
g.spec.Linux.Resources.BlockIO.LeafWeight = &weight
}
// AddLinuxResourcesBlockIOLeafWeightDevice adds or sets g.spec.Linux.Resources.BlockIO.WeightDevice.LeafWeight.
func (g *Generator) AddLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64, weight uint16) {
g.initSpecLinuxResourcesBlockIO()
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
g.spec.Linux.Resources.BlockIO.WeightDevice[i].LeafWeight = &weight
return
}
}
weightDevice := new(rspec.LinuxWeightDevice)
weightDevice.Major = major
weightDevice.Minor = minor
weightDevice.LeafWeight = &weight
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice, *weightDevice)
}
// DropLinuxResourcesBlockIOLeafWeightDevice drops a item form g.spec.Linux.Resources.BlockIO.WeightDevice.LeafWeight
func (g *Generator) DropLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.BlockIO == nil {
return
}
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
if weightDevice.Weight != nil {
newWeightDevice := new(rspec.LinuxWeightDevice)
newWeightDevice.Major = major
newWeightDevice.Minor = minor
newWeightDevice.Weight = weightDevice.Weight
g.spec.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice
} else {
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice[:i], g.spec.Linux.Resources.BlockIO.WeightDevice[i+1:]...)
}
return
}
}
}
// SetLinuxResourcesBlockIOWeight sets g.spec.Linux.Resources.BlockIO.Weight.
func (g *Generator) SetLinuxResourcesBlockIOWeight(weight uint16) {
g.initSpecLinuxResourcesBlockIO()
g.spec.Linux.Resources.BlockIO.Weight = &weight
}
// AddLinuxResourcesBlockIOWeightDevice adds or sets g.spec.Linux.Resources.BlockIO.WeightDevice.Weight.
func (g *Generator) AddLinuxResourcesBlockIOWeightDevice(major int64, minor int64, weight uint16) {
g.initSpecLinuxResourcesBlockIO()
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
g.spec.Linux.Resources.BlockIO.WeightDevice[i].Weight = &weight
return
}
}
weightDevice := new(rspec.LinuxWeightDevice)
weightDevice.Major = major
weightDevice.Minor = minor
weightDevice.Weight = &weight
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice, *weightDevice)
}
// DropLinuxResourcesBlockIOWeightDevice drops a item form g.spec.Linux.Resources.BlockIO.WeightDevice.Weight
func (g *Generator) DropLinuxResourcesBlockIOWeightDevice(major int64, minor int64) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.BlockIO == nil {
return
}
for i, weightDevice := range g.spec.Linux.Resources.BlockIO.WeightDevice {
if weightDevice.Major == major && weightDevice.Minor == minor {
if weightDevice.LeafWeight != nil {
newWeightDevice := new(rspec.LinuxWeightDevice)
newWeightDevice.Major = major
newWeightDevice.Minor = minor
newWeightDevice.LeafWeight = weightDevice.LeafWeight
g.spec.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice
} else {
g.spec.Linux.Resources.BlockIO.WeightDevice = append(g.spec.Linux.Resources.BlockIO.WeightDevice[:i], g.spec.Linux.Resources.BlockIO.WeightDevice[i+1:]...)
}
return
}
}
}
// AddLinuxResourcesBlockIOThrottleReadBpsDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices
}
// DropLinuxResourcesBlockIOThrottleReadBpsDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.BlockIO == nil {
return
}
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices
}
// AddLinuxResourcesBlockIOThrottleReadIOPSDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices
}
// DropLinuxResourcesBlockIOThrottleReadIOPSDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.BlockIO == nil {
return
}
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices
}
// AddLinuxResourcesBlockIOThrottleWriteBpsDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices
}
// DropLinuxResourcesBlockIOThrottleWriteBpsDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.BlockIO == nil {
return
}
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices
}
// AddLinuxResourcesBlockIOThrottleWriteIOPSDevice adds or sets g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice.
func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64, rate uint64) {
g.initSpecLinuxResourcesBlockIO()
throttleDevices := addOrReplaceBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor, rate)
g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices
}
// DropLinuxResourcesBlockIOThrottleWriteIOPSDevice drops a item from g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice.
func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.BlockIO == nil {
return
}
throttleDevices := dropBlockIOThrottleDevice(g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor)
g.spec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices
}
// SetLinuxResourcesCPUShares sets g.spec.Linux.Resources.CPU.Shares.
func (g *Generator) SetLinuxResourcesCPUShares(shares uint64) {
g.initSpecLinuxResourcesCPU()
@ -557,16 +725,17 @@ func (g *Generator) AddLinuxResourcesHugepageLimit(pageSize string, limit uint64
}
// DropLinuxResourcesHugepageLimit drops a hugepage limit from g.spec.Linux.Resources.HugepageLimits.
func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) error {
g.initSpecLinuxResources()
func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil {
return
}
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
}
}
return nil
}
// SetLinuxResourcesMemoryLimit sets g.spec.Linux.Resources.Memory.Limit.
@ -634,7 +803,10 @@ func (g *Generator) AddLinuxResourcesNetworkPriorities(name string, prio uint32)
// DropLinuxResourcesNetworkPriorities drops one item from g.spec.Linux.Resources.Network.Priorities.
func (g *Generator) DropLinuxResourcesNetworkPriorities(name string) {
g.initSpecLinuxResourcesNetwork()
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil || g.spec.Linux.Resources.Network == nil {
return
}
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:]...)
@ -721,8 +893,10 @@ func (g *Generator) SetLinuxRootPropagation(rp string) error {
case "rslave":
case "shared":
case "rshared":
case "unbindable":
case "runbindable":
default:
return fmt.Errorf("rootfs-propagation must be empty or one of private|rprivate|slave|rslave|shared|rshared")
return fmt.Errorf("rootfs-propagation %q must be empty or one of (r)private|(r)slave|(r)shared|(r)unbindable", rp)
}
g.initSpecLinux()
g.spec.Linux.RootfsPropagation = rp
@ -731,217 +905,99 @@ func (g *Generator) SetLinuxRootPropagation(rp string) error {
// ClearPreStartHooks clear g.spec.Hooks.Prestart.
func (g *Generator) ClearPreStartHooks() {
if g.spec == nil {
return
}
if g.spec.Hooks == nil {
if g.spec == nil || 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) {
func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) error {
g.initSpecHooks()
for i, hook := range g.spec.Hooks.Prestart {
if hook.Path == path {
g.spec.Hooks.Prestart[i].Env = envs
return
if hook.Path == preStartHook.Path {
g.spec.Hooks.Prestart[i] = preStartHook
return nil
}
}
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)
g.spec.Hooks.Prestart = append(g.spec.Hooks.Prestart, preStartHook)
return nil
}
// ClearPostStopHooks clear g.spec.Hooks.Poststop.
func (g *Generator) ClearPostStopHooks() {
if g.spec == nil {
return
}
if g.spec.Hooks == nil {
if g.spec == nil || 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) {
func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) error {
g.initSpecHooks()
for i, hook := range g.spec.Hooks.Poststop {
if hook.Path == path {
g.spec.Hooks.Poststop[i].Env = envs
return
if hook.Path == postStopHook.Path {
g.spec.Hooks.Poststop[i] = postStopHook
return nil
}
}
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)
g.spec.Hooks.Poststop = append(g.spec.Hooks.Poststop, postStopHook)
return nil
}
// ClearPostStartHooks clear g.spec.Hooks.Poststart.
func (g *Generator) ClearPostStartHooks() {
if g.spec == nil {
return
}
if g.spec.Hooks == nil {
if g.spec == nil || 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) {
func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) error {
g.initSpecHooks()
for i, hook := range g.spec.Hooks.Poststart {
if hook.Path == path {
g.spec.Hooks.Poststart[i].Env = envs
return
if hook.Path == postStartHook.Path {
g.spec.Hooks.Poststart[i] = postStartHook
return nil
}
}
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)
g.spec.Hooks.Poststart = append(g.spec.Hooks.Poststart, postStartHook)
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"}
}
// AddMount adds a mount into g.spec.Mounts.
func (g *Generator) AddMount(mnt rspec.Mount) {
g.initSpec()
// 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
g.spec.Mounts = append(g.spec.Mounts, mnt)
}
// RemoveMount removes a mount point on the dest directory
func (g *Generator) RemoveMount(dest string) {
g.initSpec()
for index, mount := range g.spec.Mounts {
if mount.Destination == dest {
g.spec.Mounts = append(g.spec.Mounts[:index], g.spec.Mounts[index+1:]...)
return
}
}
if !foundBindOption {
options = append(options, "bind")
}
}
mnt := rspec.Mount{
Destination: dest,
Type: "bind",
Source: source,
Options: options,
}
// Mounts returns the list of mounts
func (g *Generator) Mounts() []rspec.Mount {
g.initSpec()
g.spec.Mounts = append(g.spec.Mounts, mnt)
return g.spec.Mounts
}
// ClearMounts clear g.spec.Mounts
func (g *Generator) ClearMounts() {
if g.spec == nil {
return
}
g.spec.Mounts = []rspec.Mount{}
}
// SetupPrivileged sets up the privilege-related fields inside g.spec.
@ -970,7 +1026,7 @@ func (g *Generator) SetupPrivileged(privileged bool) {
// ClearProcessCapabilities clear g.spec.Process.Capabilities.
func (g *Generator) ClearProcessCapabilities() {
if g.spec == nil {
if g.spec == nil || g.spec.Process == nil || g.spec.Process.Capabilities == nil {
return
}
g.spec.Process.Capabilities.Bounding = []string{}
@ -980,8 +1036,32 @@ func (g *Generator) ClearProcessCapabilities() {
g.spec.Process.Capabilities.Ambient = []string{}
}
// AddProcessCapability adds a process capability into g.spec.Process.Capabilities.
func (g *Generator) AddProcessCapability(c string) error {
// AddProcessCapabilityAmbient adds a process capability into g.spec.Process.Capabilities.Ambient.
func (g *Generator) AddProcessCapabilityAmbient(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
return err
}
g.initSpecProcessCapabilities()
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
}
// AddProcessCapabilityBounding adds a process capability into g.spec.Process.Capabilities.Bounding.
func (g *Generator) AddProcessCapabilityBounding(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
return err
@ -1000,6 +1080,18 @@ func (g *Generator) AddProcessCapability(c string) error {
g.spec.Process.Capabilities.Bounding = append(g.spec.Process.Capabilities.Bounding, cp)
}
return nil
}
// AddProcessCapabilityEffective adds a process capability into g.spec.Process.Capabilities.Effective.
func (g *Generator) AddProcessCapabilityEffective(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
return err
}
g.initSpecProcessCapabilities()
var foundEffective bool
for _, cap := range g.spec.Process.Capabilities.Effective {
if strings.ToUpper(cap) == cp {
@ -1011,6 +1103,18 @@ func (g *Generator) AddProcessCapability(c string) error {
g.spec.Process.Capabilities.Effective = append(g.spec.Process.Capabilities.Effective, cp)
}
return nil
}
// AddProcessCapabilityInheritable adds a process capability into g.spec.Process.Capabilities.Inheritable.
func (g *Generator) AddProcessCapabilityInheritable(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
return err
}
g.initSpecProcessCapabilities()
var foundInheritable bool
for _, cap := range g.spec.Process.Capabilities.Inheritable {
if strings.ToUpper(cap) == cp {
@ -1022,6 +1126,18 @@ func (g *Generator) AddProcessCapability(c string) error {
g.spec.Process.Capabilities.Inheritable = append(g.spec.Process.Capabilities.Inheritable, cp)
}
return nil
}
// AddProcessCapabilityPermitted adds a process capability into g.spec.Process.Capabilities.Permitted.
func (g *Generator) AddProcessCapabilityPermitted(c string) error {
cp := strings.ToUpper(c)
if err := validate.CapValid(cp, g.HostSpecific); err != nil {
return err
}
g.initSpecProcessCapabilities()
var foundPermitted bool
for _, cap := range g.spec.Process.Capabilities.Permitted {
if strings.ToUpper(cap) == cp {
@ -1033,66 +1149,87 @@ func (g *Generator) AddProcessCapability(c string) error {
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 {
// DropProcessCapabilityAmbient drops a process capability from g.spec.Process.Capabilities.Ambient.
func (g *Generator) DropProcessCapabilityAmbient(c string) error {
if g.spec == nil || g.spec.Process == nil || g.spec.Process.Capabilities == nil {
return nil
}
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
return validate.CapValid(cp, false)
}
// DropProcessCapabilityBounding drops a process capability from g.spec.Process.Capabilities.Bounding.
func (g *Generator) DropProcessCapabilityBounding(c string) error {
if g.spec == nil || g.spec.Process == nil || g.spec.Process.Capabilities == nil {
return nil
}
cp := strings.ToUpper(c)
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)
}
}
return validate.CapValid(cp, false)
}
// DropProcessCapabilityEffective drops a process capability from g.spec.Process.Capabilities.Effective.
func (g *Generator) DropProcessCapabilityEffective(c string) error {
if g.spec == nil || g.spec.Process == nil || g.spec.Process.Capabilities == nil {
return nil
}
cp := strings.ToUpper(c)
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)
}
}
return validate.CapValid(cp, false)
}
// DropProcessCapabilityInheritable drops a process capability from g.spec.Process.Capabilities.Inheritable.
func (g *Generator) DropProcessCapabilityInheritable(c string) error {
if g.spec == nil || g.spec.Process == nil || g.spec.Process.Capabilities == nil {
return nil
}
cp := strings.ToUpper(c)
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)
}
}
return validate.CapValid(cp, false)
}
// DropProcessCapabilityPermitted drops a process capability from g.spec.Process.Capabilities.Permitted.
func (g *Generator) DropProcessCapabilityPermitted(c string) error {
if g.spec == nil || g.spec.Process == nil || g.spec.Process.Capabilities == nil {
return nil
}
cp := strings.ToUpper(c)
for i, cap := range g.spec.Process.Capabilities.Permitted {
if strings.ToUpper(cap) == cp {
g.spec.Process.Capabilities.Ambient = removeFunc(g.spec.Process.Capabilities.Ambient, i)
}
}
return validate.CapValid(cp, false)
}
func mapStrToNamespace(ns string, path string) (rspec.LinuxNamespace, error) {
@ -1180,18 +1317,17 @@ func (g *Generator) AddDevice(device rspec.LinuxDevice) {
}
// RemoveDevice remove a device from g.spec.Linux.Devices
func (g *Generator) RemoveDevice(path string) error {
func (g *Generator) RemoveDevice(path string) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Devices == nil {
return nil
return
}
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
}
}
return nil
}
// ClearLinuxDevices clears g.spec.Linux.Devices
@ -1203,6 +1339,39 @@ func (g *Generator) ClearLinuxDevices() {
g.spec.Linux.Devices = []rspec.LinuxDevice{}
}
// AddLinuxResourcesDevice - add a device into g.spec.Linux.Resources.Devices
func (g *Generator) AddLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) {
g.initSpecLinuxResources()
device := rspec.LinuxDeviceCgroup{
Allow: allow,
Type: devType,
Access: access,
Major: major,
Minor: minor,
}
g.spec.Linux.Resources.Devices = append(g.spec.Linux.Resources.Devices, device)
}
// RemoveLinuxResourcesDevice - remove a device from g.spec.Linux.Resources.Devices
func (g *Generator) RemoveLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) {
if g.spec == nil || g.spec.Linux == nil || g.spec.Linux.Resources == nil {
return
}
for i, device := range g.spec.Linux.Resources.Devices {
if device.Allow == allow &&
(devType == device.Type || (devType != "" && device.Type != "" && devType == device.Type)) &&
(access == device.Access || (access != "" && device.Access != "" && access == device.Access)) &&
(major == device.Major || (major != nil && device.Major != nil && *major == *device.Major)) &&
(minor == device.Minor || (minor != nil && device.Minor != nil && *minor == *device.Minor)) {
g.spec.Linux.Resources.Devices = append(g.spec.Linux.Resources.Devices[:i], g.spec.Linux.Resources.Devices[i+1:]...)
return
}
}
return
}
// strPtr returns the pointer pointing to the string s.
func strPtr(s string) *string { return &s }
@ -1254,3 +1423,122 @@ func (g *Generator) AddLinuxReadonlyPaths(path string) {
g.initSpecLinux()
g.spec.Linux.ReadonlyPaths = append(g.spec.Linux.ReadonlyPaths, path)
}
func addOrReplaceBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64, rate uint64) []rspec.LinuxThrottleDevice {
throttleDevices := tmpList
for i, throttleDevice := range throttleDevices {
if throttleDevice.Major == major && throttleDevice.Minor == minor {
throttleDevices[i].Rate = rate
return throttleDevices
}
}
throttleDevice := new(rspec.LinuxThrottleDevice)
throttleDevice.Major = major
throttleDevice.Minor = minor
throttleDevice.Rate = rate
throttleDevices = append(throttleDevices, *throttleDevice)
return throttleDevices
}
func dropBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64) []rspec.LinuxThrottleDevice {
throttleDevices := tmpList
for i, throttleDevice := range throttleDevices {
if throttleDevice.Major == major && throttleDevice.Minor == minor {
throttleDevices = append(throttleDevices[:i], throttleDevices[i+1:]...)
return throttleDevices
}
}
return throttleDevices
}
// AddSolarisAnet adds network into g.spec.Solaris.Anet
func (g *Generator) AddSolarisAnet(anet rspec.SolarisAnet) {
g.initSpecSolaris()
g.spec.Solaris.Anet = append(g.spec.Solaris.Anet, anet)
}
// SetSolarisCappedCPUNcpus sets g.spec.Solaris.CappedCPU.Ncpus
func (g *Generator) SetSolarisCappedCPUNcpus(ncpus string) {
g.initSpecSolarisCappedCPU()
g.spec.Solaris.CappedCPU.Ncpus = ncpus
}
// SetSolarisCappedMemoryPhysical sets g.spec.Solaris.CappedMemory.Physical
func (g *Generator) SetSolarisCappedMemoryPhysical(physical string) {
g.initSpecSolarisCappedMemory()
g.spec.Solaris.CappedMemory.Physical = physical
}
// SetSolarisCappedMemorySwap sets g.spec.Solaris.CappedMemory.Swap
func (g *Generator) SetSolarisCappedMemorySwap(swap string) {
g.initSpecSolarisCappedMemory()
g.spec.Solaris.CappedMemory.Swap = swap
}
// SetSolarisLimitPriv sets g.spec.Solaris.LimitPriv
func (g *Generator) SetSolarisLimitPriv(limitPriv string) {
g.initSpecSolaris()
g.spec.Solaris.LimitPriv = limitPriv
}
// SetSolarisMaxShmMemory sets g.spec.Solaris.MaxShmMemory
func (g *Generator) SetSolarisMaxShmMemory(memory string) {
g.initSpecSolaris()
g.spec.Solaris.MaxShmMemory = memory
}
// SetSolarisMilestone sets g.spec.Solaris.Milestone
func (g *Generator) SetSolarisMilestone(milestone string) {
g.initSpecSolaris()
g.spec.Solaris.Milestone = milestone
}
// SetWindowsHypervUntilityVMPath sets g.spec.Windows.HyperV.UtilityVMPath.
func (g *Generator) SetWindowsHypervUntilityVMPath(path string) {
g.initSpecWindowsHyperV()
g.spec.Windows.HyperV.UtilityVMPath = path
}
// SetWinodwsIgnoreFlushesDuringBoot sets g.spec.Winodws.IgnoreFlushesDuringBoot.
func (g *Generator) SetWinodwsIgnoreFlushesDuringBoot(ignore bool) {
g.initSpecWindows()
g.spec.Windows.IgnoreFlushesDuringBoot = ignore
}
// AddWindowsLayerFolders adds layer folders into g.spec.Windows.LayerFolders.
func (g *Generator) AddWindowsLayerFolders(folder string) {
g.initSpecWindows()
g.spec.Windows.LayerFolders = append(g.spec.Windows.LayerFolders, folder)
}
// SetWindowsNetwork sets g.spec.Windows.Network.
func (g *Generator) SetWindowsNetwork(network rspec.WindowsNetwork) {
g.initSpecWindows()
g.spec.Windows.Network = &network
}
// SetWindowsResourcesCPU sets g.spec.Windows.Resources.CPU.
func (g *Generator) SetWindowsResourcesCPU(cpu rspec.WindowsCPUResources) {
g.initSpecWindowsResources()
g.spec.Windows.Resources.CPU = &cpu
}
// SetWindowsResourcesMemoryLimit sets g.spec.Windows.Resources.Memory.Limit.
func (g *Generator) SetWindowsResourcesMemoryLimit(limit uint64) {
g.initSpecWindowsResourcesMemory()
g.spec.Windows.Resources.Memory.Limit = &limit
}
// SetWindowsResourcesStorage sets g.spec.Windows.Resources.Storage.
func (g *Generator) SetWindowsResourcesStorage(storage rspec.WindowsStorageResources) {
g.initSpecWindowsResources()
g.spec.Windows.Resources.Storage = &storage
}
// SetWinodwsServicing sets g.spec.Winodws.Servicing.
func (g *Generator) SetWinodwsServicing(servicing bool) {
g.initSpecWindows()
g.spec.Windows.Servicing = servicing
}

View file

@ -59,6 +59,13 @@ func (g *Generator) initSpecLinux() {
}
}
func (g *Generator) initSpecLinuxIntelRdt() {
g.initSpecLinux()
if g.spec.Linux.IntelRdt == nil {
g.spec.Linux.IntelRdt = &rspec.LinuxIntelRdt{}
}
}
func (g *Generator) initSpecLinuxSysctl() {
g.initSpecLinux()
if g.spec.Linux.Sysctl == nil {
@ -80,6 +87,13 @@ func (g *Generator) initSpecLinuxResources() {
}
}
func (g *Generator) initSpecLinuxResourcesBlockIO() {
g.initSpecLinuxResources()
if g.spec.Linux.Resources.BlockIO == nil {
g.spec.Linux.Resources.BlockIO = &rspec.LinuxBlockIO{}
}
}
func (g *Generator) initSpecLinuxResourcesCPU() {
g.initSpecLinuxResources()
if g.spec.Linux.Resources.CPU == nil {
@ -107,3 +121,52 @@ func (g *Generator) initSpecLinuxResourcesPids() {
g.spec.Linux.Resources.Pids = &rspec.LinuxPids{}
}
}
func (g *Generator) initSpecSolaris() {
g.initSpec()
if g.spec.Solaris == nil {
g.spec.Solaris = &rspec.Solaris{}
}
}
func (g *Generator) initSpecSolarisCappedCPU() {
g.initSpecSolaris()
if g.spec.Solaris.CappedCPU == nil {
g.spec.Solaris.CappedCPU = &rspec.SolarisCappedCPU{}
}
}
func (g *Generator) initSpecSolarisCappedMemory() {
g.initSpecSolaris()
if g.spec.Solaris.CappedMemory == nil {
g.spec.Solaris.CappedMemory = &rspec.SolarisCappedMemory{}
}
}
func (g *Generator) initSpecWindows() {
g.initSpec()
if g.spec.Windows == nil {
g.spec.Windows = &rspec.Windows{}
}
}
func (g *Generator) initSpecWindowsHyperV() {
g.initSpecWindows()
if g.spec.Windows.HyperV == nil {
g.spec.Windows.HyperV = &rspec.WindowsHyperV{}
}
}
func (g *Generator) initSpecWindowsResources() {
g.initSpecWindows()
if g.spec.Windows.Resources == nil {
g.spec.Windows.Resources = &rspec.WindowsResources{}
}
}
func (g *Generator) initSpecWindowsResourcesMemory() {
g.initSpecWindowsResources()
if g.spec.Windows.Resources.Memory == nil {
g.spec.Windows.Resources.Memory = &rspec.WindowsMemoryResources{}
}
}