184 lines
5.4 KiB
Bash
Executable File
184 lines
5.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Ver: 1.3 by Endial Fang (endial@126.com)
|
|
#
|
|
# shell 执行参数,分别为 -e(命令执行错误则退出脚本) -u(变量未定义则报错) -x(打印实际待执行的命令行)
|
|
set -eu
|
|
|
|
# 定义错误处理函数,添加错误位置信息
|
|
error() {
|
|
local error_location="$1"
|
|
local error_message="$2"
|
|
echo "Error at $error_location: $error_message" >&2
|
|
exit 1
|
|
}
|
|
|
|
print_usage() {
|
|
echo "Usage: download_pkg <COMMAND> <PACKAGE-NAME> \"<URLS>\" [OPTIONS]"
|
|
echo ""
|
|
echo "Download and install Third-Part packages"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " download Download a package."
|
|
echo " install Download and install a package."
|
|
echo " unpack Download and unpack a package."
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -g, --checkpgp Package release bucket."
|
|
echo " -s, --checksum SHA256 verification checksum."
|
|
echo " -h, --help Show this help message and exit."
|
|
echo ""
|
|
echo "PACKAGE-NAME: Name with extern name"
|
|
echo "URLS: String with URL list"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " - Unpack package"
|
|
echo " \$ download_pkg unpack redis-5.0.8.tar.gz \"http://download.redis.io/releases\""
|
|
echo ""
|
|
echo " - Verify and Install package"
|
|
echo " \$ download_pkg install redis-5.0.8.tar.gz \"http://download.redis.io/releases\" -s 42cf86a114d2a451b898fcda96acd4d01062a7dbaaad2801d9164a36f898f596"
|
|
echo ""
|
|
}
|
|
|
|
check_pgp() {
|
|
local name_asc=${1:?missing asc file name}
|
|
local name=${2:?missing file name}
|
|
local keys="${3:?missing key id}"
|
|
|
|
GNUPGHOME="$(mktemp -d)"
|
|
if which gpg >/dev/null 2>&1; then
|
|
local key_servers=("pgp.mit.edu" "keys.gnupg.net" "keyserver.pgp.com" "ha.pool.sks-keyservers.net")
|
|
for key in $keys; do
|
|
for server in "${key_servers[@]}"; do
|
|
if gpg --batch --keyserver "$server" --recv-keys "${key}" --timeout 10; then
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
gpg --batch --verify "$name_asc" "$name" || error "PGP verification" "PGP verification failed"
|
|
command -v gpgconf > /dev/null && gpgconf --kill all
|
|
fi
|
|
}
|
|
|
|
# 获取并解析参数
|
|
parsed_args=$(getopt -o g:s:h -l "checkpgp:,checksum:,help" -n "download-pkg" -- "$@")
|
|
if [ $? -ne 0 ]; then
|
|
error "Parameter parsing" "Failed to parse command line arguments."
|
|
print_usage
|
|
exit 1
|
|
fi
|
|
|
|
eval set -- "$parsed_args";
|
|
while true; do
|
|
case "$1" in
|
|
-g|--checkpgp)
|
|
shift
|
|
if [ -n "$1" ]; then
|
|
package_keys=$1
|
|
shift
|
|
fi
|
|
;;
|
|
-s|--checksum)
|
|
shift
|
|
if [ -n "$1" ]; then
|
|
package_sha256=$1
|
|
shift
|
|
fi
|
|
;;
|
|
-h|--help)
|
|
print_usage
|
|
exit 0
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# 检测输入的命令是否合法
|
|
case "$1" in
|
|
download|install|unpack) ;;
|
|
*)
|
|
error "Command validation" "Unrecognized command: $1"
|
|
print_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# 检测输入参数是否足够,需要至少提供软件包名称 及 下载路径
|
|
if [ $# -lt 3 ]; then
|
|
error "Parameter validation" "Insufficient parameters. Please provide package name and URLs."
|
|
print_usage
|
|
exit 1
|
|
fi
|
|
|
|
install_root=/usr/local
|
|
cache_root=/tmp
|
|
|
|
package="$2"
|
|
package_urls=$3
|
|
|
|
# 检查缓存目录中是否已存在该软件包
|
|
if [ -e "$cache_root/$package" ]; then
|
|
echo "Package already exists in cache: $cache_root/$package"
|
|
else
|
|
cd $install_root
|
|
echo "Downloading $package package"
|
|
for url in $package_urls; do
|
|
echo "Try $url/$package"
|
|
if wget -T 10 -O "$cache_root/$package" "$url/$package" && [ -s "$cache_root/$package" ]; then
|
|
if [ -n "${package_keys:-}" ]; then
|
|
wget -T 10 -O "$cache_root/$package.asc" "$url/$package.asc" || wget -T 10 -O "$cache_root/$package.asc" "$url/$package.sign" || :
|
|
if [ ! -e "$cache_root/$package.asc" ]; then
|
|
error "PGP signature download" "Failed to download PGP signature file."
|
|
exit 1
|
|
fi
|
|
fi
|
|
break
|
|
else
|
|
echo "Failed to download from $url/$package"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -n "${package_sha256:-}" ]; then
|
|
echo "Verifying package integrity"
|
|
if ! echo "$package_sha256 *$cache_root/$package" | sha256sum -c -; then
|
|
error "SHA256 verification" "SHA256 verification failed"
|
|
fi
|
|
fi
|
|
|
|
if [ -e "$cache_root/$package.asc" ]; then
|
|
echo "Verifying package with PGP"
|
|
check_pgp "$cache_root/$package.asc" "$cache_root/$package" "$package_keys"
|
|
fi
|
|
|
|
# If the tarball has too many files, it can trigger a bug
|
|
# in overlayfs when using tar. Install bsdtar in the container image
|
|
# to workaround it. As the overhead is too big (~40 MB), it is not added by
|
|
# default. Source: https://github.com/coreos/bugs/issues/1095
|
|
|
|
# 安装或解压软件
|
|
case "$1" in
|
|
download)
|
|
echo "Download success: $cache_root/$package"
|
|
;;
|
|
install)
|
|
echo "Installing $package"
|
|
cp $cache_root/$package /usr/local/sbin/
|
|
;;
|
|
unpack)
|
|
if ! tar -taf $cache_root/$package >/dev/null 2>&1; then
|
|
error "Package integrity check" "Invalid or corrupt '$package' package."
|
|
exit 1
|
|
fi
|
|
echo "Unpacking $package to $cache_root"
|
|
cd $cache_root
|
|
if which bsdtar >/dev/null 2>&1; then
|
|
bsdtar -xf $cache_root/$package
|
|
else
|
|
tar --no-same-owner -xaf $cache_root/$package
|
|
fi
|
|
;;
|
|
esac
|