Files
GUPKG/GUPKG_start.sh

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