package node import ( "context" "errors" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/internal/commands" "github.com/moby/moby/client" "github.com/spf13/cobra" ) func init() { commands.Register(newNodeCommand) } // newNodeCommand returns a cobra command for `node` subcommands func newNodeCommand(dockerCLI command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "node", Short: "Manage Swarm nodes", Args: cli.NoArgs, RunE: command.ShowHelp(dockerCLI.Err()), Annotations: map[string]string{ "version": "1.24", "swarm": "manager", }, DisableFlagsInUseLine: true, } cmd.AddCommand( newDemoteCommand(dockerCLI), newInspectCommand(dockerCLI), newListCommand(dockerCLI), newPromoteCommand(dockerCLI), newRemoveCommand(dockerCLI), newPsCommand(dockerCLI), newUpdateCommand(dockerCLI), ) return cmd } // Reference returns the reference of a node. The special value "self" for a node // reference is mapped to the current node, hence the node ID is retrieved using // the `/info` endpoint. func Reference(ctx context.Context, apiClient client.APIClient, ref string) (string, error) { if ref == "self" { res, err := apiClient.Info(ctx, client.InfoOptions{}) if err != nil { return "", err } if res.Info.Swarm.NodeID == "" { // If there's no node ID in /info, the node probably // isn't a manager. Call a swarm-specific endpoint to // get a more specific error message. // // FIXME(thaJeztah): this should not require calling a Swarm endpoint, and we could just suffice with info / ping (which has swarm status). _, err = apiClient.NodeList(ctx, client.NodeListOptions{}) if err != nil { return "", err } return "", errors.New("node ID not found in /info") } return res.Info.Swarm.NodeID, nil } return ref, nil }