diff options
Diffstat (limited to 'tools')
| -rwxr-xr-x | tools/build-debian-package.sh | 72 | ||||
| -rwxr-xr-x | tools/generate_support_bundle.py | 186 | ||||
| -rwxr-xr-x | tools/tarsource.sh | 336 |
3 files changed, 139 insertions, 455 deletions
diff --git a/tools/build-debian-package.sh b/tools/build-debian-package.sh index d21f468bf5..3c922c355c 100755 --- a/tools/build-debian-package.sh +++ b/tools/build-debian-package.sh @@ -1,27 +1,75 @@ #!/bin/sh # # Written by Daniil Baturin, 2018 +# Rewritten by Ondřej Surý, 2020 # This file is public domain set -e -cd "`dirname $0`" -cd .. +cd "$(dirname "$0")/.." -if [ "`id -u`" = 0 ]; then +# +# Checking requirements +# + +if [ "$(id -u)" = 0 ]; then echo "Running as root - installing dependencies" - apt-get install fakeroot debhelper devscripts + apt-get install fakeroot debhelper devscripts git-buildpackage lsb-release mk-build-deps --install debian/control exit 0 fi git diff-index --quiet HEAD || echo "Warning: git working directory is not clean!" -echo "Preparing the build" -tools/tarsource.sh -V +############################ +# Build the Debian package # +############################ -echo "Building the Debian package" -if test $# -eq 0; then - dpkg-buildpackage -b -uc -us -else - dpkg-buildpackage "$@" -fi +# +# Now we will construct an "upstream" version out of: +# 1. version in AC_INIT +# 2. the unix time from the last commit (HEAD) +# (alternatively %Y%m%d%H%M%S could be used here) +# 4. Debian version (always -1) +# + +UPSTREAM_VERSION=$(sed -ne 's/AC_INIT(\[frr\],\s\[\([^]]*\)\],.*/\1/p' configure.ac | sed -e 's/-\(\(dev\|alpha\|beta\)\d*\)/~\1/') +LAST_TIMESTAMP=$(git log --format=format:%ad --date=format:%s -1 "HEAD") +DEBIAN_VERSION="$UPSTREAM_VERSION-$LAST_TIMESTAMP-1" +DEBIAN_BRANCH=$(git rev-parse --abbrev-ref HEAD) + +# +# We add a Debian changelog entry, and use artifical "since commit" +# so there's not a whole git history in the debian/changelog. +# +# The --snapshot option appends ~1.<shorthash> to the debian version, so for the +# release build, this needs to be replaces with --release +# + +echo "Adding new snapshot debian/changelog entry for $DEBIAN_VERSION..." + +gbp dch \ + --debian-branch="$DEBIAN_BRANCH" \ + --new-version="$DEBIAN_VERSION" \ + --dch-opt="--force-bad-version" \ + --since="HEAD~" \ + --snapshot \ + --commit \ + --git-author + +echo "Building package..." + +# +# git-buildpackage will use $BUILDER command to just build new binary package +# + +BUILDER="dpkg-buildpackage -uc -us --build=binary --no-check-builddeps --no-pre-clean -sa" +UPSTREAM_COMPRESSION=xz + +gbp buildpackage \ + --git-export-dir="$WORKDIR" \ + --git-builder="$BUILDER" \ + --git-debian-branch="$DEBIAN_BRANCH" \ + --git-force-create \ + --git-compression=$UPSTREAM_COMPRESSION \ + --git-no-pristine-tar \ + --git-ignore-new diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py index 38fdbd46df..56b2872d1e 100755 --- a/tools/generate_support_bundle.py +++ b/tools/generate_support_bundle.py @@ -1,117 +1,89 @@ #!/usr/bin/env python3 +# +# Copyright (c) 2021, LabN Consulting, L.L.C. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; see the file COPYING; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# ######################################################## ### Python Script to generate the FRR support bundle ### ######################################################## +import argparse +import logging import os import subprocess -import datetime - -ETC_DIR = "/etc/frr/" -LOG_DIR = "/var/log/frr/" -SUCCESS = 1 -FAIL = 0 - -inputFile = ETC_DIR + "support_bundle_commands.conf" - -# Create the output file name -def createOutputFile(procName): - fileName = procName + "_support_bundle.log" - oldFile = LOG_DIR + fileName - cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev" - rmFileCmd = "rm -rf " + oldFile - print("Making backup of " + oldFile) - os.system(cpFileCmd) - print("Removing " + oldFile) - os.system(rmFileCmd) - return fileName - - -# Open the output file for this process -def openOutputFile(fileName): - crt_file_cmd = LOG_DIR + fileName - print(crt_file_cmd) - try: - outputFile = open(crt_file_cmd, "w") - return outputFile - except IOError: - return () - - -# Close the output file for this process -def closeOutputFile(f): - try: - f.close() - return SUCCESS - except IOError: - return FAIL - - -# Execute the command over vtysh and store in the -# output file -def executeCommand(cmd, outputFile): - cmd_exec_str = 'vtysh -c "' + cmd + '" ' +import tempfile + +def open_with_backup(path): + if os.path.exists(path): + print("Making backup of " + path) + subprocess.check_call("mv {0} {0}.prev".format(path)) + return open(path, "w") + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-c", "--config", default="/etc/frr/support_bundle_commands.conf", help="input config") + parser.add_argument("-l", "--log-dir", default="/var/log/frr", help="directory for logfiles") + args = parser.parse_args() + + collecting = False # file format has sentinels (seem superfluous) + proc_cmds = {} + proc = None + temp = None + + # Collect all the commands for each daemon try: - cmd_output = subprocess.check_output(cmd_exec_str, shell=True) - try: - dateTime = datetime.datetime.now() - outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n") - outputFile.write(str(cmd_output)) - outputFile.write( - "########################################################\n" - ) - outputFile.write("\n") - except Exception as e: - print("Writing to output file Failed: ", e) - except subprocess.CalledProcessError as e: - dateTime = datetime.datetime.now() - outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n") - outputFile.write(e.output) - outputFile.write("########################################################\n") - outputFile.write("\n") - print("Error:" + e.output) - - -# Process the support bundle configuration file -# and call appropriate functions -def processConfFile(): - - lines = list() - outputFile = None - - try: - with open(inputFile, "r") as supportBundleConfFile: - for l in supportBundleConfFile: - lines.append(l.rstrip()) - except IOError: - print("conf file {} not present".format(inputFile)) - return - - for line in lines: - if len(line) == 0 or line[0] == "#": - continue - - cmd_line = line.split(":") - if cmd_line[0] == "PROC_NAME": - outputFileName = createOutputFile(cmd_line[1]) - if outputFileName: - print(outputFileName, "created for", cmd_line[1]) - elif cmd_line[0] == "CMD_LIST_START": - outputFile = openOutputFile(outputFileName) - if outputFile: - print(outputFileName, "opened") - else: - print(outputFileName, "open failed") - return FAIL - elif cmd_line[0] == "CMD_LIST_END": - if closeOutputFile(outputFile): - print(outputFileName, "closed") + for line in open(args.config): + line = line.rstrip() + if len(line) == 0 or line[0] == "#": + continue + + cmd_line = line.split(":") + if cmd_line[0] == "PROC_NAME": + proc = cmd_line[1] + temp = tempfile.NamedTemporaryFile("w+") + collecting = False + elif cmd_line[0] == "CMD_LIST_START": + collecting = True + elif cmd_line[0] == "CMD_LIST_END": + collecting = False + temp.flush() + proc_cmds[proc] = open(temp.name) + temp.close() + elif collecting: + temp.write(line + "\n") else: - print(outputFileName, "close failed") - else: - print("Execute:", cmd_line[0]) - executeCommand(cmd_line[0], outputFile) - + print("Ignoring unexpected input " + line.rstrip()) + except IOError as error: + logging.fatal("Cannot read config file: %s: %s", args.config, str(error)) + return -# Main Function -processConfFile() + # Spawn a vtysh to fetch each set of commands + procs = [] + for proc in proc_cmds: + ofn = os.path.join(args.log_dir, proc + "_support_bundle.log") + p = subprocess.Popen( + ["/usr/bin/env", "vtysh", "-t"], + stdin=proc_cmds[proc], + stdout=open_with_backup(ofn), + stderr=subprocess.STDOUT, + ) + procs.append(p) + + for p in procs: + p.wait() + +if __name__ == "__main__": + main() diff --git a/tools/tarsource.sh b/tools/tarsource.sh deleted file mode 100755 index 4843fe88b0..0000000000 --- a/tools/tarsource.sh +++ /dev/null @@ -1,336 +0,0 @@ -#!/bin/bash -# 2018 by David Lamparter, placed in the Public Domain - -help() { - cat <<EOF -FRR tarball/dsc helper, intended to run from a git checkout - -Usage: - ./tarsource.sh [-dDn] [-i GITPATH] [-o OUTDIR] [-S KEYID] - [-C COMMIT] [-e EXTRAVERSION] [-z gz|xz] - -options: - -i GITPATH path to git working tree or bare repository. - - default: parent directory containing this script - -o OUTDIR path to place the generated output files in. - - default: current directory - -C COMMIT build tarball for specified git commit - - default: current HEAD - -e EXTRAVERSION override automatic package extraversion - - default "-YYYYMMDD-NN-gGGGGGGGGGGGG", but the script - autodetects if a release tag is checked out - -z gz|xz compression format to use - - default: xz - -S KEYID sign the output with gpg key - -d use dirty git tree with local changes - -D generate Debian .dsc and .debian.tar.xz too - (note: output files are moved to parent directory) - -l remove Debian auto-build changelog entry - (always done for releases) - -V write version information to config.version and exit - -n allow executing from non-git source (NOT RECOMMENDED) - -h show this help text - -Note(1) that this script tries very hard to generate a deterministic, -reproducible tarball by eliminating timestamps and similar things. However, -since the tarball includes autoconf/automake files, the versions of these -tools need to be _exactly_ identical to get the same tarball. - -Note(2) the debian ".orig" tarball is always identical to the "plain" tarball -generated without the -D option. - -Note(3) if you want the tool to identify github PRs, you need to edit your -.git/config to fetch PRs from github like this: - - [remote "origin"] - url = git@github.com:frrouting/frr.git - fetch = +refs/heads/*:refs/remotes/origin/* -ADD: fetch = +refs/pull/*/head:refs/remotes/origin/pull/* -EOF -} - -set -e - -options=`getopt -o 'hi:o:C:S:e:z:DdnlV' -l help -- "$@"` -debian=false -dirty=false -nongit=false -zip=xz -adjchangelog=false -writeversion=false -extraset=false -set - $options -while test $# -gt 0; do - arg="$1"; shift; optarg=$1 - case "$arg" in - -h|--help) help; exit 0;; - -d) dirty=true;; - -D) debian=true;; - -n) nongit=true;; - -i) eval src=$optarg; shift;; - -C) eval commit=$optarg; shift;; - -o) eval outdir=$optarg; shift;; - -e) eval extraver=$optarg; extraset=true; shift;; - -z) eval zip=$optarg; shift;; - -S) eval keyid=$optarg; shift;; - -l) adjchangelog=true;; - -V) writeversion=true;; - --) break;; - *) echo something went wrong with getopt >&2 - exit 1 - ;; - esac -done - -cwd="`pwd`" -outdir="${outdir:-$cwd}" - -if test -e "$outdir" -a \! -d "$outdir"; then - echo "output $outdir must be a directory" >&2 - exit 1 -elif test \! -d "$outdir"; then - mkdir -p "$outdir" -fi - -cd "$outdir" -outdir="`pwd`" -cd "$cwd" -cd "`dirname $0`/.." -selfdir="`pwd`" -src="${src:-$selfdir}" - -if $writeversion; then - if $nongit; then - echo "The -V option cannot be used without a git tree" >&2 - exit 1 - fi - dirty=true -fi - -case "$zip" in -gz) ziptarget=dist-gzip; ziptool="gzip -n -9"; unzip="gzip -k -c";; -xz) ziptarget=dist-xz; ziptool="xz -z -e"; unzip="xz -d -k -c";; -*) echo "unknown compression format $zip" >&2 - exit 1 -esac - -# always overwrite file ownership in tars -taropt="--owner=root --group=root" - -onexit() { - rv="$?" - set +e - test -n "$tmpdir" -a -d "$tmpdir" && rm -rf "$tmpdir" - - if test "$rv" -ne 0; then - echo -e "\n\033[31;1mfailed\n" >&2 - if test "$dirty" = true; then - echo please try running the script without the -d option.>&2 - fi - fi - exit $rv -} -trap onexit EXIT -tmpdir="`mktemp -d -t frrtar.XXXXXX`" - -if test -e "$src/.git"; then - commit="`git -C \"$src\" rev-parse \"${commit:-HEAD}\"`" - - if $dirty; then - cd "$src" - echo -e "\033[31;1mgit: using dirty worktree in $src\033[m" >&2 - else - echo -e "\033[33;1mgit: preparing a clean clone of $src\033[m" - branch="${tmpdir##*/}" - cd "$tmpdir" - - git -C "$src" branch "$branch" "$commit" - git clone --single-branch -s -b "$branch" "$src" source - git -C "$src" branch -D "$branch" - cd source - fi - - # if we're creating a tarball from git, force the timestamps inside - # the tar to match the commit date - this makes the tarball itself - # reproducible - gitts="`TZ=UTC git show -s --format=%cd --date=local $commit`" - gitts="`TZ=UTC date -d "$gitts" '+%Y-%m-%dT%H:%M:%SZ'`" - taropt="--mtime=$gitts $taropt" - - # check if we're on a release tag - gittag="`git -C \"$src\" describe --tags --match 'frr-*' --first-parent --long $commit`" - gittag="${gittag%-g*}" - gittag="${gittag%-*}" - - # if there have been changes to packaging or tests, it's still the - # same release - changes="`git diff --name-only "$gittag" $commit | \ - egrep -v '\.git|^m4/|^config|^README|^alpine/|^debian/|^pkgsrc/|^ports/|^redhat/|^snapcraft/|^solaris/|^tests/|^tools/|^gdb/|^docker/|^\.' | \ - wc -l`" - if test "$changes" -eq 0; then - adjchangelog=true - echo "detected release build for tag $gittag" >&2 - $extraset || extraver="" - elif ! $adjchangelog; then - gitdate="`TZ=UTC date -d "$gitts" '+%Y%m%d'`" - gitrev="`git rev-parse --short $commit`" - dayseq="`git rev-list --since \"${gitts%T*} 00:00:00 +0000\" $commit | wc -l`" - dayseq="`printf '%02d' $(( $dayseq - 1 ))`" - - $extraset || extraver="-$gitdate-$dayseq-g$gitrev" - - git -C "$src" remote -v | grep fetch | sed -e 's% (fetch)$%%' \ - | egrep -i '\b(git@github\.com:frrouting/frr\.git|https://github\.com/FRRouting/frr\.git)$' \ - | while read remote; do - remote="${remote%% *}" - - git -C "$src" var -l | egrep "^remote.$remote.fetch=" \ - | while read fetch; do - fetch="${fetch#*=}" - from="${fetch%:*}" - to="${fetch#*:}" - if test "$from" = "+refs/pull/*/head"; then - name="`git -C \"$src\" name-rev --name-only --refs \"$to\" $commit`" - test "$name" = "undefined" && continue - realname="${name%~*}" - realname="${realname%%^*}" - realname="${realname%%@*}" - if test "$realname" = "$name"; then - echo "${name##*/}" > "$tmpdir/.gitpr" - break - fi - fi - done || true - test -n "$gitpr" && break - done || true - test $extraset = false -a -f "$tmpdir/.gitpr" && extraver="-PR`cat \"$tmpdir/.gitpr\"`$extraver" - fi - - debsrc="git ls-files debian/" -else - if $nongit; then - echo -e "\033[31;1mWARNING: this script should be executed from a git tree\033[m" >&2 - else - echo -e "\033[31;1mERROR: this script should be executed from a git tree\033[m" >&2 - exit 1 - fi - debsrc="echo debian" -fi - -if $writeversion; then - pkgver="`egrep ^AC_INIT configure.ac`" - pkgver="${pkgver#*,}" - pkgver="${pkgver%,*}" - pkgver="`echo $pkgver`" # strip whitespace - pkgver="${pkgver#[}" - pkgver="${pkgver%]}" - - echo -e "\033[32;1mwriting version ID \033[36;1mfrr-$pkgver$extraver\033[m" - - cat > config.version <<EOF -# config.version override by tarsource.sh -EXTRAVERSION="$extraver" -DIST_PACKAGE_VERSION="$pkgver$extraver" -gitts="$gitts" -taropt="$taropt" -EOF - sed -e "s%@VERSION@%$pkgver$extraver%" \ - < changelog-auto.in \ - > changelog-auto - exit 0 -fi - -echo -e "\033[33;1mpreparing source tree\033[m" - -# config.version will also overwrite gitts and taropt when tarsource.sh -# was used to write the config.version file before - but configure will -# overwrite config.version down below! -if test -f config.version; then - # never executed for clean git build - . ./config.version - if $nongit; then - $extraset || extraver="$EXTRAVERSION" - fi -fi -if test \! -f configure; then - # always executed for clean git build - ./bootstrap.sh -fi -if test "$EXTRAVERSION" != "$extraver" -o \! -f config.status; then - # always executed for clean git build - # options don't matter really - we just want to make a dist tarball - ./configure --with-pkg-extra-version=$extraver -fi - -. ./config.version -PACKAGE_VERSION="$DIST_PACKAGE_VERSION" - -echo -e "\033[33;1mpacking up \033[36;1mfrr-$PACKAGE_VERSION\033[m" - -make GZIP_ENV="-n9" am__tar="tar -chof - $taropt \"\$\$tardir\"" $ziptarget -mv frr-${PACKAGE_VERSION}.tar.$zip "$outdir" || true -lsfiles="frr-${PACKAGE_VERSION}.tar.$zip" - -if $debian; then - mkdir -p "$tmpdir/debian/source" - cat debian/changelog > "$tmpdir/debian/changelog" - if $adjchangelog; then - if grep -q 'autoconf changelog entry' debian/changelog; then - tail -n +9 debian/changelog > "$tmpdir/debian/changelog" - fi - fi - echo '3.0 (quilt)' > "$tmpdir/debian/source/format" - DEBVER="`dpkg-parsechangelog -l\"$tmpdir/debian/changelog\" -SVersion`" - - eval $debsrc | tar -cho $taropt \ - --exclude-vcs --exclude debian/source/format \ - --exclude debian/changelog \ - --exclude debian/changelog-auto \ - --exclude debian/changelog-auto.in \ - --exclude debian/subdir.am \ - -T - -f ../frr_${DEBVER}.debian.tar - # add specially prepared files from above - tar -uf ../frr_${DEBVER}.debian.tar $taropt -C "$tmpdir" debian/source/format debian/changelog - - test -f ../frr_${DEBVER}.debian.tar.$zip && rm -f ../frr_${DEBVER}.debian.tar.$zip - $ziptool ../frr_${DEBVER}.debian.tar - - # pack up debian files proper - ln -s "$outdir/frr-${PACKAGE_VERSION}.tar.$zip" ../frr_${PACKAGE_VERSION}.orig.tar.$zip - dpkg-source -l"$tmpdir/debian/changelog" \ - --format='3.0 (custom)' --target-format='3.0 (quilt)' \ - -b . frr_${PACKAGE_VERSION}.orig.tar.$zip frr_${DEBVER}.debian.tar.$zip - - dpkg-genchanges -sa -S > ../frr_${DEBVER}_source.changes - - test -n "$keyid" && debsign ../frr_${DEBVER}_source.changes -k"$keyid" - - mv ../frr_${DEBVER}_source.changes "$outdir" || true - mv ../frr_${DEBVER}.dsc "$outdir" || true - mv ../frr_${DEBVER}.debian.tar.$zip "$outdir" || true - if test -h ../frr_${PACKAGE_VERSION}.orig.tar.$zip; then - rm ../frr_${PACKAGE_VERSION}.orig.tar.$zip || true - fi - ln -s frr-${PACKAGE_VERSION}.tar.$zip "$outdir/frr_${PACKAGE_VERSION}.orig.tar.$zip" || true - - cd "$outdir" - - lsfiles="$lsfiles \ - frr_${DEBVER}.dsc \ - frr_${DEBVER}.debian.tar.$zip \ - frr_${PACKAGE_VERSION}.orig.tar.$zip \ - frr_${DEBVER}_source.changes" -fi - -cd "$outdir" -if test -n "$keyid"; then - $unzip frr-${PACKAGE_VERSION}.tar.$zip > frr-${PACKAGE_VERSION}.tar - test -f frr-${PACKAGE_VERSION}.tar.asc && rm frr-${PACKAGE_VERSION}.tar.asc - if gpg -a --detach-sign -u "$keyid" frr-${PACKAGE_VERSION}.tar; then - lsfiles="$lsfiles frr-${PACKAGE_VERSION}.tar.asc" - fi - rm frr-${PACKAGE_VERSION}.tar -fi - -echo -e "\n\033[32;1mdone: \033[36;1mfrr-$PACKAGE_VERSION\033[m\n" -ls -l $lsfiles |
