diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2c129d1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,227 @@ +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'travis.yml' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/.travis.yml), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +sudo: required + +# Use matrix to run tests on different environments +matrix: + include: + + # Exherbo Linux + # Exherbo with GCC + - name: "Exherbo Linux with GCC" + os: linux + cache: + directories: + - /var/db/paludis + env: + DOCKER="exherbo_ci:latest" + VARIANT="exherbo" + TOOL="compile" + COMPILER_C="gcc" + COMPILER_CXX="g++" + # Exherbo with Clang + - name: "Exherbo Linux with Clang" + os: linux + cache: + directories: + - /var/db/paludis + env: + DOCKER="exherbo_ci:latest" + VARIANT="exherbo" + TOOL="compile" + COMPILER_C="clang" + COMPILER_CXX="clang++" + + # Ubuntu Linux + # Ubuntu 19.10 (Eoan Ermine) with GCC + - name: "Ubuntu 19.10 (Eoan Ermine) with GCC" + os: linux + cache: + directories: + - /var/cache/apt/ + dist: bionic + group: travis_latest + env: + DOCKER="ubuntu:eoan" + VARIANT="ubuntu" + TOOL="compile" + COMPILER_C="gcc" + COMPILER_CXX="g++" + # Ubuntu 19.10 (Eoan Ermine) with Clang + - name: "Ubuntu 19.10 (Eoan Ermine) with Clang" + os: linux + cache: + directories: + - /var/cache/apt/ + dist: bionic + group: travis_latest + env: + DOCKER="ubuntu:eoan" + VARIANT="ubuntu" + TOOL="compile" + COMPILER_C="clang" + COMPILER_CXX="clang++" + + # Debian Linux + # Debian Testing + - name: "Debian Testing with GCC" + os: linux + dist: bionic + group: travis_latest + env: + DOCKER="debian:testing" + VARIANT="debian" + TOOL="compile" + COMPILER_C="gcc" + COMPILER_CXX="g++" + + - name: "Debian Testing with Clang" + os: linux + dist: bionic + group: travis_latest + env: + DOCKER="debian:testing" + VARIANT="debian" + TOOL="compile" + COMPILER_C="clang" + COMPILER_CXX="clang++" + # - name: "Debian Testing packaging with pbuilder" + # os: linux + # dist: bionic + # group: travis_latest + # env: + # DOCKER="debian:testing" + # VARIANT="debian" + # TOOL="pbuilder" + + # Debian Sid + - name: "Debian Sid with GCC" + os: linux + dist: bionic + group: travis_latest + env: + DOCKER="debian:sid" + VARIANT="debian" + TOOL="compile" + COMPILER_C="gcc" + COMPILER_CXX="g++" + + - name: "Debian Sid with Clang" + os: linux + dist: bionic + group: travis_latest + env: + DOCKER="debian:sid" + VARIANT="debian" + TOOL="compile" + COMPILER_C="clang" + COMPILER_CXX="clang++" + # - name: "Debian Sid packaging with pbuilder" + # os: linux + # dist: bionic + # group: travis_latest + # env: + # DOCKER="debian:sid" + # VARIANT="debian" + # TOOL="pbuilder" + + # FreeBSD + # FreeBSD 12.0-RELEASE + - name: "FreeBSD 12.0-RELEASE with Clang" + os: linux + dist: bionic + group: travis_latest + env: + QEMU="FreeBSD" + VARIANT="12.0-RELEASE" + TOOL="compile" + COMPILER_C="clang" + COMPILER_CXX="clang++" + + - name: "FreeBSD 12.0-RELEASE with GCC" + os: linux + dist: bionic + group: travis_latest + env: + QEMU="FreeBSD" + VARIANT="12.0-RELEASE" + TOOL="compile" + COMPILER_C="gcc" + COMPILER_CXX="g++" + + # FIXME: MacOS needs refactor of C programs to be compatible (https://travis-ci.org/Kreyrock/Kreyrock/jobs/620509927?utm_medium=notification&utm_source=github_status) + # MacOS X + ## MacOS 10.14 + - name: "MacOS 10.14, xcode11.2 with clang" + os: osx + cache: + - /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula + osx_image: xcode11.2 + compiler: clang + group: travis_latest + + - name: "MacOS 10.14, xcode11.2 with gcc" + os: osx + cache: + - /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula + osx_image: xcode11.2 + compiler: gcc + group: travis_latest + + ## MacOS 10.14.4 + - name: "MacOS 10.14.4, xcode10.3 with clang" + os: osx + cache: + - /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula + osx_image: xcode10.3 + compiler: clang + group: travis_latest + + - name: "MacOS 10.14.4, xcode10.3 with gcc" + os: osx + cache: + - /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula + osx_image: xcode10.3 + compiler: gcc + group: travis_latest + + ## MacOS 10.13 + - name: "MacOS 10.13, xcode9.4 with clang" + os: osx + cache: + - /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula + osx_image: xcode9.4 + compiler: clang + group: travis_latest + + - name: "MacOS 10.13, xcode9.4 with gcc" + os: osx + cache: + - /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula + osx_image: xcode9.4 + compiler: gcc + group: travis_latest + + # Others + + # Default linux + - name: "Linux, default build" + os: linux + dist: bionic + group: travis_latest + env: + TOOL="compile" + +before-install: + - QA/travis-ci/before-install.sh + +install: + - QA/travis-ci/install.sh + +script: + - make build + # We already have logic for linting so there is no need to use 'make check' + - QA/tests/HELL/hell.sh \ No newline at end of file diff --git a/Makefile b/Makefile index c0aae3c..d606fd3 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,10 @@ all: # All build targets are expected in 'build/build-LANG' where 'LANG' is the unique identifier of the language used # FIXME: Replace 'exit 1' with helpful messages +build: + @ printf 'FIXME: %s\n' "Build all targets if executed" + @ exit 1 + # FIXME: Build in '$repodir/build/build-rustlang' instead of '$repodir/target' for multilang support build-rustlang: @ cargo build --verbose @@ -51,6 +55,10 @@ build-python: ## CHECK/TESTS ## +check: + @ printf 'FIXME: %s\n' "Check all targets if executed" + @ exit 1 + check-gc: @ printf 'FIXME: %s\n' "Add tests for gc" @ exit 1 diff --git a/QA/README.md b/QA/README.md new file mode 100644 index 0000000..1c81c53 --- /dev/null +++ b/QA/README.md @@ -0,0 +1 @@ +Backend for Quality Assurance \ No newline at end of file diff --git a/QA/circle-ci/config.yml b/QA/circle-ci/config.yml new file mode 100644 index 0000000..b1030ba --- /dev/null +++ b/QA/circle-ci/config.yml @@ -0,0 +1,10 @@ + version: 2.1 + orbs: + shellcheck: circleci/shellcheck@1.3.15 + jobs: + build: + docker: + - image: circleci/node:4.8.2 # the primary container, where your job's commands are run + steps: + - checkout # check out the code in the project directory + - run: make check diff --git a/QA/common/qemu_debian.sh b/QA/common/qemu_debian.sh new file mode 100755 index 0000000..c9e9420 --- /dev/null +++ b/QA/common/qemu_debian.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +die() { printf 'FATAL: %s\n' "$1" && exit 1 ;} + +[ ! -e debian.qcow ] && { qemu-img create -f qcow2 debian.qcow 20G || die 1 ;} + +#qemu-system-x86_64 -drive format=raw,file=test.img + +#qemu-system-x86_64 -hda debian.qcow -m 640, file=test.img + +#qemu-system-x86_64 -hda ubuntu.qcow -boot d file=test.img -m 640 + +qemu-system-x86_64 -hda debian.qcow -boot d -cdrom debian-10.2.0-amd64-netinst.iso -m 640 \ No newline at end of file diff --git a/QA/common/qemu_ubuntu.sh b/QA/common/qemu_ubuntu.sh new file mode 100755 index 0000000..72fe8c5 --- /dev/null +++ b/QA/common/qemu_ubuntu.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +die() { printf 'FATAL: %s\n' "$1" && exit 1 ;} + +[ ! -e ubuntu.qcow ] && { qemu-img create -f qcow2 ubuntu.qcow 20G || die 1 ;} + +wget http://releases.ubuntu.com/19.10/ubuntu-19.10-desktop-amd64.iso + +qemu-system-x86_64 -hda ubuntu.qcow -boot d -cdrom ubuntu-19.10-desktop-amd64.iso -m 640 \ No newline at end of file diff --git a/QA/docker/dockerfiles/Debian/debian_gcc.Dockerfile b/QA/docker/dockerfiles/Debian/debian_gcc.Dockerfile new file mode 100644 index 0000000..bec7dea --- /dev/null +++ b/QA/docker/dockerfiles/Debian/debian_gcc.Dockerfile @@ -0,0 +1,29 @@ +FROM debian/debian:testing + +USER root + +# Define libraries +RUN sh -c " \ +fixme() { printf 'FIXME: %s\n' "$1" ;} \ +warn() { printf 'WARN: %s\n' "$1" ;} \ +die() { \ + printf 'FATAL: %s\n' "$1" \ + exit 1 \ +}" + +# Install dependencies +RUN apt install -y meson cppcheck gcc libfuse3-dev gcc libcap-devgit ninja-build bison libtool autoconf pkg-config libcap-dev indent libattr1-dev fakeroot uthash-dev gzip rsync autopoint shellcheck || die "Unable to install all dependencies" + +# Install shfmt (Hack!) +RUN sh -c " \ +if [ "$(apt-cache search libfuse3-dev | grep -o "shfmt")" != "shfmt" ]; then \ + if [ ! -e /usr/bin/shfmt ]; then \ + wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt \ + [ ! -x /usr/bin/shfmt ] && chmod +x /usr/bin/shfmt \ + elif [ ! -e /usr/bin/shfmt ]; then \ + fi \ +elif [ "$(apt-cache search libfuse3-dev | grep -o "shfmt")" = "shfmt" ]; then \ + apt install -y shfmt || die "Unable to install shfmt" \ +else \ + die "Unexpected happend in shfmt hack" \ +fi" \ No newline at end of file diff --git a/QA/docker/dockerfiles/Exherbo/exherbo_clang.Dockerfile b/QA/docker/dockerfiles/Exherbo/exherbo_clang.Dockerfile new file mode 100644 index 0000000..aeaa3e4 --- /dev/null +++ b/QA/docker/dockerfiles/Exherbo/exherbo_clang.Dockerfile @@ -0,0 +1,33 @@ +FROM exherbo/exherbo_ci:latest + +USER root + +# Export paludis-config +RUN rm -r /etc/paludis && git clone https://github.com/Kreyrock/paludis-config.git /etc/paludis + +# Sync repos +RUN cave sync + +# Add required repositories +RUN [ ! -e /etc/paludis/repositories/alip.conf ] && cave resolve -x1 repository/alip +RUN [ ! -e /etc/paludis/repositories/compnerd.conf ] && cave resolve -x1 repository/compnerd +RUN [ ! -e /etc/paludis/repositories/virtualization.conf ] && cave resolve -x1 repository/virtualization +RUN [ ! -e /etc/paludis/repositories/danyspin97.conf ] && cave resolve -x1 repository/danyspin97 +RUN [ ! -e /etc/paludis/repositories/python.conf ] && cave resolve -x1 repository/python +RUN [ ! -e /etc/paludis/repositories/perl.conf ] && cave resolve -x1 repository/perl +RUN [ ! -e /etc/paludis/repositories/hasufell.conf ] && cave resolve -x1 repository/hasufell + +# Install build dependencies +RUN cave resolve sys-devel/meson sys-devel/clang sys-fs/fuse dev-scm/git sys-devel/ninja sys-devel/bison sys-devel/libtool sys-devel/autoconf dev-util/pkg-config sys-apps/fakeroot app-arch/gzip net-misc/rsync sys-devel/autoconf -x + +# Install test dependencies +RUN cave resolve dev-util/cppcheck dev-util/indent dev-util/shellcheck -x + +# Purge unwanted packages +RUN cave purge -x + +# Remove build instructions +RUN sh -c " \ +if [ -d /var/db/paludis ]; then \ + rm -r /var/db/paludis || die "Unable to remove" +" \ No newline at end of file diff --git a/QA/docker/dockerfiles/Exherbo/exherbo_gcc.Dockerfile b/QA/docker/dockerfiles/Exherbo/exherbo_gcc.Dockerfile new file mode 100644 index 0000000..3b1e831 --- /dev/null +++ b/QA/docker/dockerfiles/Exherbo/exherbo_gcc.Dockerfile @@ -0,0 +1,30 @@ +FROM exherbo/exherbo_ci:latest + +USER root + +# Export paludis-config +RUN rm -r /etc/paludis && git clone https://github.com/Kreyrock/paludis-config.git /etc/paludis + +# Sync repos +RUN cave sync + +# Add required repositories +RUN [ ! -e /etc/paludis/repositories/alip.conf ] && cave resolve -x1 repository/alip +RUN [ ! -e /etc/paludis/repositories/compnerd.conf ] && cave resolve -x1 repository/compnerd +RUN [ ! -e /etc/paludis/repositories/virtualization.conf ] && cave resolve -x1 repository/virtualization +RUN [ ! -e /etc/paludis/repositories/danyspin97.conf ] && cave resolve -x1 repository/danyspin97 +RUN [ ! -e /etc/paludis/repositories/python.conf ] && cave resolve -x1 repository/python +RUN [ ! -e /etc/paludis/repositories/perl.conf ] && cave resolve -x1 repository/perl +RUN [ ! -e /etc/paludis/repositories/hasufell.conf ] && cave resolve -x1 repository/hasufell + +# Install build dependencies +RUN cave resolve sys-devel/meson sys-devel/gcc sys-fs/fuse dev-scm/git sys-devel/ninja sys-devel/bison sys-devel/libtool sys-devel/autoconf dev-util/pkg-config sys-apps/fakeroot app-arch/gzip net-misc/rsync sys-devel/autoconf -x + +# Install test dependencies +RUN cave resolve dev-util/cppcheck dev-util/indent dev-util/shellcheck -x + +# Purge unwanted packages +RUN cave purge -x + +# Remove build instructions +RUN rm -r /var/db/paludis \ No newline at end of file diff --git a/QA/github/NAME-ME.yml b/QA/github/NAME-ME.yml new file mode 100644 index 0000000..8306399 --- /dev/null +++ b/QA/github/NAME-ME.yml @@ -0,0 +1,51 @@ +name: NAME-ME + +on: [push, pull_request] + +# TODO +## Change profile photo of this CI +## Greet end-user submiting merge request that is not in blacklist (blacklist used for trusted devs) with message ensuring QA +## Greet end-user submiting merge request with checklist +## Adapt lable handling + +jobs: + build-ubuntu: + runs-on: ubuntu-latest + steps: + - name: Install dependencies + # FIXME: Get libfuse3-dev for tests on etcfs.c + run: sudo apt-get install meson cppcheck clang gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot uthash-dev gzip rsync autopoint shellcheck -y && sudo wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt && sudo chmod +x /usr/bin/shfmt + - uses: actions/checkout@v1 + #- name: Compile + # Disable signature for tests + # run: CFLAGS="-O3 --pipe" make SKIPSIGN=true --jobs + - name: Lint + run: make check + build-macos: + runs-on: macos-latest + steps: + - name: Install dependencies + run: brew install shellcheck + - uses: actions/checkout@v1 + - name: Lint + run: make check + build-freebsd: + runs-on: freebsd-latest + steps: + - name: Install dependencies + run: pkg install hs-ShellCheck + - uses: actions/checkout@v1 + - name: Lint + run: make check + build-redox: + runs-on: redox-latest + steps: + - name: Install dependencies + run: printf '%s\n' "This is a gesture to redox developers to encourage development, once we are able to install required packages we will use them" + - name: Lint + run: make check + build-windows: + runs-on: windows-latest + steps: + - name: Lint + run: make check diff --git a/QA/tests/HELL/README.md b/QA/tests/HELL/README.md new file mode 100644 index 0000000..1359301 --- /dev/null +++ b/QA/tests/HELL/README.md @@ -0,0 +1,13 @@ +# HELL - Quality assurance for (WIP name) + +Welcome to HELL! + +![](https://media.giphy.com/media/2U1WOzgmZVw2Y/giphy.gif) + +HELL is used for the quality assurance for (WIP name) + +FIXME: Documentation here + +TODO +- ban echo +- ban cd \ No newline at end of file diff --git a/QA/tests/HELL/backend/configure_backend.sh b/QA/tests/HELL/backend/configure_backend.sh new file mode 100755 index 0000000..e3d42e9 --- /dev/null +++ b/QA/tests/HELL/backend/configure_backend.sh @@ -0,0 +1,191 @@ +#!/bin/sh +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +: ' + This file is used to configure backend depending on expected workflow. This is for example installing dependencies for tests. + + This file expects following variables: + - KERNEL = Used kernel (linux) + - VARIANT = Name of used distribution (debian) + - IDENTIFIER = name of codename or version ("bullseye" or "11") + + In case DOCKER images are used: + - DOCKER = Name of used docker container (exherbo/exherbo_ci:latest) + + In case QEMU is used: + - QEMU = Name of (FIXME, not implemented) + + TODO + - Implement building of DOCKER images + - Implement QEMU +' + +# Configure backend +if [ "$KERNEL" = linux ]; then + # Install all dependencies + info "Installing dependencies for on $KERNEL for $VARIANT-$IDENTIFIER" + + case "$VARIANT-$IDENTIFIER" in + ubuntu-bionic|ubuntu-18.04) + # Install all dependencies + apt install -y \ + meson cppcheck libcap-dev clang libfuse3-dev gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot libattr1-dev uthash-dev gzip rsync autopoint uthash-dev shellcheck \ + || die "Unable to install all dependencies for $VARIANT-$IDENTIFIER" + + # libfuse3-dev hack + if [ "$(apt-cache search libfuse3-dev | grep -o "libfuse3-dev")" != "libfuse3-dev" ]; then + warn "libfuse3-dev is not available on $VARIANT-$IDENTIFIER, trying to resolve manually" + + apt install -y ninja-build || die 1 "Unable to install dependencies for hack" + + mkdir "$HOME/build/fuse3" + + fixme "Export latest fuse3 instead of hard-coded?" + if [ ! -e "$HOME/build/fuse3/fuse-3.6.2.tar.xz" ]; then + wget https://github.com/libfuse/libfuse/releases/download/fuse-3.6.2/fuse-3.6.2.tar.xz -O "$HOME/build/fuse3/fuse-3.6.2.tar.xz" || die 1 "Unable to fetch fuse" + elif [ -e "$HOME/build/fuse3/fuse-3.6.2.tar.xz" ]; then + info "File '$HOME/build/fuse3/fuse-3.6.2.tar.xz' is already fetched" + else + die 255 "Fetching fuse3 tarball" + fi + + fixme "Sanitize tarball export (do not export if the tarball already exists)" + tar xpf "$HOME/build/fuse3/fuse-3.6.2.tar.xz" --directory="$HOME/build/fuse3/" + + # FIXME: Sanitize - Do not create a build dir if it already exists + mkdir "$HOME/build/fuse3/fuse-3.6.2/build" + + fixme "Do not use 'cd'" + cd "$HOME/build/fuse3/fuse-3.6.2/build" || die 1 "Unable to change directory in '$HOME/build/fuse3/fuse-3.6.2/build'" + + meson .. --prefix /usr || die 1 "Meson failed, (FIXME: more info required)" + + ninja || die 1 "ninja failed, (FIXME: more info required)" + + ninja install || die 1 "ninja install failed, (FIXME: more info required)" + elif [ "$(apt-cache search libfuse3-dev | grep -o "libfuse3-dev")" = "libfuse3-dev" ]; then + info "libfuse3-dev is available on this $VARIANT-$IDENTIFIER, no need to install it manually" + apt install -y libfuse3-dev || die 1 "Unable to install libfuse3-dev" + else + die 255 "libfuse3-dev in $VARIANT" + fi + + # Hack fof shfmt + if [ "$(apt-cache search shfmt | grep -o "shfmt")" != "shfmt" ]; then + warn "This system doesn't have shfmt in build instructions, trying to resolve.." + + if [ -e /usr/bin/shfmt ]; then + info "shfmt is already installed, skipping hack" + + elif [ ! -e /usr/bin/shfmt ]; then + info "shfmt is not installed, installing.." + + # Sanitized in if statement's expression + wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt + + # Make sure that it is executable + [ ! -x /usr/bin/shfmt ] && chmod +x /usr/bin/shfmt + else + die 255 "shfmt hack in $VARIANT" + fi + elif [ "$(apt-cache search shfmt | grep -o "shfmt")" = "shfmt" ]; then + info "shfmt is available on this $VARIANT, no need to install it manually" + apt install -y shfmt + else + die 255 "shfmt hack in ubuntu" + fi + ;; + ubuntu-*) + apt install -y \ + meson cppcheck libcap-dev clang libfuse3-dev gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot libattr1-dev uthash-dev gzip rsync autopoint uthash-dev shellcheck \ + || die 1 "Unable to install all dependencies for $VARIANT-$IDENTIFIER" + + # Hack fof shfmt + if [ "$(apt-cache search shfmt | grep -o "shfmt")" != "shfmt" ]; then + warn "This system doesn't have shfmt in build instructions, trying to resolve.." + + if [ -e /usr/bin/shfmt ]; then + info "shfmt is already installed, skipping hack" + elif [ ! -e /usr/bin/shfmt ]; then + info "shfmt is not installed, installing.." + wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt + [ ! -x /usr/bin/shfmt ] && chmod +x /usr/bin/shfmt + else + die 255 "shfmt hack in $VARIANT" + fi + elif [ "$(apt-cache search shfmt | grep -o "shfmt")" = "shfmt" ]; then + info "shfmt is available on this $VARIANT, no need to install it manually" + apt install -y shfmt + else + die 255 "shfmt hack in $VARIANT" + fi + ;; + *) die 2 "Unsupported VARIANT-IDENTIFIER - $VARIANT-$IDENTIFIER" + esac + + # Docker backend + if [ -n "$DOCKER" ]; then + info "Preparing the environment to run docker image '$DOCKER'" + + # Install docker dependencies + info "Installing dependencies for docker" + + case "$VARIANT-$IDENTIFIER" in + ubuntu*|debian*) + apt install -y docker-io || die 1 "Unable to install docker dependencies on $VARIANT-$IDENTIFIER" + ;; + *) die 2 "Unsupported VARIABLE-IDENTIFIER has been parsed in resoluting docker dependencies" + esac + + case "$VARIANT-$IDENTIFIER" in + debian*|ubuntu*|exherbo*) + docker run -d --name "$DOCKER" || die 1 "Unable to run docker image '$DOCKER' on $VARIANT-$IDENTIFIER" + ;; + *) die "Unsupported VARIANT-IDENTIFIER has been parsed - $VARIANT-$IDENTIRIER" + esac + + # Get docker image + case "$DOCKER_IMAGE" in + */*:*|*/*) # Fetch docker image from dockerhub + die fixme "Implement using docker images from dockerhub" + build_*) # Build docker images + info "Preparing to build docker image ${DOCKERIMAGE#build_}" + case ${DOCKER_IMAGE#build_} in + exherbo) + die fixme "Implement building exherbo docker image" + ;; + *) die 255 "DOCKER_IMAGE - build" + esac + ;; + *) die 255 "DOCKER_IMAGE" + esac + + # In case Docker is not used + elif [ -z "$DOCKER" ]; then + info "Docker is not used, skipping configuration" + else + die 255 "Docker backend in $KERNEL" + fi + + if [ -n "$QEMU" ]; then + die fixme "Implement tests on QEMU using linux" + elif [ -z "$QEMU" ]; then + info "QEMU is not used, skipping configuration" + else + die 255 "QEMU in $KERNEL" + fi + +elif [ "$KERNEL" = darwin ]; then + # Homebrew takes lots of time on runtime due to the cleanup used, this is a hotfix (https://travis-ci.community/t/macosx-brew-update-takes-too-much-time/6295) + HOMEBREW_NO_INSTALL_CLEANUP=1 brew update || die "Unable to update brew repositories" + + info "Installing dependencies on $KERNEL" + brew install shellcheck cppcheck shfmt || die "Unable to install dependencies on $KERNEL" +elif [ "$KERNEL" = freebsd ]; then + fixme "$KERNEL is not implemented" +else + die "Unsupported KERNEL used - $KERNEL" +fi \ No newline at end of file diff --git a/QA/tests/HELL/backend/get-variables.sh b/QA/tests/HELL/backend/get-variables.sh new file mode 100755 index 0000000..a9ac51d --- /dev/null +++ b/QA/tests/HELL/backend/get-variables.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +# Get KERNEL Variable +if [ -z "$KERNEL"]; then + case "$(uname -s)" in + Linux) KERNEL=linux ;; + Darwin KERNEL=darwin ;; + *) die 255 "Unsupported output of 'uname -s' has been parsed - $(uname -s)" + esac +elif [ -n "$KERNEL"]; then + warn "Variable 'KERNEL' is overwritten on '$KERNEL'" +else + die 255 "Getting KERNEL variable" +fi \ No newline at end of file diff --git a/QA/tests/HELL/backend/output.sh b/QA/tests/HELL/backend/output.sh new file mode 100755 index 0000000..143dc41 --- /dev/null +++ b/QA/tests/HELL/backend/output.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +: ' + This file is used for sourcing + + Used for output of various messages + - die Outputs a message and exits + - warn Output a warning + - info Output info +' + +# Outputs a message and exits +# SYNOPSIS: die [num] (message) +die() { + err_code="$1" + message="$2" + + case "$err_code" in + 0) true ;; + 1) + if [ -z "$message" ]; then + case $LANG in + en*) printf 'FATAL: %s\n' "Script returned true" ;; + # Do not transtale, default message + *) printf 'FATAL: %s\n' "Script returned true" + esac + elif [ -n "$message" ]; then + case $LANG in + en*) printf 'FATAL: %s\n' "$mesage" ;; + # Do not transtale, default message + *) printf 'FATAL: %s\n' "$message" + esac + else + printf 'FATAL: %s\n' "Unexpected happend in die 1" + exit 255 + fi + exit $err_code + ;; + 3) + # FIXME: Implement translate + # FIXME: Implement message handling + printf 'FATAL: %s\n' "This script is expected to be invoked as root" + ;; + 255) + # FIXME: Implement translate + # FIXME: Implement output for blank $message + + printf 'FATAL: %s\n' "Unexpected happend in $message" + exit $err_code + ;; + fixme) + # FIXME: Translate + # FIXME: Handle scenarios where message is not parsed + printf 'FIXME: $s\n' "$message" + ;; + *) printf 'FATAL: %s\n' "Unexpected argument '$err_code' has been parsed in 'die()'" ; exit 255 + esac + + unset err_code message +} + +warn() { printf 'WARN: %s\n' "$1" ;} +info() { printf 'INFO: %s\n' "$1" ;} +fixme() { + case $1 in + *) printf 'FIXME: %s\n' "$2" + esac +} \ No newline at end of file diff --git a/QA/tests/HELL/hell.sh b/QA/tests/HELL/hell.sh new file mode 100755 index 0000000..57a5fd6 --- /dev/null +++ b/QA/tests/HELL/hell.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +# NOT_PRODUCTION_READY +printf 'WARN: %s\n' "This file is not production ready, USE ON YOUR OWN RISK!" + +# Get output messages +. QA/tests/HELL/backend/output.sh + +# Get Variables +. QA/tests/HELL/backend/get-variables.sh + +# Configure backend +. QA/tests/HELL/backend/configure_backend.sh \ No newline at end of file diff --git a/QA/tests/README.md b/QA/tests/README.md new file mode 100644 index 0000000..179a3fd --- /dev/null +++ b/QA/tests/README.md @@ -0,0 +1,5 @@ +# Quality Assurance of (WIP name) + +- Check for `shift` and force `shift 1` +- https://github.com/koalaman/shellcheck/wiki/Directive#source -> Check shellcheck version +- Force using '$var' instead of '${var}' where possible diff --git a/QA/tests/backend.sh b/QA/tests/backend.sh new file mode 100644 index 0000000..08a2b24 --- /dev/null +++ b/QA/tests/backend.sh @@ -0,0 +1,274 @@ +#!/bin/sh +# shellcheck disable=SC1117 +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +: ' + This file expects following variables: + - KERNEL = Used kernel + - VARIANT = Name of used distribution (lower-case) + - IDENTIFIER = name of codename or version + + In case DOCKER images are used: + - DOCKER = Name of used docker container + + In case QEMU is used: + - QEMU = Name of (FIXME, not implemented) + + TODO + - Implement building of DOCKER images +' + +# SYNOPSIS: die [num] (message) +die() { + err_code="$1" + message="$2" + + case "$err_code" in + 0) true ;; + 1) + if [ -z "$message" ]; then + case $LANG in + en*) printf 'FATAL: %s\n' "Script returned true" ;; + # Do not transtale, default message + *) printf 'FATAL: %s\n' "Script returned true" + esac + elif [ -n "$message" ]; then + case $LANG in + en*) printf 'FATAL: %s\n' "$mesage" ;; + # Do not transtale, default message + *) printf 'FATAL: %s\n' "$message" + esac + else + printf 'FATAL: %s\n' "Unexpected happend in die 1" + exit 255 + fi + exit $err_code + ;; + 3) + # FIXME: Implement translate + # FIXME: Implement message handling + printf 'FATAL: %s\n' "This script is expected to be invoked as root" + ;; + 255) + # FIXME: Implement translate + # FIXME: Implement output for blank $message + + printf 'FATAL: %s\n' "Unexpected happend in $message" + exit $err_code + ;; + fixme) + # FIXME: Translate + # FIXME: Handle scenarios where message is not parsed + printf 'FIXME: $s\n' "$message" + ;; + *) printf 'FATAL: %s\n' "Unexpected argument '$err_code' has been parsed in 'die()'" ; exit 255 + esac + + unset err_code message +} + +warn() { printf 'WARN: %s\n' "$1" ;} +info() { printf 'INFO: %s\n' "$1" ;} +fixme() { + case $1 in + *) printf 'FIXME: %s\n' "$2" + esac +} + +# Configure backend +if [ "$KERNEL" = linux ]; then + # Install all dependencies + info "Installing dependencies for on $KERNEL for $VARIANT-$IDENTIFIER" + + case "$VARIANT-$IDENTIFIER" in + ubuntu-bionic|ubuntu-18.04) + # Install all dependencies + apt install -y \ + meson cppcheck libcap-dev clang libfuse3-dev gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot libattr1-dev uthash-dev gzip rsync autopoint uthash-dev shellcheck \ + || die "Unable to install all dependencies for $VARIANT-$IDENTIFIER" + + # libfuse3-dev hack + if [ "$(apt-cache search libfuse3-dev | grep -o "libfuse3-dev")" != "libfuse3-dev" ]; then + warn "libfuse3-dev is not available on $VARIANT-$IDENTIFIER, trying to resolve manually" + + apt install -y ninja-build || die 1 "Unable to install dependencies for hack" + + mkdir "$HOME/build/fuse3" + + fixme "Export latest fuse3 instead of hard-coded?" + if [ ! -e "$HOME/build/fuse3/fuse-3.6.2.tar.xz" ]; then + wget https://github.com/libfuse/libfuse/releases/download/fuse-3.6.2/fuse-3.6.2.tar.xz -O "$HOME/build/fuse3/fuse-3.6.2.tar.xz" || die 1 "Unable to fetch fuse" + elif [ -e "$HOME/build/fuse3/fuse-3.6.2.tar.xz" ]; then + info "File '$HOME/build/fuse3/fuse-3.6.2.tar.xz' is already fetched" + else + die 255 "Fetching fuse3 tarball" + fi + + fixme "Sanitize tarball export (do not export if the tarball already exists)" + tar xpf "$HOME/build/fuse3/fuse-3.6.2.tar.xz" --directory="$HOME/build/fuse3/" + + # FIXME: Sanitize - Do not create a build dir if it already exists + mkdir "$HOME/build/fuse3/fuse-3.6.2/build" + + fixme "Do not use 'cd'" + cd "$HOME/build/fuse3/fuse-3.6.2/build" || die 1 "Unable to change directory in '$HOME/build/fuse3/fuse-3.6.2/build'" + + meson .. --prefix /usr || die 1 "Meson failed, (FIXME: more info required)" + + ninja || die 1 "ninja failed, (FIXME: more info required)" + + ninja install || die 1 "ninja install failed, (FIXME: more info required)" + elif [ "$(apt-cache search libfuse3-dev | grep -o "libfuse3-dev")" = "libfuse3-dev" ]; then + info "libfuse3-dev is available on this $VARIANT-$IDENTIFIER, no need to install it manually" + apt install -y libfuse3-dev || die 1 "Unable to install libfuse3-dev" + else + die 255 "libfuse3-dev in $VARIANT" + fi + + # Hack fof shfmt + if [ "$(apt-cache search shfmt | grep -o "shfmt")" != "shfmt" ]; then + warn "This system doesn't have shfmt in build instructions, trying to resolve.." + + if [ -e /usr/bin/shfmt ]; then + info "shfmt is already installed, skipping hack" + + elif [ ! -e /usr/bin/shfmt ]; then + info "shfmt is not installed, installing.." + + # Sanitized in if statement's expression + wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt + + # Make sure that it is executable + [ ! -x /usr/bin/shfmt ] && chmod +x /usr/bin/shfmt + else + die 255 "shfmt hack in $VARIANT" + fi + elif [ "$(apt-cache search shfmt | grep -o "shfmt")" = "shfmt" ]; then + info "shfmt is available on this $VARIANT, no need to install it manually" + apt install -y shfmt + else + die 255 "shfmt hack in ubuntu" + fi + ;; + ubuntu-*) + apt install -y \ + meson cppcheck libcap-dev clang libfuse3-dev gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot libattr1-dev uthash-dev gzip rsync autopoint uthash-dev shellcheck \ + || die 1 "Unable to install all dependencies for $VARIANT-$IDENTIFIER" + + # Hack fof shfmt + if [ "$(apt-cache search shfmt | grep -o "shfmt")" != "shfmt" ]; then + warn "This system doesn't have shfmt in build instructions, trying to resolve.." + + if [ -e /usr/bin/shfmt ]; then + info "shfmt is already installed, skipping hack" + elif [ ! -e /usr/bin/shfmt ]; then + info "shfmt is not installed, installing.." + wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt + [ ! -x /usr/bin/shfmt ] && chmod +x /usr/bin/shfmt + else + die 255 "shfmt hack in $VARIANT" + fi + elif [ "$(apt-cache search shfmt | grep -o "shfmt")" = "shfmt" ]; then + info "shfmt is available on this $VARIANT, no need to install it manually" + apt install -y shfmt + else + die 255 "shfmt hack in $VARIANT" + fi + ;; + *) die 2 "Unsupported VARIANT-IDENTIFIER - $VARIANT-$IDENTIFIER" + esac + + # Docker backend + if [ -n "$DOCKER" ]; then + info "Preparing the environment to run docker image '$DOCKER'" + + # Install docker dependencies + info "Installing dependencies for docker" + + case "$VARIANT-$IDENTIFIER" in + ubuntu*|debian*) + apt install -y docker-io || die 1 "Unable to install docker dependencies on $VARIANT-$IDENTIFIER" + ;; + *) die 2 "Unsupported VARIABLE-IDENTIFIER has been parsed in resoluting docker dependencies" + esac + + case "$VARIANT-$IDENTIFIER" in + debian*|ubuntu*|exherbo*) + docker run -d --name "$DOCKER" || die 1 "Unable to run docker image '$DOCKER' on $VARIANT-$IDENTIFIER" + ;; + *) die "Unsupported VARIANT-IDENTIFIER has been parsed - $VARIANT-$IDENTIRIER" + esac + + # Get docker image + case "$DOCKER_IMAGE" in + */*:*|*/*) # Fetch docker image from dockerhub + die fixme "Implement using docker images from dockerhub" + build_*) # Build docker images + info "Preparing to build docker image ${DOCKERIMAGE#build_}" + case ${DOCKER_IMAGE#build_} in + exherbo) + die fixme "Implement building exherbo docker image" + ;; + *) die 255 "DOCKER_IMAGE - build" + esac + ;; + *) die 255 "DOCKER_IMAGE" + esac + + # In case Docker is not used + elif [ -z "$DOCKER" ]; then + info "Docker is not used, skipping configuration" + else + die 255 "Docker backend in $KERNEL" + fi + + if [ -n "$QEMU" ]; then + die fixme "Implement tests on QEMU using linux" + elif [ -z "$QEMU" ]; then + info "QEMU is not used, skipping configuration" + else + die 255 "QEMU in $KERNEL" + fi + +elif [ "$KERNEL" = darwin ]; then + # Homebrew takes lots of time on runtime due to the cleanup used, this is a hotfix (https://travis-ci.community/t/macosx-brew-update-takes-too-much-time/6295) + HOMEBREW_NO_INSTALL_CLEANUP=1 brew update || die "Unable to update brew repositories" + + info "Installing dependencies on $KERNEL" + brew install shellcheck cppcheck shfmt || die "Unable to install dependencies on $KERNEL" +elif [ "$KERNEL" = freebsd ]; then + fixme "$KERNEL is not implemented" +else + die "Unsupported KERNEL used - $KERNEL" +fi + +# Run tests +if [ "$TEST" = core ]; then + info "Performing core tests.." + make check || die 1 "Tests failed" +elif [ "$TEST" = extensive ]; then + info "Performing extensive tests" + fixme "Implement extensive tests" + make fullcheck || die 1 "Tests failed" +elif [ "$TEST" = skip ]; then + info "Variable 'TEST' stores value 'skip', skipping tests" +elif [ "$TEST" = '' ]; then + warn "Variable 'TEST' is not set, skipping tests" +else + die 255 "Performing tests" +fi + +# Build +if [ "$BUILD" = all ]; then + info "Performing build on kernel '$KERNEL' using $VARIANT-$IDENTIFIER" + make SKIPSIGN=true || die 1 "Build failed" +elif [ "$BUILD" = skip ]; then + info "Variable 'BUILD' stores valie 'skip', skipping build" +elif [ "$BUILD" = '' ]; then + warn "Variable 'BUILD' is not set, skipping build" +else + die 255 "Building on $KERNEL" +fi \ No newline at end of file diff --git a/QA/tests/check.sh b/QA/tests/check.sh new file mode 100755 index 0000000..fdcd1b1 --- /dev/null +++ b/QA/tests/check.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +die() { + err_code="$1" + message="$2" + + case $err_code in + 1) + printf 'FATAL: %s\n' "$message" + exit "$err_code" + ;; + lintfail) + printf 'FATAL: %s\n' "Linting file '$file', failed.." + exit 1 + ;; + 255) + printf 'FATAL: %s\n' "$message" + exit "$err_code" + ;; + *) + printf 'FATAL: %s\n' "Unrecognized error code argument has been parsed in die function in QA/tests/shell/check.sh" + exit 255 + esac + + unset err_code message +} + +fixme() { + argument="$1" + + case $argument in + LintNotImplemented) printf 'FIXME: %s\n' "Unable to check file '$file', $identifier linting is not implemented" ;; + *) printf 'FIXME: %s\n' "$*" + esac + + unset argument +} + +# shellcheck disable=SC2044 # HOTFIX! +for file in $(find . -not \( \ +-path './.git' -prune -o \ +-path './vendor' -prune -o \ +-name 'LICENSE' -prune -o \ +-name '.gitignore' -prune -o \ +-name 'os-release' -prune -o \ +-name '.keepinfodir' -prune -o \ +-name 'include-bedrock' -prune -o \ +-name 'lock' -prune \ +\) -type f); do + + # Identify file + # FIXME: In theory we can use 'file' for this instead + case "$file" in + *.c) identifier="C" ;; + *.sh) identifier="shell" ;; + *.bash) identifier="bash" ;; + *.yml) identifier="yaml" ;; + *.md) identifier="markdown" ;; + *.png) identifier="png" ;; + *.zsh) identifier="zsh" ;; + *.conf) identifier="config" ;; + *.fish) identifier="fish" ;; + *.gpg) identifier="gpg" ;; + *.service) identifier="service" ;; + *.donotcheck|*.disabled) identifier="DoNotCheck" ;; + *.json) identifier="json" ;; + *.Dockerfile) identifier="dockerfile" ;; + *.xml) identifier="xml" ;; + *.fetchnext) identifier="fetchnext" ;; + */Makefile) identifier="makefile" ;; + *.bak) identifier="backup" ;; + *) + case "$(head -n1 "$file")" in + '#!/'*'/bash'|'#!/'*' bash') identifier="bash" ;; + '#!/'*'/sh'|'#!/'*' sh') identifier="shell" ;; + '#compdef'*) identifier="zsh" ;; + *) die 255 "Unexpected file '$file' has been parsed in tests, unable to resolve for tests" + esac + esac + + # Output message about checked file + printf "checking $identifier file %s\\n" "${file#./}" + + # Test file based on identifier + case "$identifier" in + C) + cppcheck --error-exitcode=1 "$file" || die lintfail + ;; + markdown|yaml|config|makefile|service|gpg|json|xml|dockerfile) + fixme LintNotImplemented + ;; + backup|png) + true # Do not check these + ;; + DoNotCheck) + printf 'INFO: %s\n' "File $file is set to be ignored by tests" + ;; + fetchnext) + printf 'INFO: %s\n' "fetchnext files are stub" + ;; + bash) + shellcheck -x -s bash "$file" || die lintfail + ;; + shell) + shellcheck -x -s bash "$file" || die lintfail + ;; + zsh) + # zsh are apparently tested agains bash in shellcheck (FIXME: Sanity-check) + shellcheck -x -s bash "$file" || die lintfail + ;; + fish) + fixme LintNotImplemented + ;; + *) die 255 "Unknown identifier for file '$file' has been parsed, unable to resolve.." + esac +done \ No newline at end of file diff --git a/QA/tests/shell/shellizator.bash b/QA/tests/shell/shellizator.bash new file mode 100755 index 0000000..06b8fef --- /dev/null +++ b/QA/tests/shell/shellizator.bash @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# This file has to be bash since we are using non-POSIX regex + # Make it POSIX-compatible - using awk? perl? + +# shellcheck source=src/slash-bedrock/lib/shell/common-code.sh +. /bedrock/lib/shell/common-code.sh + +file="$1" +syntax_err="$2" + +# Die if more then one argument has been parsed +[ -n "$syntax_err" ] && die 1 "Wrong argumnet '$syntax_err' has been parsed in 'shellizator.sh'" + +# Shift arguments +while [ $# -gt 1 ]; do shift 1; done + +# Convert ${var} -> $var where possible (https://regex101.com/r/J7vfQC/5) +sed -i -E 's:([\/\=\ \"\>\-]|^)(\$)\{([a-zA-Z0-9_]+)\}([\,\ \"\n\,\/\!\:\\\-\.]):\1\2\3\4:' "$file" || die 1 "Unable to convert '\${var}' to '\$var' in $file" + +# Convert `if [ "${TRAVIS_OS_NAME}" == "linux" -a "${DOCKER}" == "" -a "${QEMU}" == "" ] ; then` in `if [ "${TRAVIS_OS_NAME}" == "linux" ] && [ "${DOCKER}" == "" ] && [ "${QEMU}" == "" ] ; then` + +fixme "Implement shellizator if fixing" + +# Remove unnecesary spaces in if statements after the `]` and before 'then' (https://regex101.com/r/XhNCZd/1) +sed -i -E 's:(if[^;]+)\s(\;\sthen):\1\2:gm' "$file" || die 1 "Unable to remove unnecesary spaces in if statements" diff --git a/QA/travis-ci/before-install.sh b/QA/travis-ci/before-install.sh new file mode 100755 index 0000000..aeea0a8 --- /dev/null +++ b/QA/travis-ci/before-install.sh @@ -0,0 +1,214 @@ +#!/bin/bash +# shellcheck disable=SC1117 +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +# shellcheck source=QA/travis-ci/travis-common.sh +. "QA/travis-ci/travis-common.sh" + +# shellcheck source=QA/travis-ci/get-container.sh +. "$(dirname "$0")/get-container.sh" + +fixme "Travis - before-install.sh disables SC1117 as hotfix" + +# Linux as-is +if [ "$TRAVIS_OS_NAME" = linux ] && [ -z "$DOCKER" ] && [ -z "$QEMU" ]; then + + # Nothing else to do + true + +# Linux via Docker +elif [ "$TRAVIS_OS_NAME" = linux ] && [ -n "$DOCKER" ] && [ -z "$QEMU" ]; then + # The build machine therefore needs a sufficient amount of RAM! + [ -e "$CONTAINER" ] && sudo docker rm -f "$CONTAINER" + sudo docker run -d \ + --name "$CONTAINER" \ + --tmpfs /var/cache/pbuilder:rw,exec,dev,size=4g \ + --tmpfs /var/lib/mock:rw,exec,dev,size=4g \ + --cap-add=SYS_ADMIN --cap-add=NET_ADMIN \ + --security-opt apparmor:unconfined \ + -v "$(pwd):/travis" -w /travis \ + "$DOCKER" tail -f /dev/null + sudo docker ps + +# Exherbo via Docker +elif [ "$TRAVIS_OS_NAME" = 'Exherbo Linux' ] && [ -n "$DOCKER" ] && [ -z "$QEMU" ]; then + # The build machine therefore needs a sufficient amount of RAM! + [ -e "$CONTAINER" ] && sudo docker rm -f "$CONTAINER" + + # Run docker + sudo docker run -d \ + --name "$CONTAINER" \ + --cap-add=SYS_ADMIN --cap-add=NET_ADMIN \ + --security-opt apparmor:unconfined \ + -v "$(pwd):/travis" -w /travis \ + +# FreeBSD via QEMU +# QA: Convert on POSIX-compatible +elif [ "$TRAVIS_OS_NAME" = linux ] && [ "$QEMU" = FreeBSD ]; then + + if [ -n "$VARIANT" ]; then + sudo mkdir -p /vservers/qemu-freebsd + sudo chown "$USER:$USER" /vservers/qemu-freebsd + mkdir -p /vservers/qemu-freebsd/mnt + cd /vservers/qemu-freebsd || die "Unable to change directory in '/vservers/qemu-freebsd'" + + # Download image + imageName="FreeBSD-$VARIANT-amd64.raw" + if [ -e "$imageName.xz" ] && [ ! -e "$imageName" ]; then + printf '%s\n' "Extracting existing $imageName.xz ..." + xz -T0 -dk "$imageName.xz" + elif [ ! -e "$imageName.xz" ] || [ ! -e "$imageName" ]; then + imageURL="https://download.freebsd.org/ftp/releases/VM-IMAGES/$VARIANT/amd64/Latest/$imageName.xz" + info "Downloading FreeBSD VM image from $imageURL ..." + curl "$imageURL" | tee "$imageName.xz.tmp" | xz -T0 -d - ">$imageName" + mv "$imageName.xz.tmp" "$imageName.xz" || die "Unable to rename $imageName.xz.tmp in $imageName.xz" + fi + + # Modify FreeBSD image + pushd /vservers/qemu-freebsd/ + + # Grow image + truncate -s 128G "$imageName" + echo -e "w\nY\nY\n" | LANG=C gdisk "$imageName" + parted -s "$imageName" resizepart 3 100% + parted -s "$imageName" print + + # Mount + ls -l "$imageName" + mountPoint="$(pwd)/mnt" + + sudo umount "$mountPoint" 2>/dev/null || true + LOOPDEVS="$(sudo losetup -j "$imageName" | awk '{ print $1 }' | sed -e "s/:$//g")" + for loopdev in $LOOPDEVS ;do + sudo losetup -d "$loopdev" || true + done + + sudo losetup -P -f "$imageName" + sudo losetup -j "$imageName" + LOOPDEV="$(sudo losetup -j "$imageName" | awk '{ print $1 }' | sed -e "s/:$//g")" + + echo "sudo fuse-ufs2/fuse-ufs/fuse-ufs ${LOOPDEV}p3 $mountPoint -o rw" + sudo fuse-ufs2/fuse-ufs/fuse-ufs "${LOOPDEV}p3" "$mountPoint" -o rw + + # Modify + # Set up networking: + sudo cp "$mountPoint/etc/rc.conf" . + sudo bash -c "( + echo \"sshd_enable=\\\"YES\\\"\" + echo \"ifconfig_vtnet0=\\\"DHCP\\\"\" + echo \"ifconfig_vtnet1=\\\"inet 192.168.100.100 netmask 255.255.255.0\\\"\" + echo \"nfs_client_enable=\\\"YES\\\"\" + echo \"rpc_lockd_enable=\\\"YES\\\"\" + echo \"rpc_statd_enable=\\\"YES\\\"\" + ) >>$mountPoint/etc/rc.conf" + + # Make sure that FreeBSD uses the latest packages: + sudo sed -e 's#"pkg+http://pkg.FreeBSD.org/${ABI}/quarterly"#"pkg+http://pkg.FreeBSD.org/${ABI}/latest"#g' -i "$mountPoint/etc/pkg/FreeBSD.conf" + + # Make sure that the /usr/ports directory is there. + sudo mkdir -p "$mountPoint/usr/ports" + + # Add SSH public key authentication: + sudo mkdir -p "$mountPoint/root/.ssh" + sudo chmod 700 "$mountPoint/root/.ssh" + if [ ! -e "$HOME/.ssh/id_rsa" ]; then + ssh-keygen -t rsa -b 4096 -P "" -f "$HOME/.ssh/id_rsa" + fi + sudo cp "$HOME/.ssh/id_rsa.pub" "$mountPoint/root/.ssh/authorized_keys" + sudo chmod 600 "$mountPoint/root/.ssh/authorized_keys" + + sudo bash -c "echo \"PermitRootLogin prohibit-password\" >>$mountPoint/etc/ssh/sshd_config" + # sudo tail -n 6 ${mountPoint}/etc/ssh/sshd_config + + # Set up NFS: + sudo mkdir -p "$mountPoint/travis" + sudo sed -e "/^.*\/travis.*$/d" -i~ "$mountPoint/etc/fstab" + sudo bash -c "( echo \"192.168.100.1:/travis /travis nfs rw,soft,async,noatime,nfsv3,rsize=65536,wsize=65536 0 0\" ; echo \"tmpfs /usr/ports tmpfs rw 0 0\" ) >>$mountPoint/etc/fstab" + sudo cat "$mountPoint/etc/fstab" + + # Unmount + sudo umount "$mountPoint" + sudo losetup -d "$LOOPDEV" + + popd + + # Host-only networking + sudo ip link add br0 type bridge || true + sudo ip addr flush dev br0 + sudo ip addr add 192.168.100.1/24 brd 192.168.100.255 dev br0 + sudo ip tuntap add mode tap + sudo ip link set tap0 master br0 + sudo ip link set dev br0 up + sudo ip link set dev tap0 up + sudo iptables -A INPUT -i tap0 -s 192.168.100.0/24 -j ACCEPT + sudo iptables -A OUTPUT -o tap0 -d 192.168.100.0/24 -j ACCEPT + sudo iptables -A INPUT -i br0 -s 192.168.100.0/24 -j ACCEPT + sudo iptables -A OUTPUT -o br0 -d 192.168.100.0/24 -j ACCEPT + sudo iptables -A FORWARD -s 192.168.100.0/24 -d 192.168.100.0/24 + # sudo dnsmasq --interface=br0 --bind-interfaces \ + # --dhcp-range=192.168.100.2,192.168.100.254 || true + + + # NFS + sudo mkdir -p /travis + sudo mount --bind "$(pwd)" /travis + sudo bash -c "echo \"/travis 192.168.100.0/24(rw,no_root_squash)\" >/etc/exports" + env LANG=C.UTF-8 ci/retry -t "$RETRY_MAXTRIALS" -p "$RETRY_PAUSE" -- sudo apt-get install -y qemu-kvm nfs-kernel-server + sudo exportfs -v + sudo service nfs-kernel-server restart + + # ====== Start VM ===================================================== + sudo killall -q qemu-system-x86_64 || true + ssh-keygen -R "[localhost]:8829" -f ~/.ssh/known_hosts + # Non-KVM execution: qemu-system-x86_64 \ + sudo qemu-system-x86_64 -machine type=pc,accel=kvm -nographic \ + -m 6144 -cpu host -smp "$(nproc)" \ + -drive "if=virtio,media=disk,file=/vservers/qemu-freebsd/$imageName,format=raw" \ + -netdev user,id=mynet0,hostfwd=tcp:127.0.0.1:8829-:22 -device virtio-net-pci,netdev=mynet0 \ + -netdev tap,id=network0,ifname=tap0,script=no,downscript=no -device virtio-net-pci,netdev=network0,mac=00:00:00:00:00:00 \ + & + + ready=0 + trials=20 ; sleep=15 + i=0 ; while [ "$i" -lt "$trials" ]; do + # QA: Convert on POSIX compatible + # shellcheck disable=2219 + let i=$i+1 + echo "$i/$trials: Waiting for VM to boot ..." + sleep "$sleep" + if ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost hostname; then + ready=1 + break + fi + done + if [ $ready -eq 0 ]; then + echo >&2 "VM did not boot properly!" + exit 1 + fi + + # Download fuse-ufs2 + # if [ ! -d fuse-ufs2/ ]; then + # info "Downloading fuse-ufs2 ..." + # git clone https://github.com/dreibh/fuse-ufs2 -b dreibh/ubuntu-disco-fix + # # git clone https://github.com/mkatiyar/fuse-ufs2 + # fi + + # Get repository + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + git clone https://github.com/Kreyrock/Kreyrock.git + + unset imageName imageURL + fi + +# MacOS X +elif [ "$TRAVIS_OS_NAME" = osx ]; then + + # Nothing to be done here. + true + +else + die "Invalid setting of TRAVIS_OS_NAME=$TRAVIS_OS_NAME, DOCKER=$DOCKER, QEMU=$QEMU!" +fi diff --git a/QA/travis-ci/get-container.sh b/QA/travis-ci/get-container.sh new file mode 100644 index 0000000..d02828b --- /dev/null +++ b/QA/travis-ci/get-container.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'before-install' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/before-install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +# shellcheck source=QA/travis-ci/travis-common.sh +. "$(dirname "$0")/travis-common.sh" + +if [ -n "$DOCKER" ]; then + + # Check configuration + if [ -z "$VARIANT" ] ; then + die "Variable VARIANT is not set" + fi + if [ -z "$TOOL" ] ; then + die "Variable TOOL is not set" + fi + + # Get name of package + PACKAGE="Kreyrock" + + # Set container name + CONTAINER=$(printf '%s\n' "$PACKAGE-$DOCKER-$TOOL" | sed -e "s/:/_/g") + if [ -n "$COMPILER_C" ]; then + CONTAINER="$CONTAINER-$COMPILER_C" + fi + export CONTAINER + +else + info "Docker is not used" + unset CONTAINER +fi diff --git a/QA/travis-ci/install.sh b/QA/travis-ci/install.sh new file mode 100755 index 0000000..0155f12 --- /dev/null +++ b/QA/travis-ci/install.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1117 +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'install.sh' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/install), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +# shellcheck source=QA/travis-ci/travis-common.sh +. "$(dirname "$0")/travis-common.sh" + +# shellcheck source=QA/travis-ci/get-container.sh +. "$(dirname "$0")/get-container.sh" + +fixme "Travis - install.sh is disabling SC1117 as hotfix" + +# QA: Why US mirror? +UBUNTU_MIRROR="us.archive.ubuntu.com" +RETRY_MAXTRIALS=5 +RETRY_PAUSE=60 + +# Linux as-is +if [ "$TRAVIS_OS_NAME" = linux ] && [ -z "$DOCKER" ] && [ -z "$QEMU" ] && [ "$VARIANT" = ubuntu ]; then + + sudo apt update + + if [ "$(apt-cache search libfuse3-dev | grep -o "libfuse3-dev")" = "libfuse3-dev" ]; then + + # Fetch all dependencies + sudo apt-get install meson uthash-dev libcap-dev cppcheck libattr1-dev clang libfuse3-dev gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot uthash-dev gzip rsync autopoint uthash-dev shellcheck -y + + elif [ "$(apt-cache search libfuse3-dev | grep -o "libfuse3-dev")" = "libfuse3-dev" ]; then + + sudo apt-get install meson uthash-dev libcap-dev cppcheck clang gcc git libattr1-dev ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot uthash-dev gzip rsync autopoint shellcheck -y + + # Travis is incompetent to provide usefull version of linux (https://travis-ci.community/t/more-virtual-environments/6213/7) so we have to fetch libfuse3-dev manually + warn "Travis-CI's ubuntu still doesn NOT offer 'libfuse3-dev', using hack to fetch it manually" + mkdir "$HOME/build/fuse3" + fixme "Export latest fuse3 instead of hard-coded in ci/before-install.sh" + wget https://github.com/libfuse/libfuse/releases/download/fuse-3.6.2/fuse-3.6.2.tar.xz -O "$HOME/build/fuse3/fuse-3.6.2.tar.xz" + tar xpf "$HOME/build/fuse3/fuse-3.6.2.tar.xz" --directory="$HOME/build/fuse3/" + mkdir "$HOME/build/fuse3/fuse-3.6.2/build" + fixme "Avoid using cd in ci/before-install.sh" + cd "$HOME/build/fuse3/fuse-3.6.2/build"|| die + meson .. --prefix /usr + ninja + sudo ninja install + + else + die "Unexpected in install.sh configuring linux as-is" + + fi + + # Fetch shfmt (HACK!) + if [ "$(apt-cache search shfmt | grep -o "shfmt")" = "shfmt" ]; then + info "Installing shfmt" + apt install -y shfmt + + elif [ "$(apt-cache search shfmt | grep -o "shfmt")" != "shfmt" ]; then + warn "Package shfmt is not available, using hack to fetch it manually.." + + # Get shfmt + if [ -e /usr/bin/shfmt ]; then + warn "File /usr/bin/shfmt already exists! This is unexpected assuming that shfmt is already provided on linux as-is?" + elif [ ! -e /usr/bin/shfmt ]; then + sudo wget https://github.com/mvdan/sh/releases/download/v3.0.0-beta1/shfmt_v3.0.0-beta1_linux_amd64 -O /usr/bin/shfmt + [ ! -x /usr/bin/shfmt ] && sudo chmod +x /usr/bin/shfmt + else + die "Unexpected happend in /usr/bin/shfmt" + fi + else + die "Unexpected happend in feteching shfmt in linux as-is" + fi + +# Linux via Docker +elif [ "$TRAVIS_OS_NAME" = linux ] && [ -n "$DOCKER" ] && [ -z "$QEMU" ]; then + + # Apt-based + if [ "$VARIANT" = ubuntu ] || [ "$VARIANT" = debian ]; then + # QA: Why are these variables? Looks like perfect scenario for a function.. + APT_UPDATE='env LANG=C.UTF-8 apt-get update -o Acquire::GzipIndexes=false' + APT_INSTALL="env LANG=C.UTF-8 DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --no-install-recommends" + # APT_UPGRADE="env LANG=C.UTF-8 DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef --no-install-recommends" + # APT_ADD_REPOSITORY="env LANG=C.UTF-8 apt-add-repository -y" + + # Prepare container + info "Preparing container ..." + # Use uncompressed package lists. Necessary to work around + # "apt-show-version" problems due to usage of compressed lists in + # Docker containers: + # https://askubuntu.com/questions/916199/install-apt-show-versions-inside-an-ubuntu-docker-container + sudo docker exec "$CONTAINER" env LANG=C.UTF-8 sed -e "s#http://archive.ubuntu.com/ubuntu/#http://$UBUNTU_MIRROR/ubuntu/#g" -i /etc/apt/sources.list + fixme "Do not use bash in install.sh" + #sudo docker exec "$CONTAINER" bash -c "find /var/lib/apt/lists/ -maxdepth 1 -type f | xargs rm -f" + info "Updating docker's repositories for $VARIANT" + sudo docker exec "$CONTAINER" ci/travis-ci/retry.sh -t "$RETRY_MAXTRIALS" -p "$RETRY_PAUSE" -- "$APT_UPDATE" + + info "Installing dependencies for $VARIANT" + sudo docker exec "$CONTAINER" ci/travis-ci/retry.sh -t "$RETRY_MAXTRIALS" -p "$RETRY_PAUSE" -- "$APT_INSTALL" build-essential meson cppcheck libcap-dev clang libfuse3-dev gcc git ninja-build bison libtool autoconf pkg-config libcap-dev indent fakeroot libattr1-dev uthash-dev gzip rsync autopoint uthash-dev shellcheck ca-certificates || die "Unable to install all required dependencies" + + info "Fetching repository for $VARIANT" + sudo docker exec "$CONTAINER" git clone https://github.com/Kreyrock/Kreyrock.git + + # Exherbo + elif [ "$VARIANT" = exherbo ]; then + # Get paludis-config + sudo docker exec "$CONTAINER" [ -e /etc/paludis ] && rm -r /etc/paludis + sudo docker exec "$CONTAINER" git clone https://github.com/Kreyrock/paludis-config.git /etc/paludis + + # Sync repositories + sudo docker exec "$CONTAINER" cave resolve + + # Resolve required repositories + sudo docker exec "$CONTAINER" cave resolve -x1 repository/{alip,compnerd,virtualization,danyspin97,python,perl,hasufell} || die "Unable to resolve repositories for $TRAVIS_OS_NAME" + + # Resolve required dependencies + if [ "$COMPILER_C" = gcc ]; then + info "Using GCC variant for $TRAVIS_OS_NAME" + sudo docker exec "$CONTAINER" cave resolve sys-devel/meson dev-util/cppcheck sys-devel/gcc sys-fs/fuse dev-scm/git sys-devel/ninja sys-devel/bison sys-devel/libtool sys-devel/autoconf dev-util/pkg-config dev-util/indent sys-apps/fakeroot app-arch/gzip net-misc/rsync sys-devel/autoconf dev-util/shellcheck -x || die "Unable to resolve all dependencies for $TRAVIS_OS_NAME" + + elif [ "$COMPILER_C" = clang ]; then + info "Using Clang variant for $TRAVIS_OS_NAME" + sudo docker exec "$CONTAINER" cave resolve sys-devel/meson dev-util/cppcheck sys-devel/clang sys-fs/fuse dev-scm/git sys-devel/ninja sys-devel/bison sys-devel/libtool sys-devel/autoconf dev-util/pkg-config dev-util/indent sys-apps/fakeroot app-arch/gzip net-misc/rsync sys-devel/autoconf dev-util/shellcheck -x || die "Unable to resolve all dependencies for $TRAVIS_OS_NAME" + + else + die "Unexpected COMPILER_C has been parsed in exherbo variant - '$COMPILER_C'" + + fi + + # Remove build instructions to save space + sudo docker exec "$CONTAINER" [ -e /var/db/paludis ] && rm -r var/db/paludis + + else + die "Unexpected variant has been parsed in install.sh - '$VARIANT'" + + fi + +# MacOS X +elif [ "$TRAVIS_OS_NAME" = osx ]; then + # Homebrew takes lots of time on runtime due to the cleanup used, this is a hotfix (https://travis-ci.community/t/macosx-brew-update-takes-too-much-time/6295) + HOMEBREW_NO_INSTALL_CLEANUP=1 brew update || die "Unable to update brew" + + info "Installing dependencies" + brew install shellcheck cppcheck shfmt || die "Unable to install dependencies on $TRAVIS_OS_NAME" + +# FreeBSD via QEMU +elif [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$QEMU" = "FreeBSD" ]; then + if [ -n "$VARIANT" ]; then + # Install packages + # Ensure the file system is true (fuse-ufs2 in write mode is unreliable!) + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + "mount -fr / ; fsck -y /dev/gpt/rootfs ; mount -fw / ; df -h" + + # Basic dependencies: + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + env ASSUME_ALWAYS_YES=yes pkg update + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + env ASSUME_ALWAYS_YES=yes pkg install -y bash autoconf meson cppcheck fusefs-libs3 gcc git ninja bison libtool autoconf pkg-config indent fakeroot gzip rsync autopoint shellcheck + + # Bash shell: + # Use bash, and make sure it is available under /bin/bash. + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + chsh -s /usr/local/bin/bash + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + ln -s /usr/local/bin/bash /bin/bash || true + + # Ports collection: + # This is the slow method via portsnap: + # --- ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + # --- "portsnap --interactive fetch extract | grep -v ^/usr/ports" + # Using Git is much faster: + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + "rm -rf /usr/ports ; git clone --depth=1 --filter=tree:0 https://github.com/freebsd/freebsd-ports /usr/ports" + + # Package's dependencies: + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + "cd /travis/freebsd/*/ && ( make build-depends-list && make run-depends-list ) | sed -e 's/^.*\///g' -e 's/glib20/glib/g' | sort -u | xargs -r env ASSUME_ALWAYS_YES=yes pkg install -y" + + echo "===== The FreeBSD VM is ready! =====" + + elif [ -z "$VARIANT" ]; then + die "Variable VARIANT is not set for FreeBSD via QEMU which is fatal, This should be set in travis.yml" + + else + die "Unexpected in FreeBSD using QEMU" + + fi +else + die "Invalid setting of TRAVIS_OS_NAME=$TRAVIS_OS_NAME, DOCKER=$DOCKER, QEMU=$QEMU!" + +fi diff --git a/QA/travis-ci/retry.sh b/QA/travis-ci/retry.sh new file mode 100755 index 0000000..c199235 --- /dev/null +++ b/QA/travis-ci/retry.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later +# Based in part upon 'retry.sh' from rsplib (https://raw.githubusercontent.com/dreibh/rsplib/master/ci/retry), which is: +# Copyright (C) 2018-2019 by Thomas Dreibholz as GPLv3 or any other GPL at your option + +set -e + +. QA/travis-ci/travis-common.sh + +maxTrials=3 +pause=10 + +while [ $# -gt 1 ] ; do + case "$1" in + -t|--tries) + maxTrials="$2" + shift 2 + ;; + -p|--pause) + pause="$2" + shift 2 + ;; + --) + shift + break + ;; + *) + die "Usage: $0 [-t|--trials max_trials] [-p|--pause seconds] -- command ..." + esac +done + + +attempts=1 +result=1 +command="$*" +while [ "$result" -ne 0 ] && [ "$attempts" -le "$maxTrials" ]; do + if [ "$attempts" -gt 1 ]; then + printf '%s\n' "Sleeping ${pause}s ..." + sleep "$pause" + fi + info "Trying $attempts/$maxTrials: $command" + sh -c "$command" && result=$? || result=$? + if [ "$result" -eq 127 ]; then + # Command not found => no need for a retry! + exit "$result" + elif [ "$result" -ne 0 ]; then + # Attempt failed + attempts="$((attempts=attempts+1))" + fi +done + + +exit "$result" diff --git a/QA/travis-ci/test.sh b/QA/travis-ci/test.sh new file mode 100755 index 0000000..abbdfad --- /dev/null +++ b/QA/travis-ci/test.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2019 Jacob Hrbek +# Distributed under the terms of the GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) or later + +# shellcheck source=QA/travis-ci/travis-common.sh +. "$(dirname "$0")/travis-common.sh" + +# shellcheck source=QA/travis-ci/get-container.sh +. "$(dirname "$0")/get-container.sh" + +# Linux as-is +if [ "$TRAVIS_OS_NAME" = linux ] && [ -z "$DOCKER" ] && [ -z "$QEMU" ]; then + make check + +# Linux via Docker +elif [ "$TRAVIS_OS_NAME" = linux ] && [ -n "$DOCKER" ] && [ -z "$QEMU" ]; then + sudo docker exec "$CONTAINER" make --directory="/travis/Kreyrock" check + +# MacOS X +elif [ "$TRAVIS_OS_NAME" = osx ]; then + make --directory="/Users/travis/build/Kreyrock/Kreyrock" check + +elif [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$QEMU" = "FreeBSD" ]; then + ssh -p 8829 -oStrictHostKeyChecking=no -i "$HOME/.ssh/id_rsa" root@localhost \ + make check + +else + die "Invalid setting of TRAVIS_OS_NAME=$TRAVIS_OS_NAME, DOCKER=$DOCKER, QEMU=$QEMU!" + +fi diff --git a/QA/travis-ci/travis-common.sh b/QA/travis-ci/travis-common.sh new file mode 100755 index 0000000..f7e7ee5 --- /dev/null +++ b/QA/travis-ci/travis-common.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# Simplified error handling +die() { + printf 'FATAL: %s\n' "$*" + exit 1 +} +# Simplified QA handling +fixme() { + printf 'FIXME: %s/n' "$*" +} +# Simplified info messages +info() { + printf 'INFO: %s\n' "$*" +} +warn() { + printf 'WARN: %s\n' "$*" +} \ No newline at end of file diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..0b3ecd6 --- /dev/null +++ b/docker/README.md @@ -0,0 +1 @@ +Directory for various Dockerfiles \ No newline at end of file