aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-08-16 16:11:26 +0200
committerPaul Holzinger <pholzing@redhat.com>2021-09-15 20:00:20 +0200
commit85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de (patch)
tree82b0c29102d2779c18ea8a6f10df5dc1139e3817 /pkg
parent218f132fdf4939d9e0374ef860d534f19e71df54 (diff)
downloadpodman-85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de.tar.gz
podman-85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de.tar.bz2
podman-85e8fbf7f33717ef6a0d6cf9e2143b52c874c2de.zip
Wire network interface into libpod
Make use of the new network interface in libpod. This commit contains several breaking changes: - podman network create only outputs the new network name and not file path. - podman network ls shows the network driver instead of the cni version and plugins. - podman network inspect outputs the new network struct and not the cni conflist. - The bindings and libpod api endpoints have been changed to use the new network structure. The container network status is stored in a new field in the state. The status should be received with the new `c.getNetworkStatus`. This will migrate the old status to the new format. Therefore old containers should contine to work correctly in all cases even when network connect/ disconnect is used. New features: - podman network reload keeps the ip and mac for more than one network. - podman container restore keeps the ip and mac for more than one network. - The network create compat endpoint can now use more than one ipam config. The man pages and the swagger doc are updated to reflect the latest changes. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/networks.go264
-rw-r--r--pkg/api/handlers/libpod/networks.go25
-rw-r--r--pkg/api/handlers/libpod/swagger.go14
-rw-r--r--pkg/api/server/register_networks.go10
-rw-r--r--pkg/bindings/network/network.go49
-rw-r--r--pkg/bindings/test/networks_test.go45
-rw-r--r--pkg/domain/entities/engine_container.go7
-rw-r--r--pkg/domain/entities/network.go14
-rw-r--r--pkg/domain/infra/abi/network.go122
-rw-r--r--pkg/domain/infra/tunnel/network.go23
10 files changed, 229 insertions, 344 deletions
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index 847e6dcff..28727a22b 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -4,20 +4,15 @@ import (
"encoding/json"
"net"
"net/http"
- "os"
- "strings"
- "syscall"
- "time"
- "github.com/containernetworking/cni/libcni"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network"
+ nettypes "github.com/containers/podman/v3/libpod/network/types"
+ netutil "github.com/containers/podman/v3/libpod/network/util"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
api "github.com/containers/podman/v3/pkg/api/types"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
- networkid "github.com/containers/podman/v3/pkg/network"
"github.com/containers/podman/v3/pkg/util"
"github.com/docker/docker/api/types"
@@ -27,12 +22,6 @@ import (
"github.com/sirupsen/logrus"
)
-type pluginInterface struct {
- PluginType string `json:"type"`
- IPAM network.IPAMConfig `json:"ipam"`
- IsGW bool `json:"isGateway"`
-}
-
func InspectNetwork(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
@@ -54,18 +43,13 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Invalid scope value. Can only be local.", http.StatusBadRequest, define.ErrInvalidArg)
return
}
- config, err := runtime.GetConfig()
- if err != nil {
- utils.InternalServerError(w, err)
- return
- }
name := utils.GetName(r)
- _, err = network.InspectNetwork(config, name)
+ net, err := runtime.Network().NetworkInspect(name)
if err != nil {
utils.NetworkNotFound(w, name, err)
return
}
- report, err := getNetworkResourceByNameOrID(name, runtime, nil)
+ report, err := convertLibpodNetworktoDockerNetwork(runtime, net)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -73,65 +57,18 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, report)
}
-func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filters map[string][]string) (*types.NetworkResource, error) {
- var (
- ipamConfigs []dockerNetwork.IPAMConfig
- )
- config, err := runtime.GetConfig()
- if err != nil {
- return nil, err
- }
- containerEndpoints := map[string]types.EndpointResource{}
- // Get the network path so we can get created time
- networkConfigPath, err := network.GetCNIConfigPathByNameOrID(config, nameOrID)
- if err != nil {
- return nil, err
- }
- f, err := os.Stat(networkConfigPath)
- if err != nil {
- return nil, err
- }
- stat := f.Sys().(*syscall.Stat_t)
+func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, network nettypes.Network) (*types.NetworkResource, error) {
cons, err := runtime.GetAllContainers()
if err != nil {
return nil, err
}
- conf, err := libcni.ConfListFromFile(networkConfigPath)
- if err != nil {
- return nil, err
- }
- if len(filters) > 0 {
- ok, err := network.IfPassesFilter(conf, filters)
- if err != nil {
- return nil, err
- }
- if !ok {
- // do not return the config if we did not match the filter
- return nil, nil
- }
- }
-
- plugin, err := getPlugin(conf.Plugins)
- if err != nil {
- return nil, err
- }
-
- for _, outer := range plugin.IPAM.Ranges {
- for _, n := range outer {
- ipamConfig := dockerNetwork.IPAMConfig{
- Subnet: n.Subnet,
- Gateway: n.Gateway,
- }
- ipamConfigs = append(ipamConfigs, ipamConfig)
- }
- }
-
+ containerEndpoints := make(map[string]types.EndpointResource, len(cons))
for _, con := range cons {
data, err := con.Inspect(false)
if err != nil {
return nil, err
}
- if netData, ok := data.NetworkSettings.Networks[conf.Name]; ok {
+ if netData, ok := data.NetworkSettings.Networks[network.Name]; ok {
containerEndpoint := types.EndpointResource{
Name: netData.NetworkID,
EndpointID: netData.EndpointID,
@@ -142,60 +79,47 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt
containerEndpoints[con.ID()] = containerEndpoint
}
}
-
- labels := network.GetNetworkLabels(conf)
- if labels == nil {
- labels = map[string]string{}
+ ipamConfigs := make([]dockerNetwork.IPAMConfig, 0, len(network.Subnets))
+ for _, sub := range network.Subnets {
+ ipamConfig := dockerNetwork.IPAMConfig{
+ Subnet: sub.Subnet.String(),
+ Gateway: sub.Gateway.String(),
+ // TODO add range
+ }
+ ipamConfigs = append(ipamConfigs, ipamConfig)
}
-
- isInternal := false
- dockerDriver := plugin.PluginType
- if plugin.PluginType == network.DefaultNetworkDriver {
- isInternal = !plugin.IsGW
- dockerDriver = "default"
+ ipamDriver := network.IPAMOptions["driver"]
+ if ipamDriver == nettypes.HostLocalIPAMDriver {
+ ipamDriver = "default"
+ }
+ ipam := dockerNetwork.IPAM{
+ Driver: ipamDriver,
+ Options: network.IPAMOptions,
+ Config: ipamConfigs,
}
report := types.NetworkResource{
- Name: conf.Name,
- ID: networkid.GetNetworkID(conf.Name),
- Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert
+ Name: network.Name,
+ ID: network.ID,
+ Driver: network.Driver,
+ // TODO add Created: ,
+ Internal: network.Internal,
+ EnableIPv6: network.IPv6Enabled,
+ Labels: network.Labels,
+ Options: network.Options,
+ IPAM: ipam,
Scope: "local",
- Driver: plugin.PluginType,
- EnableIPv6: false,
- IPAM: dockerNetwork.IPAM{
- Driver: dockerDriver,
- Options: map[string]string{},
- Config: ipamConfigs,
- },
- Internal: isInternal,
Attachable: false,
Ingress: false,
ConfigFrom: dockerNetwork.ConfigReference{},
ConfigOnly: false,
Containers: containerEndpoints,
- Options: map[string]string{},
- Labels: labels,
Peers: nil,
Services: nil,
}
return &report, nil
}
-func getPlugin(plugins []*libcni.NetworkConfig) (pluginInterface, error) {
- var plugin pluginInterface
-
- for _, p := range plugins {
- for _, pluginType := range network.SupportedNetworkDrivers {
- if pluginType == p.Network.Type {
- err := json.Unmarshal(p.Bytes, &plugin)
- return plugin, err
- }
- }
- }
-
- return plugin, errors.New("unable to find supported plugin")
-}
-
func ListNetworks(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
filterMap, err := util.PrepareFilters(r)
@@ -204,37 +128,32 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
return
}
- config, err := runtime.GetConfig()
- if err != nil {
- utils.InternalServerError(w, err)
- return
+ options := entities.NetworkListOptions{
+ Filters: *filterMap,
}
- netNames, err := network.GetNetworkNamesFromFileSystem(config)
+ ic := abi.ContainerEngine{Libpod: runtime}
+ nets, err := ic.NetworkList(r.Context(), options)
if err != nil {
utils.InternalServerError(w, err)
return
}
-
- reports := []*types.NetworkResource{}
- logrus.Debugf("netNames: %q", strings.Join(netNames, ", "))
- for _, name := range netNames {
- report, err := getNetworkResourceByNameOrID(name, runtime, *filterMap)
+ reports := make([]*types.NetworkResource, 0, len(nets))
+ for _, net := range nets {
+ report, err := convertLibpodNetworktoDockerNetwork(runtime, net)
if err != nil {
utils.InternalServerError(w, err)
return
}
- if report != nil {
- reports = append(reports, report)
- }
+ reports = append(reports, report)
}
utils.WriteResponse(w, http.StatusOK, reports)
}
func CreateNetwork(w http.ResponseWriter, r *http.Request) {
var (
- name string
networkCreate types.NetworkCreateRequest
+ network nettypes.Network
)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
if err := json.NewDecoder(r.Body).Decode(&networkCreate); err != nil {
@@ -242,65 +161,80 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
return
}
- if len(networkCreate.Name) > 0 {
- name = networkCreate.Name
- }
- if len(networkCreate.Driver) < 1 {
- networkCreate.Driver = network.DefaultNetworkDriver
+ network.Name = networkCreate.Name
+ if networkCreate.Driver == "" {
+ networkCreate.Driver = nettypes.DefaultNetworkDriver
}
- // At present I think we should just support the bridge driver
- // and allow demand to make us consider more
- if networkCreate.Driver != network.DefaultNetworkDriver {
- utils.InternalServerError(w, errors.New("network create only supports the bridge driver"))
- return
- }
- ncOptions := entities.NetworkCreateOptions{
- Driver: network.DefaultNetworkDriver,
- Internal: networkCreate.Internal,
- Labels: networkCreate.Labels,
+ network.Driver = networkCreate.Driver
+ network.Labels = networkCreate.Labels
+ network.Internal = networkCreate.Internal
+ network.IPv6Enabled = networkCreate.EnableIPv6
+
+ // FIXME use docker options and convert them to valid libpod options
+ // network.Options = networkCreate.Options
+
+ // dns is only enabled for the bridge driver
+ if network.Driver == nettypes.BridgeNetworkDriver {
+ network.DNSEnabled = true
}
- if networkCreate.IPAM != nil && len(networkCreate.IPAM.Config) > 0 {
- if len(networkCreate.IPAM.Config) > 1 {
- utils.InternalServerError(w, errors.New("compat network create can only support one IPAM config"))
- return
- }
- if len(networkCreate.IPAM.Config[0].Subnet) > 0 {
- _, subnet, err := net.ParseCIDR(networkCreate.IPAM.Config[0].Subnet)
- if err != nil {
- utils.InternalServerError(w, err)
- return
+ if networkCreate.IPAM != nil && len(networkCreate.IPAM.Config) > 0 {
+ for _, conf := range networkCreate.IPAM.Config {
+ s := nettypes.Subnet{}
+ if len(conf.Subnet) > 0 {
+ var err error
+ subnet, err := nettypes.ParseCIDR(conf.Subnet)
+ if err != nil {
+ utils.InternalServerError(w, errors.Wrap(err, "failed to parse subnet"))
+ return
+ }
+ s.Subnet = subnet
}
- ncOptions.Subnet = *subnet
- }
- if len(networkCreate.IPAM.Config[0].Gateway) > 0 {
- ncOptions.Gateway = net.ParseIP(networkCreate.IPAM.Config[0].Gateway)
- }
- if len(networkCreate.IPAM.Config[0].IPRange) > 0 {
- _, IPRange, err := net.ParseCIDR(networkCreate.IPAM.Config[0].IPRange)
- if err != nil {
- utils.InternalServerError(w, err)
- return
+ if len(conf.Gateway) > 0 {
+ gw := net.ParseIP(conf.Gateway)
+ if gw == nil {
+ utils.InternalServerError(w, errors.Errorf("failed to parse gateway ip %s", conf.Gateway))
+ return
+ }
+ s.Gateway = gw
+ }
+ if len(conf.IPRange) > 0 {
+ _, net, err := net.ParseCIDR(conf.IPRange)
+ if err != nil {
+ utils.InternalServerError(w, errors.Wrap(err, "failed to parse ip range"))
+ return
+ }
+ startIP, err := netutil.FirstIPInSubnet(net)
+ if err != nil {
+ utils.InternalServerError(w, errors.Wrap(err, "failed to get first ip in range"))
+ return
+ }
+ lastIP, err := netutil.LastIPInSubnet(net)
+ if err != nil {
+ utils.InternalServerError(w, errors.Wrap(err, "failed to get last ip in range"))
+ return
+ }
+ s.LeaseRange = &nettypes.LeaseRange{
+ StartIP: startIP,
+ EndIP: lastIP,
+ }
}
- ncOptions.Range = *IPRange
+ network.Subnets = append(network.Subnets, s)
}
- }
- ce := abi.ContainerEngine{Libpod: runtime}
- if _, err := ce.NetworkCreate(r.Context(), name, ncOptions); err != nil {
- utils.InternalServerError(w, err)
- return
+ // FIXME can we use the IPAM driver and options?
}
- net, err := getNetworkResourceByNameOrID(name, runtime, nil)
+ network, err := runtime.Network().NetworkCreate(network)
if err != nil {
utils.InternalServerError(w, err)
return
}
+
body := struct {
ID string `json:"Id"`
Warning []string
}{
- ID: net.ID,
+ ID: network.ID,
}
utils.WriteResponse(w, http.StatusCreated, body)
}
diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go
index 122ab1d3d..fcd8e0231 100644
--- a/pkg/api/handlers/libpod/networks.go
+++ b/pkg/api/handlers/libpod/networks.go
@@ -6,7 +6,7 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
api "github.com/containers/podman/v3/pkg/api/types"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -18,27 +18,14 @@ import (
func CreateNetwork(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
- decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
- options := entities.NetworkCreateOptions{}
- if err := json.NewDecoder(r.Body).Decode(&options); err != nil {
- utils.Error(w, "unable to marshall input", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
+ network := types.Network{}
+ if err := json.NewDecoder(r.Body).Decode(&network); err != nil {
+ utils.Error(w, "unable to marshall input", http.StatusInternalServerError, errors.Wrap(err, "decode body"))
return
}
- query := struct {
- Name string `schema:"name"`
- }{
- // override any golang type defaults
- }
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
- errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
- return
- }
- if len(options.Driver) < 1 {
- options.Driver = network.DefaultNetworkDriver
- }
+
ic := abi.ContainerEngine{Libpod: runtime}
- report, err := ic.NetworkCreate(r.Context(), query.Name, options)
+ report, err := ic.Libpod.Network().NetworkCreate(network)
if err != nil {
utils.InternalServerError(w, err)
return
diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go
index 6116a7274..7ccfdd0f3 100644
--- a/pkg/api/handlers/libpod/swagger.go
+++ b/pkg/api/handlers/libpod/swagger.go
@@ -4,9 +4,9 @@ import (
"net/http"
"os"
- "github.com/containernetworking/cni/libcni"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/pkg/errors"
@@ -103,21 +103,27 @@ type swagNetworkRmReport struct {
// swagger:response NetworkInspectReport
type swagNetworkInspectReport struct {
// in:body
- Body libcni.NetworkConfigList
+ Body types.Network
}
// Network list
// swagger:response NetworkListReport
type swagNetworkListReport struct {
// in:body
- Body []entities.NetworkListReport
+ Body []types.Network
+}
+
+// Network create
+// swagger:model NetworkCreateLibpod
+type swagNetworkCreateLibpod struct {
+ types.Network
}
// Network create
// swagger:response NetworkCreateReport
type swagNetworkCreateReport struct {
// in:body
- Body entities.NetworkCreateReport
+ Body types.Network
}
// Network prune
diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go
index cacf83a7f..641bce333 100644
--- a/pkg/api/server/register_networks.go
+++ b/pkg/api/server/register_networks.go
@@ -267,7 +267,7 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// - `id=[id]` Matches for full or partial ID.
// - `driver=[driver]` Only bridge is supported.
// - `label=[key]` or `label=[key=value]` Matches networks based on the presence of a label alone or a label and a value.
- // - `plugin=[plugin]` Matches CNI plugins included in a network (e.g `bridge`,`portmap`,`firewall`,`tuning`,`dnsname`,`macvlan`)
+ // - `until=[timestamp]` Matches all networks that were create before the given timestamp.
// produces:
// - application/json
// responses:
@@ -306,19 +306,15 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error {
// tags:
// - networks
// summary: Create network
- // description: Create a new CNI network configuration
+ // description: Create a new network configuration
// produces:
// - application/json
// parameters:
- // - in: query
- // name: name
- // type: string
- // description: optional name for new network
// - in: body
// name: create
// description: attributes for creating a container
// schema:
- // $ref: "#/definitions/NetworkCreateOptions"
+ // $ref: "#/definitions/NetworkCreateLibpod"
// responses:
// 200:
// $ref: "#/responses/NetworkCreateReport"
diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go
index 59207aa8d..5a0a34f56 100644
--- a/pkg/bindings/network/network.go
+++ b/pkg/bindings/network/network.go
@@ -6,58 +6,51 @@ import (
"net/url"
"strings"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/domain/entities"
jsoniter "github.com/json-iterator/go"
)
// Create makes a new CNI network configuration
-func Create(ctx context.Context, options *CreateOptions) (*entities.NetworkCreateReport, error) {
- var report entities.NetworkCreateReport
- if options == nil {
- options = new(CreateOptions)
- }
+func Create(ctx context.Context, network *types.Network) (types.Network, error) {
+ var report types.Network
conn, err := bindings.GetClient(ctx)
if err != nil {
- return nil, err
+ return report, err
}
- params := url.Values{}
- if options.Name != nil {
- params.Set("name", options.GetName())
+ // create empty network if the caller did not provide one
+ if network == nil {
+ network = &types.Network{}
}
- networkConfig, err := jsoniter.MarshalToString(options)
+ networkConfig, err := jsoniter.MarshalToString(*network)
if err != nil {
- return nil, err
+ return report, err
}
- stringReader := strings.NewReader(networkConfig)
- response, err := conn.DoRequest(stringReader, http.MethodPost, "/networks/create", params, nil)
+ reader := strings.NewReader(networkConfig)
+ response, err := conn.DoRequest(reader, http.MethodPost, "/networks/create", nil, nil)
if err != nil {
- return nil, err
+ return report, err
}
defer response.Body.Close()
- return &report, response.Process(&report)
+ return report, response.Process(&report)
}
// Inspect returns low level information about a CNI network configuration
-func Inspect(ctx context.Context, nameOrID string, options *InspectOptions) ([]entities.NetworkInspectReport, error) {
- var reports []entities.NetworkInspectReport
- reports = append(reports, entities.NetworkInspectReport{})
- if options == nil {
- options = new(InspectOptions)
- }
- _ = options
+func Inspect(ctx context.Context, nameOrID string, _ *InspectOptions) (types.Network, error) {
+ var net types.Network
conn, err := bindings.GetClient(ctx)
if err != nil {
- return nil, err
+ return net, err
}
response, err := conn.DoRequest(nil, http.MethodGet, "/networks/%s/json", nil, nil, nameOrID)
if err != nil {
- return nil, err
+ return net, err
}
defer response.Body.Close()
- return reports, response.Process(&reports[0])
+ return net, response.Process(&net)
}
// Remove deletes a defined CNI network configuration by name. The optional force boolean
@@ -86,10 +79,8 @@ func Remove(ctx context.Context, nameOrID string, options *RemoveOptions) ([]*en
}
// List returns a summary of all CNI network configurations
-func List(ctx context.Context, options *ListOptions) ([]*entities.NetworkListReport, error) {
- var (
- netList []*entities.NetworkListReport
- )
+func List(ctx context.Context, options *ListOptions) ([]types.Network, error) {
+ var netList []types.Network
if options == nil {
options = new(ListOptions)
}
diff --git a/pkg/bindings/test/networks_test.go b/pkg/bindings/test/networks_test.go
index b53fc4bd3..85ceeb998 100644
--- a/pkg/bindings/test/networks_test.go
+++ b/pkg/bindings/test/networks_test.go
@@ -6,6 +6,7 @@ import (
"net/http"
"time"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/bindings"
"github.com/containers/podman/v3/pkg/bindings/containers"
"github.com/containers/podman/v3/pkg/bindings/network"
@@ -41,10 +42,10 @@ var _ = Describe("Podman networks", func() {
It("podman prune unused networks with filters", func() {
name := "foobar"
- opts := network.CreateOptions{
- Name: &name,
+ net := types.Network{
+ Name: name,
}
- _, err = network.Create(connText, &opts)
+ _, err = network.Create(connText, &net)
Expect(err).To(BeNil())
// Invalid filters should return error
@@ -88,20 +89,20 @@ var _ = Describe("Podman networks", func() {
It("create network", func() {
// create a network with blank config should work
- _, err = network.Create(connText, &network.CreateOptions{})
+ _, err = network.Create(connText, nil)
Expect(err).To(BeNil())
name := "foobar"
- opts := network.CreateOptions{
- Name: &name,
+ net := types.Network{
+ Name: name,
}
- report, err := network.Create(connText, &opts)
+ report, err := network.Create(connText, &net)
Expect(err).To(BeNil())
- Expect(report.Filename).To(ContainSubstring(name))
+ Expect(report.Name).To(Equal(name))
// create network with same name should 500
- _, err = network.Create(connText, &opts)
+ _, err = network.Create(connText, &net)
Expect(err).ToNot(BeNil())
code, _ := bindings.CheckResponseCode(err)
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
@@ -109,24 +110,24 @@ var _ = Describe("Podman networks", func() {
It("inspect network", func() {
name := "foobar"
- opts := network.CreateOptions{
- Name: &name,
+ net := types.Network{
+ Name: name,
}
- _, err = network.Create(connText, &opts)
+ _, err = network.Create(connText, &net)
Expect(err).To(BeNil())
data, err := network.Inspect(connText, name, nil)
Expect(err).To(BeNil())
- Expect(data[0]["name"]).To(Equal(name))
+ Expect(data.Name).To(Equal(name))
})
It("list networks", func() {
// create a bunch of named networks and make verify with list
netNames := []string{"homer", "bart", "lisa", "maggie", "marge"}
for i := 0; i < 5; i++ {
- opts := network.CreateOptions{
- Name: &netNames[i],
+ net := types.Network{
+ Name: netNames[i],
}
- _, err = network.Create(connText, &opts)
+ _, err = network.Create(connText, &net)
Expect(err).To(BeNil())
}
list, err := network.List(connText, nil)
@@ -166,10 +167,10 @@ var _ = Describe("Podman networks", func() {
// Removing an unused network should work
name := "unused"
- opts := network.CreateOptions{
- Name: &name,
+ net := types.Network{
+ Name: name,
}
- _, err = network.Create(connText, &opts)
+ _, err = network.Create(connText, &net)
Expect(err).To(BeNil())
report, err := network.Remove(connText, name, nil)
Expect(err).To(BeNil())
@@ -177,10 +178,10 @@ var _ = Describe("Podman networks", func() {
// Removing a network that is being used without force should be 500
name = "used"
- opts = network.CreateOptions{
- Name: &name,
+ net = types.Network{
+ Name: name,
}
- _, err = network.Create(connText, &opts)
+ _, err = network.Create(connText, &net)
Expect(err).To(BeNil())
// Start container and wait
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 3da31d8a0..b916d6fc6 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/domain/entities/reports"
"github.com/containers/podman/v3/pkg/specgen"
)
@@ -58,11 +59,11 @@ type ContainerEngine interface {
HealthCheckRun(ctx context.Context, nameOrID string, options HealthCheckOptions) (*define.HealthCheckResults, error)
Info(ctx context.Context) (*define.Info, error)
NetworkConnect(ctx context.Context, networkname string, options NetworkConnectOptions) error
- NetworkCreate(ctx context.Context, name string, options NetworkCreateOptions) (*NetworkCreateReport, error)
+ NetworkCreate(ctx context.Context, network types.Network) (*NetworkCreateReport, error)
NetworkDisconnect(ctx context.Context, networkname string, options NetworkDisconnectOptions) error
NetworkExists(ctx context.Context, networkname string) (*BoolReport, error)
- NetworkInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]NetworkInspectReport, []error, error)
- NetworkList(ctx context.Context, options NetworkListOptions) ([]*NetworkListReport, error)
+ NetworkInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]types.Network, []error, error)
+ NetworkList(ctx context.Context, options NetworkListOptions) ([]types.Network, error)
NetworkPrune(ctx context.Context, options NetworkPruneOptions) ([]*NetworkPruneReport, error)
NetworkReload(ctx context.Context, names []string, options NetworkReloadOptions) ([]*NetworkReloadReport, error)
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go
index a89501664..b61297d41 100644
--- a/pkg/domain/entities/network.go
+++ b/pkg/domain/entities/network.go
@@ -2,8 +2,6 @@ package entities
import (
"net"
-
- "github.com/containernetworking/cni/libcni"
)
// NetworkListOptions describes options for listing networks in cli
@@ -13,15 +11,6 @@ type NetworkListOptions struct {
Filters map[string][]string
}
-// NetworkListReport describes the results from listing networks
-type NetworkListReport struct {
- *libcni.NetworkConfigList
- Labels map[string]string
-}
-
-// NetworkInspectReport describes the results from inspect networks
-type NetworkInspectReport map[string]interface{}
-
// NetworkReloadOptions describes options for reloading container network
// configuration.
type NetworkReloadOptions struct {
@@ -48,7 +37,6 @@ type NetworkRmReport struct {
}
// NetworkCreateOptions describes options to create a network
-// swagger:model NetworkCreateOptions
type NetworkCreateOptions struct {
DisableDNS bool
Driver string
@@ -65,7 +53,7 @@ type NetworkCreateOptions struct {
// NetworkCreateReport describes a created network for the cli
type NetworkCreateReport struct {
- Filename string
+ Name string
}
// NetworkDisconnectOptions describes options for disconnecting
diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go
index 7900caaa6..45d2c6925 100644
--- a/pkg/domain/infra/abi/network.go
+++ b/pkg/domain/infra/abi/network.go
@@ -4,60 +4,38 @@ import (
"context"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network"
+ "github.com/containers/podman/v3/libpod/network/types"
+ netutil "github.com/containers/podman/v3/libpod/network/util"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
-func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
- reports := make([]*entities.NetworkListReport, 0)
-
- config, err := ic.Libpod.GetConfig()
- if err != nil {
- return nil, err
- }
-
- networks, err := network.LoadCNIConfsFromDir(network.GetCNIConfDir(config))
+func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]types.Network, error) {
+ filters, err := netutil.GenerateNetworkFilters(options.Filters)
if err != nil {
return nil, err
}
-
- for _, n := range networks {
- ok, err := network.IfPassesFilter(n, options.Filters)
- if err != nil {
- return nil, err
- }
- if ok {
- reports = append(reports, &entities.NetworkListReport{
- NetworkConfigList: n,
- Labels: network.GetNetworkLabels(n),
- })
- }
- }
- return reports, nil
+ nets, err := ic.Libpod.Network().NetworkList(filters...)
+ return nets, err
}
-func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]entities.NetworkInspectReport, []error, error) {
- config, err := ic.Libpod.GetConfig()
- if err != nil {
- return nil, nil, err
- }
+func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]types.Network, []error, error) {
var errs []error
- rawCNINetworks := make([]entities.NetworkInspectReport, 0, len(namesOrIds))
+ networks := make([]types.Network, 0, len(namesOrIds))
for _, name := range namesOrIds {
- rawList, err := network.InspectNetwork(config, name)
+ net, err := ic.Libpod.Network().NetworkInspect(name)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchNetwork {
- errs = append(errs, errors.Errorf("no such network %s", name))
+ errs = append(errs, errors.Wrapf(err, "network %s", name))
continue
} else {
return nil, nil, errors.Wrapf(err, "error inspecting network %s", name)
}
}
- rawCNINetworks = append(rawCNINetworks, rawList)
+ networks = append(networks, net)
}
- return rawCNINetworks, errs, nil
+ return networks, errs, nil
}
func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, options entities.NetworkReloadOptions) ([]*entities.NetworkReloadReport, error) {
@@ -83,12 +61,7 @@ func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, op
}
func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) {
- reports := []*entities.NetworkRmReport{}
-
- config, err := ic.Libpod.GetConfig()
- if err != nil {
- return nil, err
- }
+ reports := make([]*entities.NetworkRmReport, 0, len(namesOrIds))
for _, name := range namesOrIds {
report := entities.NetworkRmReport{Name: name}
@@ -126,7 +99,7 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o
}
}
}
- if err := network.RemoveNetwork(config, name); err != nil {
+ if err := ic.Libpod.Network().NetworkRemove(name); err != nil {
report.Err = err
}
reports = append(reports, &report)
@@ -134,12 +107,12 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o
return reports, nil
}
-func (ic *ContainerEngine) NetworkCreate(ctx context.Context, name string, options entities.NetworkCreateOptions) (*entities.NetworkCreateReport, error) {
- runtimeConfig, err := ic.Libpod.GetConfig()
+func (ic *ContainerEngine) NetworkCreate(ctx context.Context, network types.Network) (*entities.NetworkCreateReport, error) {
+ network, err := ic.Libpod.Network().NetworkCreate(network)
if err != nil {
return nil, err
}
- return network.Create(name, options, runtimeConfig)
+ return &entities.NetworkCreateReport{Name: network.Name}, nil
}
// NetworkDisconnect removes a container from a given network
@@ -153,12 +126,12 @@ func (ic *ContainerEngine) NetworkConnect(ctx context.Context, networkname strin
// NetworkExists checks if the given network exists
func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string) (*entities.BoolReport, error) {
- config, err := ic.Libpod.GetConfig()
- if err != nil {
- return nil, err
- }
- exists, err := network.Exists(config, networkname)
- if err != nil {
+ _, err := ic.Libpod.Network().NetworkInspect(networkname)
+ exists := true
+ // if err is ErrNoSuchNetwork do not return it
+ if errors.Is(err, define.ErrNoSuchNetwork) {
+ exists = false
+ } else if err != nil {
return nil, err
}
return &entities.BoolReport{
@@ -168,19 +141,10 @@ func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string
// Network prune removes unused cni networks
func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.NetworkPruneOptions) ([]*entities.NetworkPruneReport, error) {
- runtimeConfig, err := ic.Libpod.GetConfig()
- if err != nil {
- return nil, err
- }
cons, err := ic.Libpod.GetAllContainers()
if err != nil {
return nil, err
}
- networks, err := network.LoadCNIConfsFromDir(network.GetCNIConfDir(runtimeConfig))
- if err != nil {
- return nil, err
- }
-
// Gather up all the non-default networks that the
// containers want
networksToKeep := make(map[string]bool)
@@ -193,20 +157,34 @@ func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.Ne
networksToKeep[n] = true
}
}
- if len(options.Filters) != 0 {
- for _, n := range networks {
- // This network will be kept anyway
- if _, found := networksToKeep[n.Name]; found {
- continue
- }
- ok, err := network.IfPassesPruneFilter(runtimeConfig, n, options.Filters)
- if err != nil {
- return nil, err
- }
- if !ok {
- networksToKeep[n.Name] = true
+ // ignore the default network, this one cannot be deleted
+ networksToKeep[ic.Libpod.GetDefaultNetworkName()] = true
+
+ // get all filters
+ filters, err := netutil.GenerateNetworkPruneFilters(options.Filters)
+ if err != nil {
+ return nil, err
+ }
+ danglingFilterFunc := func(net types.Network) bool {
+ for network := range networksToKeep {
+ if network == net.Name {
+ return false
}
}
+ return true
+ }
+ filters = append(filters, danglingFilterFunc)
+ nets, err := ic.Libpod.Network().NetworkList(filters...)
+ if err != nil {
+ return nil, err
+ }
+
+ pruneReport := make([]*entities.NetworkPruneReport, 0, len(nets))
+ for _, net := range nets {
+ pruneReport = append(pruneReport, &entities.NetworkPruneReport{
+ Name: net.Name,
+ Error: ic.Libpod.Network().NetworkRemove(net.Name),
+ })
}
- return network.PruneNetworks(runtimeConfig, networksToKeep)
+ return pruneReport, nil
}
diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go
index 7e59e44c2..711c2e00c 100644
--- a/pkg/domain/infra/tunnel/network.go
+++ b/pkg/domain/infra/tunnel/network.go
@@ -3,20 +3,22 @@ package tunnel
import (
"context"
+ "github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/bindings/network"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/pkg/errors"
)
-func (ic *ContainerEngine) NetworkList(ctx context.Context, opts entities.NetworkListOptions) ([]*entities.NetworkListReport, error) {
+func (ic *ContainerEngine) NetworkList(ctx context.Context, opts entities.NetworkListOptions) ([]types.Network, error) {
options := new(network.ListOptions).WithFilters(opts.Filters)
return network.List(ic.ClientCtx, options)
}
-func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, opts entities.InspectOptions) ([]entities.NetworkInspectReport, []error, error) {
+func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, opts entities.InspectOptions) ([]types.Network, []error, error) {
var (
- reports = make([]entities.NetworkInspectReport, 0, len(namesOrIds))
+ reports = make([]types.Network, 0, len(namesOrIds))
errs = []error{}
)
options := new(network.InspectOptions)
@@ -28,12 +30,12 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri
return nil, nil, err
}
if errModel.ResponseCode == 404 {
- errs = append(errs, errors.Errorf("no such network %q", name))
+ errs = append(errs, errors.Wrapf(define.ErrNoSuchNetwork, "network %s", name))
continue
}
return nil, nil, err
}
- reports = append(reports, report...)
+ reports = append(reports, report)
}
return reports, errs, nil
}
@@ -60,11 +62,12 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o
return reports, nil
}
-func (ic *ContainerEngine) NetworkCreate(ctx context.Context, name string, opts entities.NetworkCreateOptions) (*entities.NetworkCreateReport, error) {
- options := new(network.CreateOptions).WithName(name).WithDisableDNS(opts.DisableDNS).WithDriver(opts.Driver).WithGateway(opts.Gateway)
- options.WithInternal(opts.Internal).WithIPRange(opts.Range).WithIPv6(opts.IPv6).WithLabels(opts.Labels).WithIPv6(opts.IPv6)
- options.WithMacVLAN(opts.MacVLAN).WithOptions(opts.Options).WithSubnet(opts.Subnet)
- return network.Create(ic.ClientCtx, options)
+func (ic *ContainerEngine) NetworkCreate(ctx context.Context, net types.Network) (*entities.NetworkCreateReport, error) {
+ net, err := network.Create(ic.ClientCtx, &net)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.NetworkCreateReport{Name: net.Name}, nil
}
// NetworkDisconnect removes a container from a given network