From ba65301c955454e47c3893ca548f18a845a4c4a9 Mon Sep 17 00:00:00 2001 From: baude Date: Wed, 20 Mar 2019 13:00:34 -0500 Subject: podman-remote create|run add the ability to create and run containers via the podman-remote client. we now create an intermediate layer from the the create/run cli flags. the intermediate layer can be converted into a createconfig or into a varlink struct. Once transported, the varlink struct can be converted back to an intermediate layer and then to a createconfig. remote terminals are not supported yet. Signed-off-by: baude --- cmd/podman/shared/create.go | 36 +-- cmd/podman/shared/intermediate.go | 465 ++++++++++++++++++++++++++++ cmd/podman/shared/intermediate_novarlink.go | 70 +++++ cmd/podman/shared/intermediate_varlink.go | 427 +++++++++++++++++++++++++ 4 files changed, 976 insertions(+), 22 deletions(-) create mode 100644 cmd/podman/shared/intermediate.go create mode 100644 cmd/podman/shared/intermediate_novarlink.go create mode 100644 cmd/podman/shared/intermediate_varlink.go (limited to 'cmd/podman/shared') diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index cd82e4f1c..d694027db 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -13,7 +13,6 @@ import ( "time" "github.com/containers/image/manifest" - "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared/parse" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/image" @@ -34,12 +33,7 @@ import ( "github.com/sirupsen/logrus" ) -// getContext returns a non-nil, empty context -func getContext() context.Context { - return context.TODO() -} - -func CreateContainer(ctx context.Context, c *cliconfig.PodmanCommand, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) { +func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) { var ( healthCheck *manifest.Schema2HealthConfig err error @@ -221,7 +215,7 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error { return nil } -func configureEntrypoint(c *cliconfig.PodmanCommand, data *inspect.ImageData) []string { +func configureEntrypoint(c *GenericCLIResults, data *inspect.ImageData) []string { entrypoint := []string{} if c.IsSet("entrypoint") { // Force entrypoint to "" @@ -241,7 +235,7 @@ func configureEntrypoint(c *cliconfig.PodmanCommand, data *inspect.ImageData) [] return entrypoint } -func configurePod(c *cliconfig.PodmanCommand, runtime *libpod.Runtime, namespaces map[string]string, podName string) (map[string]string, error) { +func configurePod(c *GenericCLIResults, runtime *libpod.Runtime, namespaces map[string]string, podName string) (map[string]string, error) { pod, err := runtime.LookupPod(podName) if err != nil { return namespaces, err @@ -270,7 +264,7 @@ func configurePod(c *cliconfig.PodmanCommand, runtime *libpod.Runtime, namespace // Parses CLI options related to container creation into a config which can be // parsed into an OCI runtime spec -func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) { +func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) { var ( inputCommand, command []string memoryLimit, memoryReservation, memorySwap, memoryKernel int64 @@ -353,14 +347,14 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l tty := c.Bool("tty") - if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed { + if c.Changed("cpu-period") && c.Changed("cpus") { return nil, errors.Errorf("--cpu-period and --cpus cannot be set together") } - if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed { + if c.Changed("cpu-quota") && c.Changed("cpus") { return nil, errors.Errorf("--cpu-quota and --cpus cannot be set together") } - if c.Bool("no-hosts") && c.Flag("add-host").Changed { + if c.Bool("no-hosts") && c.Changed("add-host") { return nil, errors.Errorf("--no-hosts and --add-host cannot be set together") } @@ -379,7 +373,7 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l // However, that also involves setting up security opts // when the pod's namespace is integrated namespaceNet := c.String("network") - if c.Flag("net").Changed { + if c.Changed("net") { namespaceNet = c.String("net") } namespaces = map[string]string{ @@ -548,7 +542,7 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l // WORKING DIRECTORY workDir := "/" - if c.IsSet("workdir") || c.IsSet("w") { + if c.IsSet("workdir") { workDir = c.String("workdir") } else if data != nil && data.Config.WorkingDir != "" { workDir = data.Config.WorkingDir @@ -624,14 +618,12 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l // This is done because cobra cannot have two aliased flags. So we have to check // both network := c.String("network") - if c.Flag("net").Changed { + if c.Changed("net") { network = c.String("net") } - var memorySwappiness int64 - if c.Flags().Lookup("memory-swappiness") != nil { - memorySwappiness, _ = c.Flags().GetInt64("memory-swappiness") - } + memorySwappiness := c.Int64("memory-swappiness") + config := &cc.CreateConfig{ Runtime: runtime, Annotations: annotations, @@ -719,7 +711,7 @@ func ParseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l WorkDir: workDir, Rootfs: rootfs, VolumesFrom: c.StringSlice("volumes-from"), - Syslog: c.GlobalFlags.Syslog, + Syslog: c.Bool("syslog"), } if c.Bool("init") { initPath := c.String("init-path") @@ -789,7 +781,7 @@ var defaultEnvVariables = map[string]string{ "TERM": "xterm", } -func makeHealthCheckFromCli(c *cliconfig.PodmanCommand) (*manifest.Schema2HealthConfig, error) { +func makeHealthCheckFromCli(c *GenericCLIResults) (*manifest.Schema2HealthConfig, error) { inCommand := c.String("healthcheck-command") inInterval := c.String("healthcheck-interval") inRetries := c.Uint("healthcheck-retries") diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go new file mode 100644 index 000000000..9afbd68c8 --- /dev/null +++ b/cmd/podman/shared/intermediate.go @@ -0,0 +1,465 @@ +package shared + +import ( + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/sirupsen/logrus" +) + +/* +attention + +in this file you will see alot of struct duplication. this was done because people wanted a strongly typed +varlink mechanism. this resulted in us creating this intermediate layer that allows us to take the input +from the cli and make an intermediate layer which can be transferred as strongly typed structures over a varlink +interface. + +we intentionally avoided heavy use of reflection here because we were concerned about performance impacts to the +non-varlink intermediate layer generation. +*/ + +// GenericCLIResult describes the overall interface for dealing with +// the create command cli in both local and remote uses +type GenericCLIResult interface { + IsSet() bool + Name() string + Value() interface{} +} + +// CRStringSlice describes a string slice cli struct +type CRStringSlice struct { + Val []string + createResult +} + +// CRString describes a string cli struct +type CRString struct { + Val string + createResult +} + +// CRUint64 describes a uint64 cli struct +type CRUint64 struct { + Val uint64 + createResult +} + +// CRFloat64 describes a float64 cli struct +type CRFloat64 struct { + Val float64 + createResult +} + +//CRBool describes a bool cli struct +type CRBool struct { + Val bool + createResult +} + +// CRInt64 describes an int64 cli struct +type CRInt64 struct { + Val int64 + createResult +} + +// CRUint describes a uint cli struct +type CRUint struct { + Val uint + createResult +} + +// CRInt describes an int cli struct +type CRInt struct { + Val int + createResult +} + +// CRStringArray describes a stringarray cli struct +type CRStringArray struct { + Val []string + createResult +} + +type createResult struct { + Flag string + Changed bool +} + +// GenericCLIResults in the intermediate object between the cobra cli +// and createconfig +type GenericCLIResults struct { + results map[string]GenericCLIResult + InputArgs []string +} + +// IsSet returns a bool if the flag was changed +func (f GenericCLIResults) IsSet(flag string) bool { + r := f.findResult(flag) + if r == nil { + return false + } + return r.IsSet() +} + +// Value returns the value of the cli flag +func (f GenericCLIResults) Value(flag string) interface{} { + r := f.findResult(flag) + if r == nil { + return "" + } + return r.Value() +} + +func (f GenericCLIResults) findResult(flag string) GenericCLIResult { + val, ok := f.results[flag] + if ok { + return val + } + logrus.Errorf("unable to find flag %s", flag) + return nil +} + +// Bool is a wrapper to get a bool value from GenericCLIResults +func (f GenericCLIResults) Bool(flag string) bool { + r := f.findResult(flag) + if r == nil { + return false + } + return r.Value().(bool) +} + +// String is a wrapper to get a string value from GenericCLIResults +func (f GenericCLIResults) String(flag string) string { + r := f.findResult(flag) + if r == nil { + return "" + } + return r.Value().(string) +} + +// Uint is a wrapper to get an uint value from GenericCLIResults +func (f GenericCLIResults) Uint(flag string) uint { + r := f.findResult(flag) + if r == nil { + return 0 + } + return r.Value().(uint) +} + +// StringSlice is a wrapper to get a stringslice value from GenericCLIResults +func (f GenericCLIResults) StringSlice(flag string) []string { + r := f.findResult(flag) + if r == nil { + return []string{} + } + return r.Value().([]string) +} + +// StringArray is a wrapper to get a stringslice value from GenericCLIResults +func (f GenericCLIResults) StringArray(flag string) []string { + r := f.findResult(flag) + if r == nil { + return []string{} + } + return r.Value().([]string) +} + +// Uint64 is a wrapper to get an uint64 value from GenericCLIResults +func (f GenericCLIResults) Uint64(flag string) uint64 { + r := f.findResult(flag) + if r == nil { + return 0 + } + return r.Value().(uint64) +} + +// Int64 is a wrapper to get an int64 value from GenericCLIResults +func (f GenericCLIResults) Int64(flag string) int64 { + r := f.findResult(flag) + if r == nil { + return 0 + } + return r.Value().(int64) +} + +// Int is a wrapper to get an int value from GenericCLIResults +func (f GenericCLIResults) Int(flag string) int { + r := f.findResult(flag) + if r == nil { + return 0 + } + return r.Value().(int) +} + +// Float64 is a wrapper to get an float64 value from GenericCLIResults +func (f GenericCLIResults) Float64(flag string) float64 { + r := f.findResult(flag) + if r == nil { + return 0 + } + return r.Value().(float64) +} + +// Float64 is a wrapper to get an float64 value from GenericCLIResults +func (f GenericCLIResults) Changed(flag string) bool { + r := f.findResult(flag) + if r == nil { + return false + } + return r.IsSet() +} + +// IsSet ... +func (c CRStringSlice) IsSet() bool { return c.Changed } + +// Name ... +func (c CRStringSlice) Name() string { return c.Flag } + +// Value ... +func (c CRStringSlice) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRString) IsSet() bool { return c.Changed } + +// Name ... +func (c CRString) Name() string { return c.Flag } + +// Value ... +func (c CRString) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRUint64) IsSet() bool { return c.Changed } + +// Name ... +func (c CRUint64) Name() string { return c.Flag } + +// Value ... +func (c CRUint64) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRFloat64) IsSet() bool { return c.Changed } + +// Name ... +func (c CRFloat64) Name() string { return c.Flag } + +// Value ... +func (c CRFloat64) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRBool) IsSet() bool { return c.Changed } + +// Name ... +func (c CRBool) Name() string { return c.Flag } + +// Value ... +func (c CRBool) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRInt64) IsSet() bool { return c.Changed } + +// Name ... +func (c CRInt64) Name() string { return c.Flag } + +// Value ... +func (c CRInt64) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRUint) IsSet() bool { return c.Changed } + +// Name ... +func (c CRUint) Name() string { return c.Flag } + +// Value ... +func (c CRUint) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRInt) IsSet() bool { return c.Changed } + +// Name ... +func (c CRInt) Name() string { return c.Flag } + +// Value ... +func (c CRInt) Value() interface{} { return c.Val } + +// IsSet ... +func (c CRStringArray) IsSet() bool { return c.Changed } + +// Name ... +func (c CRStringArray) Name() string { return c.Flag } + +// Value ... +func (c CRStringArray) Value() interface{} { return c.Val } + +func newCreateResult(c *cliconfig.PodmanCommand, flag string) createResult { + return createResult{ + Flag: flag, + Changed: c.IsSet(flag), + } +} + +func newCRStringSlice(c *cliconfig.PodmanCommand, flag string) CRStringSlice { + return CRStringSlice{ + Val: c.StringSlice(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRString(c *cliconfig.PodmanCommand, flag string) CRString { + return CRString{ + Val: c.String(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRUint64(c *cliconfig.PodmanCommand, flag string) CRUint64 { + return CRUint64{ + Val: c.Uint64(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRFloat64(c *cliconfig.PodmanCommand, flag string) CRFloat64 { + return CRFloat64{ + Val: c.Float64(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRBool(c *cliconfig.PodmanCommand, flag string) CRBool { + return CRBool{ + Val: c.Bool(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRInt64(c *cliconfig.PodmanCommand, flag string) CRInt64 { + return CRInt64{ + Val: c.Int64(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRUint(c *cliconfig.PodmanCommand, flag string) CRUint { + return CRUint{ + Val: c.Uint(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRInt(c *cliconfig.PodmanCommand, flag string) CRInt { + return CRInt{ + Val: c.Int(flag), + createResult: newCreateResult(c, flag), + } +} + +func newCRStringArray(c *cliconfig.PodmanCommand, flag string) CRStringArray { + return CRStringArray{ + Val: c.StringArray(flag), + createResult: newCreateResult(c, flag), + } +} + +// NewIntermediateLayer creates a GenericCLIResults from a create or run cli-command +func NewIntermediateLayer(c *cliconfig.PodmanCommand) GenericCLIResults { + m := make(map[string]GenericCLIResult) + + m["add-host"] = newCRStringSlice(c, "add-host") + m["annotation"] = newCRStringSlice(c, "annotation") + m["attach"] = newCRStringSlice(c, "attach") + m["blkio-weight"] = newCRString(c, "blkio-weight") + m["blkio-weight-device"] = newCRStringSlice(c, "blkio-weight-device") + m["cap-add"] = newCRStringSlice(c, "cap-add") + m["cap-drop"] = newCRStringSlice(c, "cap-drop") + m["cgroup-parent"] = newCRString(c, "cgroup-parent") + m["cidfile"] = newCRString(c, "cidfile") + m["conmon-pidfile"] = newCRString(c, "conmon-pidfile") + m["cpu-period"] = newCRUint64(c, "cpu-period") + m["cpu-quota"] = newCRInt64(c, "cpu-quota") + m["cpu-rt-period"] = newCRUint64(c, "cpu-rt-period") + m["cpu-rt-runtime"] = newCRInt64(c, "cpu-rt-runtime") + m["cpu-shares"] = newCRUint64(c, "cpu-shares") + m["cpus"] = newCRFloat64(c, "cpus") + m["cpuset-cpus"] = newCRString(c, "cpuset-cpus") + m["cpuset-mems"] = newCRString(c, "cpuset-mems") + m["detach"] = newCRBool(c, "detach") + m["detach-keys"] = newCRString(c, "detach-keys") + m["device"] = newCRStringSlice(c, "device") + m["device-read-bps"] = newCRStringSlice(c, "device-read-bps") + m["device-read-iops"] = newCRStringSlice(c, "device-read-iops") + m["device-write-bps"] = newCRStringSlice(c, "device-write-bps") + m["device-write-iops"] = newCRStringSlice(c, "device-write-iops") + m["dns"] = newCRStringSlice(c, "dns") + m["dns-opt"] = newCRStringSlice(c, "dns-opt") + m["dns-search"] = newCRStringSlice(c, "dns-search") + m["entrypoint"] = newCRString(c, "entrypoint") + m["env"] = newCRStringArray(c, "env") + m["env-file"] = newCRStringSlice(c, "env-file") + m["expose"] = newCRStringSlice(c, "expose") + m["gidmap"] = newCRStringSlice(c, "gidmap") + m["group-add"] = newCRStringSlice(c, "group-add") + m["help"] = newCRBool(c, "help") + m["healthcheck-command"] = newCRString(c, "healthcheck-command") + m["healthcheck-interval"] = newCRString(c, "healthcheck-interval") + m["healthcheck-retries"] = newCRUint(c, "healthcheck-retries") + m["healthcheck-start-period"] = newCRString(c, "healthcheck-start-period") + m["healthcheck-timeout"] = newCRString(c, "healthcheck-timeout") + m["hostname"] = newCRString(c, "hostname") + m["image-volume"] = newCRString(c, "image-volume") + m["init"] = newCRBool(c, "init") + m["init-path"] = newCRString(c, "init-path") + m["interactive"] = newCRBool(c, "interactive") + m["ip"] = newCRString(c, "ip") + m["ipc"] = newCRString(c, "ipc") + m["kernel-memory"] = newCRString(c, "kernel-memory") + m["label"] = newCRStringArray(c, "label") + m["label-file"] = newCRStringSlice(c, "label-file") + m["log-driver"] = newCRString(c, "log-driver") + m["log-opt"] = newCRStringSlice(c, "log-opt") + m["mac-address"] = newCRString(c, "mac-address") + m["memory"] = newCRString(c, "memory") + m["memory-reservation"] = newCRString(c, "memory-reservation") + m["memory-swap"] = newCRString(c, "memory-swap") + m["memory-swappiness"] = newCRInt64(c, "memory-swappiness") + m["name"] = newCRString(c, "name") + m["net"] = newCRString(c, "net") + m["network"] = newCRString(c, "network") + m["no-hosts"] = newCRBool(c, "no-hosts") + m["oom-kill-disable"] = newCRBool(c, "oom-kill-disable") + m["oom-score-adj"] = newCRInt(c, "oom-score-adj") + m["pid"] = newCRString(c, "pid") + m["pids-limit"] = newCRInt64(c, "pids-limit") + m["pod"] = newCRString(c, "pod") + m["privileged"] = newCRBool(c, "privileged") + m["publish"] = newCRStringSlice(c, "publish") + m["publish-all"] = newCRBool(c, "publish-all") + m["quiet"] = newCRBool(c, "quiet") + m["read-only"] = newCRBool(c, "read-only") + m["restart"] = newCRString(c, "restart") + m["rm"] = newCRBool(c, "rm") + m["rootfs"] = newCRBool(c, "rootfs") + m["security-opt"] = newCRStringArray(c, "security-opt") + m["shm-size"] = newCRString(c, "shm-size") + m["stop-signal"] = newCRString(c, "stop-signal") + m["stop-timeout"] = newCRUint(c, "stop-timeout") + m["storage-opt"] = newCRStringSlice(c, "storage-opt") + m["subgidname"] = newCRString(c, "subgidname") + m["subuidname"] = newCRString(c, "subuidname") + m["sysctl"] = newCRStringSlice(c, "sysctl") + m["systemd"] = newCRBool(c, "systemd") + m["tmpfs"] = newCRStringSlice(c, "tmpfs") + m["tty"] = newCRBool(c, "tty") + m["uidmap"] = newCRStringSlice(c, "uidmap") + m["ulimit"] = newCRStringSlice(c, "ulimit") + m["user"] = newCRString(c, "user") + m["userns"] = newCRString(c, "userns") + m["uts"] = newCRString(c, "uts") + m["mount"] = newCRStringArray(c, "mount") + m["volume"] = newCRStringArray(c, "volume") + m["volumes-from"] = newCRStringSlice(c, "volumes-from") + m["workdir"] = newCRString(c, "workdir") + // global flag + m["trace"] = newCRBool(c, "trace") + m["syslog"] = newCRBool(c, "syslog") + + return GenericCLIResults{m, c.InputArgs} +} diff --git a/cmd/podman/shared/intermediate_novarlink.go b/cmd/podman/shared/intermediate_novarlink.go new file mode 100644 index 000000000..26738ce48 --- /dev/null +++ b/cmd/podman/shared/intermediate_novarlink.go @@ -0,0 +1,70 @@ +// +build !varlink +// +build !remoteclient + +package shared + +/* +attention + +in this file you will see alot of struct duplication. this was done because people wanted a strongly typed +varlink mechanism. this resulted in us creating this intermediate layer that allows us to take the input +from the cli and make an intermediate layer which can be transferred as strongly typed structures over a varlink +interface. + +we intentionally avoided heavy use of reflection here because we were concerned about performance impacts to the +non-varlink intermediate layer generation. +*/ + +// ToString wrapper for build without varlink +func (c CRStringSlice) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRString) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRBool) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRUint64) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRInt64) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRFloat64) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRUint) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRStringArray) ToVarlink() interface{} { + var v interface{} + return v +} + +// ToString wrapper for build without varlink +func (c CRInt) ToVarlink() interface{} { + var v interface{} + return v +} diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go new file mode 100644 index 000000000..95a0d6287 --- /dev/null +++ b/cmd/podman/shared/intermediate_varlink.go @@ -0,0 +1,427 @@ +// +build varlink remoteclient + +package shared + +import ( + "fmt" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/cmd/podman/varlink" + "github.com/pkg/errors" +) + +// StringSliceToPtr converts a genericcliresult value into a *[]string +func StringSliceToPtr(g GenericCLIResult) *[]string { + if !g.IsSet() { + return nil + } + newT := g.Value().([]string) + return &newT +} + +// StringToPtr converts a genericcliresult value into a *string +func StringToPtr(g GenericCLIResult) *string { + if !g.IsSet() { + return nil + } + newT := g.Value().(string) + return &newT +} + +// BoolToPtr converts a genericcliresult value into a *bool +func BoolToPtr(g GenericCLIResult) *bool { + if !g.IsSet() { + return nil + } + newT := g.Value().(bool) + return &newT +} + +// AnyIntToInt64Ptr converts a genericcliresult value into an *int64 +func AnyIntToInt64Ptr(g GenericCLIResult) *int64 { + if !g.IsSet() { + return nil + } + var newT int64 + switch g.Value().(type) { + case int: + newT = int64(g.Value().(int)) + case int64: + newT = g.Value().(int64) + case uint64: + newT = int64(g.Value().(uint64)) + case uint: + newT = int64(g.Value().(uint)) + default: + panic(errors.Errorf("invalid int type")) + } + return &newT +} + +// Float64ToPtr converts a genericcliresult into a *float64 +func Float64ToPtr(g GenericCLIResult) *float64 { + if !g.IsSet() { + return nil + } + newT := g.Value().(float64) + return &newT +} + +// MakeVarlink creates a varlink transportable struct from GenericCLIResults +func (g GenericCLIResults) MakeVarlink() iopodman.Create { + v := iopodman.Create{ + Args: g.InputArgs, + AddHost: StringSliceToPtr(g.Find("add-host")), + Annotation: StringSliceToPtr(g.Find("annotation")), + Attach: StringSliceToPtr(g.Find("attach")), + BlkioWeight: StringToPtr(g.Find("blkio-weight")), + BlkioWeightDevice: StringSliceToPtr(g.Find("blkio-weight-device")), + CapAdd: StringSliceToPtr(g.Find("cap-add")), + CapDrop: StringSliceToPtr(g.Find("cap-drop")), + CgroupParent: StringToPtr(g.Find("cgroup-parent")), + CidFile: StringToPtr(g.Find("cidfile")), + ConmonPidfile: StringToPtr(g.Find("conmon-pidfile")), + CpuPeriod: AnyIntToInt64Ptr(g.Find("cpu-period")), + CpuQuota: AnyIntToInt64Ptr(g.Find("cpu-quota")), + CpuRtPeriod: AnyIntToInt64Ptr(g.Find("cpu-rt-period")), + CpuRtRuntime: AnyIntToInt64Ptr(g.Find("cpu-rt-runtime")), + CpuShares: AnyIntToInt64Ptr(g.Find("cpu-shares")), + Cpus: Float64ToPtr(g.Find("cpus")), + CpuSetCpus: StringToPtr(g.Find("cpuset-cpus")), + CpuSetMems: StringToPtr(g.Find("cpuset-mems")), + Detach: BoolToPtr(g.Find("detach")), + DetachKeys: StringToPtr(g.Find("detach-keys")), + Device: StringSliceToPtr(g.Find("device")), + DeviceReadBps: StringSliceToPtr(g.Find("device-read-bps")), + DeviceReadIops: StringSliceToPtr(g.Find("device-read-iops")), + DeviceWriteBps: StringSliceToPtr(g.Find("device-write-bps")), + DeviceWriteIops: StringSliceToPtr(g.Find("device-write-iops")), + Dns: StringSliceToPtr(g.Find("dns")), + DnsOpt: StringSliceToPtr(g.Find("dns-opt")), + DnsSearch: StringSliceToPtr(g.Find("dns-search")), + Entrypoint: StringToPtr(g.Find("entrypoint")), + Env: StringSliceToPtr(g.Find("env")), + EnvFile: StringSliceToPtr(g.Find("env-file")), + Expose: StringSliceToPtr(g.Find("expose")), + Gidmap: StringSliceToPtr(g.Find("gidmap")), + Groupadd: StringSliceToPtr(g.Find("group-add")), + HealthcheckCommand: StringToPtr(g.Find("healthcheck-command")), + HealthcheckInterval: StringToPtr(g.Find("healthcheck-interval")), + HealthcheckRetries: AnyIntToInt64Ptr(g.Find("healthcheck-retries")), + HealthcheckStartPeriod: StringToPtr(g.Find("healthcheck-start-period")), + HealthcheckTimeout: StringToPtr(g.Find("healthcheck-timeout")), + Hostname: StringToPtr(g.Find("hostname")), + ImageVolume: StringToPtr(g.Find("image-volume")), + Init: BoolToPtr(g.Find("init")), + InitPath: StringToPtr(g.Find("init-path")), + Interactive: BoolToPtr(g.Find("interactive")), + Ip: StringToPtr(g.Find("ip")), + Ipc: StringToPtr(g.Find("ipc")), + KernelMemory: StringToPtr(g.Find("kernel-memory")), + Label: StringSliceToPtr(g.Find("label")), + LabelFile: StringSliceToPtr(g.Find("label-file")), + LogDriver: StringToPtr(g.Find("log-driver")), + LogOpt: StringSliceToPtr(g.Find("log-opt")), + MacAddress: StringToPtr(g.Find("mac-address")), + Memory: StringToPtr(g.Find("memory")), + MemoryReservation: StringToPtr(g.Find("memory-reservation")), + MemorySwap: StringToPtr(g.Find("memory-swap")), + MemorySwappiness: AnyIntToInt64Ptr(g.Find("memory-swappiness")), + Name: StringToPtr(g.Find("name")), + Net: StringToPtr(g.Find("net")), + Network: StringToPtr(g.Find("network")), + OomKillDisable: BoolToPtr(g.Find("oom-kill-disable")), + OomScoreAdj: AnyIntToInt64Ptr(g.Find("oom-score-adj")), + Pid: StringToPtr(g.Find("pid")), + PidsLimit: AnyIntToInt64Ptr(g.Find("pids-limit")), + Pod: StringToPtr(g.Find("pod")), + Privileged: BoolToPtr(g.Find("privileged")), + Publish: StringSliceToPtr(g.Find("publish")), + PublishAll: BoolToPtr(g.Find("publish-all")), + Quiet: BoolToPtr(g.Find("quiet")), + Readonly: BoolToPtr(g.Find("read-only")), + Restart: StringToPtr(g.Find("restart")), + Rm: BoolToPtr(g.Find("rm")), + Rootfs: BoolToPtr(g.Find("rootfs")), + SecurityOpt: StringSliceToPtr(g.Find("security-opt")), + ShmSize: StringToPtr(g.Find("shm-size")), + StopSignal: StringToPtr(g.Find("stop-signal")), + StopTimeout: AnyIntToInt64Ptr(g.Find("stop-timeout")), + StorageOpt: StringSliceToPtr(g.Find("storage-opt")), + Subuidname: StringToPtr(g.Find("subuidname")), + Subgidname: StringToPtr(g.Find("subgidname")), + Sysctl: StringSliceToPtr(g.Find("sysctl")), + Systemd: BoolToPtr(g.Find("systemd")), + Tmpfs: StringSliceToPtr(g.Find("tmpfs")), + Tty: BoolToPtr(g.Find("tty")), + Uidmap: StringSliceToPtr(g.Find("uidmap")), + Ulimit: StringSliceToPtr(g.Find("ulimit")), + User: StringToPtr(g.Find("user")), + Userns: StringToPtr(g.Find("userns")), + Uts: StringToPtr(g.Find("uts")), + Mount: StringSliceToPtr(g.Find("mount")), + Volume: StringSliceToPtr(g.Find("volume")), + VolumesFrom: StringSliceToPtr(g.Find("volumes-from")), + WorkDir: StringToPtr(g.Find("workdir")), + } + + return v +} + +func stringSliceFromVarlink(v *[]string, flagName string, defaultValue *[]string) CRStringSlice { + cr := CRStringSlice{} + if v == nil { + cr.Val = []string{} + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = *v + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func stringFromVarlink(v *string, flagName string, defaultValue *string) CRString { + cr := CRString{} + if v == nil { + cr.Val = "" + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = *v + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func boolFromVarlink(v *bool, flagName string, defaultValue bool) CRBool { + cr := CRBool{} + if v == nil { + // In case a cli bool default value is true + cr.Val = defaultValue + cr.Changed = false + } else { + fmt.Println(flagName, cr.Val) + cr.Val = *v + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func uint64FromVarlink(v *int64, flagName string, defaultValue *uint64) CRUint64 { + cr := CRUint64{} + if v == nil { + cr.Val = 0 + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = uint64(*v) + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func int64FromVarlink(v *int64, flagName string, defaultValue *int64) CRInt64 { + cr := CRInt64{} + if v == nil { + cr.Val = 0 + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = *v + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func float64FromVarlink(v *float64, flagName string, defaultValue *float64) CRFloat64 { + cr := CRFloat64{} + if v == nil { + cr.Val = 0 + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = *v + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func uintFromVarlink(v *int64, flagName string, defaultValue *uint) CRUint { + cr := CRUint{} + if v == nil { + cr.Val = 0 + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = uint(*v) + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func stringArrayFromVarlink(v *[]string, flagName string, defaultValue *[]string) CRStringArray { + cr := CRStringArray{} + if v == nil { + cr.Val = []string{} + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Changed = false + } else { + cr.Val = *v + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +func intFromVarlink(v *int64, flagName string, defaultValue *int) CRInt { + cr := CRInt{} + if v == nil { + if defaultValue != nil { + cr.Val = *defaultValue + } + cr.Val = 0 + cr.Changed = false + } else { + cr.Val = int(*v) + cr.Changed = true + } + cr.Flag = flagName + return cr +} + +// VarlinkCreateToGeneric creates a GenericCLIResults from the varlink create +// structure. +func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults { + + // TODO | WARN + // We do not get a default network over varlink. Unlike the other default values for some cli + // elements, it seems it gets set to the default anyway. + + m := make(map[string]GenericCLIResult) + m["add-host"] = stringSliceFromVarlink(opts.AddHost, "add-host", nil) + m["annotation"] = stringSliceFromVarlink(opts.Annotation, "annotation", nil) + m["attach"] = stringSliceFromVarlink(opts.Attach, "attach", nil) + m["blkio-weight"] = stringFromVarlink(opts.BlkioWeight, "blkio-weight", nil) + m["blkio-weight-device"] = stringSliceFromVarlink(opts.BlkioWeightDevice, "blkio-weight-device", nil) + m["cap-add"] = stringSliceFromVarlink(opts.CapAdd, "cap-add", nil) + m["cap-drop"] = stringSliceFromVarlink(opts.CapDrop, "cap-drop", nil) + m["cgroup-parent"] = stringFromVarlink(opts.CgroupParent, "cgroup-parent", nil) + m["cidfile"] = stringFromVarlink(opts.CidFile, "cidfile", nil) + m["conmon-pidfile"] = stringFromVarlink(opts.ConmonPidfile, "conmon-file", nil) + m["cpu-period"] = uint64FromVarlink(opts.CpuPeriod, "cpu-period", nil) + m["cpu-quota"] = int64FromVarlink(opts.CpuQuota, "quota", nil) + m["cpu-rt-period"] = uint64FromVarlink(opts.CpuRtPeriod, "cpu-rt-period", nil) + m["cpu-rt-runtime"] = int64FromVarlink(opts.CpuRtRuntime, "cpu-rt-quota", nil) + m["cpu-shares"] = uint64FromVarlink(opts.CpuShares, "cpu-shares", nil) + m["cpus"] = float64FromVarlink(opts.Cpus, "cpus", nil) + m["cpuset-cpus"] = stringFromVarlink(opts.CpuSetCpus, "cpuset-cpus", nil) + m["cpuset-mems"] = stringFromVarlink(opts.CpuSetMems, "cpuset-mems", nil) + m["detach"] = boolFromVarlink(opts.Detach, "detach", false) + m["detach-keys"] = stringFromVarlink(opts.DetachKeys, "detach-keys", nil) + m["device"] = stringSliceFromVarlink(opts.Device, "device", nil) + m["device-read-bps"] = stringSliceFromVarlink(opts.DeviceReadBps, "device-read-bps", nil) + m["device-read-iops"] = stringSliceFromVarlink(opts.DeviceReadIops, "device-read-iops", nil) + m["device-write-bps"] = stringSliceFromVarlink(opts.DeviceWriteBps, "write-device-bps", nil) + m["device-write-iops"] = stringSliceFromVarlink(opts.DeviceWriteIops, "write-device-iops", nil) + m["dns"] = stringSliceFromVarlink(opts.Dns, "dns", nil) + m["dns-opt"] = stringSliceFromVarlink(opts.DnsOpt, "dns-opt", nil) + m["dns-search"] = stringSliceFromVarlink(opts.DnsSearch, "dns-search", nil) + m["entrypoint"] = stringFromVarlink(opts.Entrypoint, "entrypoint", nil) + m["env"] = stringArrayFromVarlink(opts.Env, "env", nil) + m["env-file"] = stringSliceFromVarlink(opts.EnvFile, "env-file", nil) + m["expose"] = stringSliceFromVarlink(opts.Expose, "expose", nil) + m["gidmap"] = stringSliceFromVarlink(opts.Gidmap, "gidmap", nil) + m["group-add"] = stringSliceFromVarlink(opts.Groupadd, "group-add", nil) + m["healthcheck-command"] = stringFromVarlink(opts.HealthcheckCommand, "healthcheck-command", nil) + m["healthcheck-interval"] = stringFromVarlink(opts.HealthcheckInterval, "healthcheck-interval", &cliconfig.DefaultHealthCheckInterval) + m["healthcheck-retries"] = uintFromVarlink(opts.HealthcheckRetries, "healthcheck-retries", &cliconfig.DefaultHealthCheckRetries) + m["healthcheck-start-period"] = stringFromVarlink(opts.HealthcheckStartPeriod, "healthcheck-start-period", &cliconfig.DefaultHealthCheckStartPeriod) + m["healthcheck-timeout"] = stringFromVarlink(opts.HealthcheckTimeout, "healthcheck-timeout", &cliconfig.DefaultHealthCheckTimeout) + m["hostname"] = stringFromVarlink(opts.Hostname, "hostname", nil) + m["image-volume"] = stringFromVarlink(opts.ImageVolume, "image-volume", &cliconfig.DefaultImageVolume) + m["init"] = boolFromVarlink(opts.Init, "init", false) + m["init-path"] = stringFromVarlink(opts.InitPath, "init-path", nil) + m["interactive"] = boolFromVarlink(opts.Interactive, "interactive", false) + m["ip"] = stringFromVarlink(opts.Ip, "ip", nil) + m["ipc"] = stringFromVarlink(opts.Ipc, "ipc", nil) + m["kernel-memory"] = stringFromVarlink(opts.KernelMemory, "kernel-memory", nil) + m["label"] = stringArrayFromVarlink(opts.Label, "label", nil) + m["label-file"] = stringSliceFromVarlink(opts.LabelFile, "label-file", nil) + m["log-driver"] = stringFromVarlink(opts.LogDriver, "log-driver", nil) + m["log-opt"] = stringSliceFromVarlink(opts.LogOpt, "log-opt", nil) + m["mac-address"] = stringFromVarlink(opts.MacAddress, "mac-address", nil) + m["memory"] = stringFromVarlink(opts.Memory, "memory", nil) + m["memory-reservation"] = stringFromVarlink(opts.MemoryReservation, "memory-reservation", nil) + m["memory-swap"] = stringFromVarlink(opts.MemorySwap, "memory-swap", nil) + m["memory-swappiness"] = int64FromVarlink(opts.MemorySwappiness, "memory-swappiness", nil) + m["name"] = stringFromVarlink(opts.Name, "name", nil) + m["net"] = stringFromVarlink(opts.Net, "net", nil) + m["network"] = stringFromVarlink(opts.Network, "network", nil) + m["no-hosts"] = boolFromVarlink(opts.NoHosts, "no-hosts", false) + m["oom-kill-disable"] = boolFromVarlink(opts.OomKillDisable, "oon-kill-disable", false) + m["oom-score-adj"] = intFromVarlink(opts.OomScoreAdj, "oom-score-adj", nil) + m["pid"] = stringFromVarlink(opts.Pid, "pid", nil) + m["pids-limit"] = int64FromVarlink(opts.PidsLimit, "pids-limit", nil) + m["pod"] = stringFromVarlink(opts.Pod, "pod", nil) + m["privileged"] = boolFromVarlink(opts.Privileged, "privileged", false) + m["publish"] = stringSliceFromVarlink(opts.Publish, "publish", nil) + m["publish-all"] = boolFromVarlink(opts.PublishAll, "publish-all", false) + m["quiet"] = boolFromVarlink(opts.Quiet, "quiet", false) + m["read-only"] = boolFromVarlink(opts.Readonly, "read-only", false) + m["restart"] = stringFromVarlink(opts.Restart, "restart", nil) + m["rm"] = boolFromVarlink(opts.Rm, "rm", false) + m["rootfs"] = boolFromVarlink(opts.Rootfs, "rootfs", false) + m["security-opt"] = stringArrayFromVarlink(opts.SecurityOpt, "security-opt", nil) + m["shm-size"] = stringFromVarlink(opts.ShmSize, "shm-size", &cliconfig.DefaultShmSize) + m["stop-signal"] = stringFromVarlink(opts.StopSignal, "stop-signal", nil) + m["stop-timeout"] = uintFromVarlink(opts.StopTimeout, "stop-timeout", nil) + m["storage-opt"] = stringSliceFromVarlink(opts.StorageOpt, "storage-opt", nil) + m["subgidname"] = stringFromVarlink(opts.Subgidname, "subgidname", nil) + m["subuidname"] = stringFromVarlink(opts.Subuidname, "subuidname", nil) + m["sysctl"] = stringSliceFromVarlink(opts.Sysctl, "sysctl", nil) + m["systemd"] = boolFromVarlink(opts.Systemd, "systemd", cliconfig.DefaultSystemD) + m["tmpfs"] = stringSliceFromVarlink(opts.Tmpfs, "tmpfs", nil) + m["tty"] = boolFromVarlink(opts.Tty, "tty", false) + m["uidmap"] = stringSliceFromVarlink(opts.Uidmap, "uidmap", nil) + m["ulimit"] = stringSliceFromVarlink(opts.Ulimit, "ulimit", nil) + m["user"] = stringFromVarlink(opts.User, "user", nil) + m["userns"] = stringFromVarlink(opts.Userns, "userns", nil) + m["uts"] = stringFromVarlink(opts.Uts, "uts", nil) + m["mount"] = stringArrayFromVarlink(opts.Mount, "mount", nil) + m["volume"] = stringArrayFromVarlink(opts.Volume, "volume", nil) + m["volumes-from"] = stringSliceFromVarlink(opts.VolumesFrom, "volumes-from", nil) + m["workdir"] = stringFromVarlink(opts.WorkDir, "workdir", nil) + + gcli := GenericCLIResults{m, opts.Args} + return gcli +} + +// Find returns a flag from a GenericCLIResults by name +func (g GenericCLIResults) Find(name string) GenericCLIResult { + result, ok := g.results[name] + if ok { + return result + } + panic(errors.Errorf("unable to find generic flag for varlink %s", name)) +} -- cgit v1.2.3-54-g00ecf