Skip to content

Commit

Permalink
virtio-accel: Add Dockerfile and workflow to build and push image
Browse files Browse the repository at this point in the history
Signed-off-by: Kostis Papazafeiropoulos <[email protected]>
  • Loading branch information
papazof committed Sep 7, 2024
1 parent dac2338 commit acf136b
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 0 deletions.
102 changes: 102 additions & 0 deletions .github/workflows/vaccel-build-and-upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Build QEMU+vAccel docker image

on:
push:
branches: [ '*\+vaccel' ]

workflow_dispatch:

env:
REGISTRY: harbor.nbfc.io/nubificus
IMAGE_NAME: qemu-vaccel
APP: qemu-vaccel

jobs:
build:
name: Build Docker Image
runs-on: [self-hosted, gcc, lite, "${{ matrix.arch }}"]
strategy:
matrix:
#arch: [x86_64, aarch64]
arch: [x86_64]
outputs:
hash: ${{ steps.build-and-push.outputs.digest }}
tags: ${{ steps.meta.outputs.tags }}
permissions:
contents: read
id-token: write

steps:
- name: Cleanup previous jobs
run: |
echo "Cleaning up previous runs"
sudo rm -rf ${{ github.workspace }}/*
sudo rm -rf ${{ github.workspace }}/.??*
- name: Checkout code
uses: actions/checkout@v4

- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.HARBOR_USER }}
password: ${{ secrets.HARBOR_PASSWD }}

- name: Extract Docker metadata
id: meta
#uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
id: build-and-push
#uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
uses: docker/build-push-action@v6
with:
context: .
file: subprojects/vaccel/Dockerfile
no-cache: true
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.arch }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
ARCHTAG=${{ matrix.arch }}
BRANCH=${{ github.event.ref_name || github.ref_name }}
sign:
name: Sign Docker Image
runs-on: [self-hosted]
needs: [build]

steps:
- name: Install Cosign
uses: sigstore/[email protected]

- name: Check install
run: cosign version

- name: Login to Harbor
uses: docker/login-action@v3
with:
registry: harbor.nbfc.io/nubificus
username: ${{ secrets.harbor_user }}
password: ${{ secrets.harbor_secret }}

- name: Sign published Docker image
env:
COSIGN_EXPERIMENTAL: "true"
DIGEST: ${{ needs.build.outputs.hash }}
TAGS: ${{ needs.build.outputs.tags }}
run: |
cosign sign --yes harbor.nbfc.io/nubificus/${{ env.APP }}@${{ env.DIGEST }} \
-a "repo=${{ github.repository }}" \
-a "workflow=${{ github.workflow }}" \
-a "ref=${{ github.sha }}" \
-a "author=Nubificus LTD"
- name: Cleanup previous runs
if: ${{ always() }}
run: |
sudo rm -rf ${{ github.workspace }}/*
sudo rm -rf ${{ github.workspace }}/.??*
63 changes: 63 additions & 0 deletions subprojects/vaccel/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
FROM ubuntu:22.04

# Install common build utilities
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -yy eatmydata && \
DEBIAN_FRONTEND=noninteractive eatmydata \
apt-get install -y --no-install-recommends \
bison \
flex \
build-essential \
libglib2.0-dev \
libfdt-dev \
libpixman-1-dev \
zlib1g-dev \
git \
pip \
ninja-build \
pkg-config \
iproute2 \
libcap-ng-dev \
libattr1-dev \
$(apt-get -s build-dep qemu | egrep ^Inst | fgrep '[all]' | cut -d\ -f2) \
cargo \
libclang-dev \
clang \
vim \
ca-certificates \
freeglut3-dev \
&& rm -rf /var/lib/apt/lists/* \
&& pip install meson --break-system-packages

# Build & install vAccel
RUN git clone \
https://github.com/nubificus/vaccel && \
cd vaccel && \
meson setup -Dplugins=enabled -Dexamples=enabled build && \
meson compile -C build && \
meson install -C build && \
echo "/usr/local/lib" >> /etc/ld.so.conf.d/vaccel.conf && \
echo "/sbin/ldconfig" >> /root/.bashrc && \
mkdir /run/user && \
cd .. && rm -rf vaccel

ARG BRANCH=master+vaccel
ARG ARCHTAG=x86_64
COPY vq-size.patch /
# Build & install QEMU w/ vAccel backend
RUN git clone -b ${BRANCH} --depth 1 \
https://github.com/cloudkernels/qemu-vaccel.git && \
mv /vq-size.patch qemu-vaccel/ && \
cd qemu-vaccel && \
git apply vq-size.patch && \
mkdir build && cd build && \
../configure --target-list=${ARCHTAG}-softmmu --enable-virtfs && \
make -j$(nproc) && make install && \
cd ../.. && rm -rf qemu-vaccel

COPY qemu-ifup /etc/qemu-ifup
COPY qemu-script.sh /run.sh

VOLUME /data
WORKDIR /data
ENTRYPOINT ["/run.sh"]
38 changes: 38 additions & 0 deletions subprojects/vaccel/docker/qemu-ifup
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#! /bin/sh
# Script to bring a network (tap) device for qemu up.
# The idea is to add the tap device to the same bridge
# as we have default routing to.

# in order to be able to find brctl
PATH=$PATH:/sbin:/usr/sbin
ip=$(which ip)

if [ -n "$ip" ]; then
ip link set "$1" up
else
brctl=$(which brctl)
if [ ! "$ip" -o ! "$brctl" ]; then
echo "W: $0: not doing any bridge processing: neither ip nor brctl utility not found" >&2
exit 0
fi
ifconfig "$1" 0.0.0.0 up
fi

switch=virbr0

# only add the interface to default-route bridge if we
# have such interface (with default route) and if that
# interface is actually a bridge.
# It is possible to have several default routes too
for br in $switch; do
if [ -d /sys/class/net/$br/bridge/. ]; then
if [ -n "$ip" ]; then
ip link set "$1" master "$br"
else
brctl addif $br "$1"
fi
exit # exit with status of the previous command
fi
done

echo "W: $0: no bridge for guest interface found" >&2
84 changes: 84 additions & 0 deletions subprojects/vaccel/docker/qemu-script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/bash

export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH}
export QEMU_AUDIO_DRV=none
export VACCEL_BACKENDS=${VACCEL_BACKENDS:=libvaccel-noop.so}
export VACCEL_DEBUG_LEVEL=${VACCEL_DEBUG_LEVEL:=4}

smp=1
cpu=host
ram=512

machine="pc,accel=kvm"
kernel="-kernel bzImage"
dtb=""
rootfs=rootfs.img
cmdline="rw root=/dev/vda console=ttyS0 "
stderr=run/stderr.log
extra_args=
cid=

cd /data
mkdir -p run
while getopts 'c:m:r:a:s:v:n:' opt; do
case $opt in
c)
# VM vCPUs
[[ $OPTARG =~ ^[0-9]+$ ]] || error "${opt}: ${OPTARG} is not a number" 1
smp="${OPTARG}"
;;
m)
# VM RAM
[[ $OPTARG =~ ^[0-9]+$ ]] || error "${opt}: ${OPTARG} is not a number" 1
ram="${OPTARG}"
;;
r)
# VM rootfs
[[ -z "${OPTARG}" ]] && error "${opt}: requires a non-empty string" 1
rootfs="${OPTARG}"
;;
a)
# VM kernel command line append
cmdline+="${OPTARG}"
;;
s)
# QEMU output to socket
[[ -z "${OPTARG}" ]] && error "${opt}: requires a non-empty string" 1
vm_id="${OPTARG}"
stderr="${vm_id}-stderr.log"
extra_args+="-serial pipe:./run/${vm_id}.serial "
extra_args+="-chardev socket,id=monitor,path=./run/${vm_id}.monitor,server,nowait "
extra_args+="-monitor chardev:monitor "
;;
n)
# VM w/ network
[[ -z "${OPTARG}" ]] && mac="52:54:00:12:34:01" || mac="${OPTARG}"
extra_args+="-netdev type=tap,id=net0 -device virtio-net,netdev=net0 "
;;
v)
# VM w/ vsock
[[ $OPTARG =~ ^[0-9]+$ ]] || error "${opt}: ${OPTARG} is not a number" 1
cid="${OPTARG}"
extra_args+="-device vhost-vsock-pci,id=vhost-vsock-pci0,guest-cid=${cid} "
;;
:)
error "Option -$OPTARG requires an argument" 1
;;
\?)
exit 1
;;
esac
done
cmdline+="mem=${ram}M"

fsck.ext4 -fy $rootfs 1>/dev/null 2>&1

TERM=linux qemu-system-x86_64 \
-cpu $cpu -m $ram -smp $smp -M $machine -nographic $kernel $dtb -append "$cmdline" 2>stderr.log \
-drive if=none,id=rootfs,file=$rootfs,format=raw,cache=none -device virtio-blk,drive=rootfs \
-fsdev local,id=fsdev0,path=/data/data,security_model=none \
-device virtio-9p-pci,fsdev=fsdev0,mount_tag=data \
-device virtio-rng-pci \
-object acceldev-backend-vaccel,id=rt0 \
-device virtio-accel-pci,id=accel0,runtime=rt0 \
$extra_args

0 comments on commit acf136b

Please sign in to comment.