diff options
-rw-r--r-- | cmd/podman/cliconfig/config.go | 14 | ||||
-rw-r--r-- | cmd/podman/network.go | 31 | ||||
-rw-r--r-- | cmd/podman/network_inspect.go | 48 | ||||
-rw-r--r-- | cmd/podman/network_list.go | 53 | ||||
-rw-r--r-- | cmd/podman/network_rm.go | 48 | ||||
-rw-r--r-- | commands.md | 4 | ||||
-rw-r--r-- | completions/bash/podman | 72 | ||||
-rw-r--r-- | docs/podman-network-inspect.1.md | 50 | ||||
-rw-r--r-- | docs/podman-network-ls.1.md | 43 | ||||
-rw-r--r-- | docs/podman-network-rm.1.md | 25 | ||||
-rw-r--r-- | docs/podman-network.1.md | 21 | ||||
-rw-r--r-- | docs/podman.1.md | 1 | ||||
-rw-r--r-- | pkg/adapter/network.go | 147 | ||||
-rw-r--r-- | pkg/network/config.go | 4 | ||||
-rw-r--r-- | pkg/network/network.go | 26 | ||||
-rw-r--r-- | test/e2e/network_test.go | 158 |
16 files changed, 745 insertions, 0 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index d5098ee51..f7c78908f 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -258,6 +258,20 @@ type MountValues struct { Latest bool } +type NetworkListValues struct { + PodmanCommand + Filter []string + Quiet bool +} + +type NetworkRmValues struct { + PodmanCommand +} + +type NetworkInspectValues struct { + PodmanCommand +} + type PauseValues struct { PodmanCommand All bool diff --git a/cmd/podman/network.go b/cmd/podman/network.go new file mode 100644 index 000000000..83a5e71ab --- /dev/null +++ b/cmd/podman/network.go @@ -0,0 +1,31 @@ +//+build !remoteclient + +package main + +import ( + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/spf13/cobra" +) + +var networkcheckDescription = "Manage networks" +var networkcheckCommand = cliconfig.PodmanCommand{ + Command: &cobra.Command{ + Use: "network", + Short: "Manage Networks", + Long: networkcheckDescription, + RunE: commandRunE(), + }, +} + +// Commands that are universally implemented +var networkcheckCommands = []*cobra.Command{ + _networkinspectCommand, + _networklistCommand, + _networkrmCommand, +} + +func init() { + networkcheckCommand.AddCommand(networkcheckCommands...) + networkcheckCommand.SetUsageTemplate(UsageTemplate()) + rootCmd.AddCommand(networkcheckCommand.Command) +} diff --git a/cmd/podman/network_inspect.go b/cmd/podman/network_inspect.go new file mode 100644 index 000000000..38aaf6ba4 --- /dev/null +++ b/cmd/podman/network_inspect.go @@ -0,0 +1,48 @@ +// +build !remoteclient + +package main + +import ( + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/rootless" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + networkinspectCommand cliconfig.NetworkInspectValues + networkinspectDescription = `Inspect network` + _networkinspectCommand = &cobra.Command{ + Use: "inspect NETWORK [NETWORK...] [flags] ", + Short: "network inspect", + Long: networkinspectDescription, + RunE: func(cmd *cobra.Command, args []string) error { + networkinspectCommand.InputArgs = args + networkinspectCommand.GlobalFlags = MainGlobalOpts + networkinspectCommand.Remote = remoteclient + return networkinspectCmd(&networkinspectCommand) + }, + Example: `podman network inspect podman`, + } +) + +func init() { + networkinspectCommand.Command = _networkinspectCommand + networkinspectCommand.SetHelpTemplate(HelpTemplate()) + networkinspectCommand.SetUsageTemplate(UsageTemplate()) +} + +func networkinspectCmd(c *cliconfig.NetworkInspectValues) error { + if rootless.IsRootless() && !remoteclient { + return errors.New("network inspect is not supported for rootless mode") + } + if len(c.InputArgs) < 1 { + return errors.Errorf("at least one network name is required") + } + runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand) + if err != nil { + return err + } + return runtime.NetworkInspect(c) +} diff --git a/cmd/podman/network_list.go b/cmd/podman/network_list.go new file mode 100644 index 000000000..16edf743b --- /dev/null +++ b/cmd/podman/network_list.go @@ -0,0 +1,53 @@ +// +build !remoteclient + +package main + +import ( + "errors" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/rootless" + "github.com/spf13/cobra" +) + +var ( + networklistCommand cliconfig.NetworkListValues + networklistDescription = `List networks` + _networklistCommand = &cobra.Command{ + Use: "ls", + Args: noSubArgs, + Short: "network list", + Long: networklistDescription, + RunE: func(cmd *cobra.Command, args []string) error { + networklistCommand.InputArgs = args + networklistCommand.GlobalFlags = MainGlobalOpts + networklistCommand.Remote = remoteclient + return networklistCmd(&networklistCommand) + }, + Example: `podman network list`, + } +) + +func init() { + networklistCommand.Command = _networklistCommand + networklistCommand.SetHelpTemplate(HelpTemplate()) + networklistCommand.SetUsageTemplate(UsageTemplate()) + flags := networklistCommand.Flags() + // TODO enable filters based on something + //flags.StringSliceVarP(&networklistCommand.Filter, "filter", "f", []string{}, "Pause all running containers") + flags.BoolVarP(&networklistCommand.Quiet, "quiet", "q", false, "display only names") +} + +func networklistCmd(c *cliconfig.NetworkListValues) error { + if rootless.IsRootless() && !remoteclient { + return errors.New("network list is not supported for rootless mode") + } + if len(c.InputArgs) > 0 { + return errors.New("network list takes no arguments") + } + runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand) + if err != nil { + return err + } + return runtime.NetworkList(c) +} diff --git a/cmd/podman/network_rm.go b/cmd/podman/network_rm.go new file mode 100644 index 000000000..50bd48cea --- /dev/null +++ b/cmd/podman/network_rm.go @@ -0,0 +1,48 @@ +// +build !remoteclient + +package main + +import ( + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/rootless" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + networkrmCommand cliconfig.NetworkRmValues + networkrmDescription = `Remove networks` + _networkrmCommand = &cobra.Command{ + Use: "rm [flags] NETWORK [NETWORK...]", + Short: "network rm", + Long: networkrmDescription, + RunE: func(cmd *cobra.Command, args []string) error { + networkrmCommand.InputArgs = args + networkrmCommand.GlobalFlags = MainGlobalOpts + networkrmCommand.Remote = remoteclient + return networkrmCmd(&networkrmCommand) + }, + Example: `podman network rm podman`, + } +) + +func init() { + networkrmCommand.Command = _networkrmCommand + networkrmCommand.SetHelpTemplate(HelpTemplate()) + networkrmCommand.SetUsageTemplate(UsageTemplate()) +} + +func networkrmCmd(c *cliconfig.NetworkRmValues) error { + if rootless.IsRootless() && !remoteclient { + return errors.New("network rm is not supported for rootless mode") + } + if len(c.InputArgs) < 1 { + return errors.Errorf("at least one network name is required") + } + runtime, err := adapter.GetRuntimeNoStore(getContext(), &c.PodmanCommand) + if err != nil { + return err + } + return runtime.NetworkRemove(c) +} diff --git a/commands.md b/commands.md index 1b48d7862..4d3bea439 100644 --- a/commands.md +++ b/commands.md @@ -44,6 +44,10 @@ | [podman-logout(1)](/docs/podman-logout.1.md) | Logout of a container registry | | [podman-logs(1)](/docs/podman-logs.1.md) | Display the logs of a container | | [podman-mount(1)](/docs/podman-mount.1.md) | Mount a working container's root filesystem | +| [podman-network(1)](/docs/podman-network.1.md) | Manage Podman CNI networks | +| [podman-network-inspect(1)](/docs/podman-network-inspect.1.md) | Inspect one or more Podman networks | +| [podman-network-ls(1)](/docs/podman-network-ls.1.md) | Display a summary of Podman networks | +| [podman-network-rm(1)](/docs/podman-network-rm.1.md) | Remove one or more Podman networks | | [podman-pause(1)](/docs/podman-pause.1.md) | Pause one or more running containers | [![...](/docs/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) | | [podman-play(1)](/docs/podman-play.1.md) | Play pods and containers based on a structured input file | | [podman-pod(1)](/docs/podman-pod.1.md) | Simple management tool for groups of containers, called pods | diff --git a/completions/bash/podman b/completions/bash/podman index d2eb5b570..cf9b31393 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -946,6 +946,78 @@ _podman_healthcheck() { esac } +_podman_network() { + local boolean_options=" + --help + -h + " + subcommands=" + inspect + ls + rm + " + __podman_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_podman_network_inspect() { + local options_with_args=" + " + local boolean_options=" + --help + -h + " + _complete_ "$options_with_args" "$boolean_options" + + case "$cur" in + -*) + COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) + ;; + esac +} + +_podman_network_ls() { + local options_with_args=" + " + local boolean_options=" + --help + -h + --quiet + -q + " + _complete_ "$options_with_args" "$boolean_options" + + case "$cur" in + -*) + COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) + ;; + esac +} + +_podman_network_ls() { + local options_with_args=" + " + local boolean_options=" + --help + -h + " + _complete_ "$options_with_args" "$boolean_options" + + case "$cur" in + -*) + COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) + ;; + esac +} + _podman_generate() { local boolean_options=" --help diff --git a/docs/podman-network-inspect.1.md b/docs/podman-network-inspect.1.md new file mode 100644 index 000000000..576e61c79 --- /dev/null +++ b/docs/podman-network-inspect.1.md @@ -0,0 +1,50 @@ +% podman-network-inspect(1) + +## NAME +podman\-network-inspect- Inspect one or more Podman networks + +## SYNOPSIS +**podman network inspect** [*network* ...] + +## DESCRIPTION +Display the raw (JSON format) network configuration. This command is not available for rootless users. + +## EXAMPLE + +Inspect the default podman network + +``` +# podman network inspect podman +[{ + "cniVersion": "0.3.0", + "name": "podman", + "plugins": [ + { + "type": "bridge", + "bridge": "cni0", + "isGateway": true, + "ipMasq": true, + "ipam": { + "type": "host-local", + "subnet": "10.88.1.0/24", + "routes": [ + { "dst": "0.0.0.0/0" } + ] + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] +} +] +``` + +## SEE ALSO +podman(1), podman-network(1), podman-network-ls(1) + +## HISTORY +August 2019, Originally compiled by Brent Baude <bbaude@redhat.com> diff --git a/docs/podman-network-ls.1.md b/docs/podman-network-ls.1.md new file mode 100644 index 000000000..725e07dbb --- /dev/null +++ b/docs/podman-network-ls.1.md @@ -0,0 +1,43 @@ +% podman-network-ls(1) + +## NAME +podman\-network-ls- Display a summary of CNI networks + +## SYNOPSIS +**podman network ls** [*options*] + +## DESCRIPTION +Displays a list of existing podman networks. This command is not available for rootless users. + +## OPTIONS +**--quiet**, **-q** + +The `quiet` options will restrict the output to only the network names + +## EXAMPLE + +Display networks + +``` +# podman network ls +NAME VERSION PLUGINS +podman 0.3.0 bridge,portmap +podman2 0.3.0 bridge,portmap +outside 0.3.0 bridge +podman9 0.3.0 bridge,portmap +``` + +Display only network names +``` +# podman network ls -q +podman +podman2 +outside +podman9 +``` + +## SEE ALSO +podman(1), podman-network(1), podman-network-inspect(1) + +## HISTORY +August 2019, Originally compiled by Brent Baude <bbaude@redhat.com> diff --git a/docs/podman-network-rm.1.md b/docs/podman-network-rm.1.md new file mode 100644 index 000000000..f72d6a694 --- /dev/null +++ b/docs/podman-network-rm.1.md @@ -0,0 +1,25 @@ +% podman-network-rm(1) + +## NAME +podman\-network-rm- Delete a Podman CNI network + +## SYNOPSIS +**podman network rm** [*network...*] + +## DESCRIPTION +Delete one or more Podman networks. + +## EXAMPLE + +Delete the `podman9` network + +``` +# podman network rm podman +Deleted: podman9 +``` + +## SEE ALSO +podman(1), podman-network(1), podman-network-inspect(1) + +## HISTORY +August 2019, Originally compiled by Brent Baude <bbaude@redhat.com> diff --git a/docs/podman-network.1.md b/docs/podman-network.1.md new file mode 100644 index 000000000..c01adc23e --- /dev/null +++ b/docs/podman-network.1.md @@ -0,0 +1,21 @@ +% podman-network(1) + +## NAME +podman\-network- Manage podman CNI networks + +## SYNOPSIS +**podman network** *subcommand* + +## DESCRIPTION +The network command manages CNI networks for Podman. It is not supported for rootless users. + +## COMMANDS + +| Command | Man Page | Description | +| ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | +| inspect | [podman-network-inspect(1)](podman-network-inspect.1.md)| Displays the raw CNI network configuration for one or more networks| +| ls | [podman-network-ls(1)](podman-network-ls.1.md)| Display a summary of CNI networks | +| rm | [podman-network-rm(1)](podman-network-rm.1.md)| Remove one or more CNI networks | + +## SEE ALSO +podman(1) diff --git a/docs/podman.1.md b/docs/podman.1.md index 12b7866ca..33ea81ef6 100644 --- a/docs/podman.1.md +++ b/docs/podman.1.md @@ -161,6 +161,7 @@ the exit codes follow the `chroot` standard, see below: | [podman-logout(1)](podman-logout.1.md) | Logout of a container registry. | | [podman-logs(1)](podman-logs.1.md) | Display the logs of a container. | | [podman-mount(1)](podman-mount.1.md) | Mount a working container's root filesystem. | +| [podman-network(1)](podman-network.1.md) | Manage Podman CNI networks. | | [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. | | [podman-play(1)](podman-play.1.md) | Play pods and containers based on a structured input file. | | [podman-pod(1)](podman-pod.1.md) | Management tool for groups of containers, called pods. | diff --git a/pkg/adapter/network.go b/pkg/adapter/network.go new file mode 100644 index 000000000..cf3a1dfdd --- /dev/null +++ b/pkg/adapter/network.go @@ -0,0 +1,147 @@ +// +build !remoteclient + +package adapter + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" + "text/tabwriter" + + "github.com/containernetworking/cni/libcni" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/pkg/network" + "github.com/pkg/errors" +) + +func getCNIConfDir(r *LocalRuntime) (string, error) { + config, err := r.GetConfig() + if err != nil { + return "", err + } + configPath := config.CNIConfigDir + + if len(config.CNIConfigDir) < 1 { + configPath = network.CNIConfigDir + } + return configPath, nil +} + +// NetworkList displays summary information about CNI networks +func (r *LocalRuntime) NetworkList(cli *cliconfig.NetworkListValues) error { + cniConfigPath, err := getCNIConfDir(r) + if err != nil { + return err + } + networks, err := network.LoadCNIConfsFromDir(cniConfigPath) + if err != nil { + return err + } + // quiet means we only print the network names + if cli.Quiet { + for _, cniNetwork := range networks { + fmt.Println(cniNetwork.Name) + } + return nil + } + w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) + if _, err := fmt.Fprintln(w, "NAME\tVERSION\tPLUGINS"); err != nil { + return err + } + for _, cniNetwork := range networks { + if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", cniNetwork.Name, cniNetwork.CNIVersion, getCNIPlugins(cniNetwork)); err != nil { + return err + } + } + return w.Flush() +} + +// NetworkInspect displays the raw CNI configuration for one +// or more CNI networks +func (r *LocalRuntime) NetworkInspect(cli *cliconfig.NetworkInspectValues) error { + var ( + rawCNINetworks []map[string]interface{} + ) + cniConfigPath, err := getCNIConfDir(r) + if err != nil { + return err + } + for _, name := range cli.InputArgs { + b, err := readRawCNIConfByName(name, cniConfigPath) + if err != nil { + return err + } + rawList := make(map[string]interface{}) + if err := json.Unmarshal(b, &rawList); err != nil { + return fmt.Errorf("error parsing configuration list: %s", err) + } + rawCNINetworks = append(rawCNINetworks, rawList) + } + out, err := json.MarshalIndent(rawCNINetworks, "", "\t") + if err != nil { + return err + } + fmt.Printf("%s\n", out) + return nil +} + +// NetworkRemove deletes one or more CNI networks +func (r *LocalRuntime) NetworkRemove(cli *cliconfig.NetworkRmValues) error { + cniConfigPath, err := getCNIConfDir(r) + if err != nil { + return err + } + for _, name := range cli.InputArgs { + cniPath, err := getCNIConfigPathByName(name, cniConfigPath) + if err != nil { + return err + } + if err := os.Remove(cniPath); err != nil { + return err + } + fmt.Printf("Deleted: %s\n", name) + } + return nil +} + +// getCNIConfigPathByName finds a CNI network by name and +// returns its configuration file path +func getCNIConfigPathByName(name, cniConfigPath string) (string, error) { + files, err := libcni.ConfFiles(cniConfigPath, []string{".conflist"}) + if err != nil { + return "", err + } + for _, confFile := range files { + conf, err := libcni.ConfListFromFile(confFile) + if err != nil { + return "", err + } + if conf.Name == name { + return confFile, nil + } + } + return "", errors.Errorf("unable to find network configuration for %s", name) +} + +// readRawCNIConfByName reads the raw CNI configuration for a CNI +// network by name +func readRawCNIConfByName(name, cniConfigPath string) ([]byte, error) { + confFile, err := getCNIConfigPathByName(name, cniConfigPath) + if err != nil { + return nil, err + } + b, err := ioutil.ReadFile(confFile) + return b, err +} + +// getCNIPlugins returns a list of plugins that a given network +// has in the form of a string +func getCNIPlugins(list *libcni.NetworkConfigList) string { + var plugins []string + for _, plug := range list.Plugins { + plugins = append(plugins, plug.Network.Type) + } + return strings.Join(plugins, ",") +} diff --git a/pkg/network/config.go b/pkg/network/config.go new file mode 100644 index 000000000..d282f66b6 --- /dev/null +++ b/pkg/network/config.go @@ -0,0 +1,4 @@ +package network + +// CNIConfigDir is the path where CNI config files exist +const CNIConfigDir = "/etc/cni/net.d" diff --git a/pkg/network/network.go b/pkg/network/network.go new file mode 100644 index 000000000..9d04340a3 --- /dev/null +++ b/pkg/network/network.go @@ -0,0 +1,26 @@ +package network + +import ( + "sort" + + "github.com/containernetworking/cni/libcni" +) + +// LoadCNIConfsFromDir loads all the CNI configurations from a dir +func LoadCNIConfsFromDir(dir string) ([]*libcni.NetworkConfigList, error) { + var configs []*libcni.NetworkConfigList + files, err := libcni.ConfFiles(dir, []string{".conflist"}) + if err != nil { + return nil, err + } + sort.Strings(files) + + for _, confFile := range files { + conf, err := libcni.ConfListFromFile(confFile) + if err != nil { + return nil, err + } + configs = append(configs, conf) + } + return configs, nil +} diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go new file mode 100644 index 000000000..9aed5351a --- /dev/null +++ b/test/e2e/network_test.go @@ -0,0 +1,158 @@ +// +build !remoteclient + +package integration + +import ( + "fmt" + . "github.com/containers/libpod/test/utils" + "github.com/containers/storage/pkg/stringid" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "io/ioutil" + "os" + "path/filepath" +) + +func writeConf(conf []byte, confPath string) { + if err := ioutil.WriteFile(confPath, conf, 777); err != nil { + fmt.Println(err) + } +} +func removeConf(confPath string) { + if err := os.Remove(confPath); err != nil { + fmt.Println(err) + } +} + +var _ = Describe("Podman network", func() { + var ( + tempdir string + err error + podmanTest *PodmanTestIntegration + ) + + BeforeEach(func() { + tempdir, err = CreateTempDirInTempDir() + if err != nil { + os.Exit(1) + } + podmanTest = PodmanTestCreate(tempdir) + podmanTest.Setup() + }) + + AfterEach(func() { + podmanTest.Cleanup() + f := CurrentGinkgoTestDescription() + processTestResult(f) + + }) + + var ( + secondConf = `{ + "cniVersion": "0.3.0", + "name": "podman-integrationtest", + "plugins": [ + { + "type": "bridge", + "bridge": "cni1", + "isGateway": true, + "ipMasq": true, + "ipam": { + "type": "host-local", + "subnet": "10.99.0.0/16", + "routes": [ + { "dst": "0.0.0.0/0" } + ] + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] +}` + cniPath = "/etc/cni/net.d" + ) + + It("podman network list", func() { + SkipIfRootless() + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue()) + }) + + It("podman network list -q", func() { + SkipIfRootless() + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "ls", "--quiet"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue()) + }) + + It("podman network rm no args", func() { + SkipIfRootless() + session := podmanTest.Podman([]string{"network", "rm"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).ToNot(BeZero()) + }) + + It("podman network rm", func() { + SkipIfRootless() + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "ls", "--quiet"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.LineInOutputContains("podman-integrationtest")).To(BeTrue()) + + rm := podmanTest.Podman([]string{"network", "rm", "podman-integrationtest"}) + rm.WaitWithDefaultTimeout() + Expect(rm.ExitCode()).To(BeZero()) + + results := podmanTest.Podman([]string{"network", "ls", "--quiet"}) + results.WaitWithDefaultTimeout() + Expect(results.ExitCode()).To(Equal(0)) + Expect(results.LineInOutputContains("podman-integrationtest")).To(BeFalse()) + }) + + It("podman network inspect no args", func() { + SkipIfRootless() + session := podmanTest.Podman([]string{"network", "inspect"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).ToNot(BeZero()) + }) + + It("podman network inspect", func() { + SkipIfRootless() + // Setup, use uuid to prevent conflict with other tests + uuid := stringid.GenerateNonCryptoID() + secondPath := filepath.Join(cniPath, fmt.Sprintf("%s.conflist", uuid)) + writeConf([]byte(secondConf), secondPath) + defer removeConf(secondPath) + + session := podmanTest.Podman([]string{"network", "inspect", "podman-integrationtest", "podman"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.IsJSONOutputValid()).To(BeTrue()) + }) + +}) |