diff options
author | rubo77 <github@r.z11.de> | 2018-06-28 21:32:52 +0200 |
---|---|---|
committer | rubo77 <github@r.z11.de> | 2018-06-28 23:51:48 +0200 |
commit | c151b46aeb018dda3ece88d91d9c46bd506e2d33 (patch) | |
tree | a1630d7a468a8033d1606cade811f284f9c4cf24 | |
parent | 07d772809dc17ef215f17b001ea91a620afc9168 (diff) |
add GitLab CI files
-rw-r--r-- | .gitlab-ci.yml | 48 | ||||
-rw-r--r-- | .gitmodules | 0 | ||||
-rwxr-xr-x | build.sh | 369 | ||||
-rw-r--r-- | contrib/build-container/Dockerfile | 39 | ||||
-rw-r--r-- | release | 1 | ||||
-rwxr-xr-x | sign.sh | 87 |
6 files changed, 544 insertions, 0 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..c78e31f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,48 @@ +variables: + GIT_SUBMODULE_STRATEGY: recursive + GIT_SSL_CAPATH: /etc/ssl/certs/ + + +stages: + - prepare + - build + +variables: + CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/build + +prepare: + stage: prepare + image: docker:latest + services: + - docker:dind + script: + - docker info + - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY + - docker pull $CONTAINER_IMAGE:latest || true + - docker build --cache-from $CONTAINER_IMAGE:latest -t $CONTAINER_IMAGE:$CI_BUILD_REF -t $CONTAINER_IMAGE:latest contrib/build-container + - docker push $CONTAINER_IMAGE:$CI_BUILD_REF + - docker push $CONTAINER_IMAGE:latest + + +build: + stage: build + image: $CI_REGISTRY_IMAGE/build + script: + - export FORCE_UNSAFE_CONFIGURE=1 + - echo $SIGNING_KEY > signing_key + - eval $(ssh-agent -s) + - ssh-add <(echo "$SSH_KEY") + - git clone https://gitlab.toppoint.de/ffki/gluon.git -b master gluon + - ./build.sh -c update -b $CI_BUILD_REF_NAME -n $CI_JOB_ID -m "-j $(nproc --all) V=s" | tee -a debug.log + - ./build.sh -c clean -b $CI_BUILD_REF_NAME -n $CI_JOB_ID -m "-j $(nproc --all) V=s" | tee -a debug.log + #- ./build.sh -c download -b $CI_BUILD_REF_NAME -n $CI_JOB_ID -m "-j $(nproc --all) V=s" | tee -a debug.log + - ./build.sh -c build -b $CI_BUILD_REF_NAME -n $CI_JOB_ID -m "-j $(nproc --all) V=s" | tee -a debug.log + - ./build.sh -c sign -b $CI_BUILD_REF_NAME -s $(pwd)/signing_key + - ./build.sh -c upload -b $CI_BUILD_REF_NAME -n $CI_JOB_ID + artifacts: + untracked: false + paths: + - debug.log + expire_in: 1 week + + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.gitmodules diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..03b0c14 --- /dev/null +++ b/build.sh @@ -0,0 +1,369 @@ +#!/bin/bash -e +# ===================================================================== +# Build script for Freifunk Kiel firmware +# +# Source: +# Contact: +# Web: +# +# Credits: +# - Freifunk Darmstadt for your great support +# - Freifunk Fulda for the base of the gitlab-ci support +# ===================================================================== + +# Default make options +MAKEOPTS="V=s -j 4" + +# Default to build all Gluon targets if parameter -t is not set +TARGETS="ar71xx-generic ar71xx-tiny" # ar71xx-nand ar71xx-mikrotik mpc85xx-generic x86-generic x86-64" + +# Default is set to use current work directory +SITEDIR="$(pwd)" + +# Default build identifier set to snapshot +BUILD="snapshot" + +# Specify deployment server and user +DEPLOYMENT_SERVER="10.116.250.1" +DEPLOYMENT_USER="rsync" + +# Path to signing key +SIGNKEY="" + +# Error codes +E_ILLEGAL_ARGS=126 + +# Help function used in error messages and -h option +usage() { + echo "" + echo "Build script for Freifunk-Fulda gluon firmware." + echo "" + echo "-b: Firmware branch name (e.g. development)" + echo " Default: current git branch" + echo "-c: Build command: update | clean | download | build | sign | upload | prepare" + echo "-d: Enable bash debug output" + echo "-h: Show this help" + echo "-m: Setting for make options (optional)" + echo " Default: \"${MAKEOPTS}\"" + echo "-n: Build identifier (optional)" + echo " Default: \"${BUILD}\"" + echo "-t: Gluon targets architectures to build" + echo " Default: \"${TARGETS}\"" + echo "-r: Release number (optional)" + echo " Default: fetched from release file" + echo "-w: Path to site directory" + echo " Default: current working directory" + echo "-s: Path to signing key" + echo " Default: empty" +} + +# Evaluate arguments for build script. +if [[ "${#}" == 0 ]]; then + usage + exit ${E_ILLEGAL_ARGS} +fi + +# Evaluate arguments for build script. +while getopts b:c:dhm:n:t:w:s: flag; do + case ${flag} in + b) + BRANCH="${OPTARG}" + ;; + c) + case "${OPTARG}" in + update) + COMMAND="${OPTARG}" + ;; + clean) + COMMAND="${OPTARG}" + ;; + download) + COMMAND="${OPTARG}" + ;; + build) + COMMAND="${OPTARG}" + ;; + sign) + COMMAND="${OPTARG}" + ;; + upload) + COMMAND="${OPTARG}" + ;; + prepare) + COMMAND="${OPTARG}" + ;; + *) + echo "Error: Invalid build command set." + usage + exit ${E_ILLEGAL_ARGS} + ;; + esac + ;; + d) + set -x + ;; + h) + usage + exit + ;; + m) + MAKEOPTS="${OPTARG}" + ;; + n) + BUILD="${OPTARG}" + ;; + t) + TARGETS="${OPTARG}" + ;; + r) + RELEASE="${OPTARG}" + ;; + w) + # Use the root project as site-config for make commands below + SITEDIR="${OPTARG}" + ;; + s) + SIGNKEY="${OPTARG}" + ;; + *) + usage + exit ${E_ILLEGAL_ARGS} + ;; + esac +done + +# Strip of all remaining arguments +shift $((OPTIND - 1)); + +# Check if there are remaining arguments +if [[ "${#}" > 0 ]]; then + echo "Error: To many arguments: ${*}" + usage + exit ${E_ILLEGAL_ARGS} +fi + +# Set branch name +if [[ -z "${BRANCH}" ]]; then + BRANCH=$(git symbolic-ref -q HEAD) + BRANCH=${BRANCH##refs/heads/} + BRANCH=${BRANCH:-HEAD} +fi + +# Set command +if [[ -z "${COMMAND}" ]]; then + echo "Error: Build command missing." + usage + exit ${E_ILLEGAL_ARGS} +fi + +# Set release number +if [[ -z "${RELEASE}" ]]; then + RELEASE=$(cat "${SITEDIR}/release") +fi + +# Normalize the branch name +BRANCH="${BRANCH#origin/}" # Use the current git branch as autoupdate branch +BRANCH="${BRANCH//\//-}" # Replace all slashes with dashes + +# Get the GIT commit description +COMMIT="$(git describe --always --dirty)" + +# Number of days that may pass between releasing an updating +PRIORITY=1 + +update() { + make ${MAKEOPTS} \ + GLUON_SITEDIR="${SITEDIR}" \ + GLUON_OUTPUTDIR="${SITEDIR}/output" \ + GLUON_RELEASE="${RELEASE}-${BUILD}" \ + GLUON_BRANCH="${BRANCH}" \ + GLUON_PRIORITY="${PRIORITY}" \ + update +} + +clean() { + for TARGET in ${TARGETS}; do + echo "--- Update Gluon Dependencies for target: ${TARGET}" + make ${MAKEOPTS} \ + GLUON_SITEDIR="${SITEDIR}" \ + GLUON_OUTPUTDIR="${SITEDIR}/output" \ + GLUON_RELEASE="${RELEASE}-${BUILD}" \ + GLUON_BRANCH="${BRANCH}" \ + GLUON_PRIORITY="${PRIORITY}" \ + GLUON_TARGET="${TARGET}" \ + clean + done +} + +download() { + for TARGET in ${TARGETS}; do + echo "--- Download Gluon Dependencies for target: ${TARGET}" + make ${MAKEOPTS} \ + GLUON_SITEDIR="${SITEDIR}" \ + GLUON_OUTPUTDIR="${SITEDIR}/output" \ + GLUON_RELEASE="${RELEASE}-${BUILD}" \ + GLUON_BRANCH="${BRANCH}" \ + GLUON_PRIORITY="${PRIORITY}" \ + GLUON_TARGET="${TARGET}" \ + download + done +} + +build() { + for TARGET in ${TARGETS}; do + echo "--- Build Gluon Images for target: ${TARGET}" + case "${BRANCH}" in + stable| \ + testing| \ + development) + make ${MAKEOPTS} \ + GLUON_SITEDIR="${SITEDIR}" \ + GLUON_OUTPUTDIR="${SITEDIR}/output" \ + GLUON_RELEASE="${RELEASE}-${BUILD}" \ + GLUON_BRANCH="${BRANCH}" \ + GLUON_PRIORITY="${PRIORITY}" \ + GLUON_TARGET="${TARGET}" + ;; + + *) + make ${MAKEOPTS} \ + GLUON_SITEDIR="${SITEDIR}" \ + GLUON_OUTPUTDIR="${SITEDIR}/output" \ + GLUON_RELEASE="${RELEASE}-${BUILD}" \ + GLUON_BRANCH="${BRANCH}" \ + GLUON_TARGET="${TARGET}" + ;; + esac + done + + echo "--- Build Gluon Manifest" + make ${MAKEOPTS} \ + GLUON_SITEDIR="${SITEDIR}" \ + GLUON_OUTPUTDIR="${SITEDIR}/output" \ + GLUON_RELEASE="${RELEASE}-${BUILD}" \ + GLUON_BRANCH="${BRANCH}" \ + GLUON_PRIORITY="${PRIORITY}" \ + manifest + + echo "--- Write Build file" + cat > "${SITEDIR}/output/images/build" <<EOF +DATE=$(date '+%Y-%m-%d %H:%M:%S') +VERSION=$(cat "${SITEDIR}/release") +RELEASE=${RELEASE} +BUILD=${BUILD} +BRANCH=${BRANCH} +COMMIT=${COMMIT} +HOST=$(uname -n) +EOF +} + +sign() { + echo "--- Sign Gluon Firmware Build" + + # Add the signature to the local manifest + contrib/sign.sh \ + "${SIGNKEY}" \ + "${SITEDIR}/output/images/sysupgrade/${BRANCH}.manifest" +} + +upload() { + echo "--- Upload Gluon Firmware Images and Manifest" + + # Build the ssh command to use + SSH="ssh" + SSH="${SSH} -o stricthostkeychecking=no -v" + + # Determine upload target prefix + case "${BRANCH}" in + stable| \ + testing| \ + nightly| \ + development) + TARGET="${BRANCH}" + ;; + + *) + TARGET="others/${BRANCH}" + ;; + esac + + # Create the target directory on server + ${SSH} \ + ${DEPLOYMENT_USER}@${DEPLOYMENT_SERVER} \ + -- \ + mkdir \ + --parents \ + --verbose \ + "/opt/firmware/ffki/${TARGET}/${RELEASE}-${BUILD}" + + # Copy images to server + rsync \ + --verbose \ + --recursive \ + --compress \ + --progress \ + --links \ + --chmod=ugo=rwX \ + --rsh="${SSH}" \ + "${SITEDIR}/output/images/" \ + "${DEPLOYMENT_USER}@${DEPLOYMENT_SERVER}:/opt/firmware/ffki/${TARGET}/${RELEASE}-${BUILD}" + ${SSH} \ + ${DEPLOYMENT_USER}@${DEPLOYMENT_SERVER} \ + -- \ + ln -sf \ + "/opt/firmware/ffki/${TARGET}/${RELEASE}-${BUILD}/sysupgrade" \ + "/opt/firmware/ffki/${TARGET}/" + ${SSH} \ + ${DEPLOYMENT_USER}@${DEPLOYMENT_SERVER} \ + -- \ + ln -sf \ + "/opt/firmware/ffki/${TARGET}/${RELEASE}-${BUILD}/factory" \ + "/opt/firmware/ffki/${TARGET}/" + +} + +prepare() { + echo "--- Prepare directory for upload" + + # Determine upload target prefix + case "${BRANCH}" in + stable| \ + testing| \ + development) + TARGET="${BRANCH}" + ;; + + *) + TARGET="others/${BRANCH}" + ;; + esac + + # Create the target directory on server + mkdir \ + --parents \ + --verbose \ + "${SITEDIR}/output/firmware/${TARGET}" + + # Copy images to directory + mv \ + --verbose \ + "${SITEDIR}/output/images" \ + "${SITEDIR}/output/firmware/${TARGET}/${RELEASE}-${BUILD}" + + # Link latest upload in target to 'current' + cd "${SITEDIR}/output" + ln \ + --symbolic \ + --force \ + --no-target-directory \ + "${RELEASE}-${BUILD}" \ + "firmware/${TARGET}/current" +} + +( + # Change working directory to gluon tree + cd "${SITEDIR}/gluon" + + # Execute the selected command + ${COMMAND} +) diff --git a/contrib/build-container/Dockerfile b/contrib/build-container/Dockerfile new file mode 100644 index 0000000..c448193 --- /dev/null +++ b/contrib/build-container/Dockerfile @@ -0,0 +1,39 @@ +FROM debian:stretch + +RUN apt-get update && apt-get install -y \ + git \ + subversion \ + python \ + build-essential \ + gawk \ + unzip \ + libncurses5-dev \ + zlib1g-dev \ + libssl1.0-dev \ + wget \ + curl \ + openssh-client +RUN apt-get update && apt-get install -y \ + cmake \ + make \ + pkg-config && \ + cd ~ && \ + git clone http://git.universe-factory.net/libuecc && \ + cd libuecc && \ + cmake ./ && \ + make && \ + make install && \ + ldconfig && \ + cd ~ && \ + git clone https://github.com/tcatm/ecdsautils.git && \ + cd ecdsautils && \ + git checkout tags/v0.3.2 && \ + mkdir build && \ + cd build/ && \ + cmake ../ && \ + make && \ + make install && \ + cd ~ && \ + rm -rf ~/libuecc && \ + rm -rf ~/ecdsautils + @@ -0,0 +1 @@ +2017.1.8~ngly @@ -0,0 +1,87 @@ +#!/bin/bash -e +# ===================================================================== +# Downloads, signs and uploads a gluon manifest file. +# +# This is used by firmware developers to sign a release after it was +# uploaded by the build system. +# +# Source: https://github.com/freifunk-fulda +# Contact: fffd-noc@lists.open-mail.net +# Web: https://fulda.freifunk.net +# ===================================================================== + +# Basic configuration +SRV_USER="root" +SRV_HOST="firmware.fulda.freifunk.net" +SRV_PORT=22022 +SRV_PATH="/var/www/downloads.fulda.freifunk.net/firmware" + +# Help function used in error messages and -h option +usage() { + echo "" + echo "Downloads, signs and uploads a gluon manifest file." + echo "Usage ./sign.sh KEYPATH BRANCH" + echo " KEYPATH the path to the developers private key" + echo " BRANCH the branch to sign" +} + +# Evaluate arguments for build script. +if [[ "${#}" != 2 ]]; then + echo "Insufficient arguments given" + usage + exit 1 +fi + +KEYPATH="${1}" +BRANCH="${2}" + +# Subsitute all slashes in the branch name +BRANCH=${BRANCH//\//-} + +# Sanity checks for required arguments +if [[ ! -e "${KEYPATH}" ]]; then + echo "Error: Key file not found or not readable: ${KEY_PATH}" + usage + exit 1 +fi + +# Check if ecdsa utils are installed +if ! which ecdsasign 2> /dev/null; then + echo "ecdsa utils are not found." + exit 1 +fi + +# Determine temporary local file +TMP="$(mktemp)" + +# Determine upload target prefix +case "${BRANCH}" in + stable| \ + testing| \ + development) + TARGET="${BRANCH}" + ;; + + *) + TARGET="others/${BRANCH}" + ;; +esac + +# Download manifest +scp \ + -o stricthostkeychecking=no \ + -P "${SRV_PORT}" \ + "${SRV_USER}@${SRV_HOST}:${SRV_PATH}/${TARGET}/current/sysupgrade/${BRANCH}.manifest" \ + "${TMP}" + +# Sign the local file +./gluon/contrib/sign.sh \ + "${KEYPATH}" \ + "${TMP}" + +# Upload signed file +scp \ + -o stricthostkeychecking=no \ + -P "${SRV_PORT}" \ + "${TMP}" \ + "${SRV_USER}@${SRV_HOST}:${SRV_PATH}/${TARGET}/current/sysupgrade/${BRANCH}.manifest" |