github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/cli/command/swarm/unlock.go (about)

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