Skip to content

Commit b60de1f

Browse files
author
Sarah Adams
committed
all: dockerize scaleway builders
Fixes golang/go#20397 Change-Id: I353e879e61aeef56f0c228bbd37cc1eea2ce8b4e Reviewed-on: https://go-review.googlesource.com/43612 Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent fb385a2 commit b60de1f

File tree

11 files changed

+159
-266
lines changed

11 files changed

+159
-266
lines changed

cmd/buildlet/stage0/stage0.go

Lines changed: 15 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,14 @@
1111
package main
1212

1313
import (
14-
"bytes"
15-
"encoding/json"
1614
"flag"
1715
"fmt"
18-
"io/ioutil"
1916
"log"
2017
"net"
21-
"net/http"
2218
"os"
2319
"os/exec"
2420
"path/filepath"
2521
"runtime"
26-
"strings"
2722
"time"
2823

2924
"cloud.google.com/go/compute/metadata"
@@ -40,11 +35,6 @@ const osArch = runtime.GOOS + "/" + runtime.GOARCH
4035

4136
const attr = "buildlet-binary-url"
4237

43-
var (
44-
onScaleway bool
45-
scalewayMeta scalewayMetadata
46-
)
47-
4838
// untar helper, for the Windows image prep script.
4939
var (
5040
untarFile = flag.String("untar-file", "", "if non-empty, tar.gz to untar to --untar-dest-dir")
@@ -61,12 +51,11 @@ func main() {
6151

6252
switch osArch {
6353
case "linux/arm":
64-
if os.Getenv("GO_BUILDER_ENV") == "linux-arm-arm5spacemonkey" {
54+
switch env := os.Getenv("GO_BUILDER_ENV"); env {
55+
case "linux-arm-arm5spacemonkey", "host-linux-arm-scaleway":
6556
// No setup currently.
66-
} else {
67-
if _, err := os.Stat("/usr/local/bin/oc-metadata"); err == nil {
68-
initScaleway()
69-
}
57+
default:
58+
panic(fmt.Sprintf("unknown/unspecified $GO_BUILDER_ENV value %q", env))
7059
}
7160
case "linux/arm64":
7261
switch env := os.Getenv("GO_BUILDER_ENV"); env {
@@ -112,11 +101,17 @@ func main() {
112101
cmd.Stdout = os.Stdout
113102
cmd.Stderr = os.Stderr
114103
cmd.Env = env
115-
if onScaleway {
116-
cmd.Args = append(cmd.Args, scalewayBuildletArgs()...)
117-
}
118-
if os.Getenv("GO_BUILDER_ENV") == "linux-arm-arm5spacemonkey" {
119-
cmd.Args = append(cmd.Args, legacyReverseBuildletArgs("linux-arm-arm5spacemonkey")...)
104+
switch buildenv := os.Getenv("GO_BUILDER_ENV"); buildenv {
105+
case "linux-arm-arm5spacemonkey":
106+
cmd.Args = append(cmd.Args, legacyReverseBuildletArgs(buildenv)...)
107+
case "host-linux-arm-scaleway":
108+
scalewayArgs := append(
109+
legacyReverseBuildletArgs(buildenv),
110+
"--hostname="+os.Getenv("HOSTNAME"),
111+
)
112+
cmd.Args = append(cmd.Args,
113+
scalewayArgs...,
114+
)
120115
}
121116
switch osArch {
122117
case "linux/s390x":
@@ -159,38 +154,6 @@ func legacyReverseBuildletArgs(builder string) []string {
159154
}
160155
}
161156

162-
func scalewayBuildletArgs() []string {
163-
var modes []string // e.g. "linux-arm", "linux-arm-arm5"
164-
// tags are of form "buildkey_linux-arm_HEXHEXHEX"
165-
for _, tag := range scalewayMeta.Tags {
166-
if strings.HasPrefix(tag, "buildkey_") {
167-
parts := strings.Split(tag, "_")
168-
if len(parts) != 3 {
169-
log.Fatalf("invalid server tag %q", tag)
170-
}
171-
mode, buildkey := parts[1], parts[2]
172-
modes = append(modes, mode)
173-
file := "/root/.gobuildkey-" + mode
174-
if fi, err := os.Stat(file); err != nil || (err == nil && fi.Size() == 0) {
175-
if err := ioutil.WriteFile(file, []byte(buildkey), 0600); err != nil {
176-
log.Fatal(err)
177-
}
178-
}
179-
}
180-
}
181-
server := "farmer.golang.org:443"
182-
if scalewayMeta.IsStaging() {
183-
server = "104.154.113.235:443" // fixed IP, but no hostname.
184-
}
185-
return []string{
186-
"--workdir=/workdir",
187-
"--hostname=" + scalewayMeta.Hostname,
188-
"--halt=false",
189-
"--reverse=" + strings.Join(modes, ","),
190-
"--coordinator=" + server,
191-
}
192-
}
193-
194157
// awaitNetwork reports whether the network came up within 30 seconds,
195158
// determined somewhat arbitrarily via a DNS lookup for google.com.
196159
func awaitNetwork() bool {
@@ -228,13 +191,6 @@ func buildletURL() string {
228191
if v := os.Getenv("META_BUILDLET_BINARY_URL"); v != "" {
229192
return v
230193
}
231-
if onScaleway {
232-
if scalewayMeta.IsStaging() {
233-
return "https://storage.googleapis.com/dev-go-builder-data/buildlet.linux-arm"
234-
} else {
235-
return "https://storage.googleapis.com/go-builder-data/buildlet.linux-arm"
236-
}
237-
}
238194
sleepFatalf("Not on GCE, and no META_BUILDLET_BINARY_URL specified.")
239195
}
240196
v, err := metadata.InstanceAttributeValue(attr)
@@ -274,136 +230,6 @@ func download(file, url string) error {
274230
}
275231
}
276232

277-
func initScaleway() {
278-
log.Printf("On scaleway.")
279-
onScaleway = true
280-
initScalewaySwap()
281-
initScalewayWorkdir()
282-
initScalewayMeta()
283-
initScalewayDNS()
284-
initScalewayGo14()
285-
log.Printf("Scaleway init complete; metadata is %+v", scalewayMeta)
286-
}
287-
288-
type scalewayMetadata struct {
289-
Name string `json:"name"`
290-
Hostname string `json:"hostname"`
291-
Tags []string `json:"tags"`
292-
}
293-
294-
// IsStaging reports whether this instance has a "staging" tag.
295-
func (m *scalewayMetadata) IsStaging() bool {
296-
for _, t := range m.Tags {
297-
if t == "staging" {
298-
return true
299-
}
300-
}
301-
return false
302-
}
303-
304-
func initScalewayMeta() {
305-
const metaURL = "http://169.254.42.42/conf?format=json"
306-
res, err := http.Get(metaURL)
307-
if err != nil {
308-
log.Fatalf("failed to get scaleway metadata: %v", err)
309-
}
310-
defer res.Body.Close()
311-
if res.StatusCode != http.StatusOK {
312-
log.Fatalf("failed to get scaleway metadata from %s: %v", metaURL, res.Status)
313-
}
314-
if err := json.NewDecoder(res.Body).Decode(&scalewayMeta); err != nil {
315-
log.Fatalf("invalid JSON from scaleway metadata URL %s: %v", metaURL, err)
316-
}
317-
}
318-
319-
func initScalewayDNS() {
320-
setFileContents("/etc/resolv.conf", []byte("nameserver 8.8.8.8\n"))
321-
}
322-
323-
func setFileContents(file string, contents []byte) {
324-
old, err := ioutil.ReadFile(file)
325-
if err == nil && bytes.Equal(old, contents) {
326-
return
327-
}
328-
if err := ioutil.WriteFile(file, contents, 0644); err != nil {
329-
log.Fatal(err)
330-
}
331-
}
332-
333-
func initScalewaySwap() {
334-
const swapFile = "/swapfile"
335-
slurp, _ := ioutil.ReadFile("/proc/swaps")
336-
if strings.Contains(string(slurp), swapFile) {
337-
log.Printf("scaleway swapfile already active.")
338-
return
339-
}
340-
os.Remove(swapFile) // if it already exists, else ignore error
341-
log.Printf("Running fallocate on swapfile")
342-
if out, err := exec.Command("fallocate", "--length", "16GiB", swapFile).CombinedOutput(); err != nil {
343-
log.Fatalf("Failed to fallocate /swapfile: %v, %s", err, out)
344-
}
345-
log.Printf("Running mkswap")
346-
if out, err := exec.Command("mkswap", swapFile).CombinedOutput(); err != nil {
347-
log.Fatalf("Failed to mkswap /swapfile: %v, %s", err, out)
348-
}
349-
os.Chmod(swapFile, 0600)
350-
log.Printf("Running swapon")
351-
if out, err := exec.Command("swapon", swapFile).CombinedOutput(); err != nil {
352-
log.Fatalf("Failed to swapon /swapfile: %v, %s", err, out)
353-
}
354-
}
355-
356-
func initScalewayWorkdir() {
357-
const dir = "/workdir"
358-
slurp, _ := ioutil.ReadFile("/proc/mounts")
359-
if strings.Contains(string(slurp), dir) {
360-
log.Printf("scaleway workdir already mounted")
361-
return
362-
}
363-
if err := os.MkdirAll("/workdir", 0755); err != nil {
364-
log.Fatal(err)
365-
}
366-
if out, err := exec.Command("mount",
367-
"-t", "tmpfs",
368-
"-o", "size=8589934592",
369-
"tmpfs", "/workdir").CombinedOutput(); err != nil {
370-
log.Fatalf("Failed to mount /buildtmp: %v, %s", err, out)
371-
}
372-
}
373-
374-
func initScalewayGo14() {
375-
if fi, err := os.Stat("/usr/local/go"); err == nil && fi.IsDir() {
376-
log.Printf("go directory already exists.")
377-
return
378-
}
379-
os.RemoveAll("/usr/local/go") // in case it existed somehow, or as regular file
380-
if err := os.RemoveAll("/usr/local/go.tmp"); err != nil {
381-
log.Fatal(err)
382-
}
383-
if err := os.MkdirAll("/usr/local/go.tmp", 0755); err != nil {
384-
log.Fatal(err)
385-
}
386-
log.Printf("Downloading go1.4-linux-arm.tar.gz")
387-
if out, err := exec.Command("curl",
388-
"-o", "/usr/local/go.tmp/go.tar.gz",
389-
"--silent",
390-
"https://storage.googleapis.com/go-builder-data/go1.4-linux-arm.tar.gz",
391-
).CombinedOutput(); err != nil {
392-
log.Fatalf("Failed to download go1.4-linux-arm.tar.gz: %v, %s", err, out)
393-
}
394-
log.Printf("Extracting go1.4-linux-arm.tar.gz")
395-
if out, err := exec.Command("tar",
396-
"-C", "/usr/local/go.tmp",
397-
"-zx",
398-
"-f", "/usr/local/go.tmp/go.tar.gz",
399-
).CombinedOutput(); err != nil {
400-
log.Fatalf("Failed to untar go1.4-linux-arm.tar.gz: %v, %s", err, out)
401-
}
402-
if err := os.Rename("/usr/local/go.tmp", "/usr/local/go"); err != nil {
403-
log.Fatal(err)
404-
}
405-
}
406-
407233
func aptGetInstall(pkgs ...string) {
408234
args := append([]string{"--yes", "install"}, pkgs...)
409235
cmd := exec.Command("apt-get", args...)

cmd/rundockerbuildlet/rundockerbuildlet.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ package main
1010

1111
import (
1212
"bytes"
13+
"encoding/json"
1314
"flag"
1415
"fmt"
1516
"io/ioutil"
1617
"log"
18+
"net/http"
1719
"os"
1820
"os/exec"
1921
"path/filepath"
@@ -29,21 +31,28 @@ var (
2931
keyFile = flag.String("key", "/etc/gobuild.key", "go build key file")
3032
)
3133

32-
var buildKey []byte
34+
var (
35+
buildKey []byte
36+
scalewayMeta = new(scalewayMetadata)
37+
)
3338

3439
func main() {
3540
flag.Parse()
3641

3742
key, err := ioutil.ReadFile(*keyFile)
3843
if err != nil {
39-
log.Fatalf("error reading build key from --key=%s: %v", buildKey, err)
44+
log.Fatalf("error reading build key from --key=%s: %v", keyFile, err)
4045
}
4146
buildKey = bytes.TrimSpace(key)
4247

4348
if *image == "" {
4449
log.Fatalf("docker --image is required")
4550
}
4651

52+
if _, err := os.Stat("/usr/local/bin/oc-metadata"); err == nil {
53+
initScalewayMeta()
54+
}
55+
4756
log.Printf("Started. Will keep %d copies of %s running.", *numInst, *image)
4857
for {
4958
if err := checkFix(); err != nil {
@@ -71,7 +80,12 @@ func checkFix() error {
7180
continue
7281
}
7382
container, name, status := f[0], f[1], f[2]
74-
if !strings.HasPrefix(name, *basename) {
83+
prefix := *basename
84+
if scalewayMeta != nil {
85+
// scaleway containers are named after their instance.
86+
prefix = scalewayMeta.Hostname
87+
}
88+
if !strings.HasPrefix(name, prefix) {
7589
continue
7690
}
7791
if strings.HasPrefix(status, "Exited") {
@@ -85,7 +99,15 @@ func checkFix() error {
8599
}
86100

87101
for num := 1; num <= *numInst; num++ {
88-
name := fmt.Sprintf("%s%02d", *basename, num)
102+
var name string
103+
if scalewayMeta != nil {
104+
// The -name passed to 'docker run' should match the
105+
// c1 instance hostname for debugability.
106+
// There should only be one running container per c1 instance.
107+
name = scalewayMeta.Hostname
108+
} else {
109+
name = fmt.Sprintf("%s%02d", *basename, num)
110+
}
89111
if running[name] {
90112
continue
91113
}
@@ -113,3 +135,24 @@ func checkFix() error {
113135
}
114136
return nil
115137
}
138+
139+
type scalewayMetadata struct {
140+
Name string `json:"name"`
141+
Hostname string `json:"hostname"`
142+
Tags []string `json:"tags"`
143+
}
144+
145+
func initScalewayMeta() {
146+
const metaURL = "http://169.254.42.42/conf?format=json"
147+
res, err := http.Get(metaURL)
148+
if err != nil {
149+
log.Fatalf("failed to get scaleway metadata: %v", err)
150+
}
151+
defer res.Body.Close()
152+
if res.StatusCode != http.StatusOK {
153+
log.Fatalf("failed to get scaleway metadata from %s: %v", metaURL, res.Status)
154+
}
155+
if err := json.NewDecoder(res.Body).Decode(scalewayMeta); err != nil {
156+
log.Fatalf("invalid JSON from scaleway metadata URL %s: %v", metaURL, err)
157+
}
158+
}

0 commit comments

Comments
 (0)