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/
|
stage/
|
||||||
snap/.snapcraft/
|
snap/.snapcraft/
|
||||||
snap/snapcraft.yaml
|
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)
|
snap: $(SNAPCRAFT_FILE)
|
||||||
snapcraft -d
|
snapcraft -d
|
||||||
|
|
||||||
|
snap-xbuild:
|
||||||
|
cd $(MK_DIR)/snap-build; ./xbuild.sh -a all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm $(SNAPCRAFT_FILE)
|
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