mirror of
https://github.com/containers/podman.git
synced 2025-06-20 09:03:43 +08:00
v2networking enable commands
Enable the networking commands for v2. Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
|||||||
_ "github.com/containers/libpod/cmd/podman/healthcheck"
|
_ "github.com/containers/libpod/cmd/podman/healthcheck"
|
||||||
_ "github.com/containers/libpod/cmd/podman/images"
|
_ "github.com/containers/libpod/cmd/podman/images"
|
||||||
_ "github.com/containers/libpod/cmd/podman/manifest"
|
_ "github.com/containers/libpod/cmd/podman/manifest"
|
||||||
|
_ "github.com/containers/libpod/cmd/podman/networks"
|
||||||
_ "github.com/containers/libpod/cmd/podman/pods"
|
_ "github.com/containers/libpod/cmd/podman/pods"
|
||||||
"github.com/containers/libpod/cmd/podman/registry"
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
_ "github.com/containers/libpod/cmd/podman/system"
|
_ "github.com/containers/libpod/cmd/podman/system"
|
||||||
|
81
cmd/podman/networks/create.go
Normal file
81
cmd/podman/networks/create.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
|
"github.com/containers/libpod/libpod"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/containers/libpod/pkg/network"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networkCreateDescription = `create CNI networks for containers and pods`
|
||||||
|
networkCreateCommand = &cobra.Command{
|
||||||
|
Use: "create [flags] [NETWORK]",
|
||||||
|
Short: "network create",
|
||||||
|
Long: networkCreateDescription,
|
||||||
|
RunE: networkCreate,
|
||||||
|
Example: `podman network create podman1`,
|
||||||
|
Annotations: map[string]string{
|
||||||
|
registry.ParentNSRequired: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networkCreateOptions entities.NetworkCreateOptions
|
||||||
|
)
|
||||||
|
|
||||||
|
func networkCreateFlags(flags *pflag.FlagSet) {
|
||||||
|
flags.StringVarP(&networkCreateOptions.Driver, "driver", "d", "bridge", "driver to manage the network")
|
||||||
|
flags.IPVar(&networkCreateOptions.Gateway, "gateway", nil, "IPv4 or IPv6 gateway for the subnet")
|
||||||
|
flags.BoolVar(&networkCreateOptions.Internal, "internal", false, "restrict external access from this network")
|
||||||
|
flags.IPNetVar(&networkCreateOptions.Range, "ip-range", net.IPNet{}, "allocate container IP from range")
|
||||||
|
flags.StringVar(&networkCreateOptions.MacVLAN, "macvlan", "", "create a Macvlan connection based on this device")
|
||||||
|
// TODO not supported yet
|
||||||
|
//flags.StringVar(&networkCreateOptions.IPamDriver, "ipam-driver", "", "IP Address Management Driver")
|
||||||
|
// TODO enable when IPv6 is working
|
||||||
|
//flags.BoolVar(&networkCreateOptions.IPV6, "IPv6", false, "enable IPv6 networking")
|
||||||
|
flags.IPNetVar(&networkCreateOptions.Subnet, "subnet", net.IPNet{}, "subnet in CIDR format")
|
||||||
|
flags.BoolVar(&networkCreateOptions.DisableDNS, "disable-dns", false, "disable dns plugin")
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
|
Command: networkCreateCommand,
|
||||||
|
Parent: networkCmd,
|
||||||
|
})
|
||||||
|
flags := networkCreateCommand.Flags()
|
||||||
|
networkCreateFlags(flags)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkCreate(cmd *cobra.Command, args []string) error {
|
||||||
|
var (
|
||||||
|
name string
|
||||||
|
)
|
||||||
|
if err := network.IsSupportedDriver(networkCreateOptions.Driver); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(args) > 1 {
|
||||||
|
return errors.Errorf("only one network can be created at a time")
|
||||||
|
}
|
||||||
|
if len(args) > 0 && !libpod.NameRegex.MatchString(args[0]) {
|
||||||
|
return libpod.RegexError
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
name = args[0]
|
||||||
|
}
|
||||||
|
response, err := registry.ContainerEngine().NetworkCreate(registry.Context(), name, networkCreateOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(response.Filename)
|
||||||
|
return nil
|
||||||
|
}
|
46
cmd/podman/networks/inspect.go
Normal file
46
cmd/podman/networks/inspect.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networkinspectDescription = `Inspect network`
|
||||||
|
networkinspectCommand = &cobra.Command{
|
||||||
|
Use: "inspect NETWORK [NETWORK...] [flags] ",
|
||||||
|
Short: "network inspect",
|
||||||
|
Long: networkinspectDescription,
|
||||||
|
RunE: networkInspect,
|
||||||
|
Example: `podman network inspect podman`,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Annotations: map[string]string{
|
||||||
|
registry.ParentNSRequired: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
|
Command: networkinspectCommand,
|
||||||
|
Parent: networkCmd,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkInspect(cmd *cobra.Command, args []string) error {
|
||||||
|
responses, err := registry.ContainerEngine().NetworkInspect(registry.Context(), args, entities.NetworkInspectOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b, err := json.MarshalIndent(responses, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(b))
|
||||||
|
return nil
|
||||||
|
}
|
133
cmd/podman/networks/list.go
Normal file
133
cmd/podman/networks/list.go
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/validate"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/containers/libpod/pkg/network"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networklistDescription = `List networks`
|
||||||
|
networklistCommand = &cobra.Command{
|
||||||
|
Use: "ls",
|
||||||
|
Args: validate.NoArgs,
|
||||||
|
Short: "network list",
|
||||||
|
Long: networklistDescription,
|
||||||
|
RunE: networkList,
|
||||||
|
Example: `podman network list`,
|
||||||
|
Annotations: map[string]string{
|
||||||
|
registry.ParentNSRequired: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networkListOptions entities.NetworkListOptions
|
||||||
|
headers string = "NAME\tVERSION\tPLUGINS\n"
|
||||||
|
defaultListRow string = "{{.Name}}\t{{.Version}}\t{{.Plugins}}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
func networkListFlags(flags *pflag.FlagSet) {
|
||||||
|
// TODO enable filters based on something
|
||||||
|
//flags.StringSliceVarP(&networklistCommand.Filter, "filter", "f", []string{}, "Pause all running containers")
|
||||||
|
flags.StringVarP(&networkListOptions.Format, "format", "f", "", "Pretty-print containers to JSON or using a Go template")
|
||||||
|
flags.BoolVarP(&networkListOptions.Quiet, "quiet", "q", false, "display only names")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
|
Command: networklistCommand,
|
||||||
|
Parent: networkCmd,
|
||||||
|
})
|
||||||
|
flags := networklistCommand.Flags()
|
||||||
|
networkListFlags(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkList(cmd *cobra.Command, args []string) error {
|
||||||
|
var (
|
||||||
|
w io.Writer = os.Stdout
|
||||||
|
nlprs []NetworkListPrintReports
|
||||||
|
)
|
||||||
|
|
||||||
|
responses, err := registry.ContainerEngine().NetworkList(registry.Context(), networkListOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// quiet means we only print the network names
|
||||||
|
if networkListOptions.Quiet {
|
||||||
|
return quietOut(responses)
|
||||||
|
}
|
||||||
|
|
||||||
|
if networkListOptions.Format == "json" {
|
||||||
|
return jsonOut(responses)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range responses {
|
||||||
|
nlprs = append(nlprs, NetworkListPrintReports{r})
|
||||||
|
}
|
||||||
|
|
||||||
|
row := networkListOptions.Format
|
||||||
|
if len(row) < 1 {
|
||||||
|
row = defaultListRow
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(row, "\n") {
|
||||||
|
row += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
format := "{{range . }}" + row + "{{end}}"
|
||||||
|
if !cmd.Flag("format").Changed {
|
||||||
|
format = headers + format
|
||||||
|
}
|
||||||
|
tmpl, err := template.New("listNetworks").Parse(format)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tmpl.Execute(w, nlprs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if flusher, ok := w.(interface{ Flush() error }); ok {
|
||||||
|
return flusher.Flush()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func quietOut(responses []*entities.NetworkListReport) error {
|
||||||
|
for _, r := range responses {
|
||||||
|
fmt.Println(r.Name)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func jsonOut(responses []*entities.NetworkListReport) error {
|
||||||
|
b, err := json.MarshalIndent(responses, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(b))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetworkListPrintReports struct {
|
||||||
|
*entities.NetworkListReport
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkListPrintReports) Version() string {
|
||||||
|
return n.CNIVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n NetworkListPrintReports) Plugins() string {
|
||||||
|
return network.GetCNIPlugins(n.NetworkConfigList)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package images
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containers/libpod/cmd/podman/registry"
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// Command: podman _network_
|
// Command: podman _network_
|
||||||
cmd = &cobra.Command{
|
networkCmd = &cobra.Command{
|
||||||
Use: "network",
|
Use: "network",
|
||||||
Short: "Manage networks",
|
Short: "Manage networks",
|
||||||
Long: "Manage networks",
|
Long: "Manage networks",
|
||||||
@ -18,12 +18,9 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO add the following to main.go to get networks back onto the
|
|
||||||
// command list.
|
|
||||||
// _ "github.com/containers/libpod/cmd/podman/networks"
|
|
||||||
func init() {
|
func init() {
|
||||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
Mode: []entities.EngineMode{entities.ABIMode},
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
Command: cmd,
|
Command: networkCmd,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
63
cmd/podman/networks/rm.go
Normal file
63
cmd/podman/networks/rm.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/cmd/podman/registry"
|
||||||
|
"github.com/containers/libpod/cmd/podman/utils"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networkrmDescription = `Remove networks`
|
||||||
|
networkrmCommand = &cobra.Command{
|
||||||
|
Use: "rm [flags] NETWORK [NETWORK...]",
|
||||||
|
Short: "network rm",
|
||||||
|
Long: networkrmDescription,
|
||||||
|
RunE: networkRm,
|
||||||
|
Example: `podman network rm podman`,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Annotations: map[string]string{
|
||||||
|
registry.ParentNSRequired: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
networkRmOptions entities.NetworkRmOptions
|
||||||
|
)
|
||||||
|
|
||||||
|
func networkRmFlags(flags *pflag.FlagSet) {
|
||||||
|
flags.BoolVarP(&networkRmOptions.Force, "force", "f", false, "remove any containers using network")
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Mode: []entities.EngineMode{entities.ABIMode},
|
||||||
|
Command: networkrmCommand,
|
||||||
|
Parent: networkCmd,
|
||||||
|
})
|
||||||
|
flags := networkrmCommand.Flags()
|
||||||
|
networkRmFlags(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkRm(cmd *cobra.Command, args []string) error {
|
||||||
|
var (
|
||||||
|
errs utils.OutputErrors
|
||||||
|
)
|
||||||
|
|
||||||
|
responses, err := registry.ContainerEngine().NetworkRm(registry.Context(), args, networkRmOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, r := range responses {
|
||||||
|
if r.Err == nil {
|
||||||
|
fmt.Println(r.Name)
|
||||||
|
} else {
|
||||||
|
errs = append(errs, r.Err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errs.PrintErrors()
|
||||||
|
}
|
@ -44,6 +44,10 @@ type ContainerEngine interface {
|
|||||||
GenerateSystemd(ctx context.Context, nameOrID string, opts GenerateSystemdOptions) (*GenerateSystemdReport, error)
|
GenerateSystemd(ctx context.Context, nameOrID string, opts GenerateSystemdOptions) (*GenerateSystemdReport, error)
|
||||||
HealthCheckRun(ctx context.Context, nameOrId string, options HealthCheckOptions) (*define.HealthCheckResults, error)
|
HealthCheckRun(ctx context.Context, nameOrId string, options HealthCheckOptions) (*define.HealthCheckResults, error)
|
||||||
Info(ctx context.Context) (*define.Info, error)
|
Info(ctx context.Context) (*define.Info, error)
|
||||||
|
NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (*NetworkCreateReport, error)
|
||||||
|
NetworkInspect(ctx context.Context, namesOrIds []string, options NetworkInspectOptions) ([]NetworkInspectReport, error)
|
||||||
|
NetworkList(ctx context.Context, options NetworkListOptions) ([]*NetworkListReport, error)
|
||||||
|
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
|
||||||
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
|
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
|
||||||
PodExists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
PodExists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
||||||
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
|
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
|
||||||
|
52
pkg/domain/entities/network.go
Normal file
52
pkg/domain/entities/network.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package entities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/libcni"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkListOptions describes options for listing networks in cli
|
||||||
|
type NetworkListOptions struct {
|
||||||
|
Format string
|
||||||
|
Quiet bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkListReport describes the results from listing networks
|
||||||
|
type NetworkListReport struct {
|
||||||
|
*libcni.NetworkConfigList
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkInspectOptions describes options for inspect networks
|
||||||
|
type NetworkInspectOptions struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkInspectReport describes the results from inspect networks
|
||||||
|
type NetworkInspectReport map[string]interface{}
|
||||||
|
|
||||||
|
// NetworkRmOptions describes options for removing networks
|
||||||
|
type NetworkRmOptions struct {
|
||||||
|
Force bool
|
||||||
|
}
|
||||||
|
|
||||||
|
//NetworkRmReport describes the results of network removal
|
||||||
|
type NetworkRmReport struct {
|
||||||
|
Name string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkCreateOptions describes options to create a network
|
||||||
|
type NetworkCreateOptions struct {
|
||||||
|
DisableDNS bool
|
||||||
|
Driver string
|
||||||
|
Gateway net.IP
|
||||||
|
Internal bool
|
||||||
|
MacVLAN string
|
||||||
|
Range net.IPNet
|
||||||
|
Subnet net.IPNet
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkCreateReport describes a created network for the cli
|
||||||
|
type NetworkCreateReport struct {
|
||||||
|
Filename string
|
||||||
|
}
|
258
pkg/domain/infra/abi/network.go
Normal file
258
pkg/domain/infra/abi/network.go
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
package abi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
cniversion "github.com/containernetworking/cni/pkg/version"
|
||||||
|
"github.com/containers/libpod/libpod"
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
"github.com/containers/libpod/pkg/network"
|
||||||
|
"github.com/containers/libpod/pkg/util"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getCNIConfDir(r *libpod.Runtime) (string, error) {
|
||||||
|
config, err := r.GetConfig()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
configPath := config.Network.NetworkConfigDir
|
||||||
|
|
||||||
|
if len(config.Network.NetworkConfigDir) < 1 {
|
||||||
|
configPath = network.CNIConfigDir
|
||||||
|
}
|
||||||
|
return configPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
|
||||||
|
var reports []*entities.NetworkListReport
|
||||||
|
cniConfigPath, err := getCNIConfDir(ic.Libpod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
networks, err := network.LoadCNIConfsFromDir(cniConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range networks {
|
||||||
|
reports = append(reports, &entities.NetworkListReport{NetworkConfigList: n})
|
||||||
|
}
|
||||||
|
return reports, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.NetworkInspectOptions) ([]entities.NetworkInspectReport, error) {
|
||||||
|
var (
|
||||||
|
rawCNINetworks []entities.NetworkInspectReport
|
||||||
|
)
|
||||||
|
for _, name := range namesOrIds {
|
||||||
|
rawList, err := network.InspectNetwork(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rawCNINetworks = append(rawCNINetworks, rawList)
|
||||||
|
}
|
||||||
|
return rawCNINetworks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) {
|
||||||
|
var reports []*entities.NetworkRmReport
|
||||||
|
for _, name := range namesOrIds {
|
||||||
|
report := entities.NetworkRmReport{Name: name}
|
||||||
|
containers, err := ic.Libpod.GetAllContainers()
|
||||||
|
if err != nil {
|
||||||
|
return reports, err
|
||||||
|
}
|
||||||
|
// We need to iterate containers looking to see if they belong to the given network
|
||||||
|
for _, c := range containers {
|
||||||
|
if util.StringInSlice(name, c.Config().Networks) {
|
||||||
|
// if user passes force, we nuke containers
|
||||||
|
if !options.Force {
|
||||||
|
// Without the force option, we return an error
|
||||||
|
return reports, errors.Errorf("%q has associated containers with it. Use -f to forcibly delete containers", name)
|
||||||
|
}
|
||||||
|
if err := ic.Libpod.RemoveContainer(ctx, c, true, true); err != nil {
|
||||||
|
return reports, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := network.RemoveNetwork(name); err != nil {
|
||||||
|
report.Err = err
|
||||||
|
}
|
||||||
|
reports = append(reports, &report)
|
||||||
|
}
|
||||||
|
return reports, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkCreate(ctx context.Context, name string, options entities.NetworkCreateOptions) (*entities.NetworkCreateReport, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
fileName string
|
||||||
|
)
|
||||||
|
if len(options.MacVLAN) > 0 {
|
||||||
|
fileName, err = createMacVLAN(ic.Libpod, name, options)
|
||||||
|
} else {
|
||||||
|
fileName, err = createBridge(ic.Libpod, name, options)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &entities.NetworkCreateReport{Filename: fileName}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// createBridge creates a CNI network
|
||||||
|
func createBridge(r *libpod.Runtime, name string, options entities.NetworkCreateOptions) (string, error) {
|
||||||
|
isGateway := true
|
||||||
|
ipMasq := true
|
||||||
|
subnet := &options.Subnet
|
||||||
|
ipRange := options.Range
|
||||||
|
runtimeConfig, err := r.GetConfig()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// if range is provided, make sure it is "in" network
|
||||||
|
if subnet.IP != nil {
|
||||||
|
// if network is provided, does it conflict with existing CNI or live networks
|
||||||
|
err = network.ValidateUserNetworkIsAvailable(subnet)
|
||||||
|
} else {
|
||||||
|
// if no network is provided, figure out network
|
||||||
|
subnet, err = network.GetFreeNetwork()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
gateway := options.Gateway
|
||||||
|
if gateway == nil {
|
||||||
|
// if no gateway is provided, provide it as first ip of network
|
||||||
|
gateway = network.CalcGatewayIP(subnet)
|
||||||
|
}
|
||||||
|
// if network is provided and if gateway is provided, make sure it is "in" network
|
||||||
|
if options.Subnet.IP != nil && options.Gateway != nil {
|
||||||
|
if !subnet.Contains(gateway) {
|
||||||
|
return "", errors.Errorf("gateway %s is not in valid for subnet %s", gateway.String(), subnet.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if options.Internal {
|
||||||
|
isGateway = false
|
||||||
|
ipMasq = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a range is given, we need to ensure it is "in" the network range.
|
||||||
|
if options.Range.IP != nil {
|
||||||
|
if options.Subnet.IP == nil {
|
||||||
|
return "", errors.New("you must define a subnet range to define an ip-range")
|
||||||
|
}
|
||||||
|
firstIP, err := network.FirstIPInSubnet(&options.Range)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
lastIP, err := network.LastIPInSubnet(&options.Range)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !subnet.Contains(firstIP) || !subnet.Contains(lastIP) {
|
||||||
|
return "", errors.Errorf("the ip range %s does not fall within the subnet range %s", options.Range.String(), subnet.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bridgeDeviceName, err := network.GetFreeDeviceName()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(name) > 0 {
|
||||||
|
netNames, err := network.GetNetworkNamesFromFileSystem()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if util.StringInSlice(name, netNames) {
|
||||||
|
return "", errors.Errorf("the network name %s is already used", name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no name is given, we give the name of the bridge device
|
||||||
|
name = bridgeDeviceName
|
||||||
|
}
|
||||||
|
|
||||||
|
ncList := network.NewNcList(name, cniversion.Current())
|
||||||
|
var plugins []network.CNIPlugins
|
||||||
|
var routes []network.IPAMRoute
|
||||||
|
|
||||||
|
defaultRoute, err := network.NewIPAMDefaultRoute()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
routes = append(routes, defaultRoute)
|
||||||
|
ipamConfig, err := network.NewIPAMHostLocalConf(subnet, routes, ipRange, gateway)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO need to iron out the role of isDefaultGW and IPMasq
|
||||||
|
bridge := network.NewHostLocalBridge(bridgeDeviceName, isGateway, false, ipMasq, ipamConfig)
|
||||||
|
plugins = append(plugins, bridge)
|
||||||
|
plugins = append(plugins, network.NewPortMapPlugin())
|
||||||
|
plugins = append(plugins, network.NewFirewallPlugin())
|
||||||
|
// if we find the dnsname plugin, we add configuration for it
|
||||||
|
if network.HasDNSNamePlugin(runtimeConfig.Network.CNIPluginDirs) && !options.DisableDNS {
|
||||||
|
// Note: in the future we might like to allow for dynamic domain names
|
||||||
|
plugins = append(plugins, network.NewDNSNamePlugin(network.DefaultPodmanDomainName))
|
||||||
|
}
|
||||||
|
ncList["plugins"] = plugins
|
||||||
|
b, err := json.MarshalIndent(ncList, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
cniConfigPath, err := getCNIConfDir(r)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
cniPathName := filepath.Join(cniConfigPath, fmt.Sprintf("%s.conflist", name))
|
||||||
|
err = ioutil.WriteFile(cniPathName, b, 0644)
|
||||||
|
return cniPathName, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func createMacVLAN(r *libpod.Runtime, name string, options entities.NetworkCreateOptions) (string, error) {
|
||||||
|
var (
|
||||||
|
plugins []network.CNIPlugins
|
||||||
|
)
|
||||||
|
liveNetNames, err := network.GetLiveNetworkNames()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// Make sure the host-device exists
|
||||||
|
if !util.StringInSlice(options.MacVLAN, liveNetNames) {
|
||||||
|
return "", errors.Errorf("failed to find network interface %q", options.MacVLAN)
|
||||||
|
}
|
||||||
|
if len(name) > 0 {
|
||||||
|
netNames, err := network.GetNetworkNamesFromFileSystem()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if util.StringInSlice(name, netNames) {
|
||||||
|
return "", errors.Errorf("the network name %s is already used", name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name, err = network.GetFreeDeviceName()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ncList := network.NewNcList(name, cniversion.Current())
|
||||||
|
macvlan := network.NewMacVLANPlugin(options.MacVLAN)
|
||||||
|
plugins = append(plugins, macvlan)
|
||||||
|
ncList["plugins"] = plugins
|
||||||
|
b, err := json.MarshalIndent(ncList, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
cniConfigPath, err := getCNIConfDir(r)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
cniPathName := filepath.Join(cniConfigPath, fmt.Sprintf("%s.conflist", name))
|
||||||
|
err = ioutil.WriteFile(cniPathName, b, 0644)
|
||||||
|
return cniPathName, err
|
||||||
|
}
|
23
pkg/domain/infra/tunnel/network.go
Normal file
23
pkg/domain/infra/tunnel/network.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package tunnel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.NetworkInspectOptions) ([]entities.NetworkInspectReport, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) NetworkCreate(ctx context.Context, name string, options entities.NetworkCreateOptions) (*entities.NetworkCreateReport, error) {
|
||||||
|
return nil, errors.New("not implemented")
|
||||||
|
}
|
@ -76,7 +76,6 @@ var _ = Describe("Podman network create", func() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
Skip(v2fail)
|
|
||||||
SkipIfRootless()
|
SkipIfRootless()
|
||||||
tempdir, err = CreateTempDirInTempDir()
|
tempdir, err = CreateTempDirInTempDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -141,6 +140,7 @@ var _ = Describe("Podman network create", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman network create with name and subnet", func() {
|
It("podman network create with name and subnet", func() {
|
||||||
|
Skip(v2fail)
|
||||||
var (
|
var (
|
||||||
results []network.NcList
|
results []network.NcList
|
||||||
)
|
)
|
||||||
|
@ -34,7 +34,6 @@ var _ = Describe("Podman network", func() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
Skip(v2fail)
|
|
||||||
tempdir, err = CreateTempDirInTempDir()
|
tempdir, err = CreateTempDirInTempDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -159,6 +158,7 @@ var _ = Describe("Podman network", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman inspect container single CNI network", func() {
|
It("podman inspect container single CNI network", func() {
|
||||||
|
Skip(v2fail)
|
||||||
SkipIfRootless()
|
SkipIfRootless()
|
||||||
netName := "testNetSingleCNI"
|
netName := "testNetSingleCNI"
|
||||||
network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName})
|
network := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.50.0/24", netName})
|
||||||
@ -190,6 +190,7 @@ var _ = Describe("Podman network", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman inspect container two CNI networks", func() {
|
It("podman inspect container two CNI networks", func() {
|
||||||
|
Skip(v2fail)
|
||||||
SkipIfRootless()
|
SkipIfRootless()
|
||||||
netName1 := "testNetTwoCNI1"
|
netName1 := "testNetTwoCNI1"
|
||||||
network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1})
|
network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1})
|
||||||
|
Reference in New Issue
Block a user