github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/system_prune.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	"github.com/containerd/log"
    24  	"github.com/containerd/nerdctl/pkg/api/types"
    25  	"github.com/containerd/nerdctl/pkg/clientutil"
    26  	"github.com/containerd/nerdctl/pkg/cmd/system"
    27  	"github.com/spf13/cobra"
    28  )
    29  
    30  func newSystemPruneCommand() *cobra.Command {
    31  	systemPruneCommand := &cobra.Command{
    32  		Use:           "prune [flags]",
    33  		Short:         "Remove unused data",
    34  		Args:          cobra.NoArgs,
    35  		RunE:          systemPruneAction,
    36  		SilenceUsage:  true,
    37  		SilenceErrors: true,
    38  	}
    39  	systemPruneCommand.Flags().BoolP("all", "a", false, "Remove all unused images, not just dangling ones")
    40  	systemPruneCommand.Flags().BoolP("force", "f", false, "Do not prompt for confirmation")
    41  	systemPruneCommand.Flags().Bool("volumes", false, "Prune volumes")
    42  	return systemPruneCommand
    43  }
    44  
    45  func processSystemPruneOptions(cmd *cobra.Command) (types.SystemPruneOptions, error) {
    46  	globalOptions, err := processRootCmdFlags(cmd)
    47  	if err != nil {
    48  		return types.SystemPruneOptions{}, err
    49  	}
    50  
    51  	all, err := cmd.Flags().GetBool("all")
    52  	if err != nil {
    53  		return types.SystemPruneOptions{}, err
    54  	}
    55  
    56  	vFlag, err := cmd.Flags().GetBool("volumes")
    57  	if err != nil {
    58  		return types.SystemPruneOptions{}, err
    59  	}
    60  
    61  	buildkitHost, err := getBuildkitHost(cmd, globalOptions.Namespace)
    62  	if err != nil {
    63  		log.L.WithError(err).Warn("BuildKit is not running. Build caches will not be pruned.")
    64  		buildkitHost = ""
    65  	}
    66  
    67  	return types.SystemPruneOptions{
    68  		Stdout:               cmd.OutOrStdout(),
    69  		Stderr:               cmd.ErrOrStderr(),
    70  		GOptions:             globalOptions,
    71  		All:                  all,
    72  		Volumes:              vFlag,
    73  		BuildKitHost:         buildkitHost,
    74  		NetworkDriversToKeep: networkDriversToKeep,
    75  	}, nil
    76  }
    77  
    78  func grantSystemPrunePermission(cmd *cobra.Command, options types.SystemPruneOptions) (bool, error) {
    79  	force, err := cmd.Flags().GetBool("force")
    80  	if err != nil {
    81  		return false, err
    82  	}
    83  
    84  	if !force {
    85  		var confirm string
    86  		msg := `This will remove:
    87    - all stopped containers
    88    - all networks not used by at least one container`
    89  		if options.Volumes {
    90  			msg += `
    91    - all volumes not used by at least one container`
    92  		}
    93  		if options.All {
    94  			msg += `
    95    - all images without at least one container associated to them
    96    - all build cache`
    97  		} else {
    98  			msg += `
    99    - all dangling images
   100    - all dangling build cache`
   101  		}
   102  
   103  		msg += "\nAre you sure you want to continue? [y/N] "
   104  		fmt.Fprintf(options.Stdout, "WARNING! %s", msg)
   105  		fmt.Fscanf(cmd.InOrStdin(), "%s", &confirm)
   106  
   107  		if strings.ToLower(confirm) != "y" {
   108  			return false, nil
   109  		}
   110  	}
   111  
   112  	return true, nil
   113  }
   114  
   115  func systemPruneAction(cmd *cobra.Command, _ []string) error {
   116  	options, err := processSystemPruneOptions(cmd)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	if ok, err := grantSystemPrunePermission(cmd, options); err != nil {
   122  		return err
   123  	} else if !ok {
   124  		return nil
   125  	}
   126  
   127  	client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), options.GOptions.Namespace, options.GOptions.Address)
   128  	if err != nil {
   129  		return err
   130  	}
   131  	defer cancel()
   132  
   133  	return system.Prune(ctx, client, options)
   134  }