Skip to content

Commit

Permalink
snap-build: implement system to cross-build snap images
Browse files Browse the repository at this point in the history
Add scripts to cross-build snap images for all supported
architectures using virtual machines

fixes kata-containers#98

Signed-off-by: Julio Montes <julio.montes@intel.com>
  • Loading branch information
Julio Montes committed Jul 24, 2018
1 parent 9e371ed commit bc72c11
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ prime/
stage/
snap/.snapcraft/
snap/snapcraft.yaml
snap-build/amd64/log
snap-build/amd64/*.img
snap-build/arm64/log
snap-build/arm64/*.fd
snap-build/arm64/*.img
snap-build/ppc64/log
snap-build/ppc64/*.img
snap-build/id_rsa*
snap-build/*.img
snap-build/seed/user-data
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ $(SNAPCRAFT_FILE): %: %.in Makefile $(YQ) $(VERSIONS_YAML_FILE) $(VERSION_FILE)
snap: $(SNAPCRAFT_FILE)
snapcraft -d

snap-xbuild:
cd $(MK_DIR)/snap-build; ./xbuild.sh

clean:
rm $(SNAPCRAFT_FILE)

Expand Down
11 changes: 11 additions & 0 deletions snap-build/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Cross-build snap images

Build Kata Containers snap images for all supported architectures using virtual machines.

## Usage

Run following command to build the snap images for all supported images.

```
./xbuild.sh
```
31 changes: 31 additions & 0 deletions snap-build/amd64/run_qemu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

set -x

WORKDIR=${WORKDIR:-.}
source ${WORKDIR}/lib.sh

ip="${1}"
port="${2}"
arch_dir="${WORKDIR}/amd64"
image="${arch_dir}/bionic-server-cloudimg-amd64.img"
image_url=https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img
cpu="qemu64"
machine="pc"
extra_opts=""
if [ "$(arch)" == "x86_64" ];then
cpu="host"
machine="pc,accel=kvm"
extra_opts="-enable-kvm"
fi

setup_image "${image_url}" "${image}"

run_qemu x86_64 "${cpu}" "${machine}" "${ip}" "${port}" "${image}" "${extra_opts}"

exit $?
30 changes: 30 additions & 0 deletions snap-build/arm64/run_qemu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

set -x

WORKDIR=${WORKDIR:-.}
source ${WORKDIR}/lib.sh

ip="${1}"
port="${2}"
arch_dir="${WORKDIR}/arm64"
arm_bios="${arch_dir}/QEMU_EFI.fd"
arm_bios_url=https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd
image="${arch_dir}/bionic-server-cloudimg-arm64.img"
image_url=https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-arm64.img
cpu="cortex-a57"
machine="virt,usb=off"
extra_opts="-bios ${arm_bios}"

[ ! -f "${arm_bios}" ] && download "${arm_bios_url}" "${arch_dir}"

setup_image "${image_url}" "${image}"

run_qemu aarch64 "${cpu}" "${machine}" "${ip}" "${port}" "${image}" "${extra_opts}"

exit $?
111 changes: 111 additions & 0 deletions snap-build/lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/bin/bash
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

error(){
msg="$*"
echo "ERROR: $msg" >&2
}

die(){
error "$*"
exit 1
}

get_ip() {
echo "127.$((1 + RANDOM % 240)).$((1 + RANDOM % 240)).$((1 + RANDOM % 240))"
}

get_port() {
echo "$((11060 + RANDOM % 1000))"
}

get_dnssearch() {
echo "$(grep search /etc/resolv.conf | cut -d' ' -f 2)"
}

get_dns() {
v="$(grep nameserver /etc/resolv.conf | cut -d' ' -f2 | sed -e 's/^/"/g' -e 's/$/",/g')"
echo ${v} | sed -e 's|,$||g'
}

download() {
url="$1"
outdir="$2"
pushd "${outdir}"
curl -LO ${url}
popd
}

setup_image() {
img_url=$1
img=$2
[ -f "${img}" ] && return
download "${img_url}" "$(dirname ${img})"
qemu-img resize "${img}" +5G
}

# arg1: ip
# arg2: port
# arg3: ssh key
# arg4: timeout in minutes
# return: 0 on success, 1 otherwise
ping_vm() {
ip="$1"
port="$2"
sshkeyfile="$3"
timeout=$4
minute=60
sleeptime=10
timeoutsec=$((timeout*minute))
tries=$((timeoutsec/sleeptime))

for i in $(seq 1 ${tries}); do
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i "${sshkeyfile}" "${ip}" -p "${port}" true && return 0
sleep ${sleeptime}
done

return 1
}

# arg1: qemu system: ppc64, aarch64 or x86_64
# arg2: cpu model
# arg3: machine type
# arg4: ip
# arg5: port
# arg6: image path
# arg7: extra options
run_qemu() {
arch="${1}"
cpu="${2}"
machine="${3}"
ip="${4}"
port="${5}"
image="${6}"
extra_opts="${7}"
seed_img="${WORKDIR}/seed.img"
ssh_key_file="${WORKDIR}/id_rsa"
ping_timeout=15

img_opts="-drive file=${image},if=virtio,format=qcow2,aio=threads"
seed_opts="-drive file=${seed_img},if=virtio,media=cdrom"
if [ "${arch}" == "aarch64" ]; then
img_opts="-device virtio-blk-device,drive=image -drive file=${image},if=none,id=image,aio=threads"
seed_opts="-device virtio-blk-device,drive=cloud -drive file=${seed_img},if=none,id=cloud,format=raw"
fi

qemu-system-${arch} -cpu "${cpu}" -machine "${machine}" -smp cpus=4 -m 2048M \
-net nic,model=virtio -device virtio-rng-pci -net user,hostfwd=tcp:${ip}:${port}-:22,dnssearch="$(get_dnssearch)" \
${img_opts} ${seed_opts} \
-display none -vga none -daemonize ${extra_opts}
[ $? != 0 ] && return 1

# depending of the host's hw, it takes for around ~15 minutes
ping_vm "${ip}" "${port}" "${ssh_key_file}" ${ping_timeout}
[ $? != 0 ] && return 1

return 0
}
26 changes: 26 additions & 0 deletions snap-build/ppc64/run_qemu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

set -x

WORKDIR=${WORKDIR:-.}
source ${WORKDIR}/lib.sh

ip="${1}"
port="${2}"
arch_dir="${WORKDIR}/ppc64"
image="${arch_dir}/bionic-server-cloudimg-ppc64el.img"
image_url=https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-ppc64el.img
cpu="POWER8"
machine="pseries,usb=off"
extra_opts="-echr 0x05 -boot c"

setup_image "${image_url}" "${image}"

run_qemu ppc64 "${cpu}" "${machine}" "${ip}" "${port}" "${image}" "${extra_opts}"

exit $?
2 changes: 2 additions & 0 deletions snap-build/seed/meta-data
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
instance-id: snapid
local-hostname: snap
21 changes: 21 additions & 0 deletions snap-build/seed/user-data.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#cloud-config
@APT_PROXY@
package_upgrade: false
users:
- lock-passwd: true
name: @USER@
shell: /bin/bash
ssh-authorized-keys:
- @SSH_KEY@
sudo: ALL=(ALL) NOPASSWD:ALL
write_files:
- content: |
[Service]
Environment=@DOCKER_ENV@
path: /etc/systemd/system/docker.service.d/http-proxy.conf
- content: |
@ENV@
path: /etc/environment
- content: |
{"dns": [@DOCKER_DNS@]}
path: /etc/docker/daemon.json
22 changes: 22 additions & 0 deletions snap-build/snap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

# Setup the environment and build the snap image.
# This script runs in the VM.

set -x
sudo apt-get update -y
sudo apt-get install -y snapd snapcraft golang-go gcc g++ libcap-ng-dev pkg-config make libz-dev libssl-dev openssl cpio libelf-dev libnewt-dev \
libiberty-dev libdw-dev libpci-dev libpixman-1-dev libglib2.0-dev librbd-dev libcap-dev libattr1-dev autoconf flex bison python docker.io
sudo gpasswd -a ${USER} docker; newgrp docker
sudo systemctl start docker
packaging_repo_url=https://github.com/kata-containers/packaging
packaging_dir=~/packaging
rm -rf ${packaging_dir}
git clone ${packaging_repo_url} ${packaging_dir}
pushd ${packaging_dir}
make snap
96 changes: 96 additions & 0 deletions snap-build/xbuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/bash
#
# Copyright (c) 2018 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

# Build in parallel snap images using VMs.
# This script runs in the host.

source lib.sh

export WORKDIR=$(pwd)
seed_dir=${WORKDIR}/seed
seed_img=${WORKDIR}/seed.img
id_rsa_file=${WORKDIR}/id_rsa
id_rsa_pub_file=${WORKDIR}/id_rsa.pub
snap_sh=${WORKDIR}/snap.sh
ssh="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i ${id_rsa_file}"
scp="scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i ${id_rsa_file}"

gen_seed() {
rm -f "${seed_img}"
truncate --size 2M "${seed_img}"
mkfs.vfat -n cidata "${seed_img}" &> /dev/null

if [ -n "${http_proxy}" ]; then
apt_proxy="apt:\n https_proxy: ${https_proxy}\n proxy: ${http_proxy}"
docker_env="\"HTTP_PROXY=${http_proxy}\" \"HTTPS_PROXY=${https_proxy}\" \"NO_PROXY=${no_proxy}\""
env="no_proxy=${no_proxy}\n\
NO_PROXY=${no_proxy}\n\
http_proxy=${http_proxy}\n\
HTTP_PROXY=${http_proxy}\n\
https_proxy=${https_proxy}\n\
HTTPS_PROXY=${https_proxy}"
fi

docker_dns="$(get_dns)"

[ ! -f "${id_rsa_file}" ] && ssh-keygen -t rsa -f ${id_rsa_file} -P '' &> /dev/null
ssh_key="$(cat ${id_rsa_pub_file})"

sed \
-e "s|@USER@|""${USER}""|g" \
-e "s|@SSH_KEY@|""${ssh_key}""|g" \
-e "s|@APT_PROXY@|""${apt_proxy}""|g" \
-e "s|@DOCKER_ENV@|""${docker_env}""|g" \
-e "s|@DOCKER_DNS@|""${docker_dns}""|g" \
-e "s|@ENV@|""${env}""|g" \
${seed_dir}/user-data.in > ${seed_dir}/user-data

mcopy -oi "${seed_img}" ${seed_dir}/user-data ${seed_dir}/meta-data ::
}

poweroff_and_die() {
ip="$1"
port="$2"
${ssh} "${ip}" -p "${port}" sudo poweroff
die "$3"
}

build_arch() {
arch="$1"
ip="$(get_ip)"
port="$(get_port)"
${WORKDIR}/${arch}/run_qemu.sh "${ip}" "${port}" "${id_rsa_file}"
${scp} -P "${port}" "${snap_sh}" "${ip}:~/"
if [ $? != 0 ]; then
poweroff_and_die "${ip}" "${port}" "Could not copy snap script"
fi

${ssh} "${ip}" -p "${port}" "~/snap.sh"
if [ $? != 0 ]; then
poweroff_and_die "${ip}" "${port}" "Failed to run build script"
fi

${scp} -P "${port}" "${ip}:~/packaging/*.snap" .
if [ $? != 0 ]; then
poweroff_and_die "${ip}" "${port}" "Failed to get snap image"
fi

${ssh} "${ip}" -p "${port}" sudo poweroff
}

main() {
gen_seed
(build_arch amd64 &> ${WORKDIR}/amd64/log) &
sleep 1
(build_arch arm64 &> ${WORKDIR}/arm64/log) &
# FIXME: support PPC: https://github.com/kata-containers/packaging/issues/97
#sleep 1
# (build_arch ppc64 &> ${WORKDIR}/ppc64/log) &
wait
}

main

0 comments on commit bc72c11

Please sign in to comment.