cmd/gomote: consistently support a direct-to-buildlet mode, bypassing coordinator

For testing new builder images, this adds support to gomote to connect
to a buildlet directly, without going via the coordinator. If the
builder name contains a '@' character, the name is expected to be of
the form <build-config-name>@ip[:port].

Also update the gomote run -path docs while I'm here, since I always
forget the magic expansions (which at least are documentd in the
buildlet godoc). Copy them to the flags doc.

Change-Id: I50227855897106e1cc60c1881700866d5fddf2a5
Reviewed-on: https://go-review.googlesource.com/38775
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Brad Fitzpatrick 2017-03-28 20:19:09 +00:00
Родитель 0f8fc131b7
Коммит 08e0bcc981
9 изменённых файлов: 104 добавлений и 21 удалений

Просмотреть файл

@ -23,7 +23,7 @@ func destroy(args []string) error {
fs.Usage()
}
name := fs.Arg(0)
bc, err := namedClient(name)
bc, _, err := clientAndConf(name)
if err != nil {
return err
}

Просмотреть файл

@ -29,7 +29,7 @@ func getTar(args []string) error {
}
name := fs.Arg(0)
bc, err := namedClient(name)
bc, _, err := clientAndConf(name)
if err != nil {
return err
}

Просмотреть файл

@ -6,6 +6,8 @@
The gomote command is a client for the Go builder infrastructure.
It's a remote control for remote Go builder machines.
See https://golang.org/wiki/Gomote
Usage:
gomote [global-flags] cmd [cmd-flags]
@ -15,8 +17,68 @@ Usage:
user-username-openbsd-amd64-60-0
$ gomote push user-username-openbsd-amd64-60-0
$ gomote run user-username-openbsd-amd64-60-0 go/src/make.bash
$ gomote run user-username-openbsd-amd64-60-0 go/bin/go test -v -short os
To list the subcommands, run "gomote" without arguments:
Commands:
create create a buildlet
destroy destroy a buildlet
gettar extract a tar.gz from a buildlet
list list buildlets
ls list the contents of a directory on a buildlet
ping test whether a buildlet is alive and reachable
push sync the repo of your pwd to the buildlet
put put files on a buildlet
put14 put Go 1.4 in place
puttar extract a tar.gz to a buildlet
rm delete files or directories
run run a command on a buildlet
To list all the builder types available, run "create" with no arguments:
$ gomote create
(tons of builder types)
The "gomote run" command has many of its own flags:
$ gomote run -h
create usage: gomote run [run-opts] <instance> <cmd> [args...]
-builderenv string
Optional alternate builder to act like. Must share the same
underlying buildlet host type, or it's an error. For
instance, linux-amd64-race or linux-386-387 are compatible
with linux-amd64, but openbsd-amd64 and openbsd-386 are
different hosts.
-debug
write debug info about the command's execution before it begins
-dir string
Directory to run from. Defaults to the directory of the
command, or the work directory if -system is true.
-e value
Environment variable KEY=value. The -e flag may be repeated
multiple times to add multiple things to the environment.
-path string
Comma-separated list of ExecOpts.Path elements. The special
string 'EMPTY' means to run without any $PATH. The empty
string (default) does not modify the $PATH. Otherwise, the
following expansions apply: the string '$PATH' expands to
the current PATH element(s), the substring '$WORKDIR'
expands to the buildlet's temp workdir.
-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
(farmer.golang.org) and requests that it create the buildlet on your
behalf. All subsequent commands (such as "gomote run" or "gomote ls")
then proxy your request via the coordinator. To access a buildlet
directly (for example, when working on the buildlet code), you can
skip the "gomote create" step and use the special builder name
"<build-config-name>@ip[:port>", such as "windows-amd64-gce@10.1.5.3".
TODO: document more, and figure out the CLI interface more.
*/
package main

Просмотреть файл

