github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/cli/command/plugin/install.go (about)

     1  package plugin
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/docker/docker/api/types"
     9  	"github.com/docker/docker/cli"
    10  	"github.com/docker/docker/cli/command"
    11  	"github.com/docker/docker/reference"
    12  	"github.com/docker/docker/registry"
    13  	"github.com/spf13/cobra"
    14  	"golang.org/x/net/context"
    15  )
    16  
    17  type pluginOptions struct {
    18  	name       string
    19  	grantPerms bool
    20  	disable    bool
    21  	args       []string
    22  }
    23  
    24  func newInstallCommand(dockerCli *command.DockerCli) *cobra.Command {
    25  	var options pluginOptions
    26  	cmd := &cobra.Command{
    27  		Use:   "install [OPTIONS] PLUGIN [KEY=VALUE...]",
    28  		Short: "Install a plugin",
    29  		Args:  cli.RequiresMinArgs(1),
    30  		RunE: func(cmd *cobra.Command, args []string) error {
    31  			options.name = args[0]
    32  			if len(args) > 1 {
    33  				options.args = args[1:]
    34  			}
    35  			return runInstall(dockerCli, options)
    36  		},
    37  	}
    38  
    39  	flags := cmd.Flags()
    40  	flags.BoolVar(&options.grantPerms, "grant-all-permissions", false, "Grant all permissions necessary to run the plugin")
    41  	flags.BoolVar(&options.disable, "disable", false, "Do not enable the plugin on install")
    42  
    43  	return cmd
    44  }
    45  
    46  func runInstall(dockerCli *command.DockerCli, opts pluginOptions) error {
    47  	named, err := reference.ParseNamed(opts.name) // FIXME: validate
    48  	if err != nil {
    49  		return err
    50  	}
    51  	if reference.IsNameOnly(named) {
    52  		named = reference.WithDefaultTag(named)
    53  	}
    54  	ref, ok := named.(reference.NamedTagged)
    55  	if !ok {
    56  		return fmt.Errorf("invalid name: %s", named.String())
    57  	}
    58  
    59  	ctx := context.Background()
    60  
    61  	repoInfo, err := registry.ParseRepositoryInfo(named)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
    67  
    68  	encodedAuth, err := command.EncodeAuthToBase64(authConfig)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	registryAuthFunc := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "plugin install")
    74  
    75  	options := types.PluginInstallOptions{
    76  		RegistryAuth:          encodedAuth,
    77  		Disabled:              opts.disable,
    78  		AcceptAllPermissions:  opts.grantPerms,
    79  		AcceptPermissionsFunc: acceptPrivileges(dockerCli, opts.name),
    80  		// TODO: Rename PrivilegeFunc, it has nothing to do with privileges
    81  		PrivilegeFunc: registryAuthFunc,
    82  		Args:          opts.args,
    83  	}
    84  	if err := dockerCli.Client().PluginInstall(ctx, ref.String(), options); err != nil {
    85  		return err
    86  	}
    87  	fmt.Fprintln(dockerCli.Out(), opts.name)
    88  	return nil
    89  }
    90  
    91  func acceptPrivileges(dockerCli *command.DockerCli, name string) func(privileges types.PluginPrivileges) (bool, error) {
    92  	return func(privileges types.PluginPrivileges) (bool, error) {
    93  		fmt.Fprintf(dockerCli.Out(), "Plugin %q is requesting the following privileges:\n", name)
    94  		for _, privilege := range privileges {
    95  			fmt.Fprintf(dockerCli.Out(), " - %s: %v\n", privilege.Name, privilege.Value)
    96  		}
    97  
    98  		fmt.Fprint(dockerCli.Out(), "Do you grant the above permissions? [y/N] ")
    99  		reader := bufio.NewReader(dockerCli.In())
   100  		line, _, err := reader.ReadLine()
   101  		if err != nil {
   102  			return false, err
   103  		}
   104  		return strings.ToLower(string(line)) == "y", nil
   105  	}
   106  }