diff --git a/.github/workflows/artifacts.yaml b/.github/workflows/artifacts.yaml new file mode 100644 index 00000000000..92187b8e658 --- /dev/null +++ b/.github/workflows/artifacts.yaml @@ -0,0 +1,51 @@ +name: Artifacts +on: [pull_request, push] +jobs: + export-debs: + runs-on: ubuntu-22.04 + container: + image: debian@sha256:4cb3f4198e4af2d03dffe6bfa4f3686773596494ef298f3882553d52e885634b # debian:bullseye-20240110 + steps: + - name: apt update + run: apt update -y && apt upgrade -y + - name: install sudo + run: apt install -y sudo + - name: Checkout repository + uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675 # aka v2 + - name: Build debs + run: bash build_debs.sh + - name: Build debs.tar + run: find . -name 'cuttlefish-*.deb' -print0 | tar -cvf debs.tar --null --files-from - + - name: Publish debs.tar + uses: actions/upload-artifact@v3 + with: + name: debs + path: debs.tar + export-gce-image: + needs: export-debs + runs-on: ubuntu-22.04 + steps: + - name: Checkout repository + uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675 # aka v2 + - name: Download debs.tar + uses: actions/download-artifact@v3 + with: + name: debs + - name: Untar debs.tar + run: tar -xf debs.tar + - name: list pwd + run: ls + - name: Build image + run: bash tools/buildimage/main.sh + - shell: bash + run: | + export_name=gce_debian-11_amd64_$(date +%+4Y%m%d)-$(echo "${{ github.sha }}" | cut -c1-4).tar.gz + mv image.tar.gz $export_name + - name: list pwd again + run: ls + - name: Publish image + uses: actions/upload-artifact@v3 + with: + name: image + path: *.tar.gz + diff --git a/build_debs.sh b/build_debs.sh new file mode 100644 index 00000000000..d4b69742b6a --- /dev/null +++ b/build_debs.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Build the debian packages in this repository. + +set -e + +eval $(grep VERSION_CODENAME /etc/os-release) + +[[ ${VERSION_CODENAME} == "bullseye" ]] || { echo "Invalid distribution '${VERSION_CODENAME}'. Use Debian 11 (bullseye)." >&2; exit 1; } + +sudo apt install -y debconf-utils debhelper ubuntu-dev-tools equivs + +dpkg-source -b base +dpkg-source -b frontend + +for dsc in *.dsc; do + yes | sudo mk-build-deps -i "${dsc}" -t apt-get +done + +# Cleanup the `*build-deps_*_all.deb` packages created when installing the build +# dependencies. +yes | rm -f *.deb + +for dsc in *.dsc; do + # Unpack the source and build it + dpkg-source -x "${dsc}" + dir="$(basename "${dsc}" .dsc)" + dir="${dir/_/-}" + pushd "${dir}/" + debuild -uc -us + popd +done + +ls -la diff --git a/tools/buildimage/install_cf_packages.sh b/tools/buildimage/install_cf_packages.sh new file mode 100644 index 00000000000..67c216359ce --- /dev/null +++ b/tools/buildimage/install_cf_packages.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Install relevant cuttlefish packages from https://github.com/google/android-cuttlefish. + +# IMPORTANT!!! This script expects an `image_bullseye_gce_amd64.raw` file +# from https://salsa.debian.org/cloud-team/debian-cloud-images + +set -e + +usage() { + echo "usage: $0 -r /path/to/disk.raw -p /path/to/packages_dir" + exit 1 +} + +diskraw= +packages_dir= + +while getopts ":hr:p:" opt; do + case "${opt}" in + h) + usage + ;; + r) + diskraw="${OPTARG}" + ;; + p) + packages_dir="${OPTARG}" + ;; + \?) + echo "Invalid option: ${OPTARG}" >&2 + usage + ;; + :) + echo "Invalid option: ${OPTARG} requires an argument" >&2 + usage + ;; + esac +done + +mount_point="/mnt/image" +sudo mkdir ${mount_point} +# offset value is 262144 * 512, the `262144`th is the sector where the `Linux filesystem` partition +# starts and `512` bytes is the sectors size. See `sudo fdisk -l disk.raw`. +sudo mount -o loop,offset=$((262144 * 512)) ${diskraw} ${mount_point} + +cp ${packages_dir}/cuttlefish-base_0.9.28_amd64.deb ${mount_point}/tmp/ +cp ${packages_dir}/cuttlefish-user_0.9.29_amd64.deb ${mount_point}/tmp/ +cp ${packages_dir}/cuttlefish-orchestration_0.9.29_amd64.deb ${mount_point}/tmp/ + +sudo chroot /mnt/image mkdir /run/resolvconf +sudo cp /etc/resolv.conf /mnt/image/run/resolvconf/resolv.conf + +sudo chroot ${mount_point} apt update +sudo chroot ${mount_point} apt install -y /tmp/cuttlefish-base_0.9.28_amd64.deb +sudo chroot ${mount_point} apt install -y /tmp/cuttlefish-user_0.9.29_amd64.deb +sudo chroot ${mount_point} apt install -y /tmp/cuttlefish-orchestration_0.9.29_amd64.deb + +sudo rm -r ${mount_point}/run/resolvconf + +sudo umount ${mount_point} +sudo rm -r ${mount_point} diff --git a/tools/buildimage/install_gce_guest_environment.sh b/tools/buildimage/install_gce_guest_environment.sh new file mode 100644 index 00000000000..a6d81394423 --- /dev/null +++ b/tools/buildimage/install_gce_guest_environment.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Install GCP guest environment: https://cloud.google.com/compute/docs/images/install-guest-environment + +# IMPORTANT!!! This script expects debian-11-genericcloud-amd64-20240104-1616.raw image. +# https://cloud.debian.org/images/cloud/bullseye/20240104-1616/debian-11-genericcloud-amd64-20240104-1616.raw + +usage() { + echo "usage: $0 -r /path/to/disk.raw" + exit 1 +} + +diskraw= + +while getopts ":hr:" opt; do + case "${opt}" in + h) + usage + ;; + r) + diskraw="${OPTARG}" + ;; + \?) + echo "Invalid option: ${OPTARG}" >&2 + usage + ;; + :) + echo "Invalid option: ${OPTARG} requires an argument" >&2 + usage + ;; + esac +done + +mount_point="/mnt/image" +sudo mkdir ${mount_point} + +# offset value is 262144 * 512, the `262144`th is the sector where the `Linux filesystem` partition +# starts and `512` bytes is the sectors size. See `sudo fdisk -l disk.raw`. +sudo mount -o loop,offset=$((262144 * 512)) ${diskraw} ${mount_point} + +cat <<'EOF' >/tmp/rc.local +#!/bin/bash +echo "== Installing Google guest environment for Debian ==" +export DEBIAN_FRONTEND=noninteractive +sleep 30 # Wait for network. +echo "Determining Debian version..." +eval $(grep VERSION_CODENAME /etc/os-release) +if [[ -z $VERSION_CODENAME ]]; then + echo "ERROR: Could not determine Debian version." + exit 1 +fi +echo "Running apt update..." +apt update +echo "Installing gnupg..." +apt install -y gnupg +echo "Adding GPG key for Google cloud repo." +curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - +echo "Updating repo file..." +tee "/etc/apt/sources.list.d/google-cloud.list" << EOM +deb http://packages.cloud.google.com/apt google-compute-engine-${VERSION_CODENAME}-stable main +deb http://packages.cloud.google.com/apt google-cloud-packages-archive-keyring-${VERSION_CODENAME} main +EOM +echo "Running apt update..." +apt update +echo "Installing packages..." +for pkg in google-cloud-packages-archive-keyring google-compute-engine; do + echo "Running apt install ${pkg}..." + apt install -y ${pkg} + if [[ $? -ne 0 ]]; then + echo "ERROR: Failed to install ${pkg}." + fi +done +echo "Removing this rc.local script." +rm /etc/rc.local +# Move back any previous rc.local: +if [[ -f "/etc/moved-rc.local" ]]; then + echo "Restoring a previous rc.local script." + mv "/etc/moved-rc.local" "/etc/rc.local" +fi +echo "Restarting the instance..." +reboot +EOF + +if [[ -f "${mount_point}/etc/rc.local" ]]; then + sudo mv "${mount_point}/etc/rc.local" \ + "${mount_point}/etc/moved-rc.local" +fi +sudo mv /tmp/rc.local "${mount_point}/etc/rc.local" +sudo chmod 0755 "${mount_point}/etc/rc.local" +sudo chown root:root "${mount_point}/etc/rc.local" + +sudo umount ${mount_point} +sudo rm -r ${mount_point} diff --git a/tools/buildimage/main.sh b/tools/buildimage/main.sh new file mode 100644 index 00000000000..9a3df4547f7 --- /dev/null +++ b/tools/buildimage/main.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Build custom image to be used in GCE VMs. + +set -e + +script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P) + +pushd /tmp +wget https://cloud.debian.org/images/cloud/bullseye/20240104-1616/debian-11-genericcloud-amd64-20240104-1616.raw +popd + +out_dir=$(pwd) +cp /tmp/debian-11-genericcloud-amd64-20240104-1616.raw ${out_dir}/disk.raw + +bash ${script_dir}/install_gce_guest_environment.sh -r ${out_dir}/disk.raw +bash ${script_dir}/install_cf_packages.sh -r ${out_dir}/disk.raw -p $(pwd) + +tar -czvf image.tar.gz -C ${out_dir} disk.raw