diff options
31 files changed, 145 insertions, 58 deletions
diff --git a/cmd/podman/auto-update.go b/cmd/podman/auto-update.go index f8b9fba08..1dc29530e 100644 --- a/cmd/podman/auto-update.go +++ b/cmd/podman/auto-update.go @@ -57,7 +57,7 @@ func init() { flags.BoolVar(&autoUpdateOptions.Rollback, "rollback", true, "Rollback to previous image if update fails") flags.StringVar(&autoUpdateOptions.format, "format", "", "Change the output format to JSON or a Go template") - _ = autoUpdateCommand.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(autoUpdateOutput{})) + _ = autoUpdateCommand.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&autoUpdateOutput{})) } func autoUpdate(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index c7d5d6d60..ddf922b2a 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -987,14 +987,12 @@ func AutocompleteFormat(o interface{}) func(cmd *cobra.Command, args []string, t fields := strings.Split(field[len(field)-1], ".") f := reflect.ValueOf(o) for i := 1; i < len(fields); i++ { - if f.Kind() == reflect.Ptr { - f = f.Elem() - } - - // the only supported type is struct - if f.Kind() != reflect.Struct { + val := getActualStructType(f) + if val == nil { + // no struct return nothing to complete return nil, cobra.ShellCompDirectiveNoFileComp } + f = *val // last field get all names to suggest if i == len(fields)-1 { @@ -1012,17 +1010,38 @@ func AutocompleteFormat(o interface{}) func(cmd *cobra.Command, args []string, t } } -// getStructFields reads all struct field names and method names and returns them. -func getStructFields(f reflect.Value, prefix string) []string { - suggestions := []string{} +// getActualStructType take the value and check if it is a struct, +// if it is pointer it will dereference it and when it is nil, +// it will create a new value from it to get the actual struct +// returns nil when type is not a struct +func getActualStructType(f reflect.Value) *reflect.Value { // follow the pointer first if f.Kind() == reflect.Ptr { + // if the pointer is nil we create a new value from the elements type + // this allows us to follow nil pointers and get the actual struct fields + if f.IsNil() { + f = reflect.New(f.Type().Elem()) + } f = f.Elem() } // we only support structs if f.Kind() != reflect.Struct { return nil } + return &f +} + +// getStructFields reads all struct field names and method names and returns them. +func getStructFields(f reflect.Value, prefix string) []string { + suggestions := []string{} + + val := getActualStructType(f) + if val == nil { + // no struct return nothing to complete + return nil + } + f = *val + // loop over all field names for j := 0; j < f.NumField(); j++ { field := f.Type().Field(j) @@ -1037,13 +1056,12 @@ func getStructFields(f reflect.Value, prefix string) []string { if kind == reflect.Struct { suffix = "." } - if strings.HasPrefix(fname, prefix) { - // add field name with suffix - suggestions = append(suggestions, fname+suffix) - } // if field is anonymous add the child fields as well if field.Anonymous { - suggestions = append(suggestions, getStructFields(f.FieldByIndex([]int{j}), prefix)...) + suggestions = append(suggestions, getStructFields(f.Field(j), prefix)...) + } else if strings.HasPrefix(fname, prefix) { + // add field name with suffix + suggestions = append(suggestions, fname+suffix) } } diff --git a/cmd/podman/common/completion_test.go b/cmd/podman/common/completion_test.go index d28ac3928..ae117a173 100644 --- a/cmd/podman/common/completion_test.go +++ b/cmd/podman/common/completion_test.go @@ -34,10 +34,9 @@ func TestAutocompleteFormat(t *testing.T) { Name string Age int Car *Car + Car2 *Car *Anonymous - }{ - Anonymous: &Anonymous{}, - } + }{} testStruct.Car = &Car{} testStruct.Car.Extras = map[string]string{"test": "1"} @@ -80,12 +79,12 @@ func TestAutocompleteFormat(t *testing.T) { { "fist level struct field name", "{{.", - []string{"{{.Name}}", "{{.Age}}", "{{.Car.", "{{.Anonymous.", "{{.Hello}}"}, + []string{"{{.Name}}", "{{.Age}}", "{{.Car.", "{{.Car2.", "{{.Hello}}"}, }, { "fist level struct field name", "{{ .", - []string{"{{ .Name}}", "{{ .Age}}", "{{ .Car.", "{{ .Anonymous.", "{{ .Hello}}"}, + []string{"{{ .Name}}", "{{ .Age}}", "{{ .Car.", "{{ .Car2.", "{{ .Hello}}"}, }, { "fist level struct field name", @@ -103,6 +102,11 @@ func TestAutocompleteFormat(t *testing.T) { []string{"{{ .Car.Brand}}"}, }, { + "second level nil struct field name", + "{{ .Car2.", + []string{"{{ .Car2.Brand}}", "{{ .Car2.Stats.", "{{ .Car2.Extras}}", "{{ .Car2.Color}}", "{{ .Car2.Type}}"}, + }, + { "three level struct field name", "{{ .Car.Stats.", []string{"{{ .Car.Stats.HP}}", "{{ .Car.Stats.Displacement}}"}, diff --git a/cmd/podman/containers/inspect.go b/cmd/podman/containers/inspect.go index 8c219b67c..03e6411a1 100644 --- a/cmd/podman/containers/inspect.go +++ b/cmd/podman/containers/inspect.go @@ -35,12 +35,7 @@ func init() { formatFlagName := "format" flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format the output to a Go template or json") - _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectContainerData{ - State: &define.InspectContainerState{}, - NetworkSettings: &define.InspectNetworkSettings{}, - Config: &define.InspectContainerConfig{}, - HostConfig: &define.InspectContainerHostConfig{}, - })) + _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&define.InspectContainerData{})) validate.AddLatestFlag(inspectCmd, &inspectOpts.Latest) } diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go index 4adae30c2..a011a8ae6 100644 --- a/cmd/podman/containers/ps.go +++ b/cmd/podman/containers/ps.go @@ -80,7 +80,7 @@ func listFlagSet(cmd *cobra.Command) { formatFlagName := "format" flags.StringVar(&listOpts.Format, formatFlagName, "", "Pretty-print containers to JSON or using a Go template") - _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.ListContainer{})) + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&psReporter{})) lastFlagName := "last" flags.IntVarP(&listOpts.Last, lastFlagName, "n", -1, "Print the n last created containers (all states)") diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go index 715f5c081..500671d31 100644 --- a/cmd/podman/containers/stats.go +++ b/cmd/podman/containers/stats.go @@ -67,7 +67,7 @@ func statFlags(cmd *cobra.Command) { formatFlagName := "format" flags.StringVar(&statsOptions.Format, formatFlagName, "", "Pretty-print container statistics to JSON or using a Go template") - _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.ContainerStats{})) + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&containerStats{})) flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen between intervals") flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false") diff --git a/cmd/podman/images/history.go b/cmd/podman/images/history.go index 26a4b6c3b..e190941e7 100644 --- a/cmd/podman/images/history.go +++ b/cmd/podman/images/history.go @@ -69,7 +69,7 @@ func historyFlags(cmd *cobra.Command) { formatFlagName := "format" flags.StringVar(&opts.format, formatFlagName, "", "Change the output to JSON or a Go template") - _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.ImageHistoryLayer{})) + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&historyReporter{})) flags.BoolVarP(&opts.human, "human", "H", true, "Display sizes and dates in human readable format") flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate the output") diff --git a/cmd/podman/images/inspect.go b/cmd/podman/images/inspect.go index b4a79bc96..22c404b3f 100644 --- a/cmd/podman/images/inspect.go +++ b/cmd/podman/images/inspect.go @@ -34,7 +34,7 @@ func init() { formatFlagName := "format" flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format the output to a Go template or json") - _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(inspectTypes.ImageData{})) + _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&inspectTypes.ImageData{})) } func inspectExec(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go index 58fb3e919..81011f9b1 100644 --- a/cmd/podman/images/list.go +++ b/cmd/podman/images/list.go @@ -94,7 +94,7 @@ func imageListFlagSet(cmd *cobra.Command) { formatFlagName := "format" flags.StringVar(&listFlag.format, formatFlagName, "", "Change the output format to JSON or a Go template") - _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.ImageSummary{})) + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&imageReporter{})) flags.BoolVar(&listFlag.digests, "digests", false, "Show digests") flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print column headings") diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go index 7f202cb6a..335ea2b5a 100644 --- a/cmd/podman/images/search.go +++ b/cmd/podman/images/search.go @@ -9,6 +9,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/report" "github.com/containers/image/v5/types" + "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/pkg/errors" @@ -87,7 +88,7 @@ func searchFlags(cmd *cobra.Command) { formatFlagName := "format" flags.StringVar(&searchOptions.Format, formatFlagName, "", "Change the output format to JSON or a Go template") - _ = cmd.RegisterFlagCompletionFunc(formatFlagName, completion.AutocompleteNone) + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.ImageSearchReport{})) limitFlagName := "limit" flags.IntVar(&searchOptions.Limit, limitFlagName, 0, "Limit the number of results") diff --git a/cmd/podman/machine/inspect.go b/cmd/podman/machine/inspect.go index 68706226a..21e5074b7 100644 --- a/cmd/podman/machine/inspect.go +++ b/cmd/podman/machine/inspect.go @@ -41,7 +41,7 @@ func init() { flags := inspectCmd.Flags() formatFlagName := "format" flags.StringVar(&inspectFlag.format, formatFlagName, "", "Format volume output using JSON or a Go template") - _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(machine.InspectInfo{})) + _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&machine.InspectInfo{})) } func inspect(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/machine/list.go b/cmd/podman/machine/list.go index 587e521a3..c987bf71a 100644 --- a/cmd/podman/machine/list.go +++ b/cmd/podman/machine/list.go @@ -69,7 +69,7 @@ func init() { flags := lsCmd.Flags() formatFlagName := "format" flags.StringVar(&listFlag.format, formatFlagName, "{{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\t{{.CPUs}}\t{{.Memory}}\t{{.DiskSize}}\n", "Format volume output using JSON or a Go template") - _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(machineReporter{})) + _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&machineReporter{})) flags.BoolVar(&listFlag.noHeading, "noheading", false, "Do not print headers") flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Show only machine names") } diff --git a/cmd/podman/networks/inspect.go b/cmd/podman/networks/inspect.go index 3c07e5492..8f39ec395 100644 --- a/cmd/podman/networks/inspect.go +++ b/cmd/podman/networks/inspect.go @@ -1,6 +1,7 @@ package network import ( + "github.com/containers/common/libnetwork/types" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/inspect" "github.com/containers/podman/v4/cmd/podman/registry" @@ -32,7 +33,7 @@ func init() { formatFlagName := "format" flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "", "Pretty-print network to JSON or using a Go template") - _ = networkinspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil)) + _ = networkinspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&types.Network{})) } func networkInspect(_ *cobra.Command, args []string) error { diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go index f14e0ed0f..5d4be2a81 100644 --- a/cmd/podman/networks/list.go +++ b/cmd/podman/networks/list.go @@ -40,7 +40,7 @@ var ( func networkListFlags(flags *pflag.FlagSet) { formatFlagName := "format" flags.StringVar(&networkListOptions.Format, formatFlagName, "", "Pretty-print networks to JSON or using a Go template") - _ = networklistCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(ListPrintReports{})) + _ = networklistCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&ListPrintReports{})) flags.BoolVarP(&networkListOptions.Quiet, "quiet", "q", false, "display only names") flags.BoolVar(&noTrunc, "no-trunc", false, "Do not truncate the network ID") diff --git a/cmd/podman/pods/inspect.go b/cmd/podman/pods/inspect.go index ae6a5ba88..bb30fe6e6 100644 --- a/cmd/podman/pods/inspect.go +++ b/cmd/podman/pods/inspect.go @@ -9,7 +9,6 @@ import ( "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/validate" - "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -43,7 +42,7 @@ func init() { formatFlagName := "format" flags.StringVarP(&inspectOptions.Format, formatFlagName, "f", "json", "Format the output to a Go template or json") - _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectPodData{})) + _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.PodInspectReport{})) validate.AddLatestFlag(inspectCmd, &inspectOptions.Latest) } diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go index 4a049541a..1275e65dc 100644 --- a/cmd/podman/pods/ps.go +++ b/cmd/podman/pods/ps.go @@ -57,7 +57,7 @@ func init() { formatFlagName := "format" flags.StringVar(&psInput.Format, formatFlagName, "", "Pretty-print pods to JSON or using a Go template") - _ = psCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(ListPodReporter{ListPodsReport: &entities.ListPodsReport{}})) + _ = psCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&ListPodReporter{})) flags.Bool("noheading", false, "Do not print headers") flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod") diff --git a/cmd/podman/pods/stats.go b/cmd/podman/pods/stats.go index f7a56d3f3..9833f4cea 100644 --- a/cmd/podman/pods/stats.go +++ b/cmd/podman/pods/stats.go @@ -54,7 +54,7 @@ func init() { formatFlagName := "format" flags.StringVar(&statsOptions.Format, formatFlagName, "", "Pretty-print container statistics to JSON or using a Go template") - _ = statsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.PodStatsReport{})) + _ = statsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.PodStatsReport{})) flags.BoolVar(&statsOptions.NoReset, "no-reset", false, "Disable resetting the screen when streaming") flags.BoolVar(&statsOptions.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result") diff --git a/cmd/podman/secrets/inspect.go b/cmd/podman/secrets/inspect.go index 0977434f7..e8947e441 100644 --- a/cmd/podman/secrets/inspect.go +++ b/cmd/podman/secrets/inspect.go @@ -36,7 +36,7 @@ func init() { flags := inspectCmd.Flags() formatFlagName := "format" flags.StringVar(&format, formatFlagName, "", "Format volume output using Go template") - _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.SecretInfoReport{})) + _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.SecretInfoReport{})) } func inspect(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/secrets/list.go b/cmd/podman/secrets/list.go index 2ef84cd48..558a16ccf 100644 --- a/cmd/podman/secrets/list.go +++ b/cmd/podman/secrets/list.go @@ -45,7 +45,7 @@ func init() { flags := lsCmd.Flags() formatFlagName := "format" flags.StringVar(&listFlag.format, formatFlagName, "{{.ID}}\t{{.Name}}\t{{.Driver}}\t{{.CreatedAt}}\t{{.UpdatedAt}}\t\n", "Format volume output using Go template") - _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.SecretInfoReport{})) + _ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.SecretInfoReport{})) filterFlagName := "filter" flags.StringSliceVarP(&listFlag.filter, filterFlagName, "f", []string{}, "Filter secret output") _ = lsCmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteSecretFilters) diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go index fe37677df..2c5f6a310 100644 --- a/cmd/podman/system/connection/list.go +++ b/cmd/podman/system/connection/list.go @@ -38,7 +38,7 @@ func init() { }) listCmd.Flags().String("format", "", "Custom Go template for printing connections") - _ = listCmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(namedDestination{})) + _ = listCmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) } type namedDestination struct { diff --git a/cmd/podman/system/events.go b/cmd/podman/system/events.go index 2723adc43..09e589d3c 100644 --- a/cmd/podman/system/events.go +++ b/cmd/podman/system/events.go @@ -51,7 +51,7 @@ func init() { formatFlagName := "format" flags.StringVar(&eventFormat, formatFlagName, "", "format the output using a Go template") - _ = eventsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(events.Event{})) + _ = eventsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&events.Event{})) flags.BoolVar(&eventOptions.Stream, "stream", true, "stream new events; for testing only") diff --git a/cmd/podman/system/info.go b/cmd/podman/system/info.go index e95e9336d..f8fd946cd 100644 --- a/cmd/podman/system/info.go +++ b/cmd/podman/system/info.go @@ -66,7 +66,7 @@ func infoFlags(cmd *cobra.Command) { formatFlagName := "format" flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") - _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.Info{Host: &define.HostInfo{}, Store: &define.StoreInfo{}})) + _ = cmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&define.Info{})) } func info(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go index 9fb4a966a..7202b2c08 100644 --- a/cmd/podman/system/version.go +++ b/cmd/podman/system/version.go @@ -34,7 +34,7 @@ func init() { formatFlagName := "format" flags.StringVarP(&versionFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template") - _ = versionCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(entities.SystemVersionReport{})) + _ = versionCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.SystemVersionReport{})) } func version(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/volumes/inspect.go b/cmd/podman/volumes/inspect.go index 2230a2818..f21f9c233 100644 --- a/cmd/podman/volumes/inspect.go +++ b/cmd/podman/volumes/inspect.go @@ -41,7 +41,7 @@ func init() { formatFlagName := "format" flags.StringVarP(&inspectOpts.Format, formatFlagName, "f", "json", "Format volume output using Go template") - _ = inspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectVolumeData{})) + _ = inspectCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&define.InspectVolumeData{})) } func volumeInspect(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/volumes/list.go b/cmd/podman/volumes/list.go index 2edf04097..c14cf08bd 100644 --- a/cmd/podman/volumes/list.go +++ b/cmd/podman/volumes/list.go @@ -11,7 +11,6 @@ import ( "github.com/containers/podman/v4/cmd/podman/parse" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/validate" - "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -57,7 +56,7 @@ func init() { formatFlagName := "format" flags.StringVar(&cliOpts.Format, formatFlagName, "{{.Driver}}\t{{.Name}}\n", "Format volume output using Go template") - _ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(define.InspectVolumeData{})) + _ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.VolumeListReport{})) flags.Bool("noheading", false, "Do not print headers") flags.BoolVarP(&cliOpts.Quiet, "quiet", "q", false, "Print volume output in quiet mode") diff --git a/libpod/pod.go b/libpod/pod.go index ed2d97b37..6cfe76a18 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -159,6 +159,15 @@ func (p *Pod) CPUQuota() int64 { return 0 } +// NetworkMode returns the Network mode given by the user ex: pod, private... +func (p *Pod) NetworkMode() string { + infra, err := p.runtime.GetContainer(p.state.InfraContainerID) + if err != nil { + return "" + } + return infra.NetworkMode() +} + // PidMode returns the PID mode given by the user ex: pod, private... func (p *Pod) PidMode() string { infra, err := p.runtime.GetContainer(p.state.InfraContainerID) diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 48049798b..ba30d878e 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -593,7 +593,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { return nil, err } infraConfig = new(define.InspectPodInfraConfig) - infraConfig.HostNetwork = !infra.config.ContainerNetworkConfig.UseImageHosts + infraConfig.HostNetwork = p.NetworkMode() == "host" infraConfig.StaticIP = infra.config.ContainerNetworkConfig.StaticIP infraConfig.NoManageResolvConf = infra.config.UseImageResolvConf infraConfig.NoManageHosts = infra.config.UseImageHosts diff --git a/pkg/machine/e2e/config.go b/pkg/machine/e2e/config.go index 7d75ca6bc..c17b840d3 100644 --- a/pkg/machine/e2e/config.go +++ b/pkg/machine/e2e/config.go @@ -131,7 +131,7 @@ func (m *machineTestBuilder) setTimeout(timeout time.Duration) *machineTestBuild func (mb *machineTestBuilder) toQemuInspectInfo() ([]qemuMachineInspectInfo, int, error) { args := []string{"machine", "inspect"} args = append(args, mb.names...) - session, err := runWrapper(mb.podmanBinary, args, defaultTimeout) + session, err := runWrapper(mb.podmanBinary, args, defaultTimeout, true) if err != nil { return nil, -1, err } @@ -140,11 +140,15 @@ func (mb *machineTestBuilder) toQemuInspectInfo() ([]qemuMachineInspectInfo, int return mii, session.ExitCode(), err } +func (m *machineTestBuilder) runWithoutWait() (*machineSession, error) { + return runWrapper(m.podmanBinary, m.cmd, m.timeout, false) +} + func (m *machineTestBuilder) run() (*machineSession, error) { - return runWrapper(m.podmanBinary, m.cmd, m.timeout) + return runWrapper(m.podmanBinary, m.cmd, m.timeout, true) } -func runWrapper(podmanBinary string, cmdArgs []string, timeout time.Duration) (*machineSession, error) { +func runWrapper(podmanBinary string, cmdArgs []string, timeout time.Duration, wait bool) (*machineSession, error) { if len(os.Getenv("DEBUG")) > 0 { cmdArgs = append([]string{"--log-level=debug"}, cmdArgs...) } @@ -156,8 +160,10 @@ func runWrapper(podmanBinary string, cmdArgs []string, timeout time.Duration) (* return nil, err } ms := machineSession{session} - ms.waitWithTimeout(timeout) - fmt.Println("output:", ms.outputToString()) + if wait { + ms.waitWithTimeout(timeout) + fmt.Println("output:", ms.outputToString()) + } return &ms, nil } diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go index e7a439945..0ce9063f9 100644 --- a/pkg/machine/e2e/list_test.go +++ b/pkg/machine/e2e/list_test.go @@ -70,6 +70,33 @@ var _ = Describe("podman machine list", func() { Expect(util.StringInSlice(name1, listNames)).To(BeTrue()) Expect(util.StringInSlice(name2, listNames)).To(BeTrue()) }) + + It("list machine: check if running while starting", func() { + i := new(initMachine) + session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run() + Expect(err).To(BeNil()) + Expect(session).To(Exit(0)) + s := new(startMachine) + startSession, err := mb.setCmd(s).runWithoutWait() + Expect(err).To(BeNil()) + l := new(listMachine) + for { // needs to be infinite because we need to check if running when inspect returns to avoid race conditions. + listSession, err := mb.setCmd(l).run() + Expect(listSession).To(Exit(0)) + Expect(err).To(BeNil()) + if startSession.ExitCode() == -1 { + Expect(listSession.outputToString()).NotTo(ContainSubstring("Currently running")) + } else { + break + } + } + Expect(startSession).To(Exit(0)) + listSession, err := mb.setCmd(l).run() + Expect(listSession).To(Exit(0)) + Expect(err).To(BeNil()) + Expect(listSession.outputToString()).To(ContainSubstring("Currently running")) + Expect(listSession.outputToString()).NotTo(ContainSubstring("Less than a second ago")) // check to make sure time created is accurate + }) }) func stripAsterisk(sl []string) { diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 44f28f0c7..35eea5fb4 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -1065,11 +1065,11 @@ func getVMInfos() ([]*machine.ListResponse, error) { return err } - if !vm.LastUp.IsZero() { + if !vm.LastUp.IsZero() { // this means we have already written a time to the config listEntry.LastUp = vm.LastUp - } else { + } else { // else we just created the machine AKA last up = created time listEntry.LastUp = vm.Created - vm.Created = time.Now() + vm.LastUp = listEntry.LastUp if err := vm.writeConfig(); err != nil { return err } diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index ef4bf1a6c..64f95f723 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -381,4 +381,32 @@ EOF is "$output" ".*$container_3_ID.*" } +@test "podman pod create share net" { + run_podman pod create --name test + run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + is "$output" "false" "Default network sharing should be false" + run_podman pod rm test + + run_podman pod create --name test --share ipc --network private + run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + is "$output" "false" "Private network sharing with only ipc should be false" + run_podman pod rm test + + run_podman pod create --name test --share net --network private + run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + is "$output" "false" "Private network sharing with only net should be false" + run_podman pod rm test + + run_podman pod create --name test --share net --network host + run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + is "$output" "true" "Host network sharing with only net should be true" + run_podman pod rm test + + run_podman pod create --name test --share ipc --network host + run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + is "$output" "true" "Host network sharing with only ipc should be true" + run_podman pod rm test + +} + # vim: filetype=sh |