github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/internal/commands/config_trusted_builder.go (about)

     1  package commands
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/pkg/errors"
     7  	"github.com/spf13/cobra"
     8  
     9  	bldr "github.com/buildpacks/pack/internal/builder"
    10  	"github.com/buildpacks/pack/internal/config"
    11  	"github.com/buildpacks/pack/internal/style"
    12  	"github.com/buildpacks/pack/pkg/logging"
    13  )
    14  
    15  func ConfigTrustedBuilder(logger logging.Logger, cfg config.Config, cfgPath string) *cobra.Command {
    16  	cmd := &cobra.Command{
    17  		Use:   "trusted-builders",
    18  		Short: "List, add and remove trusted builders",
    19  		Long: "When pack considers a builder to be trusted, `pack build` operations will use a single lifecycle binary " +
    20  			"called the creator. This is more efficient than using an untrusted builder, where pack will execute " +
    21  			"five separate lifecycle binaries, each in its own container: analyze, detect, restore, build and export.\n\n" +
    22  			"For more on trusted builders, and when to trust or untrust a builder, " +
    23  			"check out our docs here: https://buildpacks.io/docs/tools/pack/concepts/trusted_builders/",
    24  		Aliases: []string{"trusted-builder", "trust-builder", "trust-builders"},
    25  		RunE: logError(logger, func(cmd *cobra.Command, args []string) error {
    26  			listTrustedBuilders(args, logger, cfg)
    27  			return nil
    28  		}),
    29  	}
    30  
    31  	listCmd := generateListCmd("trusted-builders", logger, cfg, listTrustedBuilders)
    32  	listCmd.Long = "List Trusted Builders.\n\nShow the builders that are either trusted by default or have been explicitly trusted locally using `trusted-builder add`"
    33  	listCmd.Example = "pack config trusted-builders list"
    34  	cmd.AddCommand(listCmd)
    35  
    36  	addCmd := generateAdd("trusted-builders", logger, cfg, cfgPath, addTrustedBuilder)
    37  	addCmd.Long = "Trust builder.\n\nWhen building with this builder, all lifecycle phases will be run in a single container using the builder image."
    38  	addCmd.Example = "pack config trusted-builders add cnbs/sample-stack-run:bionic"
    39  	cmd.AddCommand(addCmd)
    40  
    41  	rmCmd := generateRemove("trusted-builders", logger, cfg, cfgPath, removeTrustedBuilder)
    42  	rmCmd.Long = "Stop trusting builder.\n\nWhen building with this builder, all lifecycle phases will be no longer be run in a single container using the builder image."
    43  	rmCmd.Example = "pack config trusted-builders remove cnbs/sample-stack-run:bionic"
    44  	cmd.AddCommand(rmCmd)
    45  
    46  	AddHelpFlag(cmd, "trusted-builders")
    47  	return cmd
    48  }
    49  
    50  func addTrustedBuilder(args []string, logger logging.Logger, cfg config.Config, cfgPath string) error {
    51  	imageName := args[0]
    52  	builderToTrust := config.TrustedBuilder{Name: imageName}
    53  
    54  	if isTrustedBuilder(cfg, imageName) {
    55  		logger.Infof("Builder %s is already trusted", style.Symbol(imageName))
    56  		return nil
    57  	}
    58  
    59  	cfg.TrustedBuilders = append(cfg.TrustedBuilders, builderToTrust)
    60  	if err := config.Write(cfg, cfgPath); err != nil {
    61  		return errors.Wrap(err, "writing config")
    62  	}
    63  	logger.Infof("Builder %s is now trusted", style.Symbol(imageName))
    64  
    65  	return nil
    66  }
    67  
    68  func removeTrustedBuilder(args []string, logger logging.Logger, cfg config.Config, cfgPath string) error {
    69  	builder := args[0]
    70  
    71  	existingTrustedBuilders := cfg.TrustedBuilders
    72  	cfg.TrustedBuilders = []config.TrustedBuilder{}
    73  	for _, trustedBuilder := range existingTrustedBuilders {
    74  		if trustedBuilder.Name == builder {
    75  			continue
    76  		}
    77  
    78  		cfg.TrustedBuilders = append(cfg.TrustedBuilders, trustedBuilder)
    79  	}
    80  
    81  	// Builder is not in the trusted builder list
    82  	if len(existingTrustedBuilders) == len(cfg.TrustedBuilders) {
    83  		if isSuggestedBuilder(builder) {
    84  			// Attempted to untrust a suggested builder
    85  			return errors.Errorf("Builder %s is a suggested builder, and is trusted by default. Currently pack doesn't support making these builders untrusted", style.Symbol(builder))
    86  		}
    87  
    88  		logger.Infof("Builder %s wasn't trusted", style.Symbol(builder))
    89  		return nil
    90  	}
    91  
    92  	err := config.Write(cfg, cfgPath)
    93  	if err != nil {
    94  		return errors.Wrap(err, "writing config file")
    95  	}
    96  
    97  	logger.Infof("Builder %s is no longer trusted", style.Symbol(builder))
    98  	return nil
    99  }
   100  
   101  func listTrustedBuilders(args []string, logger logging.Logger, cfg config.Config) {
   102  	logger.Info("Trusted Builders:")
   103  
   104  	var trustedBuilders []string
   105  	for _, knownBuilder := range bldr.KnownBuilders {
   106  		if knownBuilder.Trusted {
   107  			trustedBuilders = append(trustedBuilders, knownBuilder.Image)
   108  		}
   109  	}
   110  
   111  	for _, builder := range cfg.TrustedBuilders {
   112  		trustedBuilders = append(trustedBuilders, builder.Name)
   113  	}
   114  
   115  	sort.Strings(trustedBuilders)
   116  
   117  	for _, builder := range trustedBuilders {
   118  		logger.Infof("  %s", builder)
   119  	}
   120  }