cmd/buildlet: support Windows ARM64 qemu guests
The Windows ARM builders on EC2 run on qemu via KVM. We use a userspace
network device for simplicity, which also conveniently restricts which
ports are exposed. In order to make a request to the metatadata service,
which is routed in a different way than the public internet, we
explicitly forward the port to the guest VM on a special ip/port.
This introduces a hard-coded value for Windows ARM64 buildlets. We
should be able to improve this code to detect it, but this will get the
buildlet unblocked.
The buildlet image also includes llvm-arm64 mingw rather than a gcc
based distribution. This change also adds the correct directory to the
path.
For golang/go#42604
Change-Id: Ife2ebb900a08034d6e0dfa0982a24b312ee6d70a
Reviewed-on: https://go-review.googlesource.com/c/build/+/322653
Trust: Alexander Rakoczy <alex@golang.org>
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go
index 9ccb554..02a54a5 100644
--- a/cmd/buildlet/buildlet.go
+++ b/cmd/buildlet/buildlet.go
@@ -41,6 +41,7 @@
"time"
"cloud.google.com/go/compute/metadata"
+ "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"golang.org/x/build/buildlet"
@@ -334,12 +335,18 @@
if ec2MdC != nil {
return ec2MdC.Available()
}
- ses, err := session.NewSession()
+ cfg := aws.NewConfig()
+ // TODO(golang/go#42604) - Improve detection of our qemu forwarded
+ // metadata service for Windows ARM VMs running on EC2.
+ if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" {
+ cfg = cfg.WithEndpoint("http://10.0.2.100:8173/latest")
+ }
+ ses, err := session.NewSession(cfg)
if err != nil {
log.Printf("unable to create aws session: %s", err)
return false
}
- ec2MdC = ec2metadata.New(ses)
+ ec2MdC = ec2metadata.New(ses, cfg)
return ec2MdC.Available()
}
@@ -1123,11 +1130,10 @@
func windowsBaseEnv(goarch string) (e []string) {
e = append(e, "GOBUILDEXIT=1") // exit all.bat with completion status
- is64 := goarch != "386"
for _, pair := range os.Environ() {
const pathEq = "PATH="
if hasPrefixFold(pair, pathEq) {
- e = append(e, "PATH="+windowsPath(pair[len(pathEq):], is64))
+ e = append(e, "PATH="+windowsPath(pair[len(pathEq):], goarch))
} else {
e = append(e, pair)
}
@@ -1143,15 +1149,18 @@
// windowsPath cleans the windows %PATH% environment.
// is64Bit is whether this is a windows-amd64-* builder.
// The PATH is assumed to be that of the image described in env/windows/README.
-func windowsPath(old string, is64Bit bool) string {
+func windowsPath(old string, goarch string) string {
vv := filepath.SplitList(old)
newPath := make([]string, 0, len(vv))
+ is64Bit := goarch != "386"
// for windows-buildlet-v2 images
for _, v := range vv {
// The base VM image has both the 32-bit and 64-bit gcc installed.
// They're both in the environment, so scrub the one
// we don't want (TDM-GCC-64 or TDM-GCC-32).
+ //
+ // This is not present in arm64 images.
if strings.Contains(v, "TDM-GCC-") {
gcc64 := strings.Contains(v, "TDM-GCC-64")
if is64Bit != gcc64 {
@@ -1161,11 +1170,13 @@
newPath = append(newPath, v)
}
- // for windows-amd64-* images
- if is64Bit {
- newPath = append(newPath, `C:\godep\gcc64\bin`)
- } else {
+ switch goarch {
+ case "arm64":
+ newPath = append(newPath, `C:\godep\llvm-aarch64\bin`)
+ case "386":
newPath = append(newPath, `C:\godep\gcc32\bin`)
+ default:
+ newPath = append(newPath, `C:\godep\gcc64\bin`)
}
return strings.Join(newPath, string(filepath.ListSeparator))
@@ -1227,6 +1238,11 @@
} else {
err = errors.New("not respecting -halt flag on macOS in unknown environment")
}
+ case "windows":
+ err = errors.New("not respsecting -halt flag on windows in unknown environment")
+ if runtime.GOARCH == "arm64" {
+ err = exec.Command("shutdown /s").Run()
+ }
default:
err = errors.New("no system-specific halt command run; will just end buildlet process")
}