-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Elbe Docker container #407
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
apt_keys/*.asc | ||
apt_keys/*.gpg | ||
elbe.tar.gz | ||
result | ||
Dockerfile_tmp | ||
sources.list |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
FROM debian:bookworm | ||
|
||
ARG USER="dev" | ||
|
||
USER root | ||
|
||
ENV DEBIAN_FRONTEND noninteractive | ||
|
||
COPY sources.list /etc/apt/sources.list | ||
|
||
RUN apt update | ||
|
||
# install build tools, QEMU and Python | ||
RUN apt -y install \ | ||
openssh-server debootstrap reprepro python3 python3-pip python3-venv \ | ||
binfmt-support qemu-user-static locales git apt python3-cherrypy3 sudo \ | ||
python3-gpg python3-lxml python3-mako python3-passlib python3-pycdlib \ | ||
python3-debian python3-suds python3-libvirt swig cpio patchelf \ | ||
python3-beaker python3-spyne python3-sqlalchemy python3-parted \ | ||
tmux dosfstools e2fsprogs xfsprogs file lsof vim | ||
|
||
RUN dpkg --add-architecture arm64 | ||
RUN apt update | ||
|
||
RUN apt -y install libc6:arm64 | ||
|
||
# setup locale | ||
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen | ||
ENV LANG en_US.UTF-8 | ||
ENV LANGUAGE en_US:en | ||
ENV LC_ALL en_US.UTF-8 | ||
|
||
##### create user ##### | ||
|
||
ARG HOST_USER=1000 | ||
ARG HOST_GROUP=1000 | ||
|
||
# Create build user mathching outside UID and GID to avoid ownership issues | ||
# and allow user to use sudo | ||
RUN addgroup --gid $HOST_GROUP $USER && \ | ||
useradd -rm -d /home/$USER -s /bin/bash -g $USER -G sudo -u $HOST_USER $USER && \ | ||
echo "$USER ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers && \ | ||
mkdir -p /home/$USER/.ssh && \ | ||
chown -R $USER:$USER /home/$USER | ||
|
||
# Prepare the elbe setup | ||
RUN mkdir -p /var/cache/elbe | ||
COPY source.xml /var/cache/elbe/ | ||
RUN mkdir -p /var/cache/elbe/installer | ||
RUN mkdir -p /var/cache/elbe/devel | ||
|
||
RUN mkdir -p /etc/ssh | ||
RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config | ||
|
||
# reduce container size | ||
# RUN sudo apt clean -y | ||
|
||
# copy repository keys | ||
RUN mkdir -p /etc/apt/trusted.gpg.d/ | ||
COPY apt_keys/* /etc/apt/trusted.gpg.d/ | ||
|
||
# Copy bashrc | ||
COPY bashrc /home/$USER/.bashrc | ||
RUN chown $USER:$USER /home/$USER/.bashrc && chmod +x /home/$USER/.bashrc | ||
COPY bashrc /root/.bashrc | ||
RUN chown root:root /root/.bashrc && chmod +x /root/.bashrc | ||
|
||
RUN chown $USER:$USER /var/cache/elbe | ||
|
||
# copy scripts | ||
COPY scripts/* /scripts/ | ||
RUN chmod +x /scripts/* | ||
|
||
# Get elbe | ||
ADD elbe.tar.gz /var/cache/elbe/devel | ||
|
||
RUN mkdir -p /build/results/images | ||
|
||
WORKDIR /var/cache/elbe | ||
USER $USER | ||
|
||
RUN PATH=$PATH:/var/cache/elbe/devel PYTHONPATH=$PYTHONPATH:/var/cache/elbe/devel elbe db init | ||
|
||
CMD "bash" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Elbe Docker container | ||
|
||
This container allows to use elbe without a initvm. | ||
|
||
Building for foreign CPU architectures is supported if the host is able to load the binfmt_misc kernel module. | ||
|
||
## Build the container | ||
|
||
- First get the Debian, Ubuntu and Elbe apt repository signing keys by running: `contrib/container/apt_keys/get_keys.sh`. | ||
- Then build the container by running `contrib/container/build_container.sh`. | ||
This script expects that you have cloned the git repository, i.e. that the elbe sources can be found at `../../` | ||
|
||
## Use the container | ||
|
||
Run `contrib/container/run_container.sh` to start the container. | ||
|
||
This script read-only bind-mounts the example images to `/images` in the container. | ||
The `.bashrc` is used to mount and writeable overlay at `/tmp/images`. | ||
|
||
The `initvm` commands are not supported in the container, but you can use `build_image` instead: | ||
```bash | ||
Usage: build_image | ||
[ -c | --build-sdk ] | ||
[ -r | --result-path ] | ||
-i | --image path/to/image/xml | ||
``` | ||
|
||
You can find this and other scripts available in the container at `contrib/container/scripts`. | ||
|
||
## More information | ||
|
||
- The elbe Docker container _simulates_ and elbe initvm. Please be aware that this means the kernel of the host OS is used and may have an impact on the build result, e.g. with respect to used filesystem drivers. | ||
- Since elbe is not modified, the _initvm_ command will not work since no libvirt or QEMU VM is available. | ||
- The container uses [qemu and bimfmt](https://wiki.debian.org/QemuUserEmulation) to allow building images for foreign architectures, which is the same mechanism as used by the elbe initvm. To use this, the kernel module *binfmt_misc* needs to be loaded. This is done in the *run_container.sh* script, but the module must be available and the user needs sudo rights. | ||
- The container needs to be a _privileged_ container, for _binfmt_ but also for different _mount_ operations needed during the image build. | ||
- The container also needs to bind-mount _dev_ form the host environment, else new devices created by _losetup_ will not show up, and the build will fail. | ||
|
||
## Known issues | ||
|
||
- Elbe initvm and related commands doesn't work. | ||
- Building ISO images doesn't work |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/bin/bash | ||
|
||
# Extract the apt keys form the docker containers. | ||
CONTAINERS="ubuntu:24.04 ubuntu:22.04 debian:bookworm" | ||
|
||
# extract the apt repo keys form the given containers | ||
for CONTAINER in $CONTAINERS; do | ||
docker run -it --rm -v ${PWD}:/keys $CONTAINER \ | ||
bash -c "cp /etc/apt/trusted.gpg.d/* /keys" | ||
done | ||
|
||
# dearmor all armored keys | ||
for KEY in $(find . -name "*.asc"); do | ||
gpg --dearmor $KEY | ||
done | ||
|
||
# add elbe key | ||
cp ../elbe.asc . | ||
gpg --dearmor elbe.asc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export PATH=/scripts:$PATH:/var/cache/elbe/devel | ||
export PYTHONPATH=$PYTHONPATH:/var/cache/elbe/devel | ||
|
||
# Register binfmt | ||
register_binfmt | ||
|
||
# Start elbe service | ||
start_elbe_service | ||
|
||
echo "Welcome to the elbe container" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/bash | ||
|
||
SCRIPT_DIR=$( dirname "${BASH_SOURCE[0]}") | ||
echo "SCRIPT: $SCRIPT_DIR" | ||
cd $SCRIPT_DIR | ||
|
||
cd ../../ | ||
tar --exclude='contrib' -zcvf contrib/container/elbe.tar.gz . | ||
cd contrib/container | ||
|
||
if [ $# -ne 0 ]; then | ||
distro=$1 | ||
else | ||
distro="debian:bookworm" | ||
fi | ||
|
||
rm -f Dockerfile_tmp | ||
sed "s/debian:bookworm/${distro}/g" Dockerfile > Dockerfile_tmp | ||
cp "sources_${distro}.list" sources.list | ||
|
||
docker build \ | ||
-f Dockerfile_tmp \ | ||
-t elbe_container:testing . |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
|
||
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 | ||
lffHf8U7HFvRg+zm | ||
=3i/P | ||
-----END PGP PUBLIC KEY BLOCK----- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/bin/bash | ||
|
||
lsmod | grep binfmt_misc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check will also fail if binfmt_misc is builtin. Instead check for "binfmt_misc" in |
||
if [ $? -ne 0 ]; then | ||
echo "Trying to load binfmt kernel module for cross-builds ..." | ||
sudo modprobe binfmt_misc | ||
fi | ||
|
||
echo "PWD: $PWD" | ||
mkdir -p result | ||
RESULT=$(realpath ./result) | ||
echo "RESULT DIR: $RESULT" | ||
|
||
SCRIPT_DIR=$(realpath "${BASH_SOURCE[0]}") | ||
echo "SCRIPT: $SCRIPT_DIR" | ||
IMAGES=$(realpath ../../examples) | ||
echo "IMAGES: $IMAGES" | ||
|
||
docker run --rm -it \ | ||
-v ${HOME}/.ssh:/home/dev/.ssh:ro \ | ||
-v ${IMAGES}:/images:ro \ | ||
-v ${RESULT}:/build/results/images:rw \ | ||
-v /dev:/dev \ | ||
--privileged \ | ||
elbe_container:testing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#!/bin/bash | ||
|
||
set +e | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This disables "abort on error", intentional? |
||
|
||
sdk=0 | ||
image="" | ||
result="/build/results/images" | ||
|
||
usage(){ | ||
>&2 cat << EOF | ||
Usage: build_image | ||
[ -c | --build-sdk ] | ||
[ -r | --result-path ] | ||
-i | --image path/to/image/xml | ||
EOF | ||
exit 1 | ||
} | ||
|
||
args=$(getopt -a -o c,h,r:,i: --long build-sdk,help,result-path:,image: -- "$@") | ||
if [[ $? -gt 0 ]]; then | ||
usage | ||
fi | ||
|
||
eval set -- "${args}" | ||
while [ : ]; do | ||
case "$1" in | ||
-c | --build-sdk) | ||
sdk=1 | ||
shift | ||
;; | ||
-r | --result-path) | ||
result=$2 | ||
shift 2 | ||
;; | ||
-i | --image) | ||
image=$2 | ||
shift 2 | ||
;; | ||
-h | --help) | ||
usage | ||
;; | ||
--) | ||
shift | ||
break | ||
;; | ||
?) | ||
echo "Unsupported option: $1" | ||
shift | ||
;; | ||
esac | ||
done | ||
|
||
echo "Build SDK: $sdk" | ||
echo "IMAGE: $image" | ||
|
||
if [ ! -f $image ]; then | ||
echo "Image $image doesn't exist!" | ||
exit 1 | ||
fi | ||
|
||
# stop on error during build preparation | ||
set -e | ||
|
||
IMAGE=$(realpath $image) | ||
IMAGE_NAME=$(basename $IMAGE) | ||
RESULT_FOLDER="${result}/${IMAGE_NAME}" | ||
PROJECT="${RESULT_FOLDER}/elbe.prj" | ||
PRE_XML="${RESULT_FOLDER}/${IMAGE_NAME}.gz" | ||
|
||
mkdir -p $RESULT_FOLDER | ||
|
||
PROJECT_ID=$(elbe control create_project) | ||
echo $PROJECT_ID > ${PROJECT} | ||
elbe preprocess --output=${PRE_XML} $IMAGE | ||
rm -f "${RESULT_FOLDER}/${IMAGE_NAME}" || true | ||
gzip -dk ${PRE_XML} | ||
elbe control set_xml ${PROJECT_ID} ${PRE_XML} | ||
elbe control build ${PROJECT_ID} | ||
|
||
# ignore build errors and complete script | ||
set +e | ||
|
||
elbe control wait_busy ${PROJECT_ID} | ||
if [ $sdk -eq 1 ]; then | ||
elbe control build_sdk ${PROJECT_ID} | ||
elbe control wait_busy ${PROJECT_ID} | ||
fi | ||
elbe control get_files --output ${RESULT_FOLDER} ${PROJECT_ID} | ||
elbe control del_project ${PROJECT_ID} | ||
|
||
echo "The build result was written to ${RESULT_FOLDER}." | ||
|
||
set +e | ||
ERROR=$(cat "${RESULT_FOLDER}/log.txt" | grep "\[ERROR\]") | ||
if [ $? -eq 0 ]; then | ||
echo "ERROR: Build failed, see log.txt!" | ||
cat "${RESULT_FOLDER}/log.txt" | grep "\[ERROR\]" | ||
exit 1 | ||
else | ||
echo "SUCCESS: Build was successful!" | ||
exit 0 | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use
pushd
andpopd
below. Or a subshell.