352 lines
11 KiB
Bash
Executable File
352 lines
11 KiB
Bash
Executable File
#!/usr/bin/bash
|
|
|
|
PACK_LIST=("curl" "git" "jq")
|
|
# 默认地址
|
|
URL_SSL="https://"
|
|
URL_ROOT="git.whlug.cn"
|
|
# 社区网段
|
|
#URL_SSL="http://"
|
|
#URL_ROOT="192.168.2.12:20012"
|
|
|
|
URL_API="${URL_SSL}${URL_ROOT}/api/v1"
|
|
URL_API_PKG="${URL_SSL}${URL_ROOT}/api/packages"
|
|
## 上传地址
|
|
URL_PUT="${URL_API_PKG}"
|
|
# 上传文件
|
|
UPFILE="空"
|
|
|
|
# 项目版本
|
|
GUPKG_VERSION="v1.2.0"
|
|
# 要上传的二进制版本
|
|
ELF_VERSION=""
|
|
# 配置文件路径
|
|
CONFIG_PATH="$HOME/.config/GUPKG"
|
|
# 组合一个常用的crul账户配置
|
|
CONFIG_UP="-u ${GUPKG_USER}:${GUPKG_PASSWD}"
|
|
# 网页缓存与相应代码
|
|
WEB_CACHE="无缓存"
|
|
WEB_CODE=200
|
|
|
|
###############################################################################
|
|
# 终端配色 #
|
|
###############################################################################
|
|
|
|
readonly COLOUR_RESET='\e[0m'
|
|
readonly aCOLOUR=(
|
|
'\e[38;5;154m' # 0: 亮绿
|
|
'\e[1m' # 1: 白
|
|
'\e[90m' # 2: 灰
|
|
'\e[91m' # 3: 红
|
|
'\e[32m' # 4: 绿
|
|
'\e[33m' # 5: 橙
|
|
'\e[95m' # 6: 紫
|
|
)
|
|
Show() {
|
|
if (($1 == 0)); then
|
|
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} 成功 $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
|
elif (($1 == 1)); then
|
|
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]} 失败 $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
|
exit 1
|
|
elif (($1 == 2)); then
|
|
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]} 信息 $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
|
elif (($1 == 3)); then
|
|
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[5]} 警告 $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
|
elif (($1 == 4)); then
|
|
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[6]} 其他 $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
|
fi
|
|
}
|
|
GreyStart() {
|
|
echo -e "${aCOLOUR[2]}\c"
|
|
}
|
|
ColorReset() {
|
|
echo -e "$COLOUR_RESET\c"
|
|
}
|
|
|
|
###############################################################################
|
|
# 函数 #
|
|
###############################################################################
|
|
|
|
# 更新包管理器
|
|
Update_PKG() {
|
|
Show 2 "更新包管理器..."
|
|
GreyStart
|
|
if [ -x "$(command -v oma)" ]; then
|
|
sudo oma refresh
|
|
elif [ -x "$(command -v apt)" ]; then
|
|
sudo apt-get update -qq
|
|
elif [ -x "$(command -v dnf)" ]; then
|
|
sudo dnf update
|
|
fi
|
|
ColorReset
|
|
Show 0 "包管理器更新完毕"
|
|
}
|
|
|
|
# 安装依赖
|
|
Install_PKG() {
|
|
# 遍历数组并检查每个命令是否存在
|
|
for cmd in "${PACK_LIST[@]}"; do
|
|
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
Show 2 "命令 '$cmd' 不存在, 自动尝试安装"
|
|
# Update_PKG
|
|
GreyStart
|
|
if [ -x "$(command -v oma)" ]; then
|
|
sudo oma install -y $cmd
|
|
elif [ -x "$(command -v apt)" ]; then
|
|
sudo apt -y install $cmd
|
|
elif [ -x "$(command -v yum)" ]; then
|
|
sudo yum install -y $cmd
|
|
elif [ -x "$(command -v pacman)" ]; then
|
|
sudo pacman -Sy --needed $cmd
|
|
else
|
|
Show 1 "未找到包管理器, 您需要手动安装: ${aCOLOUR[5]} $cmd $COLOUR_RESET"
|
|
fi
|
|
ColorReset
|
|
Show 0 "依赖安装完成"
|
|
fi
|
|
done
|
|
}
|
|
|
|
|
|
# 访问指定链接, 返回其响应码, 并且将网页内容保存到 WEB_CACHE 中
|
|
# web_repuest $1 $2 $3
|
|
# $1: 访问的基础域名
|
|
# $2: 域名参数
|
|
# $3: curl携带参数
|
|
web_repuest() {
|
|
# 判断输入值并执行对应逻辑
|
|
if [[ "$1" == "api" ]]; then
|
|
url_target=${URL_API}
|
|
elif [[ "$1" == "pkg" ]]; then
|
|
url_target=${URL_API_PKG}
|
|
else
|
|
url_target="$1"
|
|
fi
|
|
all_value=$(curl ${url_target}/$2 $3 -w "%{http_code}\n")
|
|
WEB_CACHE="${all_value:0:-3}"
|
|
WEB_CODE="${all_value: -3}"
|
|
|
|
# 判断下403的情况, 如果是少开权限了就自动跳过
|
|
if [[ "$WEB_CODE" -eq 403 ]]; then
|
|
access_urge="建议打开 用户[user] 和 组织[organization] 的可读[read]权限, 获取更好的使用体验"
|
|
Show 3 "${access_urge}"
|
|
# 判断是否有最基本的包读写权限
|
|
if [[ ${WEB_CACHE} =~ write:package ]]; then
|
|
WEB_CODE=200
|
|
else
|
|
Show 1 "请务必打开 包[package] 的读写[write]权限, 否则无法完成上传操作"
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
# 从web缓存获取值
|
|
get_json() {
|
|
echo "$WEB_CACHE" | jq -r ".$1" 2>/dev/null
|
|
}
|
|
|
|
# 上传链接
|
|
# get_put $1 $2
|
|
# $1: 包上传地址
|
|
# $2: 上传的包文件
|
|
get_put() {
|
|
web_repuest $URL_PUT $1 "${CONFIG_UP} --upload-file $2 --progress-bar"
|
|
if [[ "$WEB_CODE" -eq 201 ]]; then
|
|
Show 0 "软件包发布成功, 发布地址: ${URL_SSL}${URL_ROOT}/${GUPKG_OWNER}/-/packages "
|
|
elif [[ "$WEB_CODE" -eq 400 ]]; then
|
|
Show 1 "发布失败!(软件包名称/版本或文件名无效) ${WEB_CACHE}"
|
|
elif [[ "$WEB_CODE" -eq 409 ]]; then
|
|
Show 1 "发布失败!(具有相同名称的文件已存在于软件包中): ${WEB_CACHE}"
|
|
fi
|
|
|
|
}
|
|
|
|
# 检查用户是否存在
|
|
user_check() {
|
|
# 更新用户配置
|
|
CONFIG_UP="-u ${GUPKG_USER}:${GUPKG_PASSWD}"
|
|
web_repuest api user "${CONFIG_UP} -s"
|
|
if [[ "$WEB_CODE" -eq 200 ]]; then
|
|
user_name=$(get_json "full_name")
|
|
user_email=$(get_json "email")
|
|
Show 0 "用户测试成功(${user_name:=${GUPKG_USER}}${user_email:+:$user_email}), 配件文件: ${CONFIG_FILE}"
|
|
else
|
|
Show 3 "未找到相关用户($WEB_CODE)"
|
|
read -rp "是否重新初始化配置?[y/n]: " todo
|
|
if [[ "$todo" == "N" || "$todo" == "n" ]]; then
|
|
Show 1 "用户已取消"
|
|
fi
|
|
rm -fv ${CONFIG_FILE}
|
|
config_init
|
|
fi
|
|
}
|
|
|
|
# 检查版本号,如果找不到版本号就基于时间给个版本
|
|
get_version() {
|
|
# 给个默认版本: v1.[当前时间].[md5前六位]
|
|
ELF_VERSION="v1.$(date +%y%m%d).$(md5sum $1 | cut -c1-6)"
|
|
# 检查命令是否存在
|
|
command -v "$1" >/dev/null 2>&1 || { return 1; }
|
|
|
|
local out
|
|
for arg in --version -v version; do
|
|
if out="$("$1" "$arg" 2>/dev/null)"; then
|
|
# 提取版本号:以字母+数字 或 数字开头,包含小数点,无空格
|
|
ELF_VERSION=$(echo "$out" | awk '
|
|
match($0, /[vV]?[0-9][^ ]*\.[^ ]+/, a) {
|
|
print a[0]
|
|
exit
|
|
}') && return 0
|
|
fi
|
|
done
|
|
|
|
return 2
|
|
}
|
|
|
|
|
|
# 初始化配置
|
|
config_init() {
|
|
# 初始化配置
|
|
CONFIG_FILE="${CONFIG_PATH}/init.sh"
|
|
|
|
# 检查配置文件是否存在
|
|
if [[ ! -f "${CONFIG_FILE}" ]]; then
|
|
# 确保配置文件所在目录存在
|
|
mkdir -p ${CONFIG_PATH}
|
|
Show 2 "正在初始化配置文件..."
|
|
read -p "[1/2]请输入您Git的用户名: " GUPKG_USER
|
|
read -p "[2/2]请输入您的密码或API(填写密码并不安全,建议填写API): " GUPKG_PASSWD
|
|
user_check
|
|
# 写入默认配置模板
|
|
cat <<EOF > "$CONFIG_FILE"
|
|
# 配置脚本的版本
|
|
export GUPKG_VERSION=${GUPKG_VERSION}
|
|
# Git的账户
|
|
export GUPKG_USER=${GUPKG_USER}
|
|
# 密码或API,在这里填写您的密码并不安全,建议您填写API
|
|
# API获取方法: https://docs.gitea.com/zh-cn/development/api-usage
|
|
export GUPKG_PASSWD=${GUPKG_PASSWD}
|
|
EOF
|
|
|
|
else
|
|
source ${CONFIG_FILE}
|
|
user_check
|
|
fi
|
|
Show 0 "配置文件初始化完成"
|
|
}
|
|
|
|
# 获取当前用户的组织
|
|
# TODO: 配置文件记住一个默认的选项,减少用户操作次数
|
|
get_user_orgs() {
|
|
web_repuest api user/orgs "${CONFIG_UP} -s"
|
|
|
|
# 提取 name 并存入数组
|
|
names=($(echo "${WEB_CACHE}" | jq -r '.[].name' 2>/dev/null) )
|
|
|
|
if [ ${#names[@]} -eq 0 ]; then
|
|
Show 0 "为检测到您的组织,请手动输入"
|
|
read -p "为检测到您的组织,请手动输入(默认:${GUPKG_USER})" GUPKG_OWNER
|
|
${GUPKG_OWNER:=${GUPKG_USER}}
|
|
else
|
|
Show 0 "解析到您拥有以下组织, 请选择一个组织/个人仓库上传"
|
|
for i in "${!names[@]}"; do
|
|
Show 4 "$((i + 1)). ${names[$i]}"
|
|
done
|
|
# 提示用户输入数字
|
|
read -p "选择您要上传的组织 (1-${#names[@]}), 输入0则上传到自有源中: " choice
|
|
|
|
# 检查用户输入是否有效
|
|
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#names[@]}" ]; then
|
|
# 输出用户选择的内容
|
|
GUPKG_OWNER=${names[$((choice - 1))]}
|
|
else
|
|
GUPKG_OWNER=${GUPKG_USER}
|
|
fi
|
|
|
|
Show 0 "已为您选择 $GUPKG_OWNER"
|
|
fi
|
|
URL_PUT=${URL_PUT}/$GUPKG_OWNER
|
|
}
|
|
|
|
# 接收一个文件后缀用于判断是什么格式的
|
|
# TODO: 增加历史值记录预设功能
|
|
config_url() {
|
|
if [[ $UPFILE =~ \.deb$ ]]; then
|
|
Show 2 "[包后缀] 检测到Debian系(deb)安装包"
|
|
Show 2 "参考使用说明: https://docs.gitea.com/zh-cn/usage/packages/debian"
|
|
# 拼接地址: debian/pool/{distribution}/{component}/upload
|
|
read -p "[1/2] 请输入发行版(可能与操作系统的发行版名称匹配,例如 bionic): " GUPKG_deb_dis
|
|
read -p "[2/2] 请输入组件(可用于分组软件包,或仅为 main 或类似的组件): " GUPKG_deb_com
|
|
put_path=debian/pool/${GUPKG_deb_dis}/${GUPKG_deb_com}/upload
|
|
elif [[ $UPFILE =~ \.rpm$ ]]; then
|
|
Show 2 "[包后缀] 检测到红帽系(rpm)安装包"
|
|
Show 2 "参考使用说明: https://docs.gitea.com/zh-cn/usage/packages/packages/rpm"
|
|
# 拼接地址: rpm/{group}/upload
|
|
read -p "[1/1] 软件包自定义分组名称: " GUPKG_rpm_group
|
|
put_path=rpm/${GUPKG_rpm_group}/upload
|
|
elif [[ $UPFILE == \.pkg\.tar\.zst$ ]]; then
|
|
Show 2 "[包后缀] 检测到Arch系安装包"
|
|
Show 2 "参考使用说明: https://docs.gitea.com/zh-cn/usage/packages/arch"
|
|
# 拼接地址: arch/{repository}
|
|
read -p "[1/1] 请输入储存库(可用于对包进行分组,或者仅用于核心或类似内容) " GUPKG_arch_rep
|
|
put_path=arch/${GUPKG_arch_rep}
|
|
else
|
|
Show 2 "非已知包名后缀, 按照通用包处理"
|
|
Show 2 "使用说明: https://docs.gitea.com/zh-cn/usage/packages/generic"
|
|
# 拼接地址: generic/{package_name}/{package_version}/{file_name}
|
|
|
|
default_pkg_name=$(basename "$UPFILE")
|
|
read -p "[1/3] 软件组(用于分组软件包) [默认: ${default_pkg_name}]: " GUPKG_pkg_name
|
|
GUPKG_pkg_name=${GUPKG_pkg_name:-${default_pkg_name}}
|
|
|
|
get_version $UPFILE
|
|
read -p "[2/3] 软件包版本 [默认: ${ELF_VERSION}]: " GUPKG_pkg_ver
|
|
GUPKG_pkg_ver=${GUPKG_pkg_ver:-${ELF_VERSION}}
|
|
|
|
default_pkg_file="${GUPKG_pkg_name}-${GUPKG_pkg_ver}"
|
|
read -p "[3/3] 文件名 [默认值: ${default_pkg_file}]" GUPKG_pkg_file
|
|
GUPKG_pkg_file=${GUPKG_pkg_file:-"${default_pkg_file}"}
|
|
put_path=generic/${GUPKG_pkg_name}/${GUPKG_pkg_ver}/${GUPKG_pkg_file}
|
|
fi
|
|
|
|
Show 0 "正在向地址: ${URL_PUT}/${put_path} 上传您的包, 请等待..."
|
|
get_put ${put_path} ${UPFILE}
|
|
}
|
|
|
|
# 容器
|
|
# TODO: 后续增加容器的支持
|
|
# 使用说明: https://docs.gitea.com/zh-cn/usage/packages/container
|
|
# docker push gitea.example.com/{owner}/{image}:{tag}
|
|
## 镜像的名称
|
|
#source GUPKG_container_image=
|
|
## 镜像的标签
|
|
#source GUPKG_container_tag=
|
|
|
|
#################################################################
|
|
# 主函数(main) #
|
|
#################################################################
|
|
|
|
# 输入处理
|
|
if [[ -z "$1" ]]; then
|
|
Show 1 "未提供路径参数!\n 用法: $0 <文件>"
|
|
else
|
|
UPFILE="$1"
|
|
# 判断文件是否存在
|
|
if [[ ! -f "$UPFILE" ]]; then
|
|
Show 1 "文件不存在, 请重新输入文件路径!(可以是绝对路径也可以是相对路径)"
|
|
fi
|
|
# 判断是否是绝对路径, 不是就进行转化
|
|
if [[ "$UPFILE" != /* ]]; then
|
|
UPFILE=$(realpath "$UPFILE")
|
|
fi
|
|
fi
|
|
Show 0 "文件解析成功($UPFILE)"
|
|
|
|
# 安装必要依赖
|
|
Install_PKG
|
|
# 初始化配置模块
|
|
config_init
|
|
# 获取用户已有组
|
|
get_user_orgs
|
|
# 组合上传链接, 并启动上传
|
|
config_url
|