diff --git a/command/network/cmd.go b/command/network/cmd.go index b33f98cd30..77c8e4908e 100644 --- a/command/network/cmd.go +++ b/command/network/cmd.go @@ -26,6 +26,7 @@ func NewNetworkCommand(dockerCli *command.DockerCli) *cobra.Command { newInspectCommand(dockerCli), newListCommand(dockerCli), newRemoveCommand(dockerCli), + NewPruneCommand(dockerCli), ) return cmd } diff --git a/command/network/prune.go b/command/network/prune.go new file mode 100644 index 0000000000..00e05d3bdf --- /dev/null +++ b/command/network/prune.go @@ -0,0 +1,72 @@ +package network + +import ( + "fmt" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/cli" + "github.com/docker/docker/cli/command" + "github.com/spf13/cobra" +) + +type pruneOptions struct { + force bool +} + +// NewPruneCommand returns a new cobra prune command for networks +func NewPruneCommand(dockerCli *command.DockerCli) *cobra.Command { + var opts pruneOptions + + cmd := &cobra.Command{ + Use: "prune [OPTIONS]", + Short: "Remove all unused networks", + Args: cli.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + output, err := runPrune(dockerCli, opts) + if err != nil { + return err + } + if output != "" { + fmt.Fprintln(dockerCli.Out(), output) + } + return nil + }, + } + + flags := cmd.Flags() + flags.BoolVarP(&opts.force, "force", "f", false, "Do not prompt for confirmation") + + return cmd +} + +const warning = `WARNING! This will remove all networks not used by at least one container. +Are you sure you want to continue?` + +func runPrune(dockerCli *command.DockerCli, opts pruneOptions) (output string, err error) { + if !opts.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) { + return + } + + report, err := dockerCli.Client().NetworksPrune(context.Background(), types.NetworksPruneConfig{}) + if err != nil { + return + } + + if len(report.NetworksDeleted) > 0 { + output = "Deleted Networks:\n" + for _, id := range report.NetworksDeleted { + output += id + "\n" + } + } + + return +} + +// RunPrune calls the Network Prune API +// This returns the amount of space reclaimed and a detailed output string +func RunPrune(dockerCli *command.DockerCli) (uint64, string, error) { + output, err := runPrune(dockerCli, pruneOptions{force: true}) + return 0, output, err +} diff --git a/command/prune/prune.go b/command/prune/prune.go index fd04c590b6..a022487fd6 100644 --- a/command/prune/prune.go +++ b/command/prune/prune.go @@ -4,6 +4,7 @@ import ( "github.com/docker/docker/cli/command" "github.com/docker/docker/cli/command/container" "github.com/docker/docker/cli/command/image" + "github.com/docker/docker/cli/command/network" "github.com/docker/docker/cli/command/volume" "github.com/spf13/cobra" ) @@ -23,6 +24,11 @@ func NewImagePruneCommand(dockerCli *command.DockerCli) *cobra.Command { return image.NewPruneCommand(dockerCli) } +// NewNetworkPruneCommand returns a cobra prune command for Networks +func NewNetworkPruneCommand(dockerCli *command.DockerCli) *cobra.Command { + return network.NewPruneCommand(dockerCli) +} + // RunContainerPrune executes a prune command for containers func RunContainerPrune(dockerCli *command.DockerCli) (uint64, string, error) { return container.RunPrune(dockerCli) @@ -37,3 +43,8 @@ func RunVolumePrune(dockerCli *command.DockerCli) (uint64, string, error) { func RunImagePrune(dockerCli *command.DockerCli, all bool) (uint64, string, error) { return image.RunPrune(dockerCli, all) } + +// RunNetworkPrune executes a prune command for networks +func RunNetworkPrune(dockerCli *command.DockerCli) (uint64, string, error) { + return network.RunPrune(dockerCli) +} diff --git a/command/system/prune.go b/command/system/prune.go index ea8a41380f..c79bc6910e 100644 --- a/command/system/prune.go +++ b/command/system/prune.go @@ -39,6 +39,7 @@ const ( warning = `WARNING! This will remove: - all stopped containers - all volumes not used by at least one container + - all networks not used by at least one container %s Are you sure you want to continue?` @@ -64,13 +65,14 @@ func runPrune(dockerCli *command.DockerCli, opts pruneOptions) error { for _, pruneFn := range []func(dockerCli *command.DockerCli) (uint64, string, error){ prune.RunContainerPrune, prune.RunVolumePrune, + prune.RunNetworkPrune, } { spc, output, err := pruneFn(dockerCli) if err != nil { return err } - if spc > 0 { - spaceReclaimed += spc + spaceReclaimed += spc + if output != "" { fmt.Fprintln(dockerCli.Out(), output) } }