Skip to content

Commit d489097

Browse files
committed
all: upgrade scaleway linux-arm builders, stop using deprecated --reverse flag
Updates golang/go#21260 (no more buildlets using the --reverse flag) Updates golang/go#33574 (linux-arm kernel+userspace updated) Change-Id: I7455f6fa3e851f1f9f81d6f1eb487ef7e4bea55b Reviewed-on: https://go-review.googlesource.com/c/build/+/205603 Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 621ef1f commit d489097

File tree

7 files changed

+213
-60
lines changed

7 files changed

+213
-60
lines changed

cmd/genbootstrap/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# golang.org/x/build/cmd/genbootstrap
66

7-
The genbootstrap command prepares GO_BOOTSTRAP tarballs suitable for use on builders.
7+
The genbootstrap command prepares GOROOT_BOOTSTRAP tarballs suitable for use on builders.

cmd/genbootstrap/genbootstrap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// license that can be found in the LICENSE file.
44

55
/*
6-
The genbootstrap command prepares GO_BOOTSTRAP tarballs suitable for
6+
The genbootstrap command prepares GOROOT_BOOTSTRAP tarballs suitable for
77
use on builders. It's a wrapper around bootstrap.bash. After
88
bootstrap.bash produces the full output, genbootstrap trims it up,
99
removing unnecessary and unwanted files.

cmd/rundockerbuildlet/rundockerbuildlet.go

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"runtime"
2323
"strings"
2424
"time"
25+
26+
"golang.org/x/build/buildenv"
2527
)
2628

2729
var (
@@ -32,6 +34,7 @@ var (
3234
keyFile = flag.String("key", "/etc/gobuild.key", "go build key file")
3335
builderEnv = flag.String("env", "", "optional GO_BUILDER_ENV environment variable value to set in the guests")
3436
cpu = flag.Int("cpu", 0, "if non-zero, how many CPUs to assign from the host and pass to docker run --cpuset-cpus")
37+
pull = flag.Bool("pull", false, "whether to pull the the --image before each container starting")
3538
)
3639

3740
var (
@@ -42,26 +45,21 @@ var (
4245
func main() {
4346
flag.Parse()
4447

45-
key, err := ioutil.ReadFile(*keyFile)
46-
if err != nil {
47-
log.Fatalf("error reading build key from --key=%s: %v", *keyFile, err)
48+
if onScaleway() {
49+
*memory = ""
50+
*image = "eu.gcr.io/symbolic-datum-552/scaleway-builder"
51+
*pull = true
52+
*numInst = 1
53+
*basename = "scaleway"
54+
initScalewayMeta()
4855
}
49-
buildKey = bytes.TrimSpace(key)
56+
57+
buildKey = getBuildKey()
5058

5159
if *image == "" {
5260
log.Fatalf("docker --image is required")
5361
}
5462

55-
// If we're on linux/arm, see if we're running in a scaleway
56-
// image (which contains the oc-metadata command) and, if so,
57-
// fetch our instance metadata to make the reported hostname match
58-
// the instance hostname.
59-
if runtime.GOOS == "linux" && runtime.GOARCH == "arm" {
60-
if _, err := os.Stat("/usr/local/bin/oc-metadata"); err == nil {
61-
initScalewayMeta()
62-
}
63-
}
64-
6563
log.Printf("Started. Will keep %d copies of %s running.", *numInst, *image)
6664
for {
6765
if err := checkFix(); err != nil {
@@ -71,6 +69,34 @@ func main() {
7169
}
7270
}
7371

72+
func onScaleway() bool {
73+
if *builderEnv == "host-linux-arm-scaleway" {
74+
return true
75+
}
76+
if runtime.GOOS == "linux" && runtime.GOARCH == "arm" {
77+
if _, err := os.Stat("/usr/local/bin/oc-metadata"); err == nil {
78+
return true
79+
}
80+
}
81+
return false
82+
}
83+
84+
func getBuildKey() []byte {
85+
key, err := ioutil.ReadFile(*keyFile)
86+
if err != nil {
87+
if onScaleway() {
88+
const prefix = "buildkey_host-linux-arm-scaleway_"
89+
for _, tag := range scalewayMeta.Tags {
90+
if strings.HasPrefix(tag, prefix) {
91+
return []byte(strings.TrimPrefix(tag, prefix))
92+
}
93+
}
94+
}
95+
log.Fatalf("error reading build key from --key=%s: %v", *keyFile, err)
96+
}
97+
return bytes.TrimSpace(key)
98+
}
99+
74100
func checkFix() error {
75101
running := map[string]bool{}
76102

@@ -140,6 +166,14 @@ func checkFix() error {
140166
continue
141167
}
142168

169+
if *pull {
170+
log.Printf("Pulling %s ...", *image)
171+
out, err := exec.Command("docker", "pull", *image).CombinedOutput()
172+
if err != nil {
173+
log.Printf("docker pull %s failed: %v, %s", *image, err, out)
174+
}
175+
}
176+
143177
log.Printf("Creating %s ...", name)
144178
keyFile := fmt.Sprintf("/tmp/buildkey%02d/gobuildkey", num)
145179
if err := os.MkdirAll(filepath.Dir(keyFile), 0700); err != nil {
@@ -157,12 +191,19 @@ func checkFix() error {
157191
if *memory != "" {
158192
cmd.Args = append(cmd.Args, "--memory="+*memory)
159193
}
194+
if *cpu > 0 {
195+
cmd.Args = append(cmd.Args, fmt.Sprintf("--cpuset-cpus=%d-%d", *cpu*(num-1), *cpu*num-1))
196+
}
160197
if *builderEnv != "" {
161198
cmd.Args = append(cmd.Args, "-e", "GO_BUILDER_ENV="+*builderEnv)
162199
}
163-
if *cpu > 0 {
164-
cmd.Args = append(cmd.Args, fmt.Sprintf("--cpuset-cpus=%d-%d", *cpu*(num-1), *cpu*num-1))
200+
if u := buildletBinaryURL(); u != "" {
201+
cmd.Args = append(cmd.Args, "-e", "META_BUILDLET_BINARY_URL="+u)
165202
}
203+
cmd.Args = append(cmd.Args,
204+
"-e", "GO_BUILD_KEY_PATH=/buildkey/gobuildkey",
205+
"-e", "GO_BUILD_KEY_DELETE_AFTER_READ=true",
206+
)
166207
cmd.Args = append(cmd.Args, *image)
167208
out, err := cmd.CombinedOutput()
168209
if err != nil {
@@ -180,6 +221,18 @@ type scalewayMetadata struct {
180221
Tags []string `json:"tags"`
181222
}
182223

224+
func (m *scalewayMetadata) HasTag(t string) bool {
225+
if m == nil {
226+
return false
227+
}
228+
for _, v := range m.Tags {
229+
if v == t {
230+
return true
231+
}
232+
}
233+
return false
234+
}
235+
183236
func initScalewayMeta() {
184237
const metaURL = "http://169.254.42.42/conf?format=json"
185238
res, err := http.Get(metaURL)
@@ -202,3 +255,15 @@ func removeContainer(container string) {
202255
}
203256
log.Printf("Removed container %s", container)
204257
}
258+
259+
func buildletBinaryURL() string {
260+
if !onScaleway() {
261+
// Only used for Scaleway currently.
262+
return ""
263+
}
264+
env := buildenv.Production
265+
if scalewayMeta.HasTag("staging") {
266+
env = buildenv.Staging
267+
}
268+
return fmt.Sprintf("https://storage.googleapis.com/%s/buildlet.linux-arm", env.BuildletBucket)
269+
}

cmd/scaleway/scaleway.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"encoding/json"
1313
"flag"
1414
"fmt"
15+
"io"
1516
"io/ioutil"
1617
"log"
1718
"net/http"
@@ -30,14 +31,16 @@ var (
3031
tokenDir = flag.String("token-dir", filepath.Join(os.Getenv("HOME"), "keys"), "directory to read gobuilder-staging.key, gobuilder-master.key and go-scaleway.token from.")
3132
token = flag.String("token", "", "API token. If empty, the file is read from $(token-dir)/go-scaleway.token. Googlers on the Go team can get the value from http://go/golang-scaleway-token")
3233
org = flag.String("org", "1f34701d-668b-441b-bf08-0b13544e99de", "Organization ID (default is [email protected]'s account)")
33-
image = flag.String("image", "e488d5e3-d278-47a7-8f7d-1154e1f61dc9", "Disk image ID; default is the snapshot we made last")
34+
image = flag.String("image", "13f4c905-3a4b-475a-aaba-a13168e2b6c7", "Disk image ID; default is the snapshot we made last")
35+
bootscript = flag.String("bootscript", "5c8e4527-d166-4844-b6c6-087d7a6f5fb0", "Bootscript ID; empty means to use the default for the image. But our images don't have a correct default.")
3436
num = flag.Int("n", 0, "Number of servers to create; if zero, defaults to a value as a function of --staging")
3537
tags = flag.String("tags", "", "Comma-separated list of tags. The build key tags should be of the form 'buildkey_linux-arm_HEXHEXHEXHEXHEX'. If empty, it's automatic.")
3638
staging = flag.Bool("staging", false, "If true, deploy staging instances (with staging names and tags) instead of prod.")
3739
listAll = flag.Bool("list-all", false, "If true, list all (prod, staging, other) current Scaleway servers and stop without making changes.")
3840
list = flag.Bool("list", false, "If true, list all prod (or staging, if -staging) servers, including missing ones.")
3941
fixInterval = flag.Duration("fix-interval", 10*time.Minute, "Interval to wait before running again (only applies to daemon mode)")
4042
daemonMode = flag.Bool("daemon", false, "Run in daemon mode in a loop")
43+
ipv6 = flag.Bool("ipv6", false, "enable IPv6 on scaleway instances")
4144
)
4245

4346
const (
@@ -144,9 +147,27 @@ func checkServers() {
144147
for i := 1; i <= *num; i++ {
145148
name := serverName(i)
146149
server := servers[name]
150+
151+
if server.Image != nil && server.Image.ID != *image {
152+
log.Printf("server %s, state %q, running wrong image %s (want %s)", name, server.State, server.Image.ID, *image)
153+
switch server.State {
154+
case "running":
155+
log.Printf("powering off %s ...", name)
156+
if err := cl.PowerOff(server.ID); err != nil {
157+
log.Printf("PowerOff(%q (%q)): %v", server.ID, name, err)
158+
}
159+
case "stopped":
160+
log.Printf("deleting %s ...", name)
161+
if err := cl.Delete(server.ID); err != nil {
162+
log.Printf("Delete(%q (%q)): %v", server.ID, name, err)
163+
}
164+
}
165+
}
166+
147167
if server.Connected != nil {
148168
continue
149169
}
170+
150171
if server.State == "running" {
151172
if time.Time(server.ModificationDate).Before(time.Now().Add(15 * time.Minute)) {
152173
log.Printf("rebooting old running-but-disconnected %q server...", name)
@@ -171,11 +192,15 @@ func checkServers() {
171192
Image: *image,
172193
CommercialType: ctype,
173194
Tags: tags,
195+
EnableIPV6: *ipv6,
196+
BootType: "bootscript", // the "local" boot mode doesn't work on C1,
197+
Bootscript: *bootscript,
174198
})
175199
if err != nil {
176200
log.Fatal(err)
177201
}
178-
log.Printf("Doing req %q", body)
202+
log.Printf("sending createServerRequest: %s", body)
203+
// TODO: update to their new API path format that includes the zone.
179204
req, err := http.NewRequest("POST", scalewayAPIBase+"/servers", bytes.NewReader(body))
180205
if err != nil {
181206
log.Fatal(err)
@@ -186,7 +211,12 @@ func checkServers() {
186211
if err != nil {
187212
log.Fatal(err)
188213
}
189-
log.Printf("Create of %v: %v", i, res.Status)
214+
if res.StatusCode == http.StatusOK {
215+
log.Printf("created %v", i)
216+
} else {
217+
slurp, _ := ioutil.ReadAll(io.LimitReader(res.Body, 4<<10))
218+
log.Printf("creating number %v, %s: %s", i, res.Status, slurp)
219+
}
190220
res.Body.Close()
191221
}
192222

@@ -210,6 +240,9 @@ type createServerRequest struct {
210240
Image string `json:"image"`
211241
CommercialType string `json:"commercial_type"`
212242
Tags []string `json:"tags"`
243+
EnableIPV6 bool `json:"enable_ipv6,omitempty"`
244+
BootType string `json:"boot_type,omitempty"` // local, bootscript, rescue; the default of local doesn't work on C1 machines
245+
Bootscript string `json:"bootscript,omitempty"`
213246
}
214247

215248
type Client struct {
@@ -221,7 +254,7 @@ type Client struct {
221254
// This is currently unused. An earlier version of this tool used it briefly before
222255
// changing to use the reboot action. We might want this later.
223256
func (c *Client) Delete(serverID string) error {
224-
req, _ := http.NewRequest("DELETE", scalewayAPIBase+"/servers/"+serverID, nil)
257+
req, _ := http.NewRequest("DELETE", scalewayAPIBase+"/instance/v1/zones/fr-par-1/servers/"+serverID, nil)
225258
req.Header.Set("Content-Type", "application/json")
226259
req.Header.Set("X-Auth-Token", c.Token)
227260
res, err := http.DefaultClient.Do(req)
@@ -230,7 +263,8 @@ func (c *Client) Delete(serverID string) error {
230263
}
231264
defer res.Body.Close()
232265
if res.StatusCode != http.StatusNoContent {
233-
return fmt.Errorf("error deleting %s: %v", serverID, res.Status)
266+
slurp, _ := ioutil.ReadAll(io.LimitReader(res.Body, 1<<10))
267+
return fmt.Errorf("error deleting %s: %v, %s", serverID, res.Status, slurp)
234268
}
235269
return nil
236270
}
@@ -239,6 +273,10 @@ func (c *Client) PowerOn(serverID string) error {
239273
return c.serverAction(serverID, "poweron")
240274
}
241275

276+
func (c *Client) PowerOff(serverID string) error {
277+
return c.serverAction(serverID, "poweroff")
278+
}
279+
242280
func (c *Client) serverAction(serverID, action string) error {
243281
req, _ := http.NewRequest("POST", scalewayAPIBase+"/servers/"+serverID+"/action", strings.NewReader(fmt.Sprintf(`{"action":"%s"}`, action)))
244282
req.Header.Set("Content-Type", "application/json")
@@ -325,7 +363,9 @@ func defaultBuilderTags(baseKeyFile string) string {
325363
log.Fatal(err)
326364
}
327365
var tags []string
328-
for _, builder := range []string{"linux-arm", "linux-arm-arm5"} {
366+
for _, builder := range []string{
367+
"host-linux-arm-scaleway",
368+
} {
329369
h := hmac.New(md5.New, bytes.TrimSpace(slurp))
330370
h.Write([]byte(builder))
331371
tags = append(tags, fmt.Sprintf("buildkey_%s_%x", builder, h.Sum(nil)))

env/linux-arm/scaleway/Dockerfile

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,23 @@
22
# Use of this source code is governed by a BSD-style
33
# license that can be found in the LICENSE file.
44

5-
FROM scaleway/ubuntu:armhf-xenial
5+
FROM golang:1.13 AS build
6+
RUN go get golang.org/x/build/cmd/buildlet/stage0
7+
8+
FROM debian:buster
69

710
RUN apt-get update
811

912
RUN apt-get install --yes \
10-
gcc strace procps psmisc libc6-dev
13+
gcc strace procps psmisc libc6-dev curl netbase \
14+
openssh-server
1115

12-
RUN curl -L -o go1.8.1.tar.gz https://golang.org/dl/go1.8.1.linux-armv6l.tar.gz && \
13-
tar fxzv go1.8.1.tar.gz -C /usr/local
16+
RUN curl -L https://golang.org/dl/go1.13.4.linux-armv6l.tar.gz | \
17+
tar xzv -C /usr/local && /usr/local/go/bin/go version
1418

15-
ENV GO_BOOTSTRAP=/usr/local/go
19+
ENV GOROOT_BOOTSTRAP=/usr/local/go
1620

1721
# compiled stage0 binary must be in working dir
18-
COPY stage0 /usr/local/bin/stage0
19-
20-
ENV GO_BUILD_KEY_PATH /buildkey/gobuildkey
21-
ENV GO_BUILD_KEY_DELETE_AFTER_READ true
22-
ENV GO_BUILDER_ENV host-linux-arm-scaleway
23-
24-
# env specific
25-
ARG buildlet_bucket
26-
27-
ENV META_BUILDLET_BINARY_URL "https://storage.googleapis.com/$buildlet_bucket/buildlet.linux-arm"
22+
COPY --from=build /go/bin/stage0 /usr/local/bin/stage0
2823

29-
CMD ["/usr/local/bin/stage0"]
24+
CMD ["/usr/local/bin/stage0"]

0 commit comments

Comments
 (0)