github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/tini/ci/run_build.sh (about)

     1  #!/bin/bash
     2  # Should be run from the root dir, or SOURCE_DIR should be set.
     3  set -o errexit
     4  set -o nounset
     5  set -o pipefail
     6  
     7  # Default compiler
     8  : ${CC:="gcc"}
     9  
    10  
    11  # Paths
    12  : ${SOURCE_DIR:="."}
    13  : ${DIST_DIR:="${SOURCE_DIR}/dist"}
    14  : ${BUILD_DIR:="/tmp/build"}
    15  
    16  # GPG Configuration
    17  : ${GPG_PASSPHRASE:=""}
    18  
    19  
    20  # Make those paths absolute, and export them for the Python tests to consume.
    21  export SOURCE_DIR="$(readlink -f "${SOURCE_DIR}")"
    22  export DIST_DIR="$(readlink -f "${DIST_DIR}")"
    23  export BUILD_DIR="$(readlink -f "${BUILD_DIR}")"
    24  
    25  # Configuration
    26  : ${FORCE_SUBREAPER:="1"}
    27  export FORCE_SUBREAPER
    28  
    29  
    30  # Our build platform doesn't have those newer Linux flags, but we want Tini to have subreaper support
    31  # We also use those in our tests
    32  CFLAGS="${CFLAGS-} -DPR_SET_CHILD_SUBREAPER=36 -DPR_GET_CHILD_SUBREAPER=37"
    33  if [[ "${FORCE_SUBREAPER}" -eq 1 ]]; then
    34    # If FORCE_SUBREAPER is requested, then we set those CFLAGS for the Tini build
    35    export CFLAGS
    36  fi
    37  
    38  echo "CC=${CC}"
    39  echo "CFLAGS=${CFLAGS}"
    40  echo "MINIMAL=${MINIMAL-}"
    41  echo "ARCH_SUFFIX=${ARCH_SUFFIX-}"
    42  echo "ARCH_NATIVE=${ARCH_NATIVE-}"
    43  
    44  # Ensure Python output is not buffered (to make tests output clearer)
    45  export PYTHONUNBUFFERED=1
    46  
    47  # Set path to prioritize our utils
    48  export REAL_PATH="${PATH}"
    49  export PATH="${SOURCE_DIR}/ci/util:${PATH}"
    50  
    51  # Build
    52  CMAKE_ARGS=(-B"${BUILD_DIR}" -H"${SOURCE_DIR}")
    53  if [[ -n "${MINIMAL:-}" ]]; then
    54    CMAKE_ARGS+=(-DMINIMAL=ON)
    55  fi
    56  cmake "${CMAKE_ARGS[@]}"
    57  
    58  pushd "${BUILD_DIR}"
    59  make clean
    60  make
    61  if [[ -n "${ARCH_NATIVE-}" ]]; then
    62    make package
    63  fi
    64  popd
    65  
    66  pkg_version="$(cat "${BUILD_DIR}/VERSION")"
    67  
    68  if [[ -n "${ARCH_NATIVE-}" ]]; then
    69    echo "Built native package (ARCH_NATIVE=${ARCH_NATIVE-})"
    70    echo "Running smoke and internal tests"
    71  
    72    BIN_TEST_DIR="${BUILD_DIR}/bin-test"
    73    mkdir -p "$BIN_TEST_DIR"
    74    export PATH="${BIN_TEST_DIR}:${PATH}"
    75  
    76    # Smoke tests (actual tests need Docker to run; they don't run within the CI environment)
    77    for tini in "${BUILD_DIR}/tini" "${BUILD_DIR}/tini-static"; do
    78      echo "Smoke test for ${tini}"
    79      "$tini" --version
    80  
    81      echo "Testing ${tini} --version"
    82      "$tini" --version | grep -q "tini version"
    83  
    84      echo "Testing ${tini} without arguments exits with 1"
    85      ! "$tini" 2>/dev/null
    86  
    87      echo "Testing ${tini} shows help message"
    88      {
    89        ! "$tini" 2>&1
    90      } | grep -q "supervision of a valid init process"
    91  
    92      if [[ -n "${MINIMAL:-}" ]]; then
    93        echo "Testing $tini with: true"
    94        "${tini}" true
    95  
    96        echo "Testing $tini with: false"
    97        if "${tini}" false; then
    98          exit 1
    99        fi
   100  
   101        echo "Testing ${tini} does not reference options that don't exist"
   102        ! {
   103          ! "$tini" 2>&1
   104        } | grep -q "more verbose"
   105  
   106        # We try running binaries named after flags (both valid and invalid
   107        # flags) and test that they run.
   108        for flag in h s w x; do
   109          bin="-${flag}"
   110          echo "Testing $tini can run binary: ${bin}"
   111          cp "$(which true)" "${BIN_TEST_DIR}/${bin}"
   112          "$tini" "$bin"
   113        done
   114  
   115        echo "Testing $tini can run binary --version if args are given"
   116        cp "$(which true)" "${BIN_TEST_DIR}/--version"
   117        if "$tini" "--version" --foo | grep -q "tini version"; then
   118          exit 1
   119        fi
   120      else
   121        echo "Testing ${tini} -h"
   122        "${tini}" -h
   123  
   124        echo "Testing $tini for license"
   125        "$tini" -l | diff - "${SOURCE_DIR}/LICENSE"
   126  
   127        echo "Testing $tini with: true"
   128        "${tini}" -vvv true
   129  
   130        echo "Testing $tini with: false"
   131        if "${tini}" -vvv false; then
   132          exit 1
   133        fi
   134  
   135        echo "Testing ${tini} references options that exist"
   136        {
   137          ! "$tini" 2>&1
   138        } | grep -q "more verbose"
   139  
   140        echo "Testing $tini with: -- true (should succeed)"
   141        "${tini}" -vvv -- true
   142  
   143        echo "Testing $tini with: -- -- true (should fail)"
   144        if "${tini}" -vvv -- -- true; then
   145          exit 1
   146        fi
   147      fi
   148  
   149      echo "Testing ${tini} supports TINI_VERBOSITY"
   150      TINI_VERBOSITY=3 "$tini" true 2>&1 | grep -q 'Received SIGCHLD'
   151  
   152      echo "Testing ${tini} exits with 127 if the command does not exist"
   153      "$tini" foobar123 && rc="$?" || rc="$?"
   154      if [[ "$rc" != 127 ]]; then
   155        echo "Exit code was: ${rc}"
   156        exit 1
   157      fi
   158  
   159      echo "Testing ${tini} exits with 126 if the command is not executable"
   160      "$tini" /etc && rc="$?" || rc="$?"
   161      if [[ "$rc" != 126 ]]; then
   162        echo "Exit code was: ${rc}"
   163        exit 1
   164      fi
   165  
   166      # Test stdin / stdout are handed over to child
   167      echo "Testing ${tini} does not break pipes"
   168      echo "exit 0" | "${tini}" sh
   169      if [[ ! "$?" -eq "0" ]]; then
   170        echo "Pipe test failed"
   171        exit 1
   172      fi
   173  
   174      echo "Checking hardening on $tini"
   175      hardening_skip=(--nopie --nostackprotector --nobindnow)
   176      if [[ "$CC" == "musl-gcc" ]]; then
   177        # FORTIFY_SOURCE is a glibc thing
   178        hardening_skip=("${hardening_skip[@]}" --nofortify)
   179      fi
   180      hardening-check  "${hardening_skip[@]}" "${tini}"
   181    done
   182  
   183    # Quick package audit
   184    if which rpm >/dev/null; then
   185      echo "Contents for RPM:"
   186      rpm -qlp "${BUILD_DIR}/tini_${pkg_version}.rpm"
   187      echo "--"
   188    fi
   189  
   190    if which dpkg >/dev/null; then
   191      echo "Contents for DEB:"
   192      dpkg --contents "${BUILD_DIR}/tini_${pkg_version}.deb"
   193      echo "--"
   194    fi
   195  
   196    # Compile test code
   197    "${CC}" -o "${BUILD_DIR}/sigconf-test" "${SOURCE_DIR}/test/sigconf/sigconf-test.c"
   198  
   199    # Create virtual environment to run tests.
   200    # Accept system site packages for faster local builds.
   201    VENV="${BUILD_DIR}/venv"
   202    virtualenv --system-site-packages "${VENV}"
   203  
   204    # Don't use activate because it does not play nice with nounset
   205    export PATH="${VENV}/bin:${PATH}"
   206    export CFLAGS  # We need them to build our test suite, regardless of FORCE_SUBREAPER
   207  
   208    # Install test dependencies
   209    CC=gcc python3 -m pip install psutil python-prctl bitmap
   210  
   211    # Run tests
   212    python3 "${SOURCE_DIR}/test/run_inner_tests.py"
   213  else
   214    echo "Not a native build, skipping smoke and internal tests"
   215  fi
   216  
   217  # Now, copy over files to DIST_DIR, with appropriate names depending on the
   218  # architecture.
   219  # Handle the DEB / RPM
   220  mkdir -p "${DIST_DIR}"
   221  
   222  DIST_TINIS=()
   223  
   224  SUFFIX=""
   225  if [[ -n "$ARCH_SUFFIX" ]]; then
   226    SUFFIX="-${ARCH_SUFFIX}"
   227  elif [[ -z "$ARCH_NATIVE" ]]; then
   228    echo "Refusing to publish a non-native build without suffix!"
   229    exit 1
   230  fi
   231  
   232  for build_tini in tini tini-static; do
   233    dist_tini="${build_tini}${SUFFIX}"
   234    cp "${BUILD_DIR}/${build_tini}" "${DIST_DIR}/${dist_tini}"
   235    DIST_TINIS+=("$dist_tini")
   236  done
   237  
   238  if [[ -n "${ARCH_NATIVE-}" ]]; then
   239    for pkg_format in deb rpm; do
   240      build_tini="tini_${pkg_version}.${pkg_format}"
   241      dist_tini="tini_${pkg_version}${SUFFIX}.${pkg_format}"
   242      cp "${BUILD_DIR}/${build_tini}" "${DIST_DIR}/${dist_tini}"
   243      DIST_TINIS+=("$dist_tini")
   244    done
   245  fi
   246  
   247  echo "Tinis: ${DIST_TINIS[*]}"
   248  
   249  pushd "$DIST_DIR"
   250  
   251  for tini in "${DIST_TINIS[@]}"; do
   252    echo "${tini}:"
   253  
   254    for sum in sha1sum sha256sum; do
   255      "$sum" "$tini" | tee "${tini}.${sum}"
   256    done
   257  
   258    file "$tini"
   259    echo "--"
   260  done
   261  
   262  # If a signing key and passphrase are made available, then use it to sign the
   263  # binaries
   264  if [[ -n "$GPG_PASSPHRASE" ]] && [[ -f "${SOURCE_DIR}/sign.key" ]]; then
   265    echo "Signing tinis"
   266    GPG_SIGN_HOMEDIR="${BUILD_DIR}/gpg-sign"
   267    GPG_VERIFY_HOMEDIR="${BUILD_DIR}/gpg-verify"
   268    PGP_KEY_FINGERPRINT="595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7"
   269    PGP_KEYSERVER="ha.pool.sks-keyservers.net"
   270  
   271    mkdir "${GPG_SIGN_HOMEDIR}" "${GPG_VERIFY_HOMEDIR}"
   272    chmod 700 "${GPG_SIGN_HOMEDIR}" "${GPG_VERIFY_HOMEDIR}"
   273  
   274    gpg --homedir "${GPG_SIGN_HOMEDIR}" --import "${SOURCE_DIR}/sign.key"
   275    gpg --homedir "${GPG_VERIFY_HOMEDIR}" --keyserver "$PGP_KEYSERVER" --recv-keys "$PGP_KEY_FINGERPRINT"
   276  
   277    for tini in "${DIST_TINIS[@]}"; do
   278      echo "${GPG_PASSPHRASE}" | gpg --homedir "${GPG_SIGN_HOMEDIR}" --passphrase-fd 0 --armor --detach-sign "${tini}"
   279      gpg --homedir "${GPG_VERIFY_HOMEDIR}" --verify "${tini}.asc"
   280    done
   281  fi
   282  
   283  popd