github.com/StackExchange/blackbox/v2@v2.0.1-0.20220331193400-d84e904973ab/tools/mk_rpm_fpmdir (about)

     1  #! /usr/bin/env bash
     2  
     3  # Use fpm to package up files into an RPM.
     4  
     5  # Usage:
     6  #   mk_rpm_fpmdir PACKAGENAME MANIFEST1 MANIFEST2 ...
     7  
     8  # Example:
     9  #   Make a package foopkg manifest.txt
    10  # Where "manifest.txt" contains:
    11  #   exec /usr/bin/stack_makefqdn  misc/stack_makefqdn.py
    12  #   exec /usr/bin/bar             bar/bar.sh
    13  #   read /usr/man/man1/bar.1      bar/bar.1.man
    14  #   0444 /etc/foo.conf            bar/foo.conf
    15  
    16  set -e
    17  
    18  # Parameters for this RPM:
    19  PACKAGENAME=${1?"First arg must be the package name."}
    20  shift
    21  
    22  # What is my name?
    23  CMDNAME=$(basename $0)
    24  
    25  # Defaults that can be overridden:
    26  # Packages are 1.0 unless otherwise specifed:
    27  : ${PKGVERSION:=1.0} ;
    28  # If there is no iteration set, default to use the number of commits in the repository:
    29  if [[ -z "${PKGRELEASE}" ]]; then
    30    PKGRELEASE=$(git rev-list HEAD --count)
    31    if [[ $? != 0 ]]; then
    32      # We're not in a git repo, fall back to 1 so we cope with being built from
    33      # a tarball
    34      PKGRELEASE=1
    35    fi
    36  fi
    37  
    38  # If there is no epoch, assume 0
    39  : ${PKGEPOCH:=0}
    40  
    41  # If no arch defined, assume any. Other good values include "native".
    42  : ${PKGARCH:=all}
    43  # NOTE: If we later compile code, we set this to "native", which
    44  # FPM will translate to the correct value for local conditions.
    45  
    46  # Allow us to set a different OUTPUTDIR if we're building in CI/CD
    47  if [[ -z "${OUTPUTDIR}" ]]; then
    48    # The RPM is output here: (should be a place that can be wiped)
    49    OUTPUTDIR="${HOME}/rpmbuild-${PACKAGENAME}"
    50  else
    51    echo "Using ${OUTPUTDIR} for OUTPUTDIR instead of ${HOME}/rpmbuild-${PACKAGENAME}"
    52  fi
    53  INSTALLROOT="$OUTPUTDIR/installroot"
    54  
    55  # StackOverflow's TeamCity templates expect to find the list of artifacts here:
    56  RPM_BIN_LIST="${OUTPUTDIR}/bin-packages.txt"
    57  
    58  # -- Now the real work can be done.
    59  
    60  # Clean the output dir.
    61  rm -rf "$OUTPUTDIR"
    62  mkdir -p "$INSTALLROOT"
    63  
    64  # If there is a build script, execute it.
    65  BUILDSCRIPTNAME="./build.${PACKAGENAME}.sh"
    66  if [[ -x $BUILDSCRIPTNAME ]]; then
    67    echo "========== $BUILDSCRIPTNAME FOUND. Running."
    68    if [[ $PKGARCH == "all" ]]; then
    69      echo 'WARNING: PKGARCH=all (which may not what you want)'
    70      # If you are using a build.*.sh script, you probably want to
    71      # set PKGARCH to "native" before you run mk_rpm_fpmdir.
    72    fi
    73    $BUILDSCRIPTNAME "$INSTALLROOT" "${PKGVERSION}"
    74    # If we used the build build.*.sh script, it must do all compilation.
    75    # Therefore, we disable the automagic GO build feature.
    76    GO_COMPILE=false
    77  else
    78    GO_COMPILE=true
    79  fi
    80  
    81  # If there are additional args for fpm, read them into a variable.  There is
    82  # a chdir later, therefore we can't rely on the file path working at that time.
    83  FPM_OPTIONS_FILE="./fpm_opts.${PACKAGENAME}.sh"
    84  if [[ -f $FPM_OPTIONS_FILE ]]; then
    85    echo "========== $FPM_OPTIONS_FILE FOUND. Loading."
    86    FPM_OPTIONS=$(<$FPM_OPTIONS_FILE)
    87  fi
    88  # Warning: The contents of the file are evaluated therefore
    89  # quotes and special chars must be quoted.
    90  
    91  # Copy any static files into place:
    92  set -o pipefail  # Error out if any manifest is not found.
    93  cat "$@" | while read -a arr ; do
    94    PERM="${arr[0]}"
    95    case $PERM in
    96      \#*)  continue ;;   # Skip comments.
    97      exec) PERM=0755 ;;
    98      read) PERM=0744 ;;
    99      *) ;;
   100    esac
   101    DST="$INSTALLROOT/${arr[1]}"
   102    SRC="${arr[2]}"
   103    if [[ ${#arr[@]} != 3 ]] ; then
   104      echo "ERROR: Line must contain 3 items."
   105      echo "DEBUG NUM=${#arr[@]} PERM=$PERM DST=$DST SRC=$SRC"
   106      exit 1
   107    fi
   108    if $GO_COMPILE && [[ $SRC == "cmd/"* || $SRC == *"/cmd/"* ]]; then
   109      echo "========== BUILD&COPY $SRC"
   110      ( cd $(dirname "$SRC" ) && go get -d && go build ) 
   111      PKGARCH=native
   112    else
   113      echo "==========       COPY $SRC"
   114    fi
   115    if [[ ! -f "$SRC" ]]; then
   116      echo "${CMDNAME}: ERROR: File not found: $SRC"
   117      exit 1
   118    fi
   119    install -D -T -b -m "$PERM" -T "$SRC" "$DST"
   120  done
   121  
   122  set -x
   123  # Build the RPM out of what is found in $INSTALLROOT:
   124  cd "$OUTPUTDIR" && fpm -s dir -t rpm \
   125    -a "${PKGARCH}" \
   126    -n "${PACKAGENAME}" \
   127    --epoch "${PKGEPOCH}" \
   128    --version "${PKGVERSION}" \
   129    --iteration "${PKGRELEASE}" \
   130    ${PKGDESCRIPTION:+ --description="${PKGDESCRIPTION}"} \
   131    ${PKGVENDOR:+ --vendor="${PKGVENDOR}"} \
   132    ${FPM_OPTIONS:+ $FPM_OPTIONS} \
   133    -C "$INSTALLROOT" \
   134    .
   135  
   136  # TeamCity templates for RPMS expect to find
   137  # the list of all packages created in bin-packages.txt.
   138  # Generate that list:
   139  find "$OUTPUTDIR" -maxdepth 1 -name '*.rpm' >"$RPM_BIN_LIST"
   140  # Output it for debugging purposes:
   141  cat "$RPM_BIN_LIST"