From b0286d6b43ebec367c0d9ed87bc6566d76ece8f8 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Tue, 9 Jun 2020 17:10:37 -0400 Subject: Implement pod-network-reload This adds a new command, 'podman network reload', to reload the networks of existing containers, forcing recreation of firewall rules after e.g. `firewall-cmd --reload` wipes them out. Under the hood, this works by calling CNI to tear down the existing network, then recreate it using identical settings. We request that CNI preserve the old IP and MAC address in most cases (where the container only had 1 IP/MAC), but there will be some downtime inherent to the teardown/bring-up approach. The architecture of CNI doesn't really make doing this without downtime easy (or maybe even possible...). At present, this only works for root Podman, and only locally. I don't think there is much of a point to adding remote support (this is very much a local debugging command), but I think adding rootless support (to kill/recreate slirp4netns) could be valuable. Signed-off-by: Matthew Heon Signed-off-by: Paul Holzinger --- pkg/domain/entities/engine_container.go | 1 + pkg/domain/entities/network.go | 13 +++++++++++++ pkg/domain/infra/abi/network.go | 20 ++++++++++++++++++++ pkg/domain/infra/tunnel/network.go | 4 ++++ 4 files changed, 38 insertions(+) (limited to 'pkg/domain') diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index df7da616a..a4f6c08e9 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -55,6 +55,7 @@ type ContainerEngine interface { NetworkDisconnect(ctx context.Context, networkname string, options NetworkDisconnectOptions) error NetworkInspect(ctx context.Context, namesOrIds []string, options InspectOptions) ([]NetworkInspectReport, []error, error) NetworkList(ctx context.Context, options NetworkListOptions) ([]*NetworkListReport, error) + NetworkReload(ctx context.Context, names []string, options NetworkReloadOptions) ([]*NetworkReloadReport, error) NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error) PlayKube(ctx context.Context, path string, opts PlayKubeOptions) (*PlayKubeReport, error) PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error) diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go index 65a110fd9..b76bfcac7 100644 --- a/pkg/domain/entities/network.go +++ b/pkg/domain/entities/network.go @@ -22,6 +22,19 @@ type NetworkListReport struct { // NetworkInspectReport describes the results from inspect networks type NetworkInspectReport map[string]interface{} +// NetworkReloadOptions describes options for reloading container network +// configuration. +type NetworkReloadOptions struct { + All bool + Latest bool +} + +// NetworkReloadReport describes the results of reloading a container network. +type NetworkReloadReport struct { + Id string + Err error +} + // NetworkRmOptions describes options for removing networks type NetworkRmOptions struct { Force bool diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 6a219edd5..e5ecf5c72 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -60,6 +60,26 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri return rawCNINetworks, errs, nil } +func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, options entities.NetworkReloadOptions) ([]*entities.NetworkReloadReport, error) { + ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod) + if err != nil { + return nil, err + } + + reports := make([]*entities.NetworkReloadReport, 0, len(ctrs)) + for _, ctr := range ctrs { + report := new(entities.NetworkReloadReport) + report.Id = ctr.ID() + report.Err = ctr.ReloadNetwork() + if options.All && errors.Cause(report.Err) == define.ErrCtrStateInvalid { + continue + } + reports = append(reports, report) + } + + return reports, nil +} + func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) { reports := []*entities.NetworkRmReport{} diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go index 10ae03045..4845980f6 100644 --- a/pkg/domain/infra/tunnel/network.go +++ b/pkg/domain/infra/tunnel/network.go @@ -35,6 +35,10 @@ func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []stri return reports, errs, nil } +func (ic *ContainerEngine) NetworkReload(ctx context.Context, names []string, options entities.NetworkReloadOptions) ([]*entities.NetworkReloadReport, error) { + return nil, errors.New("not implemented") +} + func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) { reports := make([]*entities.NetworkRmReport, 0, len(namesOrIds)) for _, name := range namesOrIds { -- cgit v1.2.3-54-g00ecf