install.go 2.9 KB

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