github.com/opencontainers/runtime-tools@v0.9.0/generate/generate.go (about)

     1  // Package generate implements functions generating container config files.
     2  package generate
     3  
     4  import (
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"strings"
    10  
    11  	rspec "github.com/opencontainers/runtime-spec/specs-go"
    12  	"github.com/opencontainers/runtime-tools/generate/seccomp"
    13  	"github.com/opencontainers/runtime-tools/validate"
    14  	"github.com/syndtr/gocapability/capability"
    15  )
    16  
    17  var (
    18  	// Namespaces include the names of supported namespaces.
    19  	Namespaces = []string{"network", "pid", "mount", "ipc", "uts", "user", "cgroup"}
    20  
    21  	// we don't care about order...and this is way faster...
    22  	removeFunc = func(s []string, i int) []string {
    23  		s[i] = s[len(s)-1]
    24  		return s[:len(s)-1]
    25  	}
    26  )
    27  
    28  // Generator represents a generator for a container config.
    29  type Generator struct {
    30  	Config       *rspec.Spec
    31  	HostSpecific bool
    32  }
    33  
    34  // ExportOptions have toggles for exporting only certain parts of the specification
    35  type ExportOptions struct {
    36  	Seccomp bool // seccomp toggles if only seccomp should be exported
    37  }
    38  
    39  // New creates a configuration Generator with the default
    40  // configuration for the target operating system.
    41  func New(os string) (generator Generator, err error) {
    42  	if os != "linux" && os != "solaris" && os != "windows" {
    43  		return generator, fmt.Errorf("no defaults configured for %s", os)
    44  	}
    45  
    46  	config := rspec.Spec{
    47  		Version:  rspec.Version,
    48  		Hostname: "mrsdalloway",
    49  	}
    50  
    51  	if os == "windows" {
    52  		config.Process = &rspec.Process{
    53  			Args: []string{
    54  				"cmd",
    55  			},
    56  			Cwd: `C:\`,
    57  		}
    58  		config.Windows = &rspec.Windows{}
    59  	} else {
    60  		config.Root = &rspec.Root{
    61  			Path:     "rootfs",
    62  			Readonly: false,
    63  		}
    64  		config.Process = &rspec.Process{
    65  			Terminal: false,
    66  			Args: []string{
    67  				"sh",
    68  			},
    69  		}
    70  	}
    71  
    72  	if os == "linux" || os == "solaris" {
    73  		config.Process.User = rspec.User{}
    74  		config.Process.Env = []string{
    75  			"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    76  			"TERM=xterm",
    77  		}
    78  		config.Process.Cwd = "/"
    79  		config.Process.Rlimits = []rspec.POSIXRlimit{
    80  			{
    81  				Type: "RLIMIT_NOFILE",
    82  				Hard: uint64(1024),
    83  				Soft: uint64(1024),
    84  			},
    85  		}
    86  	}
    87  
    88  	if os == "linux" {
    89  		config.Process.Capabilities = &rspec.LinuxCapabilities{
    90  			Bounding: []string{
    91  				"CAP_CHOWN",
    92  				"CAP_DAC_OVERRIDE",
    93  				"CAP_FSETID",
    94  				"CAP_FOWNER",
    95  				"CAP_MKNOD",
    96  				"CAP_NET_RAW",
    97  				"CAP_SETGID",
    98  				"CAP_SETUID",
    99  				"CAP_SETFCAP",
   100  				"CAP_SETPCAP",
   101  				"CAP_NET_BIND_SERVICE",
   102  				"CAP_SYS_CHROOT",
   103  				"CAP_KILL",
   104  				"CAP_AUDIT_WRITE",
   105  			},
   106  			Permitted: []string{
   107  				"CAP_CHOWN",
   108  				"CAP_DAC_OVERRIDE",
   109  				"CAP_FSETID",
   110  				"CAP_FOWNER",
   111  				"CAP_MKNOD",
   112  				"CAP_NET_RAW",
   113  				"CAP_SETGID",
   114  				"CAP_SETUID",
   115  				"CAP_SETFCAP",
   116  				"CAP_SETPCAP",
   117  				"CAP_NET_BIND_SERVICE",
   118  				"CAP_SYS_CHROOT",
   119  				"CAP_KILL",
   120  				"CAP_AUDIT_WRITE",
   121  			},
   122  			Inheritable: []string{
   123  				"CAP_CHOWN",
   124  				"CAP_DAC_OVERRIDE",
   125  				"CAP_FSETID",
   126  				"CAP_FOWNER",
   127  				"CAP_MKNOD",
   128  				"CAP_NET_RAW",
   129  				"CAP_SETGID",
   130  				"CAP_SETUID",
   131  				"CAP_SETFCAP",
   132  				"CAP_SETPCAP",
   133  				"CAP_NET_BIND_SERVICE",
   134  				"CAP_SYS_CHROOT",
   135  				"CAP_KILL",
   136  				"CAP_AUDIT_WRITE",
   137  			},
   138  			Effective: []string{
   139  				"CAP_CHOWN",
   140  				"CAP_DAC_OVERRIDE",
   141  				"CAP_FSETID",
   142  				"CAP_FOWNER",
   143  				"CAP_MKNOD",
   144  				"CAP_NET_RAW",
   145  				"CAP_SETGID",
   146  				"CAP_SETUID",
   147  				"CAP_SETFCAP",
   148  				"CAP_SETPCAP",
   149  				"CAP_NET_BIND_SERVICE",
   150  				"CAP_SYS_CHROOT",
   151  				"CAP_KILL",
   152  				"CAP_AUDIT_WRITE",
   153  			},
   154  			Ambient: []string{
   155  				"CAP_CHOWN",
   156  				"CAP_DAC_OVERRIDE",
   157  				"CAP_FSETID",
   158  				"CAP_FOWNER",
   159  				"CAP_MKNOD",
   160  				"CAP_NET_RAW",
   161  				"CAP_SETGID",
   162  				"CAP_SETUID",
   163  				"CAP_SETFCAP",
   164  				"CAP_SETPCAP",
   165  				"CAP_NET_BIND_SERVICE",
   166  				"CAP_SYS_CHROOT",
   167  				"CAP_KILL",
   168  				"CAP_AUDIT_WRITE",
   169  			},
   170  		}
   171  		config.Mounts = []rspec.Mount{
   172  			{
   173  				Destination: "/proc",
   174  				Type:        "proc",
   175  				Source:      "proc",
   176  				Options:     []string{"nosuid", "noexec", "nodev"},
   177  			},
   178  			{
   179  				Destination: "/dev",
   180  				Type:        "tmpfs",
   181  				Source:      "tmpfs",
   182  				Options:     []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
   183  			},
   184  			{
   185  				Destination: "/dev/pts",
   186  				Type:        "devpts",
   187  				Source:      "devpts",
   188  				Options:     []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
   189  			},
   190  			{
   191  				Destination: "/dev/shm",
   192  				Type:        "tmpfs",
   193  				Source:      "shm",
   194  				Options:     []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
   195  			},
   196  			{
   197  				Destination: "/dev/mqueue",
   198  				Type:        "mqueue",
   199  				Source:      "mqueue",
   200  				Options:     []string{"nosuid", "noexec", "nodev"},
   201  			},
   202  			{
   203  				Destination: "/sys",
   204  				Type:        "sysfs",
   205  				Source:      "sysfs",
   206  				Options:     []string{"nosuid", "noexec", "nodev", "ro"},
   207  			},
   208  		}
   209  		config.Linux = &rspec.Linux{
   210  			Resources: &rspec.LinuxResources{
   211  				Devices: []rspec.LinuxDeviceCgroup{
   212  					{
   213  						Allow:  false,
   214  						Access: "rwm",
   215  					},
   216  				},
   217  			},
   218  			Namespaces: []rspec.LinuxNamespace{
   219  				{
   220  					Type: "pid",
   221  				},
   222  				{
   223  					Type: "network",
   224  				},
   225  				{
   226  					Type: "ipc",
   227  				},
   228  				{
   229  					Type: "uts",
   230  				},
   231  				{
   232  					Type: "mount",
   233  				},
   234  			},
   235  			Seccomp: seccomp.DefaultProfile(&config),
   236  		}
   237  	}
   238  
   239  	return Generator{Config: &config}, nil
   240  }
   241  
   242  // NewFromSpec creates a configuration Generator from a given
   243  // configuration.
   244  //
   245  // Deprecated: Replace with:
   246  //
   247  //   generator := Generator{Config: config}
   248  func NewFromSpec(config *rspec.Spec) Generator {
   249  	return Generator{
   250  		Config: config,
   251  	}
   252  }
   253  
   254  // NewFromFile loads the template specified in a file into a
   255  // configuration Generator.
   256  func NewFromFile(path string) (Generator, error) {
   257  	cf, err := os.Open(path)
   258  	if err != nil {
   259  		if os.IsNotExist(err) {
   260  			return Generator{}, fmt.Errorf("template configuration at %s not found", path)
   261  		}
   262  		return Generator{}, err
   263  	}
   264  	defer cf.Close()
   265  
   266  	return NewFromTemplate(cf)
   267  }
   268  
   269  // NewFromTemplate loads the template from io.Reader into a
   270  // configuration Generator.
   271  func NewFromTemplate(r io.Reader) (Generator, error) {
   272  	var config rspec.Spec
   273  	if err := json.NewDecoder(r).Decode(&config); err != nil {
   274  		return Generator{}, err
   275  	}
   276  	return Generator{
   277  		Config: &config,
   278  	}, nil
   279  }
   280  
   281  // SetSpec sets the configuration in the Generator g.
   282  //
   283  // Deprecated: Replace with:
   284  //
   285  //   Use generator.Config = config
   286  func (g *Generator) SetSpec(config *rspec.Spec) {
   287  	g.Config = config
   288  }
   289  
   290  // Spec gets the configuration from the Generator g.
   291  //
   292  // Deprecated: Replace with generator.Config.
   293  func (g *Generator) Spec() *rspec.Spec {
   294  	return g.Config
   295  }
   296  
   297  // Save writes the configuration into w.
   298  func (g *Generator) Save(w io.Writer, exportOpts ExportOptions) (err error) {
   299  	var data []byte
   300  
   301  	if g.Config.Linux != nil {
   302  		buf, err := json.Marshal(g.Config.Linux)
   303  		if err != nil {
   304  			return err
   305  		}
   306  		if string(buf) == "{}" {
   307  			g.Config.Linux = nil
   308  		}
   309  	}
   310  
   311  	if exportOpts.Seccomp {
   312  		data, err = json.MarshalIndent(g.Config.Linux.Seccomp, "", "\t")
   313  	} else {
   314  		data, err = json.MarshalIndent(g.Config, "", "\t")
   315  	}
   316  	if err != nil {
   317  		return err
   318  	}
   319  
   320  	_, err = w.Write(data)
   321  	if err != nil {
   322  		return err
   323  	}
   324  
   325  	return nil
   326  }
   327  
   328  // SaveToFile writes the configuration into a file.
   329  func (g *Generator) SaveToFile(path string, exportOpts ExportOptions) error {
   330  	f, err := os.Create(path)
   331  	if err != nil {
   332  		return err
   333  	}
   334  	defer f.Close()
   335  	return g.Save(f, exportOpts)
   336  }
   337  
   338  // SetVersion sets g.Config.Version.
   339  func (g *Generator) SetVersion(version string) {
   340  	g.initConfig()
   341  	g.Config.Version = version
   342  }
   343  
   344  // SetRootPath sets g.Config.Root.Path.
   345  func (g *Generator) SetRootPath(path string) {
   346  	g.initConfigRoot()
   347  	g.Config.Root.Path = path
   348  }
   349  
   350  // SetRootReadonly sets g.Config.Root.Readonly.
   351  func (g *Generator) SetRootReadonly(b bool) {
   352  	g.initConfigRoot()
   353  	g.Config.Root.Readonly = b
   354  }
   355  
   356  // SetHostname sets g.Config.Hostname.
   357  func (g *Generator) SetHostname(s string) {
   358  	g.initConfig()
   359  	g.Config.Hostname = s
   360  }
   361  
   362  // SetOCIVersion sets g.Config.Version.
   363  func (g *Generator) SetOCIVersion(s string) {
   364  	g.initConfig()
   365  	g.Config.Version = s
   366  }
   367  
   368  // ClearAnnotations clears g.Config.Annotations.
   369  func (g *Generator) ClearAnnotations() {
   370  	if g.Config == nil {
   371  		return
   372  	}
   373  	g.Config.Annotations = make(map[string]string)
   374  }
   375  
   376  // AddAnnotation adds an annotation into g.Config.Annotations.
   377  func (g *Generator) AddAnnotation(key, value string) {
   378  	g.initConfigAnnotations()
   379  	g.Config.Annotations[key] = value
   380  }
   381  
   382  // RemoveAnnotation remove an annotation from g.Config.Annotations.
   383  func (g *Generator) RemoveAnnotation(key string) {
   384  	if g.Config == nil || g.Config.Annotations == nil {
   385  		return
   386  	}
   387  	delete(g.Config.Annotations, key)
   388  }
   389  
   390  // RemoveHostname removes g.Config.Hostname, setting it to an empty string.
   391  func (g *Generator) RemoveHostname() {
   392  	if g.Config == nil {
   393  		return
   394  	}
   395  	g.Config.Hostname = ""
   396  }
   397  
   398  // SetProcessConsoleSize sets g.Config.Process.ConsoleSize.
   399  func (g *Generator) SetProcessConsoleSize(width, height uint) {
   400  	g.initConfigProcessConsoleSize()
   401  	g.Config.Process.ConsoleSize.Width = width
   402  	g.Config.Process.ConsoleSize.Height = height
   403  }
   404  
   405  // SetProcessUID sets g.Config.Process.User.UID.
   406  func (g *Generator) SetProcessUID(uid uint32) {
   407  	g.initConfigProcess()
   408  	g.Config.Process.User.UID = uid
   409  }
   410  
   411  // SetProcessUsername sets g.Config.Process.User.Username.
   412  func (g *Generator) SetProcessUsername(username string) {
   413  	g.initConfigProcess()
   414  	g.Config.Process.User.Username = username
   415  }
   416  
   417  // SetProcessGID sets g.Config.Process.User.GID.
   418  func (g *Generator) SetProcessGID(gid uint32) {
   419  	g.initConfigProcess()
   420  	g.Config.Process.User.GID = gid
   421  }
   422  
   423  // SetProcessCwd sets g.Config.Process.Cwd.
   424  func (g *Generator) SetProcessCwd(cwd string) {
   425  	g.initConfigProcess()
   426  	g.Config.Process.Cwd = cwd
   427  }
   428  
   429  // SetProcessNoNewPrivileges sets g.Config.Process.NoNewPrivileges.
   430  func (g *Generator) SetProcessNoNewPrivileges(b bool) {
   431  	g.initConfigProcess()
   432  	g.Config.Process.NoNewPrivileges = b
   433  }
   434  
   435  // SetProcessTerminal sets g.Config.Process.Terminal.
   436  func (g *Generator) SetProcessTerminal(b bool) {
   437  	g.initConfigProcess()
   438  	g.Config.Process.Terminal = b
   439  }
   440  
   441  // SetProcessApparmorProfile sets g.Config.Process.ApparmorProfile.
   442  func (g *Generator) SetProcessApparmorProfile(prof string) {
   443  	g.initConfigProcess()
   444  	g.Config.Process.ApparmorProfile = prof
   445  }
   446  
   447  // SetProcessArgs sets g.Config.Process.Args.
   448  func (g *Generator) SetProcessArgs(args []string) {
   449  	g.initConfigProcess()
   450  	g.Config.Process.Args = args
   451  }
   452  
   453  // ClearProcessEnv clears g.Config.Process.Env.
   454  func (g *Generator) ClearProcessEnv() {
   455  	if g.Config == nil || g.Config.Process == nil {
   456  		return
   457  	}
   458  	g.Config.Process.Env = []string{}
   459  }
   460  
   461  // AddProcessEnv adds name=value into g.Config.Process.Env, or replaces an
   462  // existing entry with the given name.
   463  func (g *Generator) AddProcessEnv(name, value string) {
   464  	g.initConfigProcess()
   465  
   466  	env := fmt.Sprintf("%s=%s", name, value)
   467  	for idx := range g.Config.Process.Env {
   468  		if strings.HasPrefix(g.Config.Process.Env[idx], name+"=") {
   469  			g.Config.Process.Env[idx] = env
   470  			return
   471  		}
   472  	}
   473  	g.Config.Process.Env = append(g.Config.Process.Env, env)
   474  }
   475  
   476  // AddProcessRlimits adds rlimit into g.Config.Process.Rlimits.
   477  func (g *Generator) AddProcessRlimits(rType string, rHard uint64, rSoft uint64) {
   478  	g.initConfigProcess()
   479  	for i, rlimit := range g.Config.Process.Rlimits {
   480  		if rlimit.Type == rType {
   481  			g.Config.Process.Rlimits[i].Hard = rHard
   482  			g.Config.Process.Rlimits[i].Soft = rSoft
   483  			return
   484  		}
   485  	}
   486  
   487  	newRlimit := rspec.POSIXRlimit{
   488  		Type: rType,
   489  		Hard: rHard,
   490  		Soft: rSoft,
   491  	}
   492  	g.Config.Process.Rlimits = append(g.Config.Process.Rlimits, newRlimit)
   493  }
   494  
   495  // RemoveProcessRlimits removes a rlimit from g.Config.Process.Rlimits.
   496  func (g *Generator) RemoveProcessRlimits(rType string) {
   497  	if g.Config == nil || g.Config.Process == nil {
   498  		return
   499  	}
   500  	for i, rlimit := range g.Config.Process.Rlimits {
   501  		if rlimit.Type == rType {
   502  			g.Config.Process.Rlimits = append(g.Config.Process.Rlimits[:i], g.Config.Process.Rlimits[i+1:]...)
   503  			return
   504  		}
   505  	}
   506  }
   507  
   508  // ClearProcessRlimits clear g.Config.Process.Rlimits.
   509  func (g *Generator) ClearProcessRlimits() {
   510  	if g.Config == nil || g.Config.Process == nil {
   511  		return
   512  	}
   513  	g.Config.Process.Rlimits = []rspec.POSIXRlimit{}
   514  }
   515  
   516  // ClearProcessAdditionalGids clear g.Config.Process.AdditionalGids.
   517  func (g *Generator) ClearProcessAdditionalGids() {
   518  	if g.Config == nil || g.Config.Process == nil {
   519  		return
   520  	}
   521  	g.Config.Process.User.AdditionalGids = []uint32{}
   522  }
   523  
   524  // AddProcessAdditionalGid adds an additional gid into g.Config.Process.AdditionalGids.
   525  func (g *Generator) AddProcessAdditionalGid(gid uint32) {
   526  	g.initConfigProcess()
   527  	for _, group := range g.Config.Process.User.AdditionalGids {
   528  		if group == gid {
   529  			return
   530  		}
   531  	}
   532  	g.Config.Process.User.AdditionalGids = append(g.Config.Process.User.AdditionalGids, gid)
   533  }
   534  
   535  // SetProcessSelinuxLabel sets g.Config.Process.SelinuxLabel.
   536  func (g *Generator) SetProcessSelinuxLabel(label string) {
   537  	g.initConfigProcess()
   538  	g.Config.Process.SelinuxLabel = label
   539  }
   540  
   541  // SetLinuxCgroupsPath sets g.Config.Linux.CgroupsPath.
   542  func (g *Generator) SetLinuxCgroupsPath(path string) {
   543  	g.initConfigLinux()
   544  	g.Config.Linux.CgroupsPath = path
   545  }
   546  
   547  // SetLinuxIntelRdtL3CacheSchema sets g.Config.Linux.IntelRdt.L3CacheSchema
   548  func (g *Generator) SetLinuxIntelRdtL3CacheSchema(schema string) {
   549  	g.initConfigLinuxIntelRdt()
   550  	g.Config.Linux.IntelRdt.L3CacheSchema = schema
   551  }
   552  
   553  // SetLinuxMountLabel sets g.Config.Linux.MountLabel.
   554  func (g *Generator) SetLinuxMountLabel(label string) {
   555  	g.initConfigLinux()
   556  	g.Config.Linux.MountLabel = label
   557  }
   558  
   559  // SetProcessOOMScoreAdj sets g.Config.Process.OOMScoreAdj.
   560  func (g *Generator) SetProcessOOMScoreAdj(adj int) {
   561  	g.initConfigProcess()
   562  	g.Config.Process.OOMScoreAdj = &adj
   563  }
   564  
   565  // SetLinuxResourcesBlockIOLeafWeight sets g.Config.Linux.Resources.BlockIO.LeafWeight.
   566  func (g *Generator) SetLinuxResourcesBlockIOLeafWeight(weight uint16) {
   567  	g.initConfigLinuxResourcesBlockIO()
   568  	g.Config.Linux.Resources.BlockIO.LeafWeight = &weight
   569  }
   570  
   571  // AddLinuxResourcesBlockIOLeafWeightDevice adds or sets g.Config.Linux.Resources.BlockIO.WeightDevice.LeafWeight.
   572  func (g *Generator) AddLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64, weight uint16) {
   573  	g.initConfigLinuxResourcesBlockIO()
   574  	for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice {
   575  		if weightDevice.Major == major && weightDevice.Minor == minor {
   576  			g.Config.Linux.Resources.BlockIO.WeightDevice[i].LeafWeight = &weight
   577  			return
   578  		}
   579  	}
   580  	weightDevice := new(rspec.LinuxWeightDevice)
   581  	weightDevice.Major = major
   582  	weightDevice.Minor = minor
   583  	weightDevice.LeafWeight = &weight
   584  	g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice, *weightDevice)
   585  }
   586  
   587  // DropLinuxResourcesBlockIOLeafWeightDevice drops a item form g.Config.Linux.Resources.BlockIO.WeightDevice.LeafWeight
   588  func (g *Generator) DropLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64) {
   589  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil {
   590  		return
   591  	}
   592  
   593  	for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice {
   594  		if weightDevice.Major == major && weightDevice.Minor == minor {
   595  			if weightDevice.Weight != nil {
   596  				newWeightDevice := new(rspec.LinuxWeightDevice)
   597  				newWeightDevice.Major = major
   598  				newWeightDevice.Minor = minor
   599  				newWeightDevice.Weight = weightDevice.Weight
   600  				g.Config.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice
   601  			} else {
   602  				g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice[:i], g.Config.Linux.Resources.BlockIO.WeightDevice[i+1:]...)
   603  			}
   604  			return
   605  		}
   606  	}
   607  }
   608  
   609  // SetLinuxResourcesBlockIOWeight sets g.Config.Linux.Resources.BlockIO.Weight.
   610  func (g *Generator) SetLinuxResourcesBlockIOWeight(weight uint16) {
   611  	g.initConfigLinuxResourcesBlockIO()
   612  	g.Config.Linux.Resources.BlockIO.Weight = &weight
   613  }
   614  
   615  // AddLinuxResourcesBlockIOWeightDevice adds or sets g.Config.Linux.Resources.BlockIO.WeightDevice.Weight.
   616  func (g *Generator) AddLinuxResourcesBlockIOWeightDevice(major int64, minor int64, weight uint16) {
   617  	g.initConfigLinuxResourcesBlockIO()
   618  	for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice {
   619  		if weightDevice.Major == major && weightDevice.Minor == minor {
   620  			g.Config.Linux.Resources.BlockIO.WeightDevice[i].Weight = &weight
   621  			return
   622  		}
   623  	}
   624  	weightDevice := new(rspec.LinuxWeightDevice)
   625  	weightDevice.Major = major
   626  	weightDevice.Minor = minor
   627  	weightDevice.Weight = &weight
   628  	g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice, *weightDevice)
   629  }
   630  
   631  // DropLinuxResourcesBlockIOWeightDevice drops a item form g.Config.Linux.Resources.BlockIO.WeightDevice.Weight
   632  func (g *Generator) DropLinuxResourcesBlockIOWeightDevice(major int64, minor int64) {
   633  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil {
   634  		return
   635  	}
   636  
   637  	for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice {
   638  		if weightDevice.Major == major && weightDevice.Minor == minor {
   639  			if weightDevice.LeafWeight != nil {
   640  				newWeightDevice := new(rspec.LinuxWeightDevice)
   641  				newWeightDevice.Major = major
   642  				newWeightDevice.Minor = minor
   643  				newWeightDevice.LeafWeight = weightDevice.LeafWeight
   644  				g.Config.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice
   645  			} else {
   646  				g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice[:i], g.Config.Linux.Resources.BlockIO.WeightDevice[i+1:]...)
   647  			}
   648  			return
   649  		}
   650  	}
   651  }
   652  
   653  // AddLinuxResourcesBlockIOThrottleReadBpsDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice.
   654  func (g *Generator) AddLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64, rate uint64) {
   655  	g.initConfigLinuxResourcesBlockIO()
   656  	throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor, rate)
   657  	g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices
   658  }
   659  
   660  // DropLinuxResourcesBlockIOThrottleReadBpsDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice.
   661  func (g *Generator) DropLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64) {
   662  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil {
   663  		return
   664  	}
   665  
   666  	throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor)
   667  	g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices
   668  }
   669  
   670  // AddLinuxResourcesBlockIOThrottleReadIOPSDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice.
   671  func (g *Generator) AddLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64, rate uint64) {
   672  	g.initConfigLinuxResourcesBlockIO()
   673  	throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor, rate)
   674  	g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices
   675  }
   676  
   677  // DropLinuxResourcesBlockIOThrottleReadIOPSDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice.
   678  func (g *Generator) DropLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64) {
   679  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil {
   680  		return
   681  	}
   682  
   683  	throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor)
   684  	g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices
   685  }
   686  
   687  // AddLinuxResourcesBlockIOThrottleWriteBpsDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice.
   688  func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64, rate uint64) {
   689  	g.initConfigLinuxResourcesBlockIO()
   690  	throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor, rate)
   691  	g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices
   692  }
   693  
   694  // DropLinuxResourcesBlockIOThrottleWriteBpsDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice.
   695  func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64) {
   696  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil {
   697  		return
   698  	}
   699  
   700  	throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor)
   701  	g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices
   702  }
   703  
   704  // AddLinuxResourcesBlockIOThrottleWriteIOPSDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice.
   705  func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64, rate uint64) {
   706  	g.initConfigLinuxResourcesBlockIO()
   707  	throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor, rate)
   708  	g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices
   709  }
   710  
   711  // DropLinuxResourcesBlockIOThrottleWriteIOPSDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice.
   712  func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64) {
   713  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil {
   714  		return
   715  	}
   716  
   717  	throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor)
   718  	g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices
   719  }
   720  
   721  // SetLinuxResourcesCPUShares sets g.Config.Linux.Resources.CPU.Shares.
   722  func (g *Generator) SetLinuxResourcesCPUShares(shares uint64) {
   723  	g.InitConfigLinuxResourcesCPU()
   724  	g.Config.Linux.Resources.CPU.Shares = &shares
   725  }
   726  
   727  // SetLinuxResourcesCPUQuota sets g.Config.Linux.Resources.CPU.Quota.
   728  func (g *Generator) SetLinuxResourcesCPUQuota(quota int64) {
   729  	g.InitConfigLinuxResourcesCPU()
   730  	g.Config.Linux.Resources.CPU.Quota = &quota
   731  }
   732  
   733  // SetLinuxResourcesCPUPeriod sets g.Config.Linux.Resources.CPU.Period.
   734  func (g *Generator) SetLinuxResourcesCPUPeriod(period uint64) {
   735  	g.InitConfigLinuxResourcesCPU()
   736  	g.Config.Linux.Resources.CPU.Period = &period
   737  }
   738  
   739  // SetLinuxResourcesCPURealtimeRuntime sets g.Config.Linux.Resources.CPU.RealtimeRuntime.
   740  func (g *Generator) SetLinuxResourcesCPURealtimeRuntime(time int64) {
   741  	g.InitConfigLinuxResourcesCPU()
   742  	g.Config.Linux.Resources.CPU.RealtimeRuntime = &time
   743  }
   744  
   745  // SetLinuxResourcesCPURealtimePeriod sets g.Config.Linux.Resources.CPU.RealtimePeriod.
   746  func (g *Generator) SetLinuxResourcesCPURealtimePeriod(period uint64) {
   747  	g.InitConfigLinuxResourcesCPU()
   748  	g.Config.Linux.Resources.CPU.RealtimePeriod = &period
   749  }
   750  
   751  // SetLinuxResourcesCPUCpus sets g.Config.Linux.Resources.CPU.Cpus.
   752  func (g *Generator) SetLinuxResourcesCPUCpus(cpus string) {
   753  	g.InitConfigLinuxResourcesCPU()
   754  	g.Config.Linux.Resources.CPU.Cpus = cpus
   755  }
   756  
   757  // SetLinuxResourcesCPUMems sets g.Config.Linux.Resources.CPU.Mems.
   758  func (g *Generator) SetLinuxResourcesCPUMems(mems string) {
   759  	g.InitConfigLinuxResourcesCPU()
   760  	g.Config.Linux.Resources.CPU.Mems = mems
   761  }
   762  
   763  // AddLinuxResourcesHugepageLimit adds or sets g.Config.Linux.Resources.HugepageLimits.
   764  func (g *Generator) AddLinuxResourcesHugepageLimit(pageSize string, limit uint64) {
   765  	hugepageLimit := rspec.LinuxHugepageLimit{
   766  		Pagesize: pageSize,
   767  		Limit:    limit,
   768  	}
   769  
   770  	g.initConfigLinuxResources()
   771  	for i, pageLimit := range g.Config.Linux.Resources.HugepageLimits {
   772  		if pageLimit.Pagesize == pageSize {
   773  			g.Config.Linux.Resources.HugepageLimits[i].Limit = limit
   774  			return
   775  		}
   776  	}
   777  	g.Config.Linux.Resources.HugepageLimits = append(g.Config.Linux.Resources.HugepageLimits, hugepageLimit)
   778  }
   779  
   780  // DropLinuxResourcesHugepageLimit drops a hugepage limit from g.Config.Linux.Resources.HugepageLimits.
   781  func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) {
   782  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil {
   783  		return
   784  	}
   785  
   786  	for i, pageLimit := range g.Config.Linux.Resources.HugepageLimits {
   787  		if pageLimit.Pagesize == pageSize {
   788  			g.Config.Linux.Resources.HugepageLimits = append(g.Config.Linux.Resources.HugepageLimits[:i], g.Config.Linux.Resources.HugepageLimits[i+1:]...)
   789  			return
   790  		}
   791  	}
   792  }
   793  
   794  // SetLinuxResourcesMemoryLimit sets g.Config.Linux.Resources.Memory.Limit.
   795  func (g *Generator) SetLinuxResourcesMemoryLimit(limit int64) {
   796  	g.initConfigLinuxResourcesMemory()
   797  	g.Config.Linux.Resources.Memory.Limit = &limit
   798  }
   799  
   800  // SetLinuxResourcesMemoryReservation sets g.Config.Linux.Resources.Memory.Reservation.
   801  func (g *Generator) SetLinuxResourcesMemoryReservation(reservation int64) {
   802  	g.initConfigLinuxResourcesMemory()
   803  	g.Config.Linux.Resources.Memory.Reservation = &reservation
   804  }
   805  
   806  // SetLinuxResourcesMemorySwap sets g.Config.Linux.Resources.Memory.Swap.
   807  func (g *Generator) SetLinuxResourcesMemorySwap(swap int64) {
   808  	g.initConfigLinuxResourcesMemory()
   809  	g.Config.Linux.Resources.Memory.Swap = &swap
   810  }
   811  
   812  // SetLinuxResourcesMemoryKernel sets g.Config.Linux.Resources.Memory.Kernel.
   813  func (g *Generator) SetLinuxResourcesMemoryKernel(kernel int64) {
   814  	g.initConfigLinuxResourcesMemory()
   815  	g.Config.Linux.Resources.Memory.Kernel = &kernel
   816  }
   817  
   818  // SetLinuxResourcesMemoryKernelTCP sets g.Config.Linux.Resources.Memory.KernelTCP.
   819  func (g *Generator) SetLinuxResourcesMemoryKernelTCP(kernelTCP int64) {
   820  	g.initConfigLinuxResourcesMemory()
   821  	g.Config.Linux.Resources.Memory.KernelTCP = &kernelTCP
   822  }
   823  
   824  // SetLinuxResourcesMemorySwappiness sets g.Config.Linux.Resources.Memory.Swappiness.
   825  func (g *Generator) SetLinuxResourcesMemorySwappiness(swappiness uint64) {
   826  	g.initConfigLinuxResourcesMemory()
   827  	g.Config.Linux.Resources.Memory.Swappiness = &swappiness
   828  }
   829  
   830  // SetLinuxResourcesMemoryDisableOOMKiller sets g.Config.Linux.Resources.Memory.DisableOOMKiller.
   831  func (g *Generator) SetLinuxResourcesMemoryDisableOOMKiller(disable bool) {
   832  	g.initConfigLinuxResourcesMemory()
   833  	g.Config.Linux.Resources.Memory.DisableOOMKiller = &disable
   834  }
   835  
   836  // SetLinuxResourcesNetworkClassID sets g.Config.Linux.Resources.Network.ClassID.
   837  func (g *Generator) SetLinuxResourcesNetworkClassID(classid uint32) {
   838  	g.initConfigLinuxResourcesNetwork()
   839  	g.Config.Linux.Resources.Network.ClassID = &classid
   840  }
   841  
   842  // AddLinuxResourcesNetworkPriorities adds or sets g.Config.Linux.Resources.Network.Priorities.
   843  func (g *Generator) AddLinuxResourcesNetworkPriorities(name string, prio uint32) {
   844  	g.initConfigLinuxResourcesNetwork()
   845  	for i, netPriority := range g.Config.Linux.Resources.Network.Priorities {
   846  		if netPriority.Name == name {
   847  			g.Config.Linux.Resources.Network.Priorities[i].Priority = prio
   848  			return
   849  		}
   850  	}
   851  	interfacePrio := new(rspec.LinuxInterfacePriority)
   852  	interfacePrio.Name = name
   853  	interfacePrio.Priority = prio
   854  	g.Config.Linux.Resources.Network.Priorities = append(g.Config.Linux.Resources.Network.Priorities, *interfacePrio)
   855  }
   856  
   857  // DropLinuxResourcesNetworkPriorities drops one item from g.Config.Linux.Resources.Network.Priorities.
   858  func (g *Generator) DropLinuxResourcesNetworkPriorities(name string) {
   859  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.Network == nil {
   860  		return
   861  	}
   862  
   863  	for i, netPriority := range g.Config.Linux.Resources.Network.Priorities {
   864  		if netPriority.Name == name {
   865  			g.Config.Linux.Resources.Network.Priorities = append(g.Config.Linux.Resources.Network.Priorities[:i], g.Config.Linux.Resources.Network.Priorities[i+1:]...)
   866  			return
   867  		}
   868  	}
   869  }
   870  
   871  // SetLinuxResourcesPidsLimit sets g.Config.Linux.Resources.Pids.Limit.
   872  func (g *Generator) SetLinuxResourcesPidsLimit(limit int64) {
   873  	g.initConfigLinuxResourcesPids()
   874  	g.Config.Linux.Resources.Pids.Limit = limit
   875  }
   876  
   877  // ClearLinuxSysctl clears g.Config.Linux.Sysctl.
   878  func (g *Generator) ClearLinuxSysctl() {
   879  	if g.Config == nil || g.Config.Linux == nil {
   880  		return
   881  	}
   882  	g.Config.Linux.Sysctl = make(map[string]string)
   883  }
   884  
   885  // AddLinuxSysctl adds a new sysctl config into g.Config.Linux.Sysctl.
   886  func (g *Generator) AddLinuxSysctl(key, value string) {
   887  	g.initConfigLinuxSysctl()
   888  	g.Config.Linux.Sysctl[key] = value
   889  }
   890  
   891  // RemoveLinuxSysctl removes a sysctl config from g.Config.Linux.Sysctl.
   892  func (g *Generator) RemoveLinuxSysctl(key string) {
   893  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Sysctl == nil {
   894  		return
   895  	}
   896  	delete(g.Config.Linux.Sysctl, key)
   897  }
   898  
   899  // ClearLinuxUIDMappings clear g.Config.Linux.UIDMappings.
   900  func (g *Generator) ClearLinuxUIDMappings() {
   901  	if g.Config == nil || g.Config.Linux == nil {
   902  		return
   903  	}
   904  	g.Config.Linux.UIDMappings = []rspec.LinuxIDMapping{}
   905  }
   906  
   907  // AddLinuxUIDMapping adds uidMap into g.Config.Linux.UIDMappings.
   908  func (g *Generator) AddLinuxUIDMapping(hid, cid, size uint32) {
   909  	idMapping := rspec.LinuxIDMapping{
   910  		HostID:      hid,
   911  		ContainerID: cid,
   912  		Size:        size,
   913  	}
   914  
   915  	g.initConfigLinux()
   916  	g.Config.Linux.UIDMappings = append(g.Config.Linux.UIDMappings, idMapping)
   917  }
   918  
   919  // ClearLinuxGIDMappings clear g.Config.Linux.GIDMappings.
   920  func (g *Generator) ClearLinuxGIDMappings() {
   921  	if g.Config == nil || g.Config.Linux == nil {
   922  		return
   923  	}
   924  	g.Config.Linux.GIDMappings = []rspec.LinuxIDMapping{}
   925  }
   926  
   927  // AddLinuxGIDMapping adds gidMap into g.Config.Linux.GIDMappings.
   928  func (g *Generator) AddLinuxGIDMapping(hid, cid, size uint32) {
   929  	idMapping := rspec.LinuxIDMapping{
   930  		HostID:      hid,
   931  		ContainerID: cid,
   932  		Size:        size,
   933  	}
   934  
   935  	g.initConfigLinux()
   936  	g.Config.Linux.GIDMappings = append(g.Config.Linux.GIDMappings, idMapping)
   937  }
   938  
   939  // SetLinuxRootPropagation sets g.Config.Linux.RootfsPropagation.
   940  func (g *Generator) SetLinuxRootPropagation(rp string) error {
   941  	switch rp {
   942  	case "":
   943  	case "private":
   944  	case "rprivate":
   945  	case "slave":
   946  	case "rslave":
   947  	case "shared":
   948  	case "rshared":
   949  	case "unbindable":
   950  	case "runbindable":
   951  	default:
   952  		return fmt.Errorf("rootfs-propagation %q must be empty or one of (r)private|(r)slave|(r)shared|(r)unbindable", rp)
   953  	}
   954  	g.initConfigLinux()
   955  	g.Config.Linux.RootfsPropagation = rp
   956  	return nil
   957  }
   958  
   959  // ClearPreStartHooks clear g.Config.Hooks.Prestart.
   960  func (g *Generator) ClearPreStartHooks() {
   961  	if g.Config == nil || g.Config.Hooks == nil {
   962  		return
   963  	}
   964  	g.Config.Hooks.Prestart = []rspec.Hook{}
   965  }
   966  
   967  // AddPreStartHook add a prestart hook into g.Config.Hooks.Prestart.
   968  func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) error {
   969  	g.initConfigHooks()
   970  	g.Config.Hooks.Prestart = append(g.Config.Hooks.Prestart, preStartHook)
   971  	return nil
   972  }
   973  
   974  // ClearPostStopHooks clear g.Config.Hooks.Poststop.
   975  func (g *Generator) ClearPostStopHooks() {
   976  	if g.Config == nil || g.Config.Hooks == nil {
   977  		return
   978  	}
   979  	g.Config.Hooks.Poststop = []rspec.Hook{}
   980  }
   981  
   982  // AddPostStopHook adds a poststop hook into g.Config.Hooks.Poststop.
   983  func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) error {
   984  	g.initConfigHooks()
   985  	g.Config.Hooks.Poststop = append(g.Config.Hooks.Poststop, postStopHook)
   986  	return nil
   987  }
   988  
   989  // ClearPostStartHooks clear g.Config.Hooks.Poststart.
   990  func (g *Generator) ClearPostStartHooks() {
   991  	if g.Config == nil || g.Config.Hooks == nil {
   992  		return
   993  	}
   994  	g.Config.Hooks.Poststart = []rspec.Hook{}
   995  }
   996  
   997  // AddPostStartHook adds a poststart hook into g.Config.Hooks.Poststart.
   998  func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) error {
   999  	g.initConfigHooks()
  1000  	g.Config.Hooks.Poststart = append(g.Config.Hooks.Poststart, postStartHook)
  1001  	return nil
  1002  }
  1003  
  1004  // AddMount adds a mount into g.Config.Mounts.
  1005  func (g *Generator) AddMount(mnt rspec.Mount) {
  1006  	g.initConfig()
  1007  
  1008  	g.Config.Mounts = append(g.Config.Mounts, mnt)
  1009  }
  1010  
  1011  // RemoveMount removes a mount point on the dest directory
  1012  func (g *Generator) RemoveMount(dest string) {
  1013  	g.initConfig()
  1014  
  1015  	for index, mount := range g.Config.Mounts {
  1016  		if mount.Destination == dest {
  1017  			g.Config.Mounts = append(g.Config.Mounts[:index], g.Config.Mounts[index+1:]...)
  1018  			return
  1019  		}
  1020  	}
  1021  }
  1022  
  1023  // Mounts returns the list of mounts
  1024  func (g *Generator) Mounts() []rspec.Mount {
  1025  	g.initConfig()
  1026  
  1027  	return g.Config.Mounts
  1028  }
  1029  
  1030  // ClearMounts clear g.Config.Mounts
  1031  func (g *Generator) ClearMounts() {
  1032  	if g.Config == nil {
  1033  		return
  1034  	}
  1035  	g.Config.Mounts = []rspec.Mount{}
  1036  }
  1037  
  1038  // SetupPrivileged sets up the privilege-related fields inside g.Config.
  1039  func (g *Generator) SetupPrivileged(privileged bool) {
  1040  	if privileged { // Add all capabilities in privileged mode.
  1041  		var finalCapList []string
  1042  		for _, cap := range capability.List() {
  1043  			if g.HostSpecific && cap > validate.LastCap() {
  1044  				continue
  1045  			}
  1046  			finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())))
  1047  		}
  1048  		g.initConfigLinux()
  1049  		g.initConfigProcessCapabilities()
  1050  		g.ClearProcessCapabilities()
  1051  		g.Config.Process.Capabilities.Bounding = append(g.Config.Process.Capabilities.Bounding, finalCapList...)
  1052  		g.Config.Process.Capabilities.Effective = append(g.Config.Process.Capabilities.Effective, finalCapList...)
  1053  		g.Config.Process.Capabilities.Inheritable = append(g.Config.Process.Capabilities.Inheritable, finalCapList...)
  1054  		g.Config.Process.Capabilities.Permitted = append(g.Config.Process.Capabilities.Permitted, finalCapList...)
  1055  		g.Config.Process.Capabilities.Ambient = append(g.Config.Process.Capabilities.Ambient, finalCapList...)
  1056  		g.Config.Process.SelinuxLabel = ""
  1057  		g.Config.Process.ApparmorProfile = ""
  1058  		g.Config.Linux.Seccomp = nil
  1059  	}
  1060  }
  1061  
  1062  // ClearProcessCapabilities clear g.Config.Process.Capabilities.
  1063  func (g *Generator) ClearProcessCapabilities() {
  1064  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1065  		return
  1066  	}
  1067  	g.Config.Process.Capabilities.Bounding = []string{}
  1068  	g.Config.Process.Capabilities.Effective = []string{}
  1069  	g.Config.Process.Capabilities.Inheritable = []string{}
  1070  	g.Config.Process.Capabilities.Permitted = []string{}
  1071  	g.Config.Process.Capabilities.Ambient = []string{}
  1072  }
  1073  
  1074  // AddProcessCapability adds a process capability into all 5 capability sets.
  1075  func (g *Generator) AddProcessCapability(c string) error {
  1076  	cp := strings.ToUpper(c)
  1077  	if err := validate.CapValid(cp, g.HostSpecific); err != nil {
  1078  		return err
  1079  	}
  1080  
  1081  	g.initConfigProcessCapabilities()
  1082  
  1083  	var foundAmbient, foundBounding, foundEffective, foundInheritable, foundPermitted bool
  1084  	for _, cap := range g.Config.Process.Capabilities.Ambient {
  1085  		if strings.ToUpper(cap) == cp {
  1086  			foundAmbient = true
  1087  			break
  1088  		}
  1089  	}
  1090  	if !foundAmbient {
  1091  		g.Config.Process.Capabilities.Ambient = append(g.Config.Process.Capabilities.Ambient, cp)
  1092  	}
  1093  
  1094  	for _, cap := range g.Config.Process.Capabilities.Bounding {
  1095  		if strings.ToUpper(cap) == cp {
  1096  			foundBounding = true
  1097  			break
  1098  		}
  1099  	}
  1100  	if !foundBounding {
  1101  		g.Config.Process.Capabilities.Bounding = append(g.Config.Process.Capabilities.Bounding, cp)
  1102  	}
  1103  
  1104  	for _, cap := range g.Config.Process.Capabilities.Effective {
  1105  		if strings.ToUpper(cap) == cp {
  1106  			foundEffective = true
  1107  			break
  1108  		}
  1109  	}
  1110  	if !foundEffective {
  1111  		g.Config.Process.Capabilities.Effective = append(g.Config.Process.Capabilities.Effective, cp)
  1112  	}
  1113  
  1114  	for _, cap := range g.Config.Process.Capabilities.Inheritable {
  1115  		if strings.ToUpper(cap) == cp {
  1116  			foundInheritable = true
  1117  			break
  1118  		}
  1119  	}
  1120  	if !foundInheritable {
  1121  		g.Config.Process.Capabilities.Inheritable = append(g.Config.Process.Capabilities.Inheritable, cp)
  1122  	}
  1123  
  1124  	for _, cap := range g.Config.Process.Capabilities.Permitted {
  1125  		if strings.ToUpper(cap) == cp {
  1126  			foundPermitted = true
  1127  			break
  1128  		}
  1129  	}
  1130  	if !foundPermitted {
  1131  		g.Config.Process.Capabilities.Permitted = append(g.Config.Process.Capabilities.Permitted, cp)
  1132  	}
  1133  
  1134  	return nil
  1135  }
  1136  
  1137  // AddProcessCapabilityAmbient adds a process capability into g.Config.Process.Capabilities.Ambient.
  1138  func (g *Generator) AddProcessCapabilityAmbient(c string) error {
  1139  	cp := strings.ToUpper(c)
  1140  	if err := validate.CapValid(cp, g.HostSpecific); err != nil {
  1141  		return err
  1142  	}
  1143  
  1144  	g.initConfigProcessCapabilities()
  1145  
  1146  	var foundAmbient bool
  1147  	for _, cap := range g.Config.Process.Capabilities.Ambient {
  1148  		if strings.ToUpper(cap) == cp {
  1149  			foundAmbient = true
  1150  			break
  1151  		}
  1152  	}
  1153  
  1154  	if !foundAmbient {
  1155  		g.Config.Process.Capabilities.Ambient = append(g.Config.Process.Capabilities.Ambient, cp)
  1156  	}
  1157  
  1158  	return nil
  1159  }
  1160  
  1161  // AddProcessCapabilityBounding adds a process capability into g.Config.Process.Capabilities.Bounding.
  1162  func (g *Generator) AddProcessCapabilityBounding(c string) error {
  1163  	cp := strings.ToUpper(c)
  1164  	if err := validate.CapValid(cp, g.HostSpecific); err != nil {
  1165  		return err
  1166  	}
  1167  
  1168  	g.initConfigProcessCapabilities()
  1169  
  1170  	var foundBounding bool
  1171  	for _, cap := range g.Config.Process.Capabilities.Bounding {
  1172  		if strings.ToUpper(cap) == cp {
  1173  			foundBounding = true
  1174  			break
  1175  		}
  1176  	}
  1177  	if !foundBounding {
  1178  		g.Config.Process.Capabilities.Bounding = append(g.Config.Process.Capabilities.Bounding, cp)
  1179  	}
  1180  
  1181  	return nil
  1182  }
  1183  
  1184  // AddProcessCapabilityEffective adds a process capability into g.Config.Process.Capabilities.Effective.
  1185  func (g *Generator) AddProcessCapabilityEffective(c string) error {
  1186  	cp := strings.ToUpper(c)
  1187  	if err := validate.CapValid(cp, g.HostSpecific); err != nil {
  1188  		return err
  1189  	}
  1190  
  1191  	g.initConfigProcessCapabilities()
  1192  
  1193  	var foundEffective bool
  1194  	for _, cap := range g.Config.Process.Capabilities.Effective {
  1195  		if strings.ToUpper(cap) == cp {
  1196  			foundEffective = true
  1197  			break
  1198  		}
  1199  	}
  1200  	if !foundEffective {
  1201  		g.Config.Process.Capabilities.Effective = append(g.Config.Process.Capabilities.Effective, cp)
  1202  	}
  1203  
  1204  	return nil
  1205  }
  1206  
  1207  // AddProcessCapabilityInheritable adds a process capability into g.Config.Process.Capabilities.Inheritable.
  1208  func (g *Generator) AddProcessCapabilityInheritable(c string) error {
  1209  	cp := strings.ToUpper(c)
  1210  	if err := validate.CapValid(cp, g.HostSpecific); err != nil {
  1211  		return err
  1212  	}
  1213  
  1214  	g.initConfigProcessCapabilities()
  1215  
  1216  	var foundInheritable bool
  1217  	for _, cap := range g.Config.Process.Capabilities.Inheritable {
  1218  		if strings.ToUpper(cap) == cp {
  1219  			foundInheritable = true
  1220  			break
  1221  		}
  1222  	}
  1223  	if !foundInheritable {
  1224  		g.Config.Process.Capabilities.Inheritable = append(g.Config.Process.Capabilities.Inheritable, cp)
  1225  	}
  1226  
  1227  	return nil
  1228  }
  1229  
  1230  // AddProcessCapabilityPermitted adds a process capability into g.Config.Process.Capabilities.Permitted.
  1231  func (g *Generator) AddProcessCapabilityPermitted(c string) error {
  1232  	cp := strings.ToUpper(c)
  1233  	if err := validate.CapValid(cp, g.HostSpecific); err != nil {
  1234  		return err
  1235  	}
  1236  
  1237  	g.initConfigProcessCapabilities()
  1238  
  1239  	var foundPermitted bool
  1240  	for _, cap := range g.Config.Process.Capabilities.Permitted {
  1241  		if strings.ToUpper(cap) == cp {
  1242  			foundPermitted = true
  1243  			break
  1244  		}
  1245  	}
  1246  	if !foundPermitted {
  1247  		g.Config.Process.Capabilities.Permitted = append(g.Config.Process.Capabilities.Permitted, cp)
  1248  	}
  1249  
  1250  	return nil
  1251  }
  1252  
  1253  // DropProcessCapability drops a process capability from all 5 capability sets.
  1254  func (g *Generator) DropProcessCapability(c string) error {
  1255  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1256  		return nil
  1257  	}
  1258  
  1259  	cp := strings.ToUpper(c)
  1260  	for i, cap := range g.Config.Process.Capabilities.Ambient {
  1261  		if strings.ToUpper(cap) == cp {
  1262  			g.Config.Process.Capabilities.Ambient = removeFunc(g.Config.Process.Capabilities.Ambient, i)
  1263  		}
  1264  	}
  1265  	for i, cap := range g.Config.Process.Capabilities.Bounding {
  1266  		if strings.ToUpper(cap) == cp {
  1267  			g.Config.Process.Capabilities.Bounding = removeFunc(g.Config.Process.Capabilities.Bounding, i)
  1268  		}
  1269  	}
  1270  	for i, cap := range g.Config.Process.Capabilities.Effective {
  1271  		if strings.ToUpper(cap) == cp {
  1272  			g.Config.Process.Capabilities.Effective = removeFunc(g.Config.Process.Capabilities.Effective, i)
  1273  		}
  1274  	}
  1275  	for i, cap := range g.Config.Process.Capabilities.Inheritable {
  1276  		if strings.ToUpper(cap) == cp {
  1277  			g.Config.Process.Capabilities.Inheritable = removeFunc(g.Config.Process.Capabilities.Inheritable, i)
  1278  		}
  1279  	}
  1280  	for i, cap := range g.Config.Process.Capabilities.Permitted {
  1281  		if strings.ToUpper(cap) == cp {
  1282  			g.Config.Process.Capabilities.Permitted = removeFunc(g.Config.Process.Capabilities.Permitted, i)
  1283  		}
  1284  	}
  1285  
  1286  	return validate.CapValid(cp, false)
  1287  }
  1288  
  1289  // DropProcessCapabilityAmbient drops a process capability from g.Config.Process.Capabilities.Ambient.
  1290  func (g *Generator) DropProcessCapabilityAmbient(c string) error {
  1291  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1292  		return nil
  1293  	}
  1294  
  1295  	cp := strings.ToUpper(c)
  1296  	for i, cap := range g.Config.Process.Capabilities.Ambient {
  1297  		if strings.ToUpper(cap) == cp {
  1298  			g.Config.Process.Capabilities.Ambient = removeFunc(g.Config.Process.Capabilities.Ambient, i)
  1299  		}
  1300  	}
  1301  
  1302  	return validate.CapValid(cp, false)
  1303  }
  1304  
  1305  // DropProcessCapabilityBounding drops a process capability from g.Config.Process.Capabilities.Bounding.
  1306  func (g *Generator) DropProcessCapabilityBounding(c string) error {
  1307  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1308  		return nil
  1309  	}
  1310  
  1311  	cp := strings.ToUpper(c)
  1312  	for i, cap := range g.Config.Process.Capabilities.Bounding {
  1313  		if strings.ToUpper(cap) == cp {
  1314  			g.Config.Process.Capabilities.Bounding = removeFunc(g.Config.Process.Capabilities.Bounding, i)
  1315  		}
  1316  	}
  1317  
  1318  	return validate.CapValid(cp, false)
  1319  }
  1320  
  1321  // DropProcessCapabilityEffective drops a process capability from g.Config.Process.Capabilities.Effective.
  1322  func (g *Generator) DropProcessCapabilityEffective(c string) error {
  1323  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1324  		return nil
  1325  	}
  1326  
  1327  	cp := strings.ToUpper(c)
  1328  	for i, cap := range g.Config.Process.Capabilities.Effective {
  1329  		if strings.ToUpper(cap) == cp {
  1330  			g.Config.Process.Capabilities.Effective = removeFunc(g.Config.Process.Capabilities.Effective, i)
  1331  		}
  1332  	}
  1333  
  1334  	return validate.CapValid(cp, false)
  1335  }
  1336  
  1337  // DropProcessCapabilityInheritable drops a process capability from g.Config.Process.Capabilities.Inheritable.
  1338  func (g *Generator) DropProcessCapabilityInheritable(c string) error {
  1339  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1340  		return nil
  1341  	}
  1342  
  1343  	cp := strings.ToUpper(c)
  1344  	for i, cap := range g.Config.Process.Capabilities.Inheritable {
  1345  		if strings.ToUpper(cap) == cp {
  1346  			g.Config.Process.Capabilities.Inheritable = removeFunc(g.Config.Process.Capabilities.Inheritable, i)
  1347  		}
  1348  	}
  1349  
  1350  	return validate.CapValid(cp, false)
  1351  }
  1352  
  1353  // DropProcessCapabilityPermitted drops a process capability from g.Config.Process.Capabilities.Permitted.
  1354  func (g *Generator) DropProcessCapabilityPermitted(c string) error {
  1355  	if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil {
  1356  		return nil
  1357  	}
  1358  
  1359  	cp := strings.ToUpper(c)
  1360  	for i, cap := range g.Config.Process.Capabilities.Permitted {
  1361  		if strings.ToUpper(cap) == cp {
  1362  			g.Config.Process.Capabilities.Permitted = removeFunc(g.Config.Process.Capabilities.Permitted, i)
  1363  		}
  1364  	}
  1365  
  1366  	return validate.CapValid(cp, false)
  1367  }
  1368  
  1369  func mapStrToNamespace(ns string, path string) (rspec.LinuxNamespace, error) {
  1370  	switch ns {
  1371  	case "network":
  1372  		return rspec.LinuxNamespace{Type: rspec.NetworkNamespace, Path: path}, nil
  1373  	case "pid":
  1374  		return rspec.LinuxNamespace{Type: rspec.PIDNamespace, Path: path}, nil
  1375  	case "mount":
  1376  		return rspec.LinuxNamespace{Type: rspec.MountNamespace, Path: path}, nil
  1377  	case "ipc":
  1378  		return rspec.LinuxNamespace{Type: rspec.IPCNamespace, Path: path}, nil
  1379  	case "uts":
  1380  		return rspec.LinuxNamespace{Type: rspec.UTSNamespace, Path: path}, nil
  1381  	case "user":
  1382  		return rspec.LinuxNamespace{Type: rspec.UserNamespace, Path: path}, nil
  1383  	case "cgroup":
  1384  		return rspec.LinuxNamespace{Type: rspec.CgroupNamespace, Path: path}, nil
  1385  	default:
  1386  		return rspec.LinuxNamespace{}, fmt.Errorf("unrecognized namespace %q", ns)
  1387  	}
  1388  }
  1389  
  1390  // ClearLinuxNamespaces clear g.Config.Linux.Namespaces.
  1391  func (g *Generator) ClearLinuxNamespaces() {
  1392  	if g.Config == nil || g.Config.Linux == nil {
  1393  		return
  1394  	}
  1395  	g.Config.Linux.Namespaces = []rspec.LinuxNamespace{}
  1396  }
  1397  
  1398  // AddOrReplaceLinuxNamespace adds or replaces a namespace inside
  1399  // g.Config.Linux.Namespaces.
  1400  func (g *Generator) AddOrReplaceLinuxNamespace(ns string, path string) error {
  1401  	namespace, err := mapStrToNamespace(ns, path)
  1402  	if err != nil {
  1403  		return err
  1404  	}
  1405  
  1406  	g.initConfigLinux()
  1407  	for i, ns := range g.Config.Linux.Namespaces {
  1408  		if ns.Type == namespace.Type {
  1409  			g.Config.Linux.Namespaces[i] = namespace
  1410  			return nil
  1411  		}
  1412  	}
  1413  	g.Config.Linux.Namespaces = append(g.Config.Linux.Namespaces, namespace)
  1414  	return nil
  1415  }
  1416  
  1417  // RemoveLinuxNamespace removes a namespace from g.Config.Linux.Namespaces.
  1418  func (g *Generator) RemoveLinuxNamespace(ns string) error {
  1419  	namespace, err := mapStrToNamespace(ns, "")
  1420  	if err != nil {
  1421  		return err
  1422  	}
  1423  
  1424  	if g.Config == nil || g.Config.Linux == nil {
  1425  		return nil
  1426  	}
  1427  	for i, ns := range g.Config.Linux.Namespaces {
  1428  		if ns.Type == namespace.Type {
  1429  			g.Config.Linux.Namespaces = append(g.Config.Linux.Namespaces[:i], g.Config.Linux.Namespaces[i+1:]...)
  1430  			return nil
  1431  		}
  1432  	}
  1433  	return nil
  1434  }
  1435  
  1436  // AddDevice - add a device into g.Config.Linux.Devices
  1437  func (g *Generator) AddDevice(device rspec.LinuxDevice) {
  1438  	g.initConfigLinux()
  1439  
  1440  	for i, dev := range g.Config.Linux.Devices {
  1441  		if dev.Path == device.Path {
  1442  			g.Config.Linux.Devices[i] = device
  1443  			return
  1444  		}
  1445  		if dev.Type == device.Type && dev.Major == device.Major && dev.Minor == device.Minor {
  1446  			fmt.Fprintln(os.Stderr, "WARNING: The same type, major and minor should not be used for multiple devices.")
  1447  		}
  1448  	}
  1449  
  1450  	g.Config.Linux.Devices = append(g.Config.Linux.Devices, device)
  1451  }
  1452  
  1453  // RemoveDevice remove a device from g.Config.Linux.Devices
  1454  func (g *Generator) RemoveDevice(path string) {
  1455  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Devices == nil {
  1456  		return
  1457  	}
  1458  
  1459  	for i, device := range g.Config.Linux.Devices {
  1460  		if device.Path == path {
  1461  			g.Config.Linux.Devices = append(g.Config.Linux.Devices[:i], g.Config.Linux.Devices[i+1:]...)
  1462  			return
  1463  		}
  1464  	}
  1465  }
  1466  
  1467  // ClearLinuxDevices clears g.Config.Linux.Devices
  1468  func (g *Generator) ClearLinuxDevices() {
  1469  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Devices == nil {
  1470  		return
  1471  	}
  1472  
  1473  	g.Config.Linux.Devices = []rspec.LinuxDevice{}
  1474  }
  1475  
  1476  // AddLinuxResourcesDevice - add a device into g.Config.Linux.Resources.Devices
  1477  func (g *Generator) AddLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) {
  1478  	g.initConfigLinuxResources()
  1479  
  1480  	device := rspec.LinuxDeviceCgroup{
  1481  		Allow:  allow,
  1482  		Type:   devType,
  1483  		Access: access,
  1484  		Major:  major,
  1485  		Minor:  minor,
  1486  	}
  1487  	g.Config.Linux.Resources.Devices = append(g.Config.Linux.Resources.Devices, device)
  1488  }
  1489  
  1490  // RemoveLinuxResourcesDevice - remove a device from g.Config.Linux.Resources.Devices
  1491  func (g *Generator) RemoveLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) {
  1492  	if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil {
  1493  		return
  1494  	}
  1495  	for i, device := range g.Config.Linux.Resources.Devices {
  1496  		if device.Allow == allow &&
  1497  			(devType == device.Type || (devType != "" && device.Type != "" && devType == device.Type)) &&
  1498  			(access == device.Access || (access != "" && device.Access != "" && access == device.Access)) &&
  1499  			(major == device.Major || (major != nil && device.Major != nil && *major == *device.Major)) &&
  1500  			(minor == device.Minor || (minor != nil && device.Minor != nil && *minor == *device.Minor)) {
  1501  
  1502  			g.Config.Linux.Resources.Devices = append(g.Config.Linux.Resources.Devices[:i], g.Config.Linux.Resources.Devices[i+1:]...)
  1503  			return
  1504  		}
  1505  	}
  1506  	return
  1507  }
  1508  
  1509  // strPtr returns the pointer pointing to the string s.
  1510  func strPtr(s string) *string { return &s }
  1511  
  1512  // SetSyscallAction adds rules for syscalls with the specified action
  1513  func (g *Generator) SetSyscallAction(arguments seccomp.SyscallOpts) error {
  1514  	g.initConfigLinuxSeccomp()
  1515  	return seccomp.ParseSyscallFlag(arguments, g.Config.Linux.Seccomp)
  1516  }
  1517  
  1518  // SetDefaultSeccompAction sets the default action for all syscalls not defined
  1519  // and then removes any syscall rules with this action already specified.
  1520  func (g *Generator) SetDefaultSeccompAction(action string) error {
  1521  	g.initConfigLinuxSeccomp()
  1522  	return seccomp.ParseDefaultAction(action, g.Config.Linux.Seccomp)
  1523  }
  1524  
  1525  // SetDefaultSeccompActionForce only sets the default action for all syscalls not defined
  1526  func (g *Generator) SetDefaultSeccompActionForce(action string) error {
  1527  	g.initConfigLinuxSeccomp()
  1528  	return seccomp.ParseDefaultActionForce(action, g.Config.Linux.Seccomp)
  1529  }
  1530  
  1531  // SetSeccompArchitecture sets the supported seccomp architectures
  1532  func (g *Generator) SetSeccompArchitecture(architecture string) error {
  1533  	g.initConfigLinuxSeccomp()
  1534  	return seccomp.ParseArchitectureFlag(architecture, g.Config.Linux.Seccomp)
  1535  }
  1536  
  1537  // RemoveSeccompRule removes rules for any specified syscalls
  1538  func (g *Generator) RemoveSeccompRule(arguments string) error {
  1539  	g.initConfigLinuxSeccomp()
  1540  	return seccomp.RemoveAction(arguments, g.Config.Linux.Seccomp)
  1541  }
  1542  
  1543  // RemoveAllSeccompRules removes all syscall rules
  1544  func (g *Generator) RemoveAllSeccompRules() error {
  1545  	g.initConfigLinuxSeccomp()
  1546  	return seccomp.RemoveAllSeccompRules(g.Config.Linux.Seccomp)
  1547  }
  1548  
  1549  // AddLinuxMaskedPaths adds masked paths into g.Config.Linux.MaskedPaths.
  1550  func (g *Generator) AddLinuxMaskedPaths(path string) {
  1551  	g.initConfigLinux()
  1552  	g.Config.Linux.MaskedPaths = append(g.Config.Linux.MaskedPaths, path)
  1553  }
  1554  
  1555  // AddLinuxReadonlyPaths adds readonly paths into g.Config.Linux.MaskedPaths.
  1556  func (g *Generator) AddLinuxReadonlyPaths(path string) {
  1557  	g.initConfigLinux()
  1558  	g.Config.Linux.ReadonlyPaths = append(g.Config.Linux.ReadonlyPaths, path)
  1559  }
  1560  
  1561  func addOrReplaceBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64, rate uint64) []rspec.LinuxThrottleDevice {
  1562  	throttleDevices := tmpList
  1563  	for i, throttleDevice := range throttleDevices {
  1564  		if throttleDevice.Major == major && throttleDevice.Minor == minor {
  1565  			throttleDevices[i].Rate = rate
  1566  			return throttleDevices
  1567  		}
  1568  	}
  1569  	throttleDevice := new(rspec.LinuxThrottleDevice)
  1570  	throttleDevice.Major = major
  1571  	throttleDevice.Minor = minor
  1572  	throttleDevice.Rate = rate
  1573  	throttleDevices = append(throttleDevices, *throttleDevice)
  1574  
  1575  	return throttleDevices
  1576  }
  1577  
  1578  func dropBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64) []rspec.LinuxThrottleDevice {
  1579  	throttleDevices := tmpList
  1580  	for i, throttleDevice := range throttleDevices {
  1581  		if throttleDevice.Major == major && throttleDevice.Minor == minor {
  1582  			throttleDevices = append(throttleDevices[:i], throttleDevices[i+1:]...)
  1583  			return throttleDevices
  1584  		}
  1585  	}
  1586  
  1587  	return throttleDevices
  1588  }
  1589  
  1590  // AddSolarisAnet adds network into g.Config.Solaris.Anet
  1591  func (g *Generator) AddSolarisAnet(anet rspec.SolarisAnet) {
  1592  	g.initConfigSolaris()
  1593  	g.Config.Solaris.Anet = append(g.Config.Solaris.Anet, anet)
  1594  }
  1595  
  1596  // SetSolarisCappedCPUNcpus sets g.Config.Solaris.CappedCPU.Ncpus
  1597  func (g *Generator) SetSolarisCappedCPUNcpus(ncpus string) {
  1598  	g.initConfigSolarisCappedCPU()
  1599  	g.Config.Solaris.CappedCPU.Ncpus = ncpus
  1600  }
  1601  
  1602  // SetSolarisCappedMemoryPhysical sets g.Config.Solaris.CappedMemory.Physical
  1603  func (g *Generator) SetSolarisCappedMemoryPhysical(physical string) {
  1604  	g.initConfigSolarisCappedMemory()
  1605  	g.Config.Solaris.CappedMemory.Physical = physical
  1606  }
  1607  
  1608  // SetSolarisCappedMemorySwap sets g.Config.Solaris.CappedMemory.Swap
  1609  func (g *Generator) SetSolarisCappedMemorySwap(swap string) {
  1610  	g.initConfigSolarisCappedMemory()
  1611  	g.Config.Solaris.CappedMemory.Swap = swap
  1612  }
  1613  
  1614  // SetSolarisLimitPriv sets g.Config.Solaris.LimitPriv
  1615  func (g *Generator) SetSolarisLimitPriv(limitPriv string) {
  1616  	g.initConfigSolaris()
  1617  	g.Config.Solaris.LimitPriv = limitPriv
  1618  }
  1619  
  1620  // SetSolarisMaxShmMemory sets g.Config.Solaris.MaxShmMemory
  1621  func (g *Generator) SetSolarisMaxShmMemory(memory string) {
  1622  	g.initConfigSolaris()
  1623  	g.Config.Solaris.MaxShmMemory = memory
  1624  }
  1625  
  1626  // SetSolarisMilestone sets g.Config.Solaris.Milestone
  1627  func (g *Generator) SetSolarisMilestone(milestone string) {
  1628  	g.initConfigSolaris()
  1629  	g.Config.Solaris.Milestone = milestone
  1630  }
  1631  
  1632  // SetVMHypervisorPath sets g.Config.VM.Hypervisor.Path
  1633  func (g *Generator) SetVMHypervisorPath(path string) error {
  1634  	if !strings.HasPrefix(path, "/") {
  1635  		return fmt.Errorf("hypervisorPath %v is not an absolute path", path)
  1636  	}
  1637  	g.initConfigVMHypervisor()
  1638  	g.Config.VM.Hypervisor.Path = path
  1639  	return nil
  1640  }
  1641  
  1642  // SetVMHypervisorParameters sets g.Config.VM.Hypervisor.Parameters
  1643  func (g *Generator) SetVMHypervisorParameters(parameters []string) {
  1644  	g.initConfigVMHypervisor()
  1645  	g.Config.VM.Hypervisor.Parameters = parameters
  1646  }
  1647  
  1648  // SetVMKernelPath sets g.Config.VM.Kernel.Path
  1649  func (g *Generator) SetVMKernelPath(path string) error {
  1650  	if !strings.HasPrefix(path, "/") {
  1651  		return fmt.Errorf("kernelPath %v is not an absolute path", path)
  1652  	}
  1653  	g.initConfigVMKernel()
  1654  	g.Config.VM.Kernel.Path = path
  1655  	return nil
  1656  }
  1657  
  1658  // SetVMKernelParameters sets g.Config.VM.Kernel.Parameters
  1659  func (g *Generator) SetVMKernelParameters(parameters []string) {
  1660  	g.initConfigVMKernel()
  1661  	g.Config.VM.Kernel.Parameters = parameters
  1662  }
  1663  
  1664  // SetVMKernelInitRD sets g.Config.VM.Kernel.InitRD
  1665  func (g *Generator) SetVMKernelInitRD(initrd string) error {
  1666  	if !strings.HasPrefix(initrd, "/") {
  1667  		return fmt.Errorf("kernelInitrd %v is not an absolute path", initrd)
  1668  	}
  1669  	g.initConfigVMKernel()
  1670  	g.Config.VM.Kernel.InitRD = initrd
  1671  	return nil
  1672  }
  1673  
  1674  // SetVMImagePath sets g.Config.VM.Image.Path
  1675  func (g *Generator) SetVMImagePath(path string) error {
  1676  	if !strings.HasPrefix(path, "/") {
  1677  		return fmt.Errorf("imagePath %v is not an absolute path", path)
  1678  	}
  1679  	g.initConfigVMImage()
  1680  	g.Config.VM.Image.Path = path
  1681  	return nil
  1682  }
  1683  
  1684  // SetVMImageFormat sets g.Config.VM.Image.Format
  1685  func (g *Generator) SetVMImageFormat(format string) error {
  1686  	switch format {
  1687  	case "raw":
  1688  	case "qcow2":
  1689  	case "vdi":
  1690  	case "vmdk":
  1691  	case "vhd":
  1692  	default:
  1693  		return fmt.Errorf("Commonly supported formats are: raw, qcow2, vdi, vmdk, vhd")
  1694  	}
  1695  	g.initConfigVMImage()
  1696  	g.Config.VM.Image.Format = format
  1697  	return nil
  1698  }
  1699  
  1700  // SetWindowsHypervUntilityVMPath sets g.Config.Windows.HyperV.UtilityVMPath.
  1701  func (g *Generator) SetWindowsHypervUntilityVMPath(path string) {
  1702  	g.initConfigWindowsHyperV()
  1703  	g.Config.Windows.HyperV.UtilityVMPath = path
  1704  }
  1705  
  1706  // SetWindowsIgnoreFlushesDuringBoot sets g.Config.Windows.IgnoreFlushesDuringBoot.
  1707  func (g *Generator) SetWindowsIgnoreFlushesDuringBoot(ignore bool) {
  1708  	g.initConfigWindows()
  1709  	g.Config.Windows.IgnoreFlushesDuringBoot = ignore
  1710  }
  1711  
  1712  // AddWindowsLayerFolders adds layer folders into  g.Config.Windows.LayerFolders.
  1713  func (g *Generator) AddWindowsLayerFolders(folder string) {
  1714  	g.initConfigWindows()
  1715  	g.Config.Windows.LayerFolders = append(g.Config.Windows.LayerFolders, folder)
  1716  }
  1717  
  1718  // AddWindowsDevices adds or sets g.Config.Windwos.Devices
  1719  func (g *Generator) AddWindowsDevices(id, idType string) error {
  1720  	if idType != "class" {
  1721  		return fmt.Errorf("Invalid idType value: %s. Windows only supports a value of class", idType)
  1722  	}
  1723  	device := rspec.WindowsDevice{
  1724  		ID:     id,
  1725  		IDType: idType,
  1726  	}
  1727  
  1728  	g.initConfigWindows()
  1729  	for i, device := range g.Config.Windows.Devices {
  1730  		if device.ID == id {
  1731  			g.Config.Windows.Devices[i].IDType = idType
  1732  			return nil
  1733  		}
  1734  	}
  1735  	g.Config.Windows.Devices = append(g.Config.Windows.Devices, device)
  1736  	return nil
  1737  }
  1738  
  1739  // SetWindowsNetwork sets g.Config.Windows.Network.
  1740  func (g *Generator) SetWindowsNetwork(network rspec.WindowsNetwork) {
  1741  	g.initConfigWindows()
  1742  	g.Config.Windows.Network = &network
  1743  }
  1744  
  1745  // SetWindowsNetworkAllowUnqualifiedDNSQuery sets g.Config.Windows.Network.AllowUnqualifiedDNSQuery
  1746  func (g *Generator) SetWindowsNetworkAllowUnqualifiedDNSQuery(setting bool) {
  1747  	g.initConfigWindowsNetwork()
  1748  	g.Config.Windows.Network.AllowUnqualifiedDNSQuery = setting
  1749  }
  1750  
  1751  // SetWindowsNetworkNamespace sets g.Config.Windows.Network.NetworkNamespace
  1752  func (g *Generator) SetWindowsNetworkNamespace(path string) {
  1753  	g.initConfigWindowsNetwork()
  1754  	g.Config.Windows.Network.NetworkNamespace = path
  1755  }
  1756  
  1757  // SetWindowsResourcesCPU sets g.Config.Windows.Resources.CPU.
  1758  func (g *Generator) SetWindowsResourcesCPU(cpu rspec.WindowsCPUResources) {
  1759  	g.initConfigWindowsResources()
  1760  	g.Config.Windows.Resources.CPU = &cpu
  1761  }
  1762  
  1763  // SetWindowsResourcesMemoryLimit sets g.Config.Windows.Resources.Memory.Limit.
  1764  func (g *Generator) SetWindowsResourcesMemoryLimit(limit uint64) {
  1765  	g.initConfigWindowsResourcesMemory()
  1766  	g.Config.Windows.Resources.Memory.Limit = &limit
  1767  }
  1768  
  1769  // SetWindowsResourcesStorage sets g.Config.Windows.Resources.Storage.
  1770  func (g *Generator) SetWindowsResourcesStorage(storage rspec.WindowsStorageResources) {
  1771  	g.initConfigWindowsResources()
  1772  	g.Config.Windows.Resources.Storage = &storage
  1773  }
  1774  
  1775  // SetWindowsServicing sets g.Config.Windows.Servicing.
  1776  func (g *Generator) SetWindowsServicing(servicing bool) {
  1777  	g.initConfigWindows()
  1778  	g.Config.Windows.Servicing = servicing
  1779  }