mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 09:13:29 +00:00
snap-build: implement system to cross-build snap images
Add scripts to cross-build snap images for all supported architectures using virtual machines fixes #98 Signed-off-by: Julio Montes <julio.montes@intel.com>
This commit is contained in:
parent
f9aef172be
commit
a8a4e15951
5
.gitignore
vendored
5
.gitignore
vendored
@ -9,3 +9,8 @@ prime/
|
||||
stage/
|
||||
snap/.snapcraft/
|
||||
snap/snapcraft.yaml
|
||||
snap-build/*.log
|
||||
snap-build/*.img
|
||||
snap-build/*.fd
|
||||
snap-build/id_rsa*
|
||||
snap-build/seed/user-data
|
||||
|
3
Makefile
3
Makefile
@ -59,6 +59,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 -a all
|
||||
|
||||
clean:
|
||||
rm $(SNAPCRAFT_FILE)
|
||||
|
||||
|
11
snap-build/README.md
Normal file
11
snap-build/README.md
Normal file
@ -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 -a all
|
||||
```
|
20
snap-build/config_amd64.sh
Executable file
20
snap-build/config_amd64.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2018 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
local arch_qemu="x86_64"
|
||||
local arch_image="bionic-server-cloudimg-amd64.img"
|
||||
local arch_image_url="https://cloud-images.ubuntu.com/bionic/current/${arch_image}"
|
||||
local arch_bios=""
|
||||
local arch_bios_url=""
|
||||
local arch_qemu_cpu="qemu64"
|
||||
local arch_qemu_machine="pc"
|
||||
local arch_qemu_extra_opts=""
|
||||
if [ "$(arch)" == "x86_64" ];then
|
||||
arch_qemu_cpu="host"
|
||||
arch_qemu_machine="pc,accel=kvm"
|
||||
arch_qemu_extra_opts="-enable-kvm"
|
||||
fi
|
15
snap-build/config_arm64.sh
Executable file
15
snap-build/config_arm64.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2018 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
local arch_qemu="aarch64"
|
||||
local arch_image="bionic-server-cloudimg-arm64.img"
|
||||
local arch_image_url="https://cloud-images.ubuntu.com/bionic/current/${arch_image}"
|
||||
local arch_bios="QEMU_EFI.fd"
|
||||
local arch_bios_url="https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/${arch_bios}"
|
||||
local arch_qemu_cpu="cortex-a57"
|
||||
local arch_qemu_machine="virt,usb=off"
|
||||
local arch_qemu_extra_opts=""
|
15
snap-build/config_ppc64.sh
Executable file
15
snap-build/config_ppc64.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2018 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
local arch_qemu="ppc64"
|
||||
local arch_image="bionic-server-cloudimg-ppc64el.img"
|
||||
local arch_image_url="https://cloud-images.ubuntu.com/bionic/current/${arch_image}"
|
||||
local arch_bios="QEMU_EFI.fd"
|
||||
local arch_bios_url="https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/${arch_bios}"
|
||||
local arch_qemu_cpu="POWER8"
|
||||
local arch_qemu_machine="pseries,usb=off"
|
||||
local arch_qemu_extra_opts="-echr 0x05 -boot c"
|
115
snap-build/lib.sh
Normal file
115
snap-build/lib.sh
Normal file
@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2018 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
error(){
|
||||
msg="$*"
|
||||
echo "ERROR: $msg" >&2
|
||||
}
|
||||
|
||||
die(){
|
||||
error "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
make_random_ip_addr() {
|
||||
echo "127.$((1 + RANDOM % 240)).$((1 + RANDOM % 240)).$((1 + RANDOM % 240))"
|
||||
}
|
||||
|
||||
make_random_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}
|
||||
ret=$?
|
||||
popd
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
setup_image() {
|
||||
img_url=$1
|
||||
img=$2
|
||||
[ -f "${img}" ] && return
|
||||
{ download "${img_url}" "$(dirname ${img})"; ret=$?; } || true
|
||||
[ ${ret} != 0 ] && rm -f "${img}" && return
|
||||
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: seed image path
|
||||
# arg8: extra options
|
||||
run_qemu() {
|
||||
local arch="${1}"
|
||||
local cpu="${2}"
|
||||
local machine="${3}"
|
||||
local ip="${4}"
|
||||
local port="${5}"
|
||||
local image="${6}"
|
||||
local seed_img="${7}"
|
||||
local extra_opts="${8}"
|
||||
local ssh_key_file="id_rsa"
|
||||
local ping_timeout=15
|
||||
|
||||
local img_opts="-drive file=${image},if=virtio,format=qcow2,aio=threads"
|
||||
local 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
|
||||
}
|
2
snap-build/seed/meta-data
Normal file
2
snap-build/seed/meta-data
Normal file
@ -0,0 +1,2 @@
|
||||
instance-id: snapid
|
||||
local-hostname: snap
|
21
snap-build/seed/user-data.in
Normal file
21
snap-build/seed/user-data.in
Normal file
@ -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
|
48
snap-build/snap.sh
Executable file
48
snap-build/snap.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/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 -e
|
||||
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y \
|
||||
build-essential \
|
||||
cpio \
|
||||
docker.io \
|
||||
golang-go \
|
||||
libattr1-dev \
|
||||
libcap-dev \
|
||||
libcap-ng-dev \
|
||||
libdw-dev \
|
||||
libelf-dev \
|
||||
libfdt-dev \
|
||||
libglib2.0-dev \
|
||||
libiberty-dev \
|
||||
libnewt-dev \
|
||||
libpci-dev \
|
||||
libpixman-1-dev \
|
||||
librbd-dev \
|
||||
libssl-dev \
|
||||
libz-dev \
|
||||
openssl \
|
||||
python \
|
||||
snapcraft \
|
||||
snapd
|
||||
|
||||
# start docker
|
||||
sudo systemctl start docker
|
||||
|
||||
# clone packaging reposiory and make snap
|
||||
packaging_repo_url=https://github.com/kata-containers/packaging
|
||||
packaging_dir=~/packaging
|
||||
sudo rm -rf ${packaging_dir}
|
||||
git clone ${packaging_repo_url} ${packaging_dir}
|
||||
pushd ${packaging_dir}
|
||||
sudo -E PATH=$PATH make snap
|
||||
sudo chown ${USER}:${USER} *.snap
|
157
snap-build/xbuild.sh
Executable file
157
snap-build/xbuild.sh
Executable file
@ -0,0 +1,157 @@
|
||||
#!/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
|
||||
|
||||
readonly supported_archs=(all amd64 ppc64 arm64)
|
||||
|
||||
seed_dir=seed
|
||||
seed_img=seed.img
|
||||
id_rsa_file=id_rsa
|
||||
id_rsa_pub_file=id_rsa.pub
|
||||
snap_sh=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() {
|
||||
set -x -e
|
||||
local arch="$1"
|
||||
source "config_${arch}.sh"
|
||||
local ip="$(make_random_ip_addr)"
|
||||
local port="$(make_random_port)"
|
||||
|
||||
setup_image "${arch_image_url}" "${arch_image}"
|
||||
|
||||
# download bios if needed
|
||||
if [ -n "${arch_bios}" ] && [ -n "${arch_bios_url}" ]; then
|
||||
arch_qemu_extra_opts+=" -bios ${arch_bios}"
|
||||
[ -f "${arch_bios}" ] || download "${arch_bios_url}" "."
|
||||
fi
|
||||
|
||||
# run QEMU
|
||||
run_qemu "${arch_qemu}" \
|
||||
"${arch_qemu_cpu}" \
|
||||
"${arch_qemu_machine}" \
|
||||
"${ip}" \
|
||||
"${port}" \
|
||||
"${arch_image}" \
|
||||
"${seed_img}" \
|
||||
"${arch_qemu_extra_opts}"
|
||||
|
||||
# copy snap script to VM
|
||||
${scp} -P "${port}" "${snap_sh}" "${ip}:~/" || poweroff_and_die "${ip}" "${port}" "Could not copy snap script"
|
||||
|
||||
# run snap script in the VM
|
||||
${ssh} "${ip}" -p "${port}" "~/snap.sh" || poweroff_and_die "${ip}" "${port}" "Failed to run build script"
|
||||
|
||||
# copy snap image from VM
|
||||
${scp} -P "${port}" "${ip}:~/packaging/*.snap" . || poweroff_and_die "${ip}" "${port}" "Failed to get snap image"
|
||||
|
||||
# poweroff VM
|
||||
${ssh} "${ip}" -p "${port}" sudo poweroff
|
||||
}
|
||||
|
||||
help()
|
||||
{
|
||||
usage=$(cat << EOF
|
||||
Usage: $0 [-h] [options]
|
||||
Description:
|
||||
Build snap images.
|
||||
Options:
|
||||
-a <arch>, Build snap image for all or a specific architecture (mandatory).
|
||||
-h, Show this help text and exit.
|
||||
|
||||
Supported architectures:
|
||||
$(IFS=$'\t'; echo -e "${supported_archs[*]}")
|
||||
EOF
|
||||
)
|
||||
echo "$usage"
|
||||
}
|
||||
|
||||
main() {
|
||||
local arch
|
||||
local OPTIND
|
||||
while getopts "a:h" opt; do
|
||||
case ${opt} in
|
||||
a)
|
||||
arch="${OPTARG}"
|
||||
;;
|
||||
h)
|
||||
help
|
||||
exit 0;
|
||||
;;
|
||||
?)
|
||||
# parse failure
|
||||
help
|
||||
die "Failed to parse arguments"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
[ -z "${arch}" ] && help && die "Mandatory architecture not supplied"
|
||||
if ! [[ " ${supported_archs[@]} " =~ " ${arch} " ]]; then
|
||||
help
|
||||
die "Architecture '${arch}' not supported"
|
||||
fi
|
||||
|
||||
gen_seed
|
||||
|
||||
if [ "${arch}" != "all" ]; then
|
||||
build_arch "${arch}" &> "${arch}.log"
|
||||
else
|
||||
for a in ${supported_archs[@]}; do
|
||||
(build_arch "${a}" &> "${a}.log") &
|
||||
done
|
||||
wait
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in New Issue
Block a user