mirror of
https://github.com/containers/podman.git
synced 2025-06-26 12:56:45 +08:00
inclusion of podman network
adding podman network and the subcommands inspect, list, and rm. the inspect subcommand displays the raw cni network configuration. the list subcommand displays a summary of the cni networks ala ps. and the rm subcommand removes a cni network. Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
@ -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
|
||||
|
31
cmd/podman/network.go
Normal file
31
cmd/podman/network.go
Normal file
@ -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)
|
||||
}
|
48
cmd/podman/network_inspect.go
Normal file
48
cmd/podman/network_inspect.go
Normal file
@ -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)
|
||||
}
|
53
cmd/podman/network_list.go
Normal file
53
cmd/podman/network_list.go
Normal file
@ -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)
|
||||
}
|
48
cmd/podman/network_rm.go
Normal file
48
cmd/podman/network_rm.go
Normal file
@ -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)
|
||||
}
|
@ -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 | [](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 |
|
||||
|
@ -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
|
||||
|
50
docs/podman-network-inspect.1.md
Normal file
50
docs/podman-network-inspect.1.md
Normal file
@ -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>
|
43
docs/podman-network-ls.1.md
Normal file
43
docs/podman-network-ls.1.md
Normal file
@ -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>
|
25
docs/podman-network-rm.1.md
Normal file
25
docs/podman-network-rm.1.md
Normal file
@ -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>
|
21
docs/podman-network.1.md
Normal file
21
docs/podman-network.1.md
Normal file
@ -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)
|
@ -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. |
|
||||
|
147
pkg/adapter/network.go
Normal file
147
pkg/adapter/network.go
Normal file
@ -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, ",")
|
||||
}
|
4
pkg/network/config.go
Normal file
4
pkg/network/config.go
Normal file
@ -0,0 +1,4 @@
|
||||
package network
|
||||
|
||||
// CNIConfigDir is the path where CNI config files exist
|
||||
const CNIConfigDir = "/etc/cni/net.d"
|
26
pkg/network/network.go
Normal file
26
pkg/network/network.go
Normal file
@ -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
|
||||
}
|
158
test/e2e/network_test.go
Normal file
158
test/e2e/network_test.go
Normal file
@ -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())
|
||||
})
|
||||
|
||||
})
|
Reference in New Issue
Block a user