Skip to content

Commit

Permalink
cmd/gomote: add groups
Browse files Browse the repository at this point in the history
This change adds the concept of gomote groups into the CLI, where the
user may manage one or more gomotes with a shorter set of commands.

The gomote command manages the necessary state for each group. This
change adds the group subcommand which allows for creating and
destroying groups, and also adds global group tracking across all
the other subcommands.

For now, this CL does essentially nothing other than add groups to the
CLI. The groups are effectively non-functional as all subcommands fail
when there's an active group specified. Follow-up CLs will
incrementally enable group support across these subcommands.

For golang/go#53956.

Change-Id: I4d4d7c4f8aebfe8640fd68a9c6f8ec1211693efd
Reviewed-on: https://go-review.googlesource.com/c/build/+/418154
Reviewed-by: Carlos Amedee <[email protected]>
Run-TryBot: Michael Knyszek <[email protected]>
Auto-Submit: Michael Knyszek <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
mknyszek authored and gopherbot committed Nov 18, 2022
1 parent 1954702 commit f0acaeb
Show file tree
Hide file tree
Showing 13 changed files with 451 additions and 26 deletions.
8 changes: 8 additions & 0 deletions cmd/gomote/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ func builders() (bt []builderType) {
}

func legacyCreate(args []string) error {
if activeGroup != nil {
return fmt.Errorf("command does not support groups")
}

fs := flag.NewFlagSet("create", flag.ContinueOnError)

fs.Usage = func() {
Expand Down Expand Up @@ -133,6 +137,10 @@ func legacyCreate(args []string) error {
}

func create(args []string) error {
if activeGroup != nil {
return fmt.Errorf("command does not yet support groups")
}

fs := flag.NewFlagSet("create", flag.ContinueOnError)

fs.Usage = func() {
Expand Down
8 changes: 8 additions & 0 deletions cmd/gomote/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
)

func legacyDestroy(args []string) error {
if activeGroup != nil {
return fmt.Errorf("command does not support groups")
}

fs := flag.NewFlagSet("destroy", flag.ContinueOnError)
fs.Usage = func() {
fmt.Fprintln(os.Stderr, "destroy usage: gomote destroy <instance>")
Expand Down Expand Up @@ -53,6 +57,10 @@ func legacyDestroy(args []string) error {
}

func destroy(args []string) error {
if activeGroup != nil {
return fmt.Errorf("command does not yet support groups")
}

fs := flag.NewFlagSet("destroy", flag.ContinueOnError)
fs.Usage = func() {
fmt.Fprintln(os.Stderr, "destroy usage: gomote destroy <instance>")
Expand Down
8 changes: 8 additions & 0 deletions cmd/gomote/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import (

// legacyGetTar a .tar.gz
func legacyGetTar(args []string) error {
if activeGroup != nil {
return fmt.Errorf("command does not support groups")
}

fs := flag.NewFlagSet("get", flag.ContinueOnError)
fs.Usage = func() {
fmt.Fprintln(os.Stderr, "gettar usage: gomote gettar [get-opts] <buildlet-name>")
Expand Down Expand Up @@ -48,6 +52,10 @@ func legacyGetTar(args []string) error {

// getTar a .tar.gz
func getTar(args []string) error {
if activeGroup != nil {
return fmt.Errorf("command does not yet support groups")
}

fs := flag.NewFlagSet("get", flag.ContinueOnError)
fs.Usage = func() {
fmt.Fprintln(os.Stderr, "gettar usage: gomote gettar [get-opts] <buildlet-name>")
Expand Down
41 changes: 37 additions & 4 deletions cmd/gomote/gomote.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ To list the subcommands, run "gomote" without arguments:
rm delete files or directories
rdp RDP (Remote Desktop Protocol) to a Windows buildlet
run run a command on a buildlet
group manage gomote groups (v2 only)
ssh ssh to a buildlet
To list all the builder types available, run "create" with no arguments:
Expand Down Expand Up @@ -71,6 +72,7 @@ The "gomote run" command has many of its own flags:
-system
run inside the system, and not inside the workdir; this is implicit if cmd starts with '/'
# Debugging buildlets directly
Using "gomote create" contacts the build coordinator
Expand All @@ -95,11 +97,13 @@ import (
"golang.org/x/build/buildlet"
"golang.org/x/build/internal/gomote/protos"
"golang.org/x/build/internal/iapclient"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

var (
buildEnv *buildenv.Environment
buildEnv *buildenv.Environment
activeGroup *groupData
)

type command struct {
Expand Down Expand Up @@ -148,6 +152,7 @@ func registerCommands(version int) {
registerCommand("create", "create a buildlet; with no args, list types of buildlets", create)
registerCommand("destroy", "destroy a buildlet", destroy)
registerCommand("gettar", "extract a tar.gz from a buildlet", getTar)
registerCommand("group", "manage groups of instances", group)
registerCommand("ls", "list the contents of a directory on a buildlet", ls)
registerCommand("list", "list active buildlets", list)
registerCommand("ping", "test whether a buildlet is alive and reachable ", ping)
Expand All @@ -174,6 +179,7 @@ func registerCommands(version int) {
registerCommand("rdp", "RDP (Remote Desktop Protocol) to a Windows buildlet", rdp)
registerCommand("rm", "delete files or directories", legacyRm)
registerCommand("run", "run a command on a buildlet", legacyRun)
registerCommand("group", "manage gomote groups (v2 only)", group)
registerCommand("ssh", "ssh to a buildlet", legacySSH)
}

Expand All @@ -182,6 +188,8 @@ var (
)

func main() {
// Set up and parse global flags.
groupName := flag.String("group", os.Getenv("GOMOTE_GROUP"), "name of the gomote group to apply commands to (default is $GOMOTE_GROUP)")
buildlet.RegisterFlags()
version := 2
if vs := os.Getenv("GOMOTE_VERSION"); vs != "" {
Expand All @@ -196,19 +204,40 @@ func main() {
registerCommands(version)
flag.Usage = usage
flag.Parse()
buildEnv = buildenv.FromFlags()
args := flag.Args()
if len(args) == 0 {
usage()
}

// Set up globals.
buildEnv = buildenv.FromFlags()
if *groupName != "" {
var err error
activeGroup, err = loadGroup(*groupName)
if os.Getenv("GOMOTE_GROUP") != *groupName {
// Only fail hard since it was specified by the flag.
if err != nil {
fmt.Fprintf(os.Stderr, "Failure: %v\n", err)
usage()
}
} else {
// With a valid group from GOMOTE_GROUP,
// make it explicit to the user that we're going
// ahead with it. We don't need this with the flag
// because it's explicit.
if err == nil {
fmt.Fprintf(os.Stderr, "# Using group %q from GOMOTE_GROUP\n", *groupName)
}
}
}

cmdName := args[0]
cmd, ok := commands[cmdName]
if !ok {
fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmdName)
usage()
}
err := cmd.run(args[1:])
if err != nil {
if err := cmd.run(args[1:]); err != nil {
logAndExitf("Error running %s: %v\n", cmdName, err)
}
}
Expand All @@ -233,3 +262,7 @@ func logAndExitf(format string, v ...interface{}) {
func statusFromError(err error) string {
return status.Convert(err).Message()
}

func instanceDoesNotExist(err error) bool {
return status.Code(err) == codes.NotFound
}
Loading

0 comments on commit f0acaeb

Please sign in to comment.