Skip to content

Commit

Permalink
CI: build snap package in Gitlab CI
Browse files Browse the repository at this point in the history
  • Loading branch information
aarani committed Nov 18, 2021
1 parent 415f75f commit b8e044b
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 23 deletions.
43 changes: 20 additions & 23 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,23 @@ newmono_test_integration:
make &&
make update-servers

# snap package generation is not working with GitLabCI; TODO: report bug
#stockoldmono_package:
# image: ubuntu:18.04
# stage: package
# script:
# - ./scripts/install_mono_from_microsoft_deb_packages.sh
#
# - apt install -y sudo
# - ./scripts/install_snapcraft_dockerless.sh
# # finish installation of snapcraft
# - export SNAP=/snap/snapcraft/current
# - export SNAP_NAME=snapcraft
# - export SNAP_ARCH=amd64
# - export PATH="/snap/bin:$PATH"
#
# - /snap/bin/snapcraft --version
#
# - ./scripts/snap_build.sh
#
# artifacts:
# paths:
# - gwallet*.snap
# expire_in: 50days
stockmono_snap:
image: ubuntu:20.04
stage: package

variables:
# Fixes:
# "Cannot connect to the Docker daemon. Is the docker daemon running on this host?"
DOCKER_HOST: tcp://docker:2375
services:
# To support docker-in-docker
- docker:dind

script:
- ./scripts/snap_build_as_docker.sh

artifacts:
paths:
- "*.snap"
expire_in: 50days

37 changes: 37 additions & 0 deletions scripts/snap_build_as_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euxo pipefail

# Update system
apt update -y

# Install dependencies
apt install lsb-release docker.io -y

# Install snap and snapcraft
./scripts/snap_install_as_docker.sh

# Build repo from source inside snappy container
docker exec snappy ./configure.sh --prefix=./staging
docker exec snappy make
docker exec snappy make install

# Install snapcraft and dependencies
docker exec snappy snap version
docker exec snappy snap install core20
docker exec snappy snap install --classic --stable snapcraft
docker exec snappy snapcraft --version

# Build snap package
docker exec snappy snapcraft --destructive-mode

# Copy built files from container to host to get the .snap package
#
# Make sure to keep /. at the end of the source directory
# This way docker will copy the directory contents
# instead of the entire directory into the destination directoy.
#
# This method has to be used because `docker cp` does not support
# wildcards (*) in directory paths.
# The name of the .snap package depends on the version so it changes
# and cannot be hardcoded.
docker cp snappy:/geewallet/. $(pwd)
136 changes: 136 additions & 0 deletions scripts/snap_install_as_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
#!/usr/bin/env bash
set -euxo pipefail

CONTNAME=snappy
IMGNAME=snapd
RELEASE=20.04

SUDO=""
if [ -z "$(id -Gn|grep docker)" ] && [ "$(id -u)" != "0" ]; then
SUDO="sudo"
fi

if [ "$(which docker)" = "/snap/bin/docker" ]; then
export TMPDIR="$(readlink -f ~/snap/docker/current)"
# we need to run the snap once to have $SNAP_USER_DATA created
/snap/bin/docker >/dev/null 2>&1
fi

BUILDDIR=$(mktemp -d)
# Copy repo contents to build dir
$SUDO cp -r $(pwd) $BUILDDIR/geewallet

usage() {
echo "usage: $(basename $0) [options]"
echo
echo " -c|--containername <name> (default: snappy)"
echo " -i|--imagename <name> (default: snapd)"
rm_builddir
}

print_info() {
echo
echo "use: $SUDO docker exec -it $CONTNAME <command> ... to run a command inside this container"
echo
echo "to remove the container use: $SUDO docker rm -f $CONTNAME"
echo "to remove the related image use: $SUDO docker rmi $IMGNAME"
}

clean_up() {
sleep 1
$SUDO docker rm -f $CONTNAME >/dev/null 2>&1 || true
$SUDO docker rmi $IMGNAME >/dev/null 2>&1 || true
$SUDO docker rmi $($SUDO docker images -f "dangling=true" -q) >/dev/null 2>&1 || true
rm_builddir
}

rm_builddir() {
rm -rf $BUILDDIR || true
exit 0
}

trap clean_up 1 2 3 4 9 15

while [ $# -gt 0 ]; do
case "$1" in
-c|--containername)
[ -n "$2" ] && CONTNAME=$2 shift || usage
;;
-i|--imagename)
[ -n "$2" ] && IMGNAME=$2 shift || usage
;;
-h|--help)
usage
;;
*)
usage
;;
esac
shift
done

if [ -n "$($SUDO docker ps -f name=$CONTNAME -q)" ]; then
echo "Container $CONTNAME already running!"
print_info
rm_builddir
fi

if [ -z "$($SUDO docker images|grep $IMGNAME)" ]; then
cat << EOF > $BUILDDIR/Dockerfile
FROM ubuntu:$RELEASE
ENV container docker
ENV PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
RUN apt update &&\
DEBIAN_FRONTEND=noninteractive\
apt install -y fuse snapd snap-confine squashfuse sudo init lsb-release git docker.io fsharp build-essential pkg-config cli-common-dev mono-devel &&\
apt clean &&\
dpkg-divert --local --rename --add /sbin/udevadm &&\
ln -s /bin/true /sbin/udevadm
RUN systemctl enable snapd
VOLUME ["/sys/fs/cgroup"]
STOPSIGNAL SIGRTMIN+3
RUN mkdir -p /geewallet
WORKDIR /geewallet
ADD geewallet /geewallet
CMD ["/sbin/init"]
EOF
$SUDO docker build -t $IMGNAME --force-rm=true --rm=true $BUILDDIR || clean_up
fi

# start the detached container
$SUDO docker run \
--name=$CONTNAME \
-ti \
--tmpfs /run \
--tmpfs /run/lock \
--tmpfs /tmp \
--cap-add SYS_ADMIN \
--device=/dev/fuse \
--security-opt apparmor:unconfined \
--security-opt seccomp:unconfined \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /lib/modules:/lib/modules:ro \
-d $IMGNAME || clean_up

# wait for snapd to start
TIMEOUT=100
SLEEP=0.1
echo -n "Waiting up to $(($TIMEOUT/10)) seconds for snapd startup "
while [ "$($SUDO docker exec $CONTNAME sh -c 'systemctl status snapd.seeded >/dev/null 2>&1; echo $?')" != "0" ]; do
echo -n "."
sleep $SLEEP || clean_up
if [ "$TIMEOUT" -le "0" ]; then
echo " Timed out!"
clean_up
fi
TIMEOUT=$(($TIMEOUT-1))
done
echo " done"

$SUDO docker exec $CONTNAME snap install core --edge || clean_up
echo "container $CONTNAME started ..."

print_info
rm_builddir

0 comments on commit b8e044b

Please sign in to comment.