unlock.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package swarm
  2. import (
  3. "bufio"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "github.com/spf13/cobra"
  9. "golang.org/x/crypto/ssh/terminal"
  10. "github.com/docker/docker/api/types/swarm"
  11. "github.com/docker/docker/cli"
  12. "github.com/docker/docker/cli/command"
  13. "golang.org/x/net/context"
  14. )
  15. type unlockOptions struct{}
  16. func newUnlockCommand(dockerCli command.Cli) *cobra.Command {
  17. opts := unlockOptions{}
  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(dockerCli, opts)
  24. },
  25. }
  26. return cmd
  27. }
  28. func runUnlock(dockerCli command.Cli, opts unlockOptions) error {
  29. client := dockerCli.Client()
  30. ctx := context.Background()
  31. // First see if the node is actually part of a swarm, and if it is actually locked first.
  32. // If it's in any other state than locked, don't ask for the key.
  33. info, err := client.Info(ctx)
  34. if err != nil {
  35. return err
  36. }
  37. switch info.Swarm.LocalNodeState {
  38. case swarm.LocalNodeStateInactive:
  39. return errors.New("Error: This node is not part of a swarm")
  40. case swarm.LocalNodeStateLocked:
  41. break
  42. default:
  43. return errors.New("Error: swarm is not locked")
  44. }
  45. key, err := readKey(dockerCli.In(), "Please enter unlock key: ")
  46. if err != nil {
  47. return err
  48. }
  49. req := swarm.UnlockRequest{
  50. UnlockKey: key,
  51. }
  52. return client.SwarmUnlock(ctx, req)
  53. }
  54. func readKey(in *command.InStream, prompt string) (string, error) {
  55. if in.IsTerminal() {
  56. fmt.Print(prompt)
  57. dt, err := terminal.ReadPassword(int(in.FD()))
  58. fmt.Println()
  59. return string(dt), err
  60. }
  61. key, err := bufio.NewReader(in).ReadString('\n')
  62. if err == io.EOF {
  63. err = nil
  64. }
  65. return strings.TrimSpace(key), err
  66. }