2020-12-30 17:56:41 +08:00
# vim: set filetype=sh ts=4 sw=4 sts=4 et:
# shellcheck shell=bash
# common parts of install-ttyrec.sh and install-yubico-piv-checker.sh
# shellcheck source=lib/shell/functions.inc disable=SC2128
. " $ (dirname " $BASH_SOURCE " ) " / functions . inc
install_usage () {
cat << EOF
Options :
- s Download and install precompiled $PROGRAM_NAME static binaries in / usr / local / bin
- d Download the prebuilt Debian package , and install it ( for Debian , Ubuntu and derivatives )
- r Download the prebuild RPM package , and install it ( for RHEL , CentOS and derivatives )
- a Automatically detect the OS to install the proper package type , fallback to static binaries if no package applies
- h Show this help
EOF
}
set_download_url () {
2021-12-27 21:43:35 +08:00
local pattern = " $ 1 "
local verbosity = " "
2020-12-30 17:56:41 +08:00
action_doing " Looking for download tool... "
if command - v wget >/ dev / null ; then
action_done wget
2021-12-27 21:43:35 +08:00
verbosity = " -q "
[ " $CI " = true ] && verbosity = " -v "
2020-12-30 17:56:41 +08:00
_apicall () {
2021-12-27 21:43:35 +08:00
wget $verbosity - O - -- header = " Accept: application/vnd.github.v3+json " " $ 1 " || true
2020-12-30 17:56:41 +08:00
}
_download () {
2021-12-27 21:43:35 +08:00
wget $verbosity " $ 1 "
2020-12-30 17:56:41 +08:00
}
elif command - v fetch >/ dev / null ; then
action_done fetch
2021-12-27 21:43:35 +08:00
[ " $CI " = true ] && verbosity = " -v "
2020-12-30 17:56:41 +08:00
_apicall () {
2021-12-27 21:43:35 +08:00
fetch $verbosity - o - " $ 1 " || true
2020-12-30 17:56:41 +08:00
}
_download () {
2021-12-27 21:43:35 +08:00
fetch $verbosity " $ 1 "
2020-12-30 17:56:41 +08:00
}
2021-06-02 23:36:58 +08:00
elif command - v curl >/ dev / null ; then
action_done curl
2021-12-27 21:43:35 +08:00
verbosity = " -s "
[ " $CI " = true ] && verbosity = " -v "
2021-06-02 23:36:58 +08:00
_apicall () {
2021-12-27 21:43:35 +08:00
curl $verbosity - L - H 'Accept: application/vnd.github.v3+json' " $ 1 " || true
2021-06-02 23:36:58 +08:00
}
_download () {
2021-12-27 21:43:35 +08:00
curl $verbosity - L - O " $ 1 "
2021-06-02 23:36:58 +08:00
}
2020-12-30 17:56:41 +08:00
else
action_error " Couldn't find wget, curl nor fetch "
exit 1
fi
action_doing " Getting latest release for arch $arch ... "
payload = $ ( mktemp )
# shellcheck disable=SC2064
trap " rm -f $payload " EXIT
2021-12-22 21:56:05 +08:00
# shellcheck disable=SC2034
for try in 1 2 ; do
if [ " $USE_DEFAULT_URLS " = 1 ]; then
urls = " $ (default_urls) "
2021-03-19 23:28:32 +08:00
else
2021-12-22 21:56:05 +08:00
_apicall " $RELEASE_API_URL " > " $payload "
if [ ! - s " $payload " ]; then
action_error " API returned an empty body, did we hit the query limit? Auto-retrying with hardcoded URLs "
USE_DEFAULT_URLS = 1
continue
fi
if command - v jq >/ dev / null ; then
# If we have jq, we can do it properly
2021-12-27 21:04:36 +08:00
urls = " $ (jq -r '.[0].assets|.[]|.browser_download_url' < " $payload " || true) "
2021-12-22 21:56:05 +08:00
elif perl - MJSON - e 1 2 >/ dev / null ; then
# If we don't, there's a good chance we have Perl with the JSON module, use it
urls = " $ (perl -MJSON -e 'undef $ /; $d =decode_json(<>); exit if ref $d ne " ARRAY " ; foreach(@ { $d ->[0] { assets} || [] }) { print $_ -> { browser_download_url}. " \n " }' " $payload " ) "
else
# Otherwise, go the ugly way, don't bother the user in installing jq just for this need
urls = " $ (grep -Eo 'https://[a-z0-9./_-]+' " $payload " ) "
fi
2021-03-19 23:28:32 +08:00
fi
2020-12-30 17:56:41 +08:00
2021-03-19 23:28:32 +08:00
url = " $ (echo " $urls " | grep -E " $pattern " | head -n1) "
2020-12-30 17:56:41 +08:00
2021-03-19 23:28:32 +08:00
if [ - n " $url " ]; then
# success
action_detail " $url "
return 0
elif [ - z " $urls " ]; then
action_error " Couldn't find any URL in the returned body, did we hit the query limit? Body follows: "
cat " $payload "
2021-12-22 21:56:05 +08:00
action_error " Auto-retrying with hardcoded URLs "
USE_DEFAULT_URLS = 1
continue
2021-03-19 23:28:32 +08:00
else
action_error " Couldn't find a proper URL for your architecture ( $arch ), looked for pattern ' $pattern '. You may have to compile $PROGRAM_NAME yourself! "
action_detail " Maybe the release asset naming pattern has changed and we're not aware, if you think one of the packages below match your OS & arch, you may download & install them manually: "
for line in $urls ; do
action_detail " $line "
done
exit 1
fi
done
2021-12-22 21:56:05 +08:00
# unreachable code, but fail just in case
2021-03-19 23:28:32 +08:00
exit 1
2020-12-30 17:56:41 +08:00
}
prepare_temp_folder () {
tmpfolder = $ ( mktemp - d )
# shellcheck disable=SC2064
trap " test -d ' $tmpfolder ' && rm -rf -- ' $tmpfolder ' " EXIT
cd " $tmpfolder " || exit 1
}
# shellcheck disable=SC2034
set_archre () {
if command - v dpkg >/ dev / null ; then
arch = $ ( dpkg -- print - architecture )
elif command - v rpm >/ dev / null ; then
arch = $ ( rpm - E '%{_arch}' )
# in some cases, %{_arch} is not defined, so the macro isn't expanded,
# we have to find it ourselves
if [ " $arch " = " % { _arch} " ]; then
arch = $ ( rpm -- showrc | grep " ^install arch " | awk '{print $4}' )
fi
else
arch = $ ( uname - m )
fi
if [ " $arch " = " x86_64 " ] || [ " $arch " = " amd64 " ]; then
archre = " (x86_|amd)64 "
2021-03-17 21:42:54 +08:00
elif [ " $arch " = " ppc64el " ]; then
archre = " ppc64(le|el) "
2020-12-30 17:56:41 +08:00
else
archre = " $arch "
fi
}
action_package () {
type = " $ 1 "
case " $type " in
deb )
if ! command - v dpkg >/ dev / null ; then
echo " Couldn't find dpkg, aborting " >& 2
exit 1
fi ;;
rpm )
if ! command - v rpm >/ dev / null ; then
echo " Couldn't find rpm, aborting " >& 2
exit 1
fi ;;
* ) echo " Unsupported package type $type " >& 2 ; exit 1 ;;
esac
set_archre
set_download_url_package " $type "
prepare_temp_folder
_download " $url "
action_done
action_doing " Installing package "
case " $type " in
deb ) dpkg - i -- *. deb ; ret = $ ? ;;
rpm ) rpm - Uvh -- *. rpm ; ret = $ ? ;;
* ) exit 1 ;;
esac
if [ " $ret " = 0 ]; then
action_done
else
action_error
fi
cd /
}
action_auto () {
action_doing " Detecting OS... "
action_detail " Found $OS_FAMILY "
if [ " $OS_FAMILY " = Linux ]; then
action_detail " Found distro $LINUX_DISTRO version $DISTRO_VERSION (major $DISTRO_VERSION_MAJOR ), distro like $DISTRO_LIKE "
fi
action_done
case " $DISTRO_LIKE " in
* debian * ) action_package deb ;;
* rhel * ) action_package rpm ;;
* suse * ) action_package rpm ;;
2021-12-16 19:10:01 +08:00
freebsd ) action_static ;;
2020-12-30 17:56:41 +08:00
* )
if [ " $OS_FAMILY " = Linux ]; then
action_static
else
2021-12-16 19:10:01 +08:00
echo " This script doesn't support this OS yet ( $OS_FAMILY / $DISTRO_LIKE ) " >& 2
2020-12-30 17:56:41 +08:00
exit 1
fi ;;
esac
}
install_main () {
if [ " $OS_FAMILY " != " Linux " ] && [ " $OS_FAMILY " != " FreeBSD " ]; then
echo " Sorry, your OS ( $OS_FAMILY ) is not supported. " >& 2
exit 1
fi
2021-12-27 22:00:20 +08:00
# in CI mode, delay a random amount of time, to avoid getting blocked
# when several runs are started in parallel
if [ " $CI " = true ]; then
amount = $ (( RANDOM % 10 * 3 ))
action_doing " Sleeping $amount seconds in CI mode... "
sleep $amount
action_done
fi
2020-12-30 17:56:41 +08:00
while getopts : sdrah arg ; do
case " $arg " in
s ) action_static ; exit 0 ;;
d ) action_package deb ; exit 0 ;;
r ) action_package rpm ; exit 0 ;;
a ) action_auto ; exit 0 ;;
2021-12-16 19:10:01 +08:00
h ) install_usage ; exit 0 ;;
2021-12-29 01:03:20 +08:00
* ) echo " Invalid option: - $OPTARG " ; usage ; exit 1 ;;
2020-12-30 17:56:41 +08:00
esac
done
install_usage
}