mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-28 03:01:54 +08:00
317 lines
11 KiB
Bash
Executable File
317 lines
11 KiB
Bash
Executable File
#!/bin/bash /etc/rc.common
|
|
# Copyright (C) 2023-2024 muink
|
|
|
|
. "${IPKG_INSTROOT}/lib/functions.sh"
|
|
. "${IPKG_INSTROOT}/usr/share/libubox/jshn.sh"
|
|
|
|
START=99
|
|
USE_PROCD=1
|
|
|
|
EXTRA_COMMANDS="getinfo checkln symln setcron cleanup"
|
|
EXTRA_HELP=\
|
|
" getinfo Get releases/targets/archs list
|
|
checkln Check home path
|
|
symln [home_url] Make symlink to mount porint
|
|
setcron [cron] Add cron expression to crontabs
|
|
cleanup [autorm] Clean up invalid versions"
|
|
|
|
CONFIG_NAME='packagesync'
|
|
SCONFIG='config'
|
|
RELEASE='release'
|
|
|
|
MNTPKGS='/mnt/packagesync'
|
|
CRONTABS='/etc/crontabs/root'
|
|
SYNCEXE='/usr/libexec/packagesync/sync'
|
|
PIDFILE='/var/run/packagesync.pid'
|
|
DEF_HOMEURL="packagesync"
|
|
DEF_HOMEPATH="/www/$DEF_HOMEURL"
|
|
RELEASES_LIST="/var/packagesync/releaseslist"
|
|
TARGETS_LIST="/var/packagesync/targetslist"
|
|
PKGARCHS_LIST="/var/packagesync/pkgarchslist"
|
|
RESULTPATH='/var/packagesync/results'
|
|
# url path
|
|
DOWNLOAD_URL="https://downloads.openwrt.org"
|
|
URLHREF_RELEASES='releases'
|
|
URLHREF_SNAPSHOTS='snapshots'
|
|
URLHREF_PACKAGES_PREFIX='packages-' # packages-22.03
|
|
URLHREF_VERS_PACKAGES='packages'
|
|
URLHREF_VERS_TARGETS='targets'
|
|
|
|
config_load $CONFIG_NAME
|
|
|
|
|
|
|
|
# define global var: GLOBAL_*
|
|
define_global() {
|
|
[ "$2" == "0" ] || { >&2 echo "$(basename $0): section $1 validation failed"; return 1; }
|
|
|
|
local error=0
|
|
local v ucivv="download_url rsync_url home_url bwlimit proxy_enabled proxy_protocol proxy_server"
|
|
for v in $ucivv; do
|
|
[ -z "$(config_get $1 $v)" ] && grep -qEv "^(download_url|rsync_url|proxy_protocol|proxy_server)$" <<< "$v" && {
|
|
>&2 echo "$(basename $0): section $1 option $v cannot be empty"
|
|
let error++
|
|
}
|
|
config_get GLOBAL_$v $1 $v
|
|
done
|
|
|
|
[ "$error" -gt 0 ] && return 1 || return 0
|
|
}
|
|
|
|
validate_section_config() {
|
|
uci_load_validate "$CONFIG_NAME" "$SCONFIG" "$1" "$2" \
|
|
'download_url:string' \
|
|
'rsync_url:string' \
|
|
'home_url:string' \
|
|
'bwlimit:uinteger:8000' \
|
|
'auto_exec:bool:1' \
|
|
'cron_expression:string' \
|
|
'proxy_enabled:bool:0' \
|
|
'proxy_protocol:string:socks5' \
|
|
'proxy_server:string'
|
|
}
|
|
|
|
validate_section_release() {
|
|
uci_load_validate $CONFIG_NAME $RELEASE "$1" "$2" \
|
|
'enabled:bool:0' \
|
|
'name:uciname' \
|
|
'version:string' \
|
|
'target:string' \
|
|
'pkgarch:string' \
|
|
'model:string' \
|
|
'extra:bool:0'
|
|
}
|
|
|
|
gen_order() {
|
|
[ "$2" == "0" ] || { >&2 echo "section $1 validation failed"; return 1; }
|
|
[ "$enabled" == "0" ] && return 0
|
|
|
|
json_init
|
|
json_load "$orders"
|
|
json_select orders
|
|
json_add_object
|
|
json_add_string name "$name"
|
|
json_add_string version "$version"
|
|
json_add_string target "$target"
|
|
json_add_string arch "$pkgarch"
|
|
json_add_string model "$model"
|
|
json_add_boolean extra "$extra"
|
|
json_close_object
|
|
orders="$(json_dump)"
|
|
}
|
|
|
|
sync_instance() {
|
|
[ -z "$1" ] && return 1
|
|
|
|
procd_open_instance 'sync'
|
|
procd_set_param command "$SYNCEXE" -o "$1"
|
|
procd_append_param command -l "$bwlimit" -d "$homepath" ${ALL_PROXY:+-x $ALL_PROXY} \
|
|
${GLOBAL_rsync_url:+--rsyncurl "$GLOBAL_rsync_url"}
|
|
#procd_set_param respawn
|
|
#procd_set_param stdout 1
|
|
procd_set_param stderr 1
|
|
procd_set_param user root
|
|
procd_set_param pidfile "$PIDFILE"
|
|
procd_close_instance
|
|
}
|
|
|
|
start_service() {
|
|
# locked file check
|
|
[ -n "$(cat "$PIDFILE" 2>/dev/null)" -a -n "$(ps|grep -E "^\s*$(cat "$PIDFILE" 2>/dev/null)")" ] && return 1
|
|
# mount point check
|
|
[ -n "$(df -hT|grep "$MNTPKGS")" ] || return 1
|
|
|
|
validate_section_config "$SCONFIG" define_global || return $?
|
|
local homepath bwlimit
|
|
[ -n "$GLOBAL_home_url" ] && homepath="/www/$GLOBAL_home_url" || homepath="$DEF_HOMEPATH"
|
|
[ -d "$homepath" ] || { >&2 echo -e "$CONFIG_NAME: The Home Path '$homepath' is invalid. please check the 'home_url'"; return 1; }
|
|
bwlimit="$GLOBAL_bwlimit"
|
|
[ "$GLOBAL_proxy_enabled" = "1" ] && {
|
|
export ALL_PROXY=$GLOBAL_proxy_protocol://$GLOBAL_proxy_server
|
|
}
|
|
|
|
local orders='{ "orders": [] }'
|
|
config_foreach validate_section_release $RELEASE gen_order
|
|
|
|
sync_instance "$(jsonfilter -q -s "$orders" -e @.orders)"
|
|
#$SYNCEXE -l|--bwlimit "$bwlimit" -d|--homedir "$homepath" -n|--name "x64_21_02_5" -s|--version "21.02.5" -t|--target "x86/64" -k|--arch "x86_64";
|
|
#$SYNCEXE -l|--bwlimit "$bwlimit" -d|--homedir "$homepath" -n|--name "x64_22_03_2" -s|--version "22.03.2" -t|--target "x86/64" -k|--arch "x86_64";
|
|
#$SYNCEXE -l|--bwlimit "$bwlimit" -d|--homedir "$homepath" -n|--name "ath79_21_02_5" -s|--version "21.02.5" -t|--target "ath79/nand" -k|--arch "mips_24kc";
|
|
#$SYNCEXE -l|--bwlimit "$bwlimit" -d|--homedir "$homepath" -n|--name "ath79_22_03_2" -s|--version "22.03.2" -t|--target "ath79/nand" -k|--arch "mips_24kc";
|
|
#
|
|
#$SYNCEXE -l|--bwlimit "$bwlimit" -o|--orders '[ {"homedir": "$homepath", "name": "x64_21_02_5", "version": "21.02.5", "target": "x86/64", "arch": "x86_64"}, \
|
|
# {"homedir": "$homepath", "name": "x64_22_03_2", "version": "22.03.2", "target": "x86/64", "arch": "x86_64"}, \
|
|
# {"homedir": "$homepath", "name": "ath79_21_02_5", "version": "21.02.5", "target": "ath79/nand", "arch": "mips_24kc"}, \
|
|
# {"homedir": "$homepath", "name": "ath79_22_03_2", "version": "22.03.2", "target": "ath79/nand", "arch": "mips_24kc"} ]'
|
|
#
|
|
#$SYNCEXE -l|--bwlimit "$bwlimit" -d|--homedir "$homepath" -o|--orders '[ {"name": "x64_21_02_5", "version": "21.02.5", "target": "x86/64", "arch": "x86_64"}, \
|
|
# {"name": "x64_22_03_2", "version": "22.03.2", "target": "x86/64", "arch": "x86_64"}, \
|
|
# {"name": "ath79_21_02_5", "version": "21.02.5", "target": "ath79/nand", "arch": "mips_24kc"}, \
|
|
# {"name": "ath79_22_03_2", "version": "22.03.2", "target": "ath79/nand", "arch": "mips_24kc"} ]'
|
|
|
|
return 0
|
|
}
|
|
|
|
getinfo() {
|
|
validate_section_config "$SCONFIG" define_global
|
|
local rawhtml stables releases targets pkgarchs download_url="${GLOBAL_download_url:-$DOWNLOAD_URL}"
|
|
|
|
# Versions
|
|
rawhtml="$(curl --connect-timeout 10 --retry 3 -sSL "$download_url/")"
|
|
stables="$( \
|
|
echo "$rawhtml" | sed -n '/Stable Release/,/Development Snapshots/p' \
|
|
| sed -n '/<ul>/,/<\/ul>/p' | grep 'OpenWrt' \
|
|
| sed -E "s|.+\breleases/([^/]+)/.+|\1|g" \
|
|
)"
|
|
releases="$( \
|
|
echo "$rawhtml" | sed -n '/Release Archive/,/\$/p' \
|
|
| sed -n '/<ul>/,/<\/ul>/p' | grep 'OpenWrt' \
|
|
| sed -E "s|.+\breleases/([^/]+)/.+|\1|g" \
|
|
)"
|
|
mkdir -p "${RELEASES_LIST%/*}" 2>/dev/null
|
|
echo -e "Releases:"
|
|
echo -e "$stables\n$releases"
|
|
echo -e "$stables\n$releases" > "$RELEASES_LIST"
|
|
|
|
# Targets
|
|
for stable in $stables; do
|
|
rawhtml="$(curl --connect-timeout 10 --retry 3 -sSL "$download_url/$URLHREF_RELEASES/$stable/$URLHREF_VERS_TARGETS/")"
|
|
targets="$( \
|
|
echo "$rawhtml" \
|
|
| grep -E '<a href=.+\d+:\d+' \
|
|
| sed -E "s|.+\bhref=\"([^/]+)/.+|\1|g" \
|
|
)"
|
|
## subTargets
|
|
fulltargets="$( \
|
|
for target in $targets; do
|
|
subtargets="$(curl -sL "$download_url/$URLHREF_RELEASES/$stable/$URLHREF_VERS_TARGETS/$target/" \
|
|
| grep -E '<a href=.+\d+:\d+' \
|
|
| sed -E "s|.+\bhref=\"([^/]+)/.+|\1|g" \
|
|
)"
|
|
for subtarget in $subtargets; do sed "s|^|$target/|" <<< "$subtarget"; done
|
|
done \
|
|
)"
|
|
fulltargetss="$(echo -e "$fulltargetss\n$fulltargets" | sort -u | grep -v '^$')"
|
|
done
|
|
mkdir -p "${TARGETS_LIST%/*}" 2>/dev/null
|
|
echo "Targets:"
|
|
echo "$fulltargetss"
|
|
echo "$fulltargetss" > "$TARGETS_LIST"
|
|
|
|
# Archs
|
|
for stable in $stables; do
|
|
rawhtml="$(curl --connect-timeout 10 --retry 3 -sSL "$download_url/$URLHREF_RELEASES/$stable/$URLHREF_VERS_PACKAGES/")"
|
|
pkgarchs="$( \
|
|
echo "$rawhtml" \
|
|
| grep -E '<a href=.+\d+:\d+' \
|
|
| sed -E "s|.+\bhref=\"([^/]+)/.+|\1|g" \
|
|
)"
|
|
pkgarchss="$(echo -e "$pkgarchss\n$pkgarchs" | sort -u | grep -v '^$')"
|
|
done
|
|
mkdir -p "${PKGARCHS_LIST%/*}" 2>/dev/null
|
|
echo "PKGArchs:"
|
|
echo "$pkgarchss"
|
|
echo "$pkgarchss" > "$PKGARCHS_LIST"
|
|
}
|
|
|
|
gethome() {
|
|
home_url="${1:-$(uci -q get $CONFIG_NAME.$SCONFIG.home_url)}"
|
|
home_url="${home_url:-$DEF_HOMEURL}"
|
|
home_path="/www/$home_url"
|
|
}
|
|
|
|
checkln() {
|
|
gethome
|
|
|
|
# clean up old symlink
|
|
ls -l /www | grep "\-> $MNTPKGS" | grep -v " $home_url -> $MNTPKGS" | sed -En "s,.+ ('.+'|\S+) -> ${MNTPKGS}$,'/www/\1',p" | xargs rm -f
|
|
# show occupied
|
|
find /www/* ! -type l -maxdepth 0 | sed "s|.*/||g"
|
|
}
|
|
|
|
symln() {
|
|
gethome "$1"
|
|
|
|
# make mount dir
|
|
[ -e "$home_path" ] || { ln -s "$MNTPKGS" "$home_path" 2>/dev/null; ln -s "$RESULTPATH" "$home_path/results" 2>/dev/null; return 0; }
|
|
[ -L "$home_path" ] || { >&2 echo "The Name $home_url is already used, please use another name"; return 1; }
|
|
[ -n "$(ls -l "$home_path" | grep " $home_path -> $MNTPKGS")" ] || { >&2 echo "The Name $home_url is already used, please use another name"; return 1; }
|
|
return 0
|
|
}
|
|
|
|
setcron() {
|
|
local cron="$1" exist=$(cat "$CRONTABS" | sed -n "/\/etc\/init.d\/packagesync start/=")
|
|
|
|
if [ -n "$cron" ]; then
|
|
[ -n "$exist" ] && sed -i "/\/etc\/init.d\/packagesync start/d" "$CRONTABS"
|
|
sed -i "\$a$cron /etc/init.d/packagesync start" "$CRONTABS"
|
|
else
|
|
[ -n "$exist" ] && sed -i "/\/etc\/init.d\/packagesync start/d" "$CRONTABS"
|
|
fi
|
|
}
|
|
|
|
cleanup_regex() {
|
|
[ "$2" == "0" ] || { >&2 echo "section $1 validation failed"; return 1; }
|
|
targets="${targets:+$targets|}/$version/$URLHREF_VERS_TARGETS/$target\b"
|
|
packages="${packages:+$packages|}/$version/$URLHREF_VERS_PACKAGES\b"
|
|
pkgarchs="${pkgarchs:+$pkgarchs|}/$URLHREF_PACKAGES_PREFIX${version%\.*}/$pkgarch\b"
|
|
}
|
|
|
|
cleanup() {
|
|
local autorm="$1"
|
|
gethome
|
|
|
|
local count targets packages pkgarchs
|
|
[ -d "$home_path/$URLHREF_RELEASES" ] || return 1
|
|
|
|
config_foreach validate_section_release $RELEASE cleanup_regex || return $?
|
|
|
|
#count=$(uci -q show $CONFIG_NAME|grep "=$RELEASE"|sed -E "s|.+@$RELEASE\[(\d+)\].+|\1|"|tail -n1)
|
|
#
|
|
#local ucivv="version target pkgarch"
|
|
#for i in $(seq 0 $count); do
|
|
# for _var in $ucivv; do
|
|
# eval "local $_var=\$(uci -q get $CONFIG_NAME.@$RELEASE[$i].$_var)"
|
|
# done
|
|
# targets="${targets:+$targets|}/$version/$URLHREF_VERS_TARGETS/$target\b"
|
|
# packages="${packages:+$packages|}/$version/$URLHREF_VERS_PACKAGES\b"
|
|
# pkgarchs="${pkgarchs:+$pkgarchs|}/$URLHREF_PACKAGES_PREFIX${version%\.*}/$pkgarch\b"
|
|
#done
|
|
#echo "$targets"
|
|
#echo "$packages"
|
|
#echo "$pkgarchs"
|
|
|
|
local rm_path="$( \
|
|
find $home_path/$URLHREF_RELEASES/* -type d -o -type l -maxdepth 3 | grep -Ev "$targets" | grep -Ev "$packages" | grep -Ev "$pkgarchs" \
|
|
| grep -E "(/\d+\.\d+[^/]*/($URLHREF_VERS_PACKAGES|$URLHREF_VERS_TARGETS/[^/]+/[^/]+)\$|/${URLHREF_PACKAGES_PREFIX}\d+\.\d+/[^/]+\$)" \
|
|
)"
|
|
sed "s|^/|rm -rf '/|g;s|$|'|g" <<< "$rm_path"
|
|
[ -z "$autorm" ] && return 0 || echo "$rm_path" | xargs rm -rf
|
|
|
|
}
|
|
|
|
restart() {
|
|
start
|
|
}
|
|
|
|
boot() {
|
|
mkdir -p "$RESULTPATH" 2>/dev/null
|
|
gethome
|
|
if [ -e "$home_path" ]; then
|
|
if [ -L "$home_path" -a "$(readlink "$home_path")" = "$MNTPKGS" ]; then
|
|
sleep 0
|
|
else
|
|
uci set $CONFIG_NAME.$SCONFIG.home_url="$DEF_HOMEURL"
|
|
uci commit $CONFIG_NAME
|
|
ln -s "$MNTPKGS" "$DEF_HOMEPATH"
|
|
fi
|
|
else
|
|
ln -s "$MNTPKGS" "$home_path"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_reload_trigger "$CONFIG_NAME"
|
|
}
|