github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/shared/intermediate.go (about)

     1  package shared
     2  
     3  import (
     4  	"github.com/containers/libpod/cmd/podman/cliconfig"
     5  	"github.com/sirupsen/logrus"
     6  )
     7  
     8  /*
     9  attention
    10  
    11  in this file you will see a lot of struct duplication.  this was done because people wanted a strongly typed
    12  varlink mechanism.  this resulted in us creating this intermediate layer that allows us to take the input
    13  from the cli and make an intermediate layer which can be transferred as strongly typed structures over a varlink
    14  interface.
    15  
    16  we intentionally avoided heavy use of reflection here because we were concerned about performance impacts to the
    17  non-varlink intermediate layer generation.
    18  */
    19  
    20  // GenericCLIResult describes the overall interface for dealing with
    21  // the create command cli in both local and remote uses
    22  type GenericCLIResult interface {
    23  	IsSet() bool
    24  	Name() string
    25  	Value() interface{}
    26  }
    27  
    28  // CRStringSlice describes a string slice cli struct
    29  type CRStringSlice struct {
    30  	Val []string
    31  	createResult
    32  }
    33  
    34  // CRString describes a string cli struct
    35  type CRString struct {
    36  	Val string
    37  	createResult
    38  }
    39  
    40  // CRUint64 describes a uint64 cli struct
    41  type CRUint64 struct {
    42  	Val uint64
    43  	createResult
    44  }
    45  
    46  // CRFloat64 describes a float64 cli struct
    47  type CRFloat64 struct {
    48  	Val float64
    49  	createResult
    50  }
    51  
    52  //CRBool describes a bool cli struct
    53  type CRBool struct {
    54  	Val bool
    55  	createResult
    56  }
    57  
    58  // CRInt64 describes an int64 cli struct
    59  type CRInt64 struct {
    60  	Val int64
    61  	createResult
    62  }
    63  
    64  // CRUint describes a uint cli struct
    65  type CRUint struct {
    66  	Val uint
    67  	createResult
    68  }
    69  
    70  // CRInt describes an int cli struct
    71  type CRInt struct {
    72  	Val int
    73  	createResult
    74  }
    75  
    76  // CRStringArray describes a stringarray cli struct
    77  type CRStringArray struct {
    78  	Val []string
    79  	createResult
    80  }
    81  
    82  type createResult struct {
    83  	Flag    string
    84  	Changed bool
    85  }
    86  
    87  // GenericCLIResults in the intermediate object between the cobra cli
    88  // and createconfig
    89  type GenericCLIResults struct {
    90  	results   map[string]GenericCLIResult
    91  	InputArgs []string
    92  }
    93  
    94  // IsSet returns a bool if the flag was changed
    95  func (f GenericCLIResults) IsSet(flag string) bool {
    96  	r := f.findResult(flag)
    97  	if r == nil {
    98  		return false
    99  	}
   100  	return r.IsSet()
   101  }
   102  
   103  // Value returns the value of the cli flag
   104  func (f GenericCLIResults) Value(flag string) interface{} {
   105  	r := f.findResult(flag)
   106  	if r == nil {
   107  		return ""
   108  	}
   109  	return r.Value()
   110  }
   111  
   112  func (f GenericCLIResults) findResult(flag string) GenericCLIResult {
   113  	val, ok := f.results[flag]
   114  	if ok {
   115  		return val
   116  	}
   117  	logrus.Debugf("unable to find flag %s", flag)
   118  	return nil
   119  }
   120  
   121  // Bool is a wrapper to get a bool value from GenericCLIResults
   122  func (f GenericCLIResults) Bool(flag string) bool {
   123  	r := f.findResult(flag)
   124  	if r == nil {
   125  		return false
   126  	}
   127  	return r.Value().(bool)
   128  }
   129  
   130  // String is a wrapper to get a string value from GenericCLIResults
   131  func (f GenericCLIResults) String(flag string) string {
   132  	r := f.findResult(flag)
   133  	if r == nil {
   134  		return ""
   135  	}
   136  	return r.Value().(string)
   137  }
   138  
   139  // Uint is a wrapper to get an uint value from GenericCLIResults
   140  func (f GenericCLIResults) Uint(flag string) uint {
   141  	r := f.findResult(flag)
   142  	if r == nil {
   143  		return 0
   144  	}
   145  	return r.Value().(uint)
   146  }
   147  
   148  // StringSlice is a wrapper to get a stringslice value from GenericCLIResults
   149  func (f GenericCLIResults) StringSlice(flag string) []string {
   150  	r := f.findResult(flag)
   151  	if r == nil {
   152  		return []string{}
   153  	}
   154  	return r.Value().([]string)
   155  }
   156  
   157  // StringArray is a wrapper to get a stringslice value from GenericCLIResults
   158  func (f GenericCLIResults) StringArray(flag string) []string {
   159  	r := f.findResult(flag)
   160  	if r == nil {
   161  		return []string{}
   162  	}
   163  	return r.Value().([]string)
   164  }
   165  
   166  // Uint64 is a wrapper to get an uint64 value from GenericCLIResults
   167  func (f GenericCLIResults) Uint64(flag string) uint64 {
   168  	r := f.findResult(flag)
   169  	if r == nil {
   170  		return 0
   171  	}
   172  	return r.Value().(uint64)
   173  }
   174  
   175  // Int64 is a wrapper to get an int64 value from GenericCLIResults
   176  func (f GenericCLIResults) Int64(flag string) int64 {
   177  	r := f.findResult(flag)
   178  	if r == nil {
   179  		return 0
   180  	}
   181  	return r.Value().(int64)
   182  }
   183  
   184  // Int is a wrapper to get an int value from GenericCLIResults
   185  func (f GenericCLIResults) Int(flag string) int {
   186  	r := f.findResult(flag)
   187  	if r == nil {
   188  		return 0
   189  	}
   190  	return r.Value().(int)
   191  }
   192  
   193  // Float64 is a wrapper to get an float64 value from GenericCLIResults
   194  func (f GenericCLIResults) Float64(flag string) float64 {
   195  	r := f.findResult(flag)
   196  	if r == nil {
   197  		return 0
   198  	}
   199  	return r.Value().(float64)
   200  }
   201  
   202  // Float64 is a wrapper to get an float64 value from GenericCLIResults
   203  func (f GenericCLIResults) Changed(flag string) bool {
   204  	r := f.findResult(flag)
   205  	if r == nil {
   206  		return false
   207  	}
   208  	return r.IsSet()
   209  }
   210  
   211  // IsSet ...
   212  func (c CRStringSlice) IsSet() bool { return c.Changed }
   213  
   214  // Name ...
   215  func (c CRStringSlice) Name() string { return c.Flag }
   216  
   217  // Value ...
   218  func (c CRStringSlice) Value() interface{} { return c.Val }
   219  
   220  // IsSet ...
   221  func (c CRString) IsSet() bool { return c.Changed }
   222  
   223  // Name ...
   224  func (c CRString) Name() string { return c.Flag }
   225  
   226  // Value ...
   227  func (c CRString) Value() interface{} { return c.Val }
   228  
   229  // IsSet ...
   230  func (c CRUint64) IsSet() bool { return c.Changed }
   231  
   232  // Name ...
   233  func (c CRUint64) Name() string { return c.Flag }
   234  
   235  // Value ...
   236  func (c CRUint64) Value() interface{} { return c.Val }
   237  
   238  // IsSet ...
   239  func (c CRFloat64) IsSet() bool { return c.Changed }
   240  
   241  // Name ...
   242  func (c CRFloat64) Name() string { return c.Flag }
   243  
   244  // Value ...
   245  func (c CRFloat64) Value() interface{} { return c.Val }
   246  
   247  // IsSet ...
   248  func (c CRBool) IsSet() bool { return c.Changed }
   249  
   250  // Name ...
   251  func (c CRBool) Name() string { return c.Flag }
   252  
   253  // Value ...
   254  func (c CRBool) Value() interface{} { return c.Val }
   255  
   256  // IsSet ...
   257  func (c CRInt64) IsSet() bool { return c.Changed }
   258  
   259  // Name ...
   260  func (c CRInt64) Name() string { return c.Flag }
   261  
   262  // Value ...
   263  func (c CRInt64) Value() interface{} { return c.Val }
   264  
   265  // IsSet ...
   266  func (c CRUint) IsSet() bool { return c.Changed }
   267  
   268  // Name ...
   269  func (c CRUint) Name() string { return c.Flag }
   270  
   271  // Value ...
   272  func (c CRUint) Value() interface{} { return c.Val }
   273  
   274  // IsSet ...
   275  func (c CRInt) IsSet() bool { return c.Changed }
   276  
   277  // Name ...
   278  func (c CRInt) Name() string { return c.Flag }
   279  
   280  // Value ...
   281  func (c CRInt) Value() interface{} { return c.Val }
   282  
   283  // IsSet ...
   284  func (c CRStringArray) IsSet() bool { return c.Changed }
   285  
   286  // Name ...
   287  func (c CRStringArray) Name() string { return c.Flag }
   288  
   289  // Value ...
   290  func (c CRStringArray) Value() interface{} { return c.Val }
   291  
   292  func newCreateResult(c *cliconfig.PodmanCommand, flag string) createResult {
   293  	return createResult{
   294  		Flag:    flag,
   295  		Changed: c.IsSet(flag),
   296  	}
   297  }
   298  
   299  func newCRStringSlice(c *cliconfig.PodmanCommand, flag string) CRStringSlice {
   300  	return CRStringSlice{
   301  		Val:          c.StringSlice(flag),
   302  		createResult: newCreateResult(c, flag),
   303  	}
   304  }
   305  
   306  func newCRString(c *cliconfig.PodmanCommand, flag string) CRString {
   307  	return CRString{
   308  		Val:          c.String(flag),
   309  		createResult: newCreateResult(c, flag),
   310  	}
   311  }
   312  
   313  func newCRUint64(c *cliconfig.PodmanCommand, flag string) CRUint64 {
   314  	return CRUint64{
   315  		Val:          c.Uint64(flag),
   316  		createResult: newCreateResult(c, flag),
   317  	}
   318  }
   319  
   320  func newCRFloat64(c *cliconfig.PodmanCommand, flag string) CRFloat64 {
   321  	return CRFloat64{
   322  		Val:          c.Float64(flag),
   323  		createResult: newCreateResult(c, flag),
   324  	}
   325  }
   326  
   327  func newCRBool(c *cliconfig.PodmanCommand, flag string) CRBool {
   328  	return CRBool{
   329  		Val:          c.Bool(flag),
   330  		createResult: newCreateResult(c, flag),
   331  	}
   332  }
   333  
   334  func newCRInt64(c *cliconfig.PodmanCommand, flag string) CRInt64 {
   335  	return CRInt64{
   336  		Val:          c.Int64(flag),
   337  		createResult: newCreateResult(c, flag),
   338  	}
   339  }
   340  
   341  func newCRUint(c *cliconfig.PodmanCommand, flag string) CRUint {
   342  	return CRUint{
   343  		Val:          c.Uint(flag),
   344  		createResult: newCreateResult(c, flag),
   345  	}
   346  }
   347  
   348  func newCRInt(c *cliconfig.PodmanCommand, flag string) CRInt {
   349  	return CRInt{
   350  		Val:          c.Int(flag),
   351  		createResult: newCreateResult(c, flag),
   352  	}
   353  }
   354  
   355  func newCRStringArray(c *cliconfig.PodmanCommand, flag string) CRStringArray {
   356  	return CRStringArray{
   357  		Val:          c.StringArray(flag),
   358  		createResult: newCreateResult(c, flag),
   359  	}
   360  }
   361  
   362  // NewIntermediateLayer creates a GenericCLIResults from a create or run cli-command
   363  func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIResults {
   364  	m := make(map[string]GenericCLIResult)
   365  
   366  	m["add-host"] = newCRStringSlice(c, "add-host")
   367  	m["annotation"] = newCRStringSlice(c, "annotation")
   368  	m["attach"] = newCRStringSlice(c, "attach")
   369  	m["blkio-weight"] = newCRString(c, "blkio-weight")
   370  	m["blkio-weight-device"] = newCRStringSlice(c, "blkio-weight-device")
   371  	m["cap-add"] = newCRStringSlice(c, "cap-add")
   372  	m["cap-drop"] = newCRStringSlice(c, "cap-drop")
   373  	m["cgroupns"] = newCRString(c, "cgroupns")
   374  	m["cgroups"] = newCRString(c, "cgroups")
   375  	m["cgroup-parent"] = newCRString(c, "cgroup-parent")
   376  	m["cidfile"] = newCRString(c, "cidfile")
   377  	m["conmon-pidfile"] = newCRString(c, "conmon-pidfile")
   378  	m["cpu-period"] = newCRUint64(c, "cpu-period")
   379  	m["cpu-quota"] = newCRInt64(c, "cpu-quota")
   380  	m["cpu-rt-period"] = newCRUint64(c, "cpu-rt-period")
   381  	m["cpu-rt-runtime"] = newCRInt64(c, "cpu-rt-runtime")
   382  	m["cpu-shares"] = newCRUint64(c, "cpu-shares")
   383  	m["cpus"] = newCRFloat64(c, "cpus")
   384  	m["cpuset-cpus"] = newCRString(c, "cpuset-cpus")
   385  	m["cpuset-mems"] = newCRString(c, "cpuset-mems")
   386  	m["detach"] = newCRBool(c, "detach")
   387  	m["detach-keys"] = newCRString(c, "detach-keys")
   388  	m["device"] = newCRStringSlice(c, "device")
   389  	m["device-cgroup-rule"] = newCRStringSlice(c, "device-cgroup-rule")
   390  	m["device-read-bps"] = newCRStringSlice(c, "device-read-bps")
   391  	m["device-read-iops"] = newCRStringSlice(c, "device-read-iops")
   392  	m["device-write-bps"] = newCRStringSlice(c, "device-write-bps")
   393  	m["device-write-iops"] = newCRStringSlice(c, "device-write-iops")
   394  	m["dns"] = newCRStringSlice(c, "dns")
   395  	m["dns-opt"] = newCRStringSlice(c, "dns-opt")
   396  	m["dns-search"] = newCRStringSlice(c, "dns-search")
   397  	m["entrypoint"] = newCRString(c, "entrypoint")
   398  	m["env"] = newCRStringArray(c, "env")
   399  	m["env-file"] = newCRStringSlice(c, "env-file")
   400  	m["expose"] = newCRStringSlice(c, "expose")
   401  	m["gidmap"] = newCRStringSlice(c, "gidmap")
   402  	m["group-add"] = newCRStringSlice(c, "group-add")
   403  	m["help"] = newCRBool(c, "help")
   404  	m["healthcheck-command"] = newCRString(c, "health-cmd")
   405  	m["healthcheck-interval"] = newCRString(c, "health-interval")
   406  	m["healthcheck-retries"] = newCRUint(c, "health-retries")
   407  	m["healthcheck-start-period"] = newCRString(c, "health-start-period")
   408  	m["healthcheck-timeout"] = newCRString(c, "health-timeout")
   409  	m["hostname"] = newCRString(c, "hostname")
   410  	m["image-volume"] = newCRString(c, "image-volume")
   411  	m["init"] = newCRBool(c, "init")
   412  	m["init-path"] = newCRString(c, "init-path")
   413  	m["interactive"] = newCRBool(c, "interactive")
   414  	m["ip"] = newCRString(c, "ip")
   415  	m["ipc"] = newCRString(c, "ipc")
   416  	m["kernel-memory"] = newCRString(c, "kernel-memory")
   417  	m["label"] = newCRStringArray(c, "label")
   418  	m["label-file"] = newCRStringSlice(c, "label-file")
   419  	m["log-driver"] = newCRString(c, "log-driver")
   420  	m["log-opt"] = newCRStringSlice(c, "log-opt")
   421  	m["mac-address"] = newCRString(c, "mac-address")
   422  	m["memory"] = newCRString(c, "memory")
   423  	m["memory-reservation"] = newCRString(c, "memory-reservation")
   424  	m["memory-swap"] = newCRString(c, "memory-swap")
   425  	m["memory-swappiness"] = newCRInt64(c, "memory-swappiness")
   426  	m["name"] = newCRString(c, "name")
   427  	m["network"] = newCRString(c, "network")
   428  	m["no-healthcheck"] = newCRBool(c, "no-healthcheck")
   429  	m["no-hosts"] = newCRBool(c, "no-hosts")
   430  	m["oom-kill-disable"] = newCRBool(c, "oom-kill-disable")
   431  	m["oom-score-adj"] = newCRInt(c, "oom-score-adj")
   432  	m["override-arch"] = newCRString(c, "override-arch")
   433  	m["override-os"] = newCRString(c, "override-os")
   434  	m["pid"] = newCRString(c, "pid")
   435  	m["pids-limit"] = newCRInt64(c, "pids-limit")
   436  	m["pod"] = newCRString(c, "pod")
   437  	m["privileged"] = newCRBool(c, "privileged")
   438  	m["publish"] = newCRStringSlice(c, "publish")
   439  	m["publish-all"] = newCRBool(c, "publish-all")
   440  	m["pull"] = newCRString(c, "pull")
   441  	m["quiet"] = newCRBool(c, "quiet")
   442  	m["read-only"] = newCRBool(c, "read-only")
   443  	m["read-only-tmpfs"] = newCRBool(c, "read-only-tmpfs")
   444  	m["restart"] = newCRString(c, "restart")
   445  	m["rm"] = newCRBool(c, "rm")
   446  	m["rootfs"] = newCRBool(c, "rootfs")
   447  	m["security-opt"] = newCRStringArray(c, "security-opt")
   448  	m["shm-size"] = newCRString(c, "shm-size")
   449  	m["stop-signal"] = newCRString(c, "stop-signal")
   450  	m["stop-timeout"] = newCRUint(c, "stop-timeout")
   451  	m["storage-opt"] = newCRStringSlice(c, "storage-opt")
   452  	m["subgidname"] = newCRString(c, "subgidname")
   453  	m["subuidname"] = newCRString(c, "subuidname")
   454  	m["sysctl"] = newCRStringSlice(c, "sysctl")
   455  	m["systemd"] = newCRString(c, "systemd")
   456  	m["tmpfs"] = newCRStringArray(c, "tmpfs")
   457  	m["tty"] = newCRBool(c, "tty")
   458  	m["uidmap"] = newCRStringSlice(c, "uidmap")
   459  	m["ulimit"] = newCRStringSlice(c, "ulimit")
   460  	m["user"] = newCRString(c, "user")
   461  	m["userns"] = newCRString(c, "userns")
   462  	m["uts"] = newCRString(c, "uts")
   463  	m["mount"] = newCRStringArray(c, "mount")
   464  	m["volume"] = newCRStringArray(c, "volume")
   465  	m["volumes-from"] = newCRStringSlice(c, "volumes-from")
   466  	m["workdir"] = newCRString(c, "workdir")
   467  	m["seccomp-policy"] = newCRString(c, "seccomp-policy")
   468  	// global flag
   469  	if !remote {
   470  		m["authfile"] = newCRString(c, "authfile")
   471  		m["cgroupns"] = newCRString(c, "cgroupns")
   472  		m["env-host"] = newCRBool(c, "env-host")
   473  		m["http-proxy"] = newCRBool(c, "http-proxy")
   474  		m["trace"] = newCRBool(c, "trace")
   475  		m["syslog"] = newCRBool(c, "syslog")
   476  	}
   477  
   478  	return GenericCLIResults{m, c.InputArgs}
   479  }