@ -43,7 +43,36 @@ func list(args []string) error {
return nil
}
// clientAndConfig returns a buildlet.Client and its build config for
// a named remote buildlet (a buildlet connection owned by the build
// coordinator).
//
// As a special case, if name contains '@', the name is expected to be
// of the form <build-config-name>@ip[:port]. For example,
// "windows-amd64-race@10.0.0.1".
func clientAndConf(name string) (bc *buildlet.Client, conf dashboard.BuildConfig, err error) {
var ok bool
if strings.Contains(name, "@") {
f := strings.SplitN(name, "@", 2)
if len(f) != 2 {
err = fmt.Errorf("unsupported name %q; for @ form expect <build-config-name>@host[:port]")
return
}
builderType := f[0]
conf, ok = dashboard.Builders[builderType]
if !ok {
err = fmt.Errorf("unknown builder type %q", name, builderType)
return
}
ipPort := f[1]
if !strings.Contains(ipPort, ":") {
ipPort += ":80"
}
bc = buildlet.NewClient(ipPort, buildlet.NoKeyPair)
return
}
cc, err := buildlet.NewCoordinatorClientFromFlags()
if err != nil {
return
@ -53,7 +82,6 @@ func clientAndConf(name string) (bc *buildlet.Client, conf dashboard.BuildConfig
if err != nil {
return
}
var ok bool
for _, rb := range rbs {
if rb.Name == name {
conf, ok = dashboard.Builders[rb.BuilderType]
@ -69,17 +97,9 @@ func clientAndConf(name string) (bc *buildlet.Client, conf dashboard.BuildConfig
return
}
bc, err = namedClient(name)
return
}
func namedClient(name string) (*buildlet.Client, error) {
if strings.Contains(name, ":") {
return buildlet.NewClient(name, buildlet.NoKeyPair), nil
}
cc, err := buildlet.NewCoordinatorClientFromFlags()
bc, err = cc.NamedBuildlet(name)
if err != nil {
return nil, err
return
}
return cc.NamedBuildlet(name)
return bc, conf, nil
}

Просмотреть файл

@ -35,7 +35,7 @@ func ls(args []string) error {
dir = fs.Arg(1)
}
name := fs.Arg(0)
bc, err := namedClient(name)
bc, _, err := clientAndConf(name)
if err != nil {
return err
}

Просмотреть файл

@ -23,7 +23,7 @@ func ping(args []string) error {
fs.Usage()
}
name := fs.Arg(0)
bc, err := namedClient(name)
bc, _, err := clientAndConf(name)
if err != nil {
return err
}

Просмотреть файл

@ -46,7 +46,7 @@ func putTar(args []string) error {
}
name := fs.Arg(0)
bc, err := namedClient(name)
bc, _, err := clientAndConf(name)
if err != nil {
return err
}
@ -125,7 +125,7 @@ func put(args []string) error {
fs.Usage()
}
bc, err := namedClient(fs.Arg(0))
bc, _, err := clientAndConf(fs.Arg(0))
if err != nil {
return err
}

Просмотреть файл

@ -25,7 +25,7 @@ func rm(args []string) error {
}
name := fs.Arg(0)
args = fs.Args()[1:]
bc, err := namedClient(name)
bc, _, err := clientAndConf(name)
if err != nil {
return err
}

Просмотреть файл

@ -29,7 +29,8 @@ func run(args []string) error {
var env stringSlice
fs.Var(&env, "e", "Environment variable KEY=value. The -e flag may be repeated multiple times to add multiple things to the environment.")
var path string
fs.StringVar(&path, "path", "", "Comma-separated list of ExecOpts.Path elements. The special string 'EMPTY' means to run without any $PATH. The empty string (default) does not modify the $PATH.")
fs.StringVar(&path, "path", "", "Comma-separated list of ExecOpts.Path elements. The special string 'EMPTY' means to run without any $PATH. The empty string (default) does not modify the $PATH. Otherwise, the following expansions apply: the string '$PATH' expands to the current PATH element(s), the substring '$WORKDIR' expands to the buildlet's temp workdir.")
var dir string
fs.StringVar(&dir, "dir", "", "Directory to run from. Defaults to the directory of the command, or the work directory if -system is true.")
var builderEnv string