Skip to content

Commit

Permalink
env/openbsd-amd64,cmd/bootstrapswarm: get openbsd working with LUCI
Browse files Browse the repository at this point in the history
Teach bootstrapswarm to read the hostname from GCE when sending a VM
token, since that's all that'll work.

Update openbsd's make.bash:
- Do all work in a temp directory so that we don't have to manage
  individual files.
- Pass -I to pkg_add to avoid prompts.
- Increase ulimits on the worker user.
- Install python and sudo.
- Use rc.firsttime rather than reinventing it with /firstboot.
- Decide whether to start the buildlet or Swarming bot based on the
  GCE project as usual.
- Package bootstrapswarm into the image.

Change-Id: I61bbc1903f8eab596bf0d19a316993a92f6bd599
Reviewed-on: https://go-review.googlesource.com/c/build/+/526618
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Carlos Amedee <[email protected]>
Auto-Submit: Heschi Kreinick <[email protected]>
  • Loading branch information
heschi authored and gopherbot committed Sep 12, 2023
1 parent 5105b99 commit 95a10b2
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 50 deletions.
14 changes: 12 additions & 2 deletions cmd/bootstrapswarm/bootstrapswarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"

"cloud.google.com/go/compute/metadata"
)

var (
tokenFilePath = flag.String("token-file-path", defaultTokenLocation(), "Path to the token file (used when not on GCE)")
hostname = flag.String("hostname", os.Getenv("HOSTNAME"), "Hostname of machine to bootstrap (required)")
hostname = flag.String("hostname", os.Getenv("HOSTNAME"), "Hostname of machine to bootstrap")
swarming = flag.String("swarming", "chromium-swarm.appspot.com", "Swarming server to connect to")
)

Expand All @@ -70,7 +71,7 @@ func main() {
var httpClient = http.DefaultClient

func bootstrap(ctx context.Context, hostname, tokenPath string) error {
httpHeaders := map[string]string{"X-Luci-Swarming-Bot-ID": hostname}
httpHeaders := map[string]string{}
if metadata.OnGCE() {
log.Println("Bootstrapping the swarming bot with GCE authentication")
log.Println("retrieving the GCE VM token")
Expand All @@ -79,6 +80,14 @@ func bootstrap(ctx context.Context, hostname, tokenPath string) error {
return fmt.Errorf("unable to retrieve GCE Machine Token: %w", err)
}
httpHeaders["X-Luci-Gce-Vm-Token"] = token

// Override the hostname flag with the GCE hostname. This is a hard
// requirement for LUCI, so there's no point in trying anything else.
fullHost, err := metadata.Hostname()
if err != nil {
return fmt.Errorf("retrieving hostname: %w", err)
}
hostname = strings.Split(fullHost, ".")[0]
} else {
log.Println("Bootstrapping the swarming bot with certificate authentication")
log.Println("retrieving the luci-machine-token from the token file")
Expand All @@ -98,6 +107,7 @@ func bootstrap(ctx context.Context, hostname, tokenPath string) error {
}
httpHeaders["X-Luci-Machine-Token"] = tok.LuciMachineToken
}
httpHeaders["X-Luci-Swarming-Bot-ID"] = hostname
log.Println("Downloading the swarming bot")
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://"+*swarming+"/bot_code", nil)
if err != nil {
Expand Down
117 changes: 69 additions & 48 deletions env/openbsd-amd64/make.bash
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ readonly SNAPSHOT=false
readonly ARCH="${ARCH:-amd64}"
readonly MIRROR="${MIRROR:-cdn.openbsd.org}"

readonly WORK="$(mktemp -d)"
readonly SITE="${WORK}/site"

if [[ "${ARCH}" != "amd64" && "${ARCH}" != "i386" ]]; then
echo "ARCH must be amd64 or i386"
exit 1
Expand All @@ -31,45 +34,48 @@ if [[ ! -f "${ISO}" ]]; then
fi

function cleanup() {
rm -f "${ISO_PATCHED}"
rm -f auto_install.conf
rm -f boot.conf
rm -f disk.raw
rm -f disklabel.template
rm -f etc/{installurl,rc.local,sysctl.conf}
rm -f install.site
rm -f random.seed
rm -f site${RELNO}.tgz
rmdir etc
rm -rf "${WORK}"
}

trap cleanup EXIT INT

# Create custom siteXX.tgz set.
PKG_ADD_OPTIONS=""
PKG_ADD_OPTIONS="-I"
if [[ "$SNAPSHOT" = true ]]; then
PKG_ADD_OPTIONS="-D snap"
PKG_ADD_OPTIONS="-I -D snap"
fi
mkdir -p etc
cat >install.site <<EOF
mkdir -p ${SITE}/etc
cat >${SITE}/install.site <<EOF
#!/bin/sh
touch /firstboot
echo 'set tty com0' > boot.conf
EOF

cat >etc/installurl <<EOF
cat >${SITE}/etc/installurl <<EOF
https://${MIRROR}/pub/OpenBSD
EOF
cat >etc/rc.local <<EOF
if [[ -f /firstboot ]]; then
syspatch
# Run syspatch twice in case syspatch itself needs patching (this is the case with OpenBSD
# 7.1: https://www.openbsd.org/errata71.html )
syspatch
pkg_add -iv ${PKG_ADD_OPTIONS} bash curl git
rm -f /firstboot
fi
cat >${SITE}/etc/rc.firsttime <<EOF
set -x
cat > /etc/login.conf.d/moreres <<'EOLOGIN'
moreres:\
:maxproc-max=1024: \
:maxproc-cur=1024: \
:openfiles-max=4096: \
:openfiles-cur=4096: \
:tc=default:
EOLOGIN
cap_mkdb
usermod -L moreres swarming
syspatch
# Run syspatch twice in case syspatch itself needs patching (this is the case with OpenBSD
# 7.1: https://www.openbsd.org/errata71.html )
syspatch
pkg_add -iv ${PKG_ADD_OPTIONS} bash curl git python3 sudo--gettext
chown root:wheel /etc/sudoers
halt -p
EOF

cat >${SITE}/etc/rc.local <<EOF
(
set -x
Expand All @@ -83,37 +89,52 @@ fi
(
set -e
export PATH="\$PATH:/usr/local/bin"
/usr/local/bin/curl -o /buildlet \$(/usr/local/bin/curl --fail -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/buildlet-binary-url)
chmod +x /buildlet
exec /buildlet
project=\$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/project-id)
case "\$project" in
*luci*)
gcehost=\$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/hostname | cut -d . -f 1)
su -l swarming -c "/usr/local/bin/bootstrapswarm --hostname \$gcehost"
;;
*)
/usr/local/bin/curl -o /buildlet \$(/usr/local/bin/curl --fail -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/buildlet-binary-url)
chmod +x /buildlet
exec /buildlet
;;
esac
)
echo "giving up"
(
sleep 10
sleep 60
halt -p
)&
)
EOF
cat >etc/sysctl.conf <<EOF
cat >${SITE}/etc/sysctl.conf <<EOF
hw.smt=1
kern.timecounter.hardware=tsc
EOF
chmod +x install.site
tar -zcvf site${RELNO}.tgz install.site etc/{installurl,rc.local,sysctl.conf}
cat >${SITE}/etc/sudoers <<EOF
root ALL=(ALL:ALL) ALL
swarming ALL=NOPASSWD:/sbin/shutdown -r now
EOF
chmod +x ${SITE}/install.site
mkdir -p ${SITE}/usr/local/bin
CGO_ENABLED=0 GOOS=openbsd GOARCH=amd64 go1.21.0 build -o ${SITE}/usr/local/bin/bootstrapswarm golang.org/x/build/cmd/bootstrapswarm
tar -C ${SITE} -zcf ${WORK}/site${RELNO}.tgz .

# Autoinstall script.
cat >auto_install.conf <<EOF
System hostname = buildlet
cat >${WORK}/auto_install.conf <<EOF
System hostname = openbsd-amd64
Which network interface = vio0
IPv4 address for vio0 = dhcp
IPv6 address for vio0 = none
Password for root account = root
Do you expect to run the X Window System = no
Change the default console to com0 = yes
Which speed should com0 use = 115200
Setup a user = gopher
Full name for user gopher = Gopher Gopherson
Password for user gopher = gopher
Setup a user = swarming
Full name for user swarming = Swarming Gopher Gopherson
Password for user swarming = swarming
Allow root ssh login = no
What timezone = US/Pacific
Which disk = sd0
Expand All @@ -126,32 +147,32 @@ Directory does not contain SHA256.sig. Continue without verification = yes
EOF

# Disklabel template.
cat >disklabel.template <<EOF
cat >${WORK}/disklabel.template <<EOF
/ 5G-* 95%
swap 1G
EOF

# Hack install CD a bit.
echo 'set tty com0' > boot.conf
dd if=/dev/urandom of=random.seed bs=4096 count=1
echo 'set tty com0' > ${WORK}/boot.conf
dd if=/dev/urandom of=${WORK}/random.seed bs=4096 count=1
cp "${ISO}" "${ISO_PATCHED}"
growisofs -M "${ISO_PATCHED}" -l -R -graft-points \
/${VERSION}/${ARCH}/site${RELNO}.tgz=site${RELNO}.tgz \
/auto_install.conf=auto_install.conf \
/disklabel.template=disklabel.template \
/etc/boot.conf=boot.conf \
/etc/random.seed=random.seed
/${VERSION}/${ARCH}/site${RELNO}.tgz=${WORK}/site${RELNO}.tgz \
/auto_install.conf=${WORK}/auto_install.conf \
/disklabel.template=${WORK}/disklabel.template \
/etc/boot.conf=${WORK}/boot.conf \
/etc/random.seed=${WORK}/random.seed

# Initialize disk image.
rm -f disk.raw
qemu-img create -f raw disk.raw 10G
rm -f ${WORK}/disk.raw
qemu-img create -f raw ${WORK}/disk.raw 30G

# Run the installer to create the disk image.
expect <<EOF
set timeout 1800
spawn qemu-system-x86_64 -nographic -smp 2 \
-drive if=virtio,file=disk.raw,format=raw -cdrom "${ISO_PATCHED}" \
-drive if=virtio,file=${WORK}/disk.raw,format=raw -cdrom "${ISO_PATCHED}" \
-net nic,model=virtio -net user -boot once=d
expect timeout { exit 1 } "boot>"
Expand All @@ -174,6 +195,6 @@ EOF

# Create Compute Engine disk image.
echo "Archiving disk.raw... (this may take a while)"
tar -Szcf "openbsd-${VERSION}-${ARCH}-gce.tar.gz" disk.raw
tar -C ${WORK} -Szcf "openbsd-${VERSION}-${ARCH}-gce.tar.gz" disk.raw

echo "Done. GCE image is openbsd-${VERSION}-${ARCH}-gce.tar.gz."

0 comments on commit 95a10b2

Please sign in to comment.