Go Wiki: Gomote

gomote 命令是 Go 构建器基础设施的客户端。它是远程 Go 构建器机器的遥控器。

安装

$ go install golang.org/x/build/cmd/gomote@latest  # Go 1.16 and later

用法

gomote 工具最基本的用法只涉及几个步骤

  1. 创建一个实例。
  2. 将代码推送到实例。
  3. 在实例上运行命令。

运行带有 -list 标志的 create 命令将列出可用的实例类型。

$ gomote create -list
(list tons of builder types)

然后,可以通过指定实例类型来创建实例。实例的名称将打印到 stdout,因此结果可以存储在环境变量中。(可能还有其他日志消息,但它们会输出到 stderr,并且每行都带有 '#' 前缀。)

$ gomote create gotip-linux-amd64
# still creating gotip-linux-amd64 (1) after 5s; 0 requests ahead of you
user-gotip-linux-amd64-0

有了该实例的名称,您现在可以将 GOROOT 推送到实例并安装一个引导工具链。您同步的仓库将出现在 $WORKDIR(所有 gomote 操作的默认目录)的 go 子目录下。引导工具链将始终位于 go1.4 子目录中(即使引导工具链不是来自版本 1.4)。

$ GOROOT=/path/to/local/go/repo gomote push user-gotip-linux-amd64-0
$ gomote ls user-gotip-linux-amd64-0
go
go1.4

请注意,push 实际上是一个“同步”操作,因此下次您执行 push 时,gomote 工具只会推送发生更改的内容(添加、修改或删除的文件)。

安装了工具链后,您现在可以通过在实例上运行命令来构建它。run 命令允许您指定要运行的可执行文件。可执行文件必须相对于 $WORKDIR(例如 go/bin/go)或通过绝对路径(例如 /bin/bash)指定。然后,该可执行文件将在包含该可执行文件的目录作为其当前工作目录的环境下运行。

$ gomote run user-gotip-linux-amd64-0 go/src/make.bash

要运行构建好的 Go 工具链,请使用 go/bin/go

$ gomote run user-gotip-linux-amd64-0 go/bin/go test -run="TestSomething" -v runtime

您还可以通过 run 命令的标志指定工作目录和环境变量,这些标志将在命令执行前应用。

请注意,gomote 实例在闲置 30 分钟后将自动消失。使用 list 命令可以查看剩余时间。

$ gomote list
user-gotip-linux-amd64-0    gotip-linux-amd64   gotip-linux-amd64   expires in 10m27.339494527s

如果没有其他命令正在针对某个实例运行,可以使用 ping 命令使其保持活动状态。

有关每个命令的更多信息,请运行 gomote help <command>。有关更多命令,请运行 gomote help

构建器类型

可用的构建器类型遵循一定的结构,大致为 $GOBRANCH-($REPO-)?$GOOS-$GOARCH(_$OS)-$EXTRA

关于这些名称的一些有用说明。

直接调试 buildlets

create 命令联系构建协调器 (farmer.golang.org) 并请求它为您创建一个 buildlet。所有后续命令(例如 gomote rungomote ls)都通过协调器代理您的请求。要直接访问 buildlet(例如,在处理 buildlet 代码时),您可以跳过 gomote create 步骤,使用特殊的构建器名称 <build-config-name>@ip[:port>,例如 windows-amd64-2008@10.1.5.3

分组

实例可以在命名分组中进行管理,命令会广播到分组中的所有实例。

分组可以通过全局标志 -group 或通过 GOMOTE_GROUP 环境变量指定。-group 标志必须始终指定一个有效的分组,而 GOMOTE_GROUP 可能包含一个无效的分组。一个实例可以属于多个分组。

分组可以使用“group”子命令进行显式管理,但在大多数情况下,有几个快捷方式可以避免这种显式管理

因此,使用分组最简单的方法就是设置 GOMOTE_GROUP 环境变量

$ export GOMOTE_GROUP=debug
$ gomote create gotip-linux-amd64
$ GOROOT=/path/to/goroot gomote push
$ gomote run go/src/make.bash

如本例所示,即使分组只包含一个实例,分组也很有用:它可以极大地缩短大多数 gomote 命令。

技巧与窍门

一般

create 命令接受 -setup 标志,该标志也会推送 GOROOT 并为实例运行相应的 make.bash 等效命令。

示例

$ GOROOT=/path/to/my/goroot gomote create -setup gotip-linux-amd64
# Creating user-gotip-linux-amd64-0...
# Pushing /path/to/my/goroot to user-gotip-linux-amd64-0
# Running make.bash on user-gotip-linux-amd64-0...

create 命令接受 -count 标志,用于一次创建多个实例。

示例

$ gomote create -count=3 gotip-linux-amd64
# Creating user-gotip-linux-amd64-0...
# Creating user-gotip-linux-amd64-1...
# Creating user-gotip-linux-amd64-2...

run 命令接受 -collect 标志,用于自动将命令的输出写入当前工作目录的文件中,以及实例完整文件树的副本。此命令对于以“设置后即忘”的方式捕获长时间运行命令的输出很有用。

示例

$ gomote run -collect user-gotip-linux-amd64-0 /bin/bash -c 'echo hi'
# Writing output to user-gotip-linux-amd64-0.stdout...
$ cat user-gotip-linux-amd64-0.stdout
hi
$ ls user-gotip-linux-amd64-0.tar.gz
user-gotip-linux-amd64-0.tar.gz

run 命令接受 -until 标志,用于持续执行命令直到命令的输出匹配某个模式。这对于重现罕见问题很有用,特别是与 -collect 结合使用时。

示例

$ gomote run -until 'FAIL' -collect user-gotip-linux-amd64-0 go/bin/go test -run 'TestFlaky' -count=1000 runtime
# Writing output to user-gotip-linux-amd64-0.stdout...
$ cat user-gotip-linux-amd64-0.stdout
...
--- FAIL: TestFlaky ---
...
$ ls user-gotip-linux-amd64-0.tar.gz
user-gotip-linux-amd64-0.tar.gz

请注意,无论是否有附加标志,run 命令始终将输出流式传输到临时文件,以避免因终端回滚而丢失输出。它总是打印文件位置。

重现罕见故障

结合上面的一些技巧并利用分组,持续对某些测试进行尝试以重现罕见故障会容易得多。例如

$ export GOMOTE_GROUP=debug
$ GOROOT=/path/to/goroot gomote create -setup -count=10 gotip-linux-amd64
$ gomote run -until='unexpected return pc' -collect go/bin/go run -run="TestFlaky" -count=100 runtime

Darwin

已知 Darwin gomotes 需要几分钟来设置,即使有可用机器。这是由于设置 Xcode 需要额外时间。

Windows

$ gomote run -path '$PATH,$WORKDIR/go/bin' $MOTE go/src/make.bat
$ gomote run -path '$PATH,$WORKDIR/go/bin' $MOTE go/bin/go.exe test cmd/go -short

注意:wiki 的先前版本建议为 gomote ‘run’ 命令设置 GOROOT(例如 “-e GOROOT=%WORKDIR%\go”);现在不推荐这样做(会导致 Go 命令缓存出现问题)。

Windows 上的子仓库

$ tar --exclude .git -C ~/go/src/ -zc golang.org/x/tools | gomote puttar -dir=gopath/src $MOTE -
$ gomote run -e 'GOPATH=%WORKDIR%\gopath' $MOTE go/bin/go test -run=TestFixImportsVendorPackage golang.org/x/tools/imports

如果通过 ssh 连接到机器,这些环境变量可能会很方便

$ set GOPATH=%WORKDIR%\gopath
$ set PATH=%PATH%;%WORKDIR%\gopath\bin;%WORKDIR%\go\bin
$ set CGO_ENABLED=0

Unix 上的子仓库

在 $MOTE 上测试 golang.org/x/sys/unix

$ tar -C $GOPATH/src/ -zc golang.org/x/sys/unix | gomote puttar -dir=gopath/src $MOTE
$ gomote run -e 'GOPATH=/tmp/workdir/gopath' -dir 'gopath/src/golang.org/x/sys/unix' $MOTE go/bin/go test -v golang.org/x/sys/unix

(GOPATH 部分用于 GOPATH 兼容模式;-dir 用于模块模式,它会在工作目录及向上查找 go.mod

Android

export MOTE=`gomote create android-arm64-wikofever`
gomote push $MOTE
gomote run $MOTE go/src/make.bash

PATH 必须包含由 make.bash 构建的 exec wrapper,go_android_*_exec

gomote run -path '$PATH,$WORKDIR/go/bin' $MOTE go/bin/go test math/big

关于 buildlets

https://farmer.golang.org/builders 列出了关于每个 buildlet 如何部署和配置的信息。这些信息来自 golang.org/x/build/dashboard 和 golang.org/x/build/env。

访问权限

自 2025 年 1 月起,gomote 访问权限将自动授予拥有 Approvers 访问权限的贡献者。

2022 年 8 月,部署了新的基础设施,需要移除先前已批准用户的所有 gomote 访问权限。如果您仍然需要访问权限,请重新申请。

要申请 gomote 服务访问权限,请提交一个新 issue (https://golang.ac.cn/issue/new?title=access:+&body=See+https://golang.ac.cn/wiki/Gomote%23access.) 并说明您用于登录 Gerrit 的 Google 帐户。提供的帐户仅用于身份验证。

首次调用命令时会触发身份验证

$ gomote create gotip-linux-amd64
Please visit https://www.google.com/device in your browser and enter verification code:
 ABCD-4567
...

login 命令也会启动身份验证流程

$ gomote login
Please visit https://www.google.com/device in your browser and enter verification code:
 ABCD-4567
...

使用提供的链接打开浏览器后,用户必须使用 Google 帐户进行身份验证,并将验证码粘贴到浏览器中。稍等片刻后,客户端将完成身份验证。

gomote ssh

gomote ssh 命令使用专门为 gomote 创建的 SSH 密钥。首次使用 gomote ssh 时,会创建一组密钥并存储在本地用户配置目录中。您可能会被要求为密钥设置密码(密码不是必需的)。SSH 功能通过 OpenSSH 证书认证进行操作,不需要任何额外配置。并非所有构建器类型都支持 gomote ssh


此内容是 Go Wiki 的一部分。