add docker network prune
`docker network prune` prunes unused networks, including overlay ones. `docker system prune` also prunes unused networks. Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp> Upstream-commit: 7e24c16086a9a4f38e241e51837f2be4877c04a6 Component: engine
This commit is contained in:
12
components/engine/daemon/cluster.go
Normal file
12
components/engine/daemon/cluster.go
Normal file
@ -0,0 +1,12 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
apitypes "github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
// Cluster is the interface for github.com/docker/docker/daemon/cluster.(*Cluster).
|
||||
type Cluster interface {
|
||||
GetNetwork(input string) (apitypes.NetworkResource, error)
|
||||
GetNetworks() ([]apitypes.NetworkResource, error)
|
||||
RemoveNetwork(input string) error
|
||||
}
|
||||
@ -102,6 +102,7 @@ type Daemon struct {
|
||||
containerdRemote libcontainerd.Remote
|
||||
defaultIsolation containertypes.Isolation // Default isolation mode on Windows
|
||||
clusterProvider cluster.Provider
|
||||
cluster Cluster
|
||||
}
|
||||
|
||||
// HasExperimental returns whether the experimental features of the daemon are enabled or not
|
||||
@ -1234,3 +1235,13 @@ func copyBlkioEntry(entries []*containerd.BlkioStatsEntry) []types.BlkioStatEntr
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// GetCluster returns the cluster
|
||||
func (daemon *Daemon) GetCluster() Cluster {
|
||||
return daemon.cluster
|
||||
}
|
||||
|
||||
// SetCluster sets the cluster
|
||||
func (daemon *Daemon) SetCluster(cluster Cluster) {
|
||||
daemon.cluster = cluster
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/digest"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -8,7 +10,9 @@ import (
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/pkg/directory"
|
||||
"github.com/docker/docker/reference"
|
||||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/libnetwork"
|
||||
)
|
||||
|
||||
// ContainersPrune removes unused containers
|
||||
@ -150,3 +154,72 @@ func (daemon *Daemon) ImagesPrune(config *types.ImagesPruneConfig) (*types.Image
|
||||
|
||||
return rep, nil
|
||||
}
|
||||
|
||||
// localNetworksPrune removes unused local networks
|
||||
func (daemon *Daemon) localNetworksPrune(config *types.NetworksPruneConfig) (*types.NetworksPruneReport, error) {
|
||||
rep := &types.NetworksPruneReport{}
|
||||
var err error
|
||||
// When the function returns true, the walk will stop.
|
||||
l := func(nw libnetwork.Network) bool {
|
||||
nwName := nw.Name()
|
||||
predefined := runconfig.IsPreDefinedNetwork(nwName)
|
||||
if !predefined && len(nw.Endpoints()) == 0 {
|
||||
if err = daemon.DeleteNetwork(nw.ID()); err != nil {
|
||||
logrus.Warnf("could not remove network %s: %v", nwName, err)
|
||||
return false
|
||||
}
|
||||
rep.NetworksDeleted = append(rep.NetworksDeleted, nwName)
|
||||
}
|
||||
return false
|
||||
}
|
||||
daemon.netController.WalkNetworks(l)
|
||||
return rep, err
|
||||
}
|
||||
|
||||
// clusterNetworksPrune removes unused cluster networks
|
||||
func (daemon *Daemon) clusterNetworksPrune(config *types.NetworksPruneConfig) (*types.NetworksPruneReport, error) {
|
||||
rep := &types.NetworksPruneReport{}
|
||||
cluster := daemon.GetCluster()
|
||||
networks, err := cluster.GetNetworks()
|
||||
if err != nil {
|
||||
return rep, err
|
||||
}
|
||||
networkIsInUse := regexp.MustCompile(`network ([[:alnum:]]+) is in use`)
|
||||
for _, nw := range networks {
|
||||
if nw.Name == "ingress" {
|
||||
continue
|
||||
}
|
||||
// https://github.com/docker/docker/issues/24186
|
||||
// `docker network inspect` unfortunately displays ONLY those containers that are local to that node.
|
||||
// So we try to remove it anyway and check the error
|
||||
err = cluster.RemoveNetwork(nw.ID)
|
||||
if err != nil {
|
||||
// we can safely ignore the "network .. is in use" error
|
||||
match := networkIsInUse.FindStringSubmatch(err.Error())
|
||||
if len(match) != 2 || match[1] != nw.ID {
|
||||
logrus.Warnf("could not remove network %s: %v", nw.Name, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
rep.NetworksDeleted = append(rep.NetworksDeleted, nw.Name)
|
||||
}
|
||||
return rep, nil
|
||||
}
|
||||
|
||||
// NetworksPrune removes unused networks
|
||||
func (daemon *Daemon) NetworksPrune(config *types.NetworksPruneConfig) (*types.NetworksPruneReport, error) {
|
||||
rep := &types.NetworksPruneReport{}
|
||||
clusterRep, err := daemon.clusterNetworksPrune(config)
|
||||
if err != nil {
|
||||
logrus.Warnf("could not remove cluster networks: %v", err)
|
||||
} else {
|
||||
rep.NetworksDeleted = append(rep.NetworksDeleted, clusterRep.NetworksDeleted...)
|
||||
}
|
||||
localRep, err := daemon.localNetworksPrune(config)
|
||||
if err != nil {
|
||||
logrus.Warnf("could not remove local networks: %v", err)
|
||||
} else {
|
||||
rep.NetworksDeleted = append(rep.NetworksDeleted, localRep.NetworksDeleted...)
|
||||
}
|
||||
return rep, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user