From 34cb6d98300cd5287bca166396d0e970f6b2c223 Mon Sep 17 00:00:00 2001 From: Mike Maxim Date: Wed, 18 Dec 2024 10:53:37 -0500 Subject: [PATCH] linux client build on arm64 host (#28278) --- packaging/linux/Dockerfile | 2 +- packaging/linux/build_binaries.sh | 33 ++++++++++++++--- packaging/linux/tuxbot/Vagrantfile | 30 +-------------- packaging/linux/tuxbot/Vagrantfile.amd64 | 29 +++++++++++++++ packaging/linux/tuxbot/Vagrantfile.arm64 | 28 ++++++++++++++ .../linux/tuxbot/provision_tuxbot_disk.arm64 | 5 +++ .../linux/tuxbot/provision_tuxbot_root.arm64 | 22 +++++++++++ .../linux/tuxbot/provision_tuxbot_user.arm64 | 37 +++++++++++++++++++ 8 files changed, 150 insertions(+), 36 deletions(-) mode change 100644 => 120000 packaging/linux/tuxbot/Vagrantfile create mode 100644 packaging/linux/tuxbot/Vagrantfile.amd64 create mode 100644 packaging/linux/tuxbot/Vagrantfile.arm64 create mode 100755 packaging/linux/tuxbot/provision_tuxbot_disk.arm64 create mode 100755 packaging/linux/tuxbot/provision_tuxbot_root.arm64 create mode 100755 packaging/linux/tuxbot/provision_tuxbot_user.arm64 diff --git a/packaging/linux/Dockerfile b/packaging/linux/Dockerfile index b2eff4532e48..c32375c2bdad 100644 --- a/packaging/linux/Dockerfile +++ b/packaging/linux/Dockerfile @@ -13,7 +13,7 @@ LABEL maintainer="Keybase " # - unzip because electron6 packager requires it RUN apt-get update RUN apt-get install -y fakeroot reprepro rpm createrepo-c git wget \ - build-essential curl s3cmd gnupg2 unzip rsync + build-essential curl s3cmd gnupg2 unzip rsync gcc-x86-64-linux-gnu # Install nodejs and yarn. (Note that this depends on curl above.) RUN mkdir -p /etc/apt/keyrings diff --git a/packaging/linux/build_binaries.sh b/packaging/linux/build_binaries.sh index 32ca2d2af79d..427d234c07c9 100755 --- a/packaging/linux/build_binaries.sh +++ b/packaging/linux/build_binaries.sh @@ -2,6 +2,11 @@ set -euox pipefail +# check host arch +is_arm64_host() { + [[ $(uname -m) == "arm64" ]] || [[ $(uname -m) == "aarch64" ]] +} + here="$(dirname "${BASH_SOURCE[0]}")" this_repo="$(git -C "$here" rev-parse --show-toplevel || echo -n "$GOPATH/src/github.com/keybase/client")" @@ -128,11 +133,21 @@ build_one_architecture() { (cd "$client_dir" && go build -tags "$go_tags" -ldflags "$ldflags_kbnm" -buildmode="$buildmode" -o \ "$layout_dir/usr/bin/kbnm" github.com/keybase/client/go/kbnm) - # Write allowlists into the overlay. Note that we have to explicitly set USER - # here, because docker doesn't do it by default, and so otherwise the - # CGO-disabled i386 cross platform build will fail because it's unable to - # find the current user. - USER="$(whoami)" KBNM_INSTALL_ROOT=1 KBNM_INSTALL_OVERLAY="$layout_dir" "$layout_dir/usr/bin/kbnm" install + + if is_arm64_host ; then + echo "is_arm64_host, building native kbnm for install" + + (cd "$client_dir" && GOARCH=arm64 CC=gcc CXX=g++ go build -tags "$go_tags" -ldflags "$ldflags_kbnm" -buildmode="$buildmode" -o \ + "$layout_dir/usr/bin/kbnm_arm64" github.com/keybase/client/go/kbnm) + USER="$(whoami)" KBNM_INSTALL_ROOT=1 KBNM_INSTALL_OVERLAY="$layout_dir" "$layout_dir/usr/bin/kbnm_arm64" install + rm "$layout_dir/usr/bin/kbnm_arm64" + else + # Write allowlists into the overlay. Note that we have to explicitly set USER + # here, because docker doesn't do it by default, and so otherwise the + # CGO-disabled i386 cross platform build will fail because it's unable to + # find the current user. + USER="$(whoami)" KBNM_INSTALL_ROOT=1 KBNM_INSTALL_OVERLAY="$layout_dir" "$layout_dir/usr/bin/kbnm" install + fi # Build Electron. echo "Building Electron client for $electron_arch..." @@ -195,7 +210,13 @@ if [ -n "${KEYBASE_BUILD_ARM_ONLY:-}" ] ; then fi if [ -z "${KEYBASE_SKIP_64_BIT:-}" ] ; then - echo "Keybase: Building for x86-64" + if is_arm64_host ; then + echo "Keybase: Building for x86-64 (arm64 host cross compile)" + export CC=x86_64-linux-gnu-gcc + export CXX=x86_64-linux-gnu-g++ + else + echo "Keybase: Building for x86-64" + fi export GOARCH=amd64 export debian_arch=amd64 export electron_arch=x64 diff --git a/packaging/linux/tuxbot/Vagrantfile b/packaging/linux/tuxbot/Vagrantfile deleted file mode 100644 index c115eacbde1a..000000000000 --- a/packaging/linux/tuxbot/Vagrantfile +++ /dev/null @@ -1,29 +0,0 @@ -Vagrant.configure("2") do |config| - config.vm.box = "debian/bullseye64" - config.vm.disk :disk, size: "100GB", primary: true - config.vm.provider "virtualbox" do |vb| - vb.memory = "24576" - end - config.vm.provision "shell", path: "provision_tuxbot_disk", privileged: true - config.vm.provision "shell", path: "provision_tuxbot_root", privileged: true - config.vm.provision "shell", path: "provision_tuxbot_user", privileged: false - config.vm.provision "file", - source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/cleanup", - destination: "~/cleanup", run: "always" - config.vm.provision "file", - source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/restartdocker", - destination: "~/restartdocker", run: "always" - config.vm.provision "file", - source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/ssh_config", - destination: "~/.ssh/config", run: "always" - config.vm.provision "file", - source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/ssh_known_hosts", - destination: "~/.ssh/known_hosts", run: "always" - config.vm.provision "file", - source: "~/tuxbot_vagrant_env", - destination: "~/tuxbot.env", - run: "always" - config.vm.synced_folder ".", "/vagrant" - config.vm.provision "shell", path: "provision_tuxbot_env", privileged: true, run: "always" - config.vm.provision "docker" -end diff --git a/packaging/linux/tuxbot/Vagrantfile b/packaging/linux/tuxbot/Vagrantfile new file mode 120000 index 000000000000..9653736d9d6c --- /dev/null +++ b/packaging/linux/tuxbot/Vagrantfile @@ -0,0 +1 @@ +Vagrantfile.arm64 \ No newline at end of file diff --git a/packaging/linux/tuxbot/Vagrantfile.amd64 b/packaging/linux/tuxbot/Vagrantfile.amd64 new file mode 100644 index 000000000000..c115eacbde1a --- /dev/null +++ b/packaging/linux/tuxbot/Vagrantfile.amd64 @@ -0,0 +1,29 @@ +Vagrant.configure("2") do |config| + config.vm.box = "debian/bullseye64" + config.vm.disk :disk, size: "100GB", primary: true + config.vm.provider "virtualbox" do |vb| + vb.memory = "24576" + end + config.vm.provision "shell", path: "provision_tuxbot_disk", privileged: true + config.vm.provision "shell", path: "provision_tuxbot_root", privileged: true + config.vm.provision "shell", path: "provision_tuxbot_user", privileged: false + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/cleanup", + destination: "~/cleanup", run: "always" + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/restartdocker", + destination: "~/restartdocker", run: "always" + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/ssh_config", + destination: "~/.ssh/config", run: "always" + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/ssh_known_hosts", + destination: "~/.ssh/known_hosts", run: "always" + config.vm.provision "file", + source: "~/tuxbot_vagrant_env", + destination: "~/tuxbot.env", + run: "always" + config.vm.synced_folder ".", "/vagrant" + config.vm.provision "shell", path: "provision_tuxbot_env", privileged: true, run: "always" + config.vm.provision "docker" +end diff --git a/packaging/linux/tuxbot/Vagrantfile.arm64 b/packaging/linux/tuxbot/Vagrantfile.arm64 new file mode 100644 index 000000000000..282e61f33c82 --- /dev/null +++ b/packaging/linux/tuxbot/Vagrantfile.arm64 @@ -0,0 +1,28 @@ +Vagrant.configure("2") do |config| + config.vm.box = "bento/debian-11" + config.vm.provider "vmware_desktop" do |v| + v.gui = true + end + config.vm.provision "shell", path: "provision_tuxbot_disk.arm64", privileged: true + config.vm.provision "shell", path: "provision_tuxbot_root.arm64", privileged: true + config.vm.provision "shell", path: "provision_tuxbot_user.arm64", privileged: false + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/cleanup", + destination: "~/cleanup", run: "always" + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/restartdocker", + destination: "~/restartdocker", run: "always" + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/ssh_config", + destination: "~/.ssh/config", run: "always" + config.vm.provision "file", + source: "#{ENV['GOPATH']}/src/github.com/keybase/client/packaging/linux/tuxbot/ssh_known_hosts", + destination: "~/.ssh/known_hosts", run: "always" + config.vm.provision "file", + source: "~/tuxbot_vagrant_env", + destination: "~/tuxbot.env", + run: "always" + config.vm.synced_folder ".", "/vagrant" + config.vm.provision "shell", path: "provision_tuxbot_env", privileged: true, run: "always" + config.vm.provision "docker" +end diff --git a/packaging/linux/tuxbot/provision_tuxbot_disk.arm64 b/packaging/linux/tuxbot/provision_tuxbot_disk.arm64 new file mode 100755 index 000000000000..d2941ddb9815 --- /dev/null +++ b/packaging/linux/tuxbot/provision_tuxbot_disk.arm64 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euox pipefail + +export DEBIAN_FRONTEND=noninteractive +apt-get --allow-releaseinfo-change update diff --git a/packaging/linux/tuxbot/provision_tuxbot_root.arm64 b/packaging/linux/tuxbot/provision_tuxbot_root.arm64 new file mode 100755 index 000000000000..cbd5ee44ef87 --- /dev/null +++ b/packaging/linux/tuxbot/provision_tuxbot_root.arm64 @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euox pipefail + +export DEBIAN_FRONTEND=noninteractive + +apt-get --allow-releaseinfo-change update +apt-get install -yq git curl vim python3-pip jq + +GOLANG_VERSION=1.21.6 +GOLANG_DOWNLOAD_URL=https://dl.google.com/go/go$GOLANG_VERSION.linux-arm64.tar.gz +GOLANG_DOWNLOAD_SHA256=e2e8aa88e1b5170a0d495d7d9c766af2b2b6c6925a8f8956d834ad6b4cacbd9a +wget "$GOLANG_DOWNLOAD_URL" -O /root/go.tar.gz +echo "$GOLANG_DOWNLOAD_SHA256 /root/go.tar.gz" | sha256sum --check --status --strict - +tar -C /usr/local -xzf /root/go.tar.gz +ln -sf /usr/local/go/bin/go /usr/bin/go +rm /root/go.tar.gz + +pip3 install s3cmd +apt-get -yq install libssl-dev libffi-dev +pip3 install triplesec + +usermod -aG systemd-journal vagrant diff --git a/packaging/linux/tuxbot/provision_tuxbot_user.arm64 b/packaging/linux/tuxbot/provision_tuxbot_user.arm64 new file mode 100755 index 000000000000..f3141988a363 --- /dev/null +++ b/packaging/linux/tuxbot/provision_tuxbot_user.arm64 @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -euox pipefail + +KBCLID="$HOME/go/src/github.com/keybase/client" +TUXBOTD="$KBCLID/packaging/linux/tuxbot" + +# clone in gopath for bot +mkdir -p "$HOME/go/src/github.com/keybase" +git clone https://github.com/keybase/client.git "$HOME/go/src/github.com/keybase/client" +cd "$KBCLID/go" +go install -tags "prerelease production" ./keybase +sudo cp $HOME/go/bin/keybase /usr/bin +go install -tags "prerelease production" ./kbfs/kbfsfuse +sudo cp $HOME/go/bin/kbfsfuse /usr/bin +( + # install deps + cd "$TUXBOTD/bot" + git checkout master + go mod tidy +) +systemctl --user link "$KBCLID/packaging/linux/systemd/keybase.service" +systemctl --user link "$KBCLID/packaging/linux/systemd/kbfs.service" +systemctl --user link "$TUXBOTD/tuxbot.service" +systemctl --user link "$TUXBOTD/nightly.service" +systemctl --user link "$TUXBOTD/nightly.timer" +systemctl --user link "$TUXBOTD/docker-cleanup.service" +systemctl --user link "$TUXBOTD/docker-cleanup.timer" +systemctl --user daemon-reload +systemctl --user enable "$TUXBOTD/nightly.timer" +systemctl --user enable "$TUXBOTD/docker-cleanup.timer" + +keybase config set -b enable_bot_lite_mode true +keybase config set kbfs.mode constrained +systemctl --user enable --now keybase.service kbfs.service + +# clone for the build +git clone https://github.com/keybase/client.git "$HOME/client"