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 实际上是一个“同步”操作,因此下次推送时,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

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

  • 不同的 $GOBRANCH 主要修改预装工具的版本,例如引导 Go 工具链。
  • 带有 $REPO 的构建器类型将在工作根目录的 tip-of-tree 处下载指定的存储库。

直接调试构建代理

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

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

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

组可以使用“group”子命令显式管理,但有几种快捷方式可以使在大多数情况下不需要这样做。

  • create 命令可以使用 -new-group 标志为实例创建新组。
  • 如果 GOMOTE_GROUP 中不存在该组且未显式指定其他组,create 命令将自动在 GOMOTE_GROUP 中创建该组。
  • destroy 命令除了销毁实例外,还可以使用 -destroy-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 gomote 的设置需要几分钟时间,即使有可用的机器。这是因为设置 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)

安卓

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

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

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

关于构建代理

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

访问权限

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

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

要请求对 gomote 服务的访问权限,请提交一个新问题 (https://go-lang.org.cn/issue/new?title=access:+&body=See+https://go-lang.org.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 的一部分。