From cb077c968de08c98eda023f5eeefc7d9d8e79231 Mon Sep 17 00:00:00 2001 From: cdoern Date: Wed, 15 Sep 2021 15:08:42 -0400 Subject: Created MapOptions for PodCreate MapOptions take the pod and container create options, assigning matching values from infra back to the pod for the Libpod API. This function, unlike the previous one, does not require any manual additions when new options are added since it uses the structs JSON tags, this is a more modular approach. Signed-off-by: cdoern --- cmd/podman/common/create.go | 12 +++++++++ cmd/podman/common/create_test.go | 53 ++++++++++++++++++++++++++++++++++++++++ cmd/podman/pods/create.go | 32 +++++++++--------------- 3 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 cmd/podman/common/create_test.go (limited to 'cmd') diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 6200592b4..a65e90fab 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -15,6 +15,18 @@ const sizeWithUnitFormat = "(format: `[]`, where unit = b (bytes), var containerConfig = registry.PodmanConfig() +// ContainerToPodOptions takes the Container and Pod Create options, assigning the matching values back to podCreate for the purpose of the libpod API +// For this function to succeed, the JSON tags in PodCreateOptions and ContainerCreateOptions need to match due to the Marshaling and Unmarshaling done. +// The types of the options also need to match or else the unmarshaling will fail even if the tags match +func ContainerToPodOptions(containerCreate *entities.ContainerCreateOptions, podCreate *entities.PodCreateOptions) error { + contMarshal, err := json.Marshal(containerCreate) + if err != nil { + return err + } + return json.Unmarshal(contMarshal, podCreate) +} + +// DefineCreateFlags declares and instantiates the container create flags func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions, isInfra bool) { createFlags := cmd.Flags() diff --git a/cmd/podman/common/create_test.go b/cmd/podman/common/create_test.go new file mode 100644 index 000000000..17b47dd16 --- /dev/null +++ b/cmd/podman/common/create_test.go @@ -0,0 +1,53 @@ +package common_test + +import ( + "reflect" + "strings" + "testing" + + "github.com/containers/podman/v3/cmd/podman/common" + "github.com/containers/podman/v3/pkg/domain/entities" + "github.com/stretchr/testify/assert" +) + +func TestPodOptions(t *testing.T) { + entry := "/test1" + exampleOptions := entities.ContainerCreateOptions{CPUS: 5.5, CPUSetCPUs: "0-4", Entrypoint: &entry, Hostname: "foo", Name: "testing123", Volume: []string{"/fakeVol1", "/fakeVol2"}, Net: &entities.NetOptions{CNINetworks: []string{"FakeNetwork"}}, PID: "ns:/proc/self/ns"} + + podOptions := entities.PodCreateOptions{} + err := common.ContainerToPodOptions(&exampleOptions, &podOptions) + assert.Nil(t, err) + + cc := reflect.ValueOf(&exampleOptions).Elem() + pc := reflect.ValueOf(&podOptions).Elem() + + pcType := reflect.TypeOf(podOptions) + for i := 0; i < pc.NumField(); i++ { + podField := pc.FieldByIndex([]int{i}) + podType := pcType.Field(i) + for j := 0; j < cc.NumField(); j++ { + containerField := cc.FieldByIndex([]int{j}) + containerType := reflect.TypeOf(exampleOptions).Field(j) + tagPod := strings.Split(string(podType.Tag.Get("json")), ",")[0] + tagContainer := strings.Split(string(containerType.Tag.Get("json")), ",")[0] + if tagPod == tagContainer && (tagPod != "" && tagContainer != "") { + areEqual := true + if containerField.Kind() == podField.Kind() { + switch containerField.Kind() { + case reflect.Slice: + for i, w := range containerField.Interface().([]string) { + areEqual = podField.Interface().([]string)[i] == w + } + case reflect.String: + areEqual = (podField.String() == containerField.String()) + case reflect.Bool: + areEqual = (podField.Bool() == containerField.Bool()) + case reflect.Ptr: + areEqual = (reflect.DeepEqual(podField.Elem().Interface(), containerField.Elem().Interface())) + } + } + assert.True(t, areEqual) + } + } + } +} diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 7000c92c8..ca73a8356 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -132,7 +132,6 @@ func create(cmd *cobra.Command, args []string) error { createOptions.Share = nil } else { // reassign certain optios for lbpod api, these need to be populated in spec - MapOptions() flags := cmd.Flags() infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false) if err != nil { @@ -142,13 +141,11 @@ func create(cmd *cobra.Command, args []string) error { if err != nil { return err } - createOptions.Net = infraOptions.Net createOptions.Share = strings.Split(share, ",") if cmd.Flag("infra-command").Changed { // Only send content to server side if user changed defaults cmdIn, err := cmd.Flags().GetString("infra-command") infraOptions.Entrypoint = &cmdIn - createOptions.InfraCommand = cmdIn if err != nil { return err } @@ -161,6 +158,10 @@ func create(cmd *cobra.Command, args []string) error { return err } } + err = common.ContainerToPodOptions(&infraOptions, &createOptions) + if err != nil { + return err + } } if cmd.Flag("pod-id-file").Changed { @@ -196,8 +197,8 @@ func create(cmd *cobra.Command, args []string) error { if createOptions.Cpus > float64(numCPU) { createOptions.Cpus = float64(numCPU) } - copy := createOptions.CpusetCpus - cpuSet := createOptions.Cpus + copy := infraOptions.CPUSetCPUs + cpuSet := infraOptions.CPUS if cpuSet == 0 { cpuSet = float64(sysinfo.NumCPU()) } @@ -217,10 +218,10 @@ func create(cmd *cobra.Command, args []string) error { if core > int(cpuSet) { if copy == "" { copy = "0-" + strconv.Itoa(int(cpuSet)) - createOptions.CpusetCpus = copy + infraOptions.CPUSetCPUs = copy break } else { - createOptions.CpusetCpus = copy + infraOptions.CPUSetCPUs = copy break } } else if ind != 0 { @@ -229,6 +230,8 @@ func create(cmd *cobra.Command, args []string) error { copy = "" + strconv.Itoa(core) } } + createOptions.Cpus = infraOptions.CPUS + createOptions.CpusetCpus = infraOptions.CPUSetCPUs podSpec := specgen.NewPodSpecGenerator() podSpec, err = entities.ToPodSpecGen(*podSpec, &createOptions) if err != nil { @@ -248,11 +251,8 @@ func create(cmd *cobra.Command, args []string) error { } podSpec.InfraImage = imageName if infraOptions.Entrypoint != nil { - createOptions.InfraCommand = *infraOptions.Entrypoint + createOptions.InfraCommand = infraOptions.Entrypoint } - infraOptions.CPUS = createOptions.Cpus - infraOptions.CPUSetCPUs = createOptions.CpusetCpus - infraOptions.PID = createOptions.Pid podSpec.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false) podSpec.InfraContainerSpec.RawImageName = rawImageName podSpec.InfraContainerSpec.NetworkOptions = podSpec.NetworkOptions @@ -290,13 +290,3 @@ func replacePod(name string) error { } return removePods([]string{name}, rmOptions, false) } - -func MapOptions() { - createOptions.Cpus = infraOptions.CPUS - createOptions.CpusetCpus = infraOptions.CPUSetCPUs - createOptions.Hostname = infraOptions.Hostname - createOptions.InfraConmonPidFile = infraOptions.ConmonPIDFile - createOptions.InfraName = infraOptions.Name - createOptions.Pid = infraOptions.PID - createOptions.Volume = infraOptions.Volume -} -- cgit v1.2.3-54-g00ecf