unlock.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package swarm
  2. import (
  3. "bufio"
  4. "context"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "github.com/docker/cli/cli"
  9. "github.com/docker/cli/cli/command"
  10. "github.com/docker/cli/cli/command/completion"
  11. "github.com/docker/cli/cli/streams"
  12. "github.com/docker/docker/api/types/swarm"
  13. "github.com/pkg/errors"
  14. "github.com/spf13/cobra"
  15. "golang.org/x/term"
  16. )
  17. func newUnlockCommand(dockerCli command.Cli) *cobra.Command {
  18. cmd := &cobra.Command{
  19. Use: "unlock",
  20. Short: "Unlock swarm",
  21. Args: cli.NoArgs,
  22. RunE: func(cmd *cobra.Command, args []string) error {
  23. return runUnlock(cmd.Context(), dockerCli)
  24. },
  25. Annotations: map[string]string{
  26. "version": "1.24",
  27. "swarm": "manager",
  28. },
  29. ValidArgsFunction: completion.NoComplete,
  30. }
  31. return cmd
  32. }
  33. func runUnlock(ctx context.Context, dockerCli command.Cli) error {
  34. client := dockerCli.Client()
  35. // First see if the node is actually part of a swarm, and if it is actually locked first.
  36. // If it's in any other state than locked, don't ask for the key.
  37. info, err := client.Info(ctx)
  38. if err != nil {
  39. return err
  40. }
  41. switch info.Swarm.LocalNodeState {
  42. case swarm.LocalNodeStateInactive:
  43. return errors.New("Error: This node is not part of a swarm")
  44. case swarm.LocalNodeStateLocked:
  45. break
  46. default:
  47. return errors.New("Error: swarm is not locked")
  48. }
  49. key, err := readKey(dockerCli.In(), "Enter unlock key: ")
  50. if err != nil {
  51. return err
  52. }
  53. req := swarm.UnlockRequest{
  54. UnlockKey: key,
  55. }
  56. return client.SwarmUnlock(ctx, req)
  57. }
  58. func readKey(in *streams.In, prompt string) (string, error) {
  59. if in.IsTerminal() {
  60. fmt.Print(prompt)
  61. dt, err := term.ReadPassword(int(in.FD()))
  62. fmt.Println()
  63. return string(dt), err
  64. }
  65. key, err := bufio.NewReader(in).ReadString('\n')
  66. if err == io.EOF {
  67. err = nil
  68. }
  69. return strings.TrimSpace(key), err
  70. }