mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-04-26 01:10:16 +08:00
Merge V4
This commit is contained in:
16
tool/apt-fast-conf/aptss-apt.conf
Normal file
16
tool/apt-fast-conf/aptss-apt.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
Debug::RunScripts true;
|
||||
Dir::Cache::archives "/var/cache/apt/archives";
|
||||
Dir::Cache "/var/lib/aptss/";
|
||||
Dir::Etc::SourceParts "/opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d/";
|
||||
Dir::State::lists "/var/lib/aptss/lists/";
|
||||
|
||||
APT::Get::Fix-Broken true;
|
||||
APT::Get::List-Cleanup="0";
|
||||
|
||||
Acquire::GzipIndexes "false";
|
||||
|
||||
#clear APT::Update::Post-Invoke-Success;
|
||||
|
||||
#clear DPkg::Post-Invoke;
|
||||
|
||||
#clear DPkg::Pre-Install-Pkgs;
|
||||
0
tool/apt-fast-conf/sources.list.d/.keep
Normal file
0
tool/apt-fast-conf/sources.list.d/.keep
Normal file
865
tool/apt-fast/ss-apt-fast
Executable file
865
tool/apt-fast/ss-apt-fast
Executable file
@@ -0,0 +1,865 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# apt-fast v1.10.0
|
||||
# Use this just like aptitude or apt-get for faster package downloading.
|
||||
#
|
||||
# Copyright: 2008-2012 Matt Parnell, http://www.mattparnell.com
|
||||
# Improvements, maintenance, revisions - 2012, 2017-2019 Dominique Lasserre
|
||||
#
|
||||
# You may distribute this file under the terms of the GNU General
|
||||
# Public License as published by the Free Software Foundation; either
|
||||
# version 3 of the License, or (at your option) any later version.
|
||||
#
|
||||
|
||||
shopt -s nullglob
|
||||
[ -n "$DEBUG" ] && set -xv
|
||||
|
||||
# Print colored messages.
|
||||
# Usage: msg "message text" "message type" "optional: err"
|
||||
# Message types are 'normal', 'hint' or 'warning'. Warnings and messages with a
|
||||
# third argument are piped to stderr.
|
||||
|
||||
THREADS=$(nproc 2>/dev/null || echo 4)
|
||||
|
||||
# Set color variables.
|
||||
cGreen='\e[0;32m'
|
||||
cRed='\e[0;31m'
|
||||
cBlue='\e[0;34m'
|
||||
endColor='\e[0m'
|
||||
|
||||
msg(){
|
||||
msg_options=()
|
||||
case "$2" in
|
||||
normal) beginColor="$cGreen";;
|
||||
hint) beginColor="$cBlue";;
|
||||
warning) beginColor="$cRed";;
|
||||
question) beginColor="$cRed"; msg_options=(-n);;
|
||||
*) beginColor= ;;
|
||||
esac
|
||||
|
||||
if [ -z "$3" ] && [ "$2" != "warning" ]; then
|
||||
echo -e "${msg_options[@]}" "${aptfast_prefix}${beginColor}$1${endColor}"
|
||||
else
|
||||
echo -e "${msg_options[@]}" "${aptfast_prefix}${beginColor}$1${endColor}" >&2
|
||||
fi
|
||||
}
|
||||
msg_already_running()
|
||||
{
|
||||
msg "Other aptss is running. Waited $timer senconds..." "normal"
|
||||
msg "有其他的aptss正在运行。已经等待了$timer秒" "normal"
|
||||
}
|
||||
|
||||
# Check if a lock file exists.
|
||||
#if [ -f "$LCK_FILE.lock" ]; then
|
||||
# msg_already_running
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
# Move download file away so missing permissions won't stop usage.
|
||||
CLEANUP_STATE=0
|
||||
cleanup_dllist()
|
||||
{
|
||||
if [ -f "$DLLIST" ]
|
||||
then
|
||||
if ! mv -- "$DLLIST{,.old}" 2>/dev/null
|
||||
then
|
||||
if ! rm -fr -- "${LISTTEMP}" 2>/dev/null
|
||||
then
|
||||
msg "Could not clean up download list file." "warning"
|
||||
msg "无法清除下载列表文件." "warning"
|
||||
CLEANUP_STATE=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_aptfast()
|
||||
{
|
||||
local last_exit_code=$?
|
||||
[ "$CLEANUP_STATE" -eq 0 ] && CLEANUP_STATE=$last_exit_code
|
||||
cleanup_dllist
|
||||
_remove_lock
|
||||
# 添加删除临时目录的逻辑
|
||||
if [ -n "$LISTTEMP" ] && [ -d "$LISTTEMP" ]; then
|
||||
rm -rf "$LISTTEMP"
|
||||
fi
|
||||
}
|
||||
exit_cleanup_state()
|
||||
{
|
||||
cleanup_aptfast
|
||||
exit $CLEANUP_STATE
|
||||
}
|
||||
|
||||
LCK_FD=99
|
||||
# create the lock file and lock it, die on failure
|
||||
_create_lock()
|
||||
{
|
||||
eval "exec $LCK_FD>\"$LCK_FILE.lock\""
|
||||
|
||||
# 设置 trap 来清理资源
|
||||
trap "cleanup_aptfast" EXIT
|
||||
trap "cleanup_aptfast; exit 1" INT TERM
|
||||
|
||||
timer=0
|
||||
max_wait=180 # 最大等待时间为180秒(3分钟)
|
||||
|
||||
until $(flock -xn $LCK_FD); do
|
||||
msg_already_running
|
||||
sleep 1
|
||||
let timer+=1
|
||||
|
||||
if [ $timer -ge $max_wait ]; then
|
||||
echo "timeout"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
unset timer
|
||||
}
|
||||
|
||||
# unlock and remove the lock file
|
||||
_remove_lock()
|
||||
{
|
||||
# Only unlock if lock file exists (was created by _create_lock)
|
||||
if [ -f "$LCK_FILE.lock" ]; then
|
||||
flock -u "$LCK_FD" 2>/dev/null
|
||||
rm -f "$LCK_FILE.lock"
|
||||
fi
|
||||
}
|
||||
|
||||
# Search for known options and decide if root privileges are needed.
|
||||
root=$#
|
||||
option=
|
||||
for argument in "$@"; do
|
||||
case "$argument" in
|
||||
upgrade | full-upgrade | install | dist-upgrade | build-dep)
|
||||
option="install"
|
||||
_create_lock
|
||||
;;
|
||||
clean | autoclean)
|
||||
option="clean"
|
||||
;;
|
||||
download)
|
||||
option="download"
|
||||
root=0
|
||||
;;
|
||||
source)
|
||||
option="source"
|
||||
root=0
|
||||
;;
|
||||
*)
|
||||
root=0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# To handle priority of options correctly (environment over config file vars)
|
||||
# we need to preserve all interesting env variables. As this wouldn't be
|
||||
# difficult enough we have to preserve complete env vars (especially if value
|
||||
# ist set (even empty) or not) when changing context (sudo)...
|
||||
# Set a 'random' string to all unset variables.
|
||||
TMP_RANDOM="13979853562951413"
|
||||
TMP_LCK_FILE="${LCK_FILE-${TMP_RANDOM}}"
|
||||
TMP_DOWNLOADBEFORE="${DOWNLOADBEFORE-${TMP_RANDOM}}"
|
||||
TMP__APTMGR="${_APTMGR-${TMP_RANDOM}}"
|
||||
TMP_APTCACHE="${APTCACHE-${TMP_RANDOM}}"
|
||||
TMP_DLDIR="${DLDIR-${TMP_RANDOM}}"
|
||||
TMP_DLLIST="${DLLIST-${TMP_RANDOM}}"
|
||||
TMP__MAXNUM="${MAXNUM-${TMP_RANDOM}}"
|
||||
TMP__MAXCONPERSRV="${MAXCONPERSRV-${TMP_RANDOM}}"
|
||||
TMP__SPLITCON="${SPLITCON-${TMP_RANDOM}}"
|
||||
TMP__MINSPLITSZ=${MINSPLITSZ-${TMP_RANDOM}}
|
||||
TMP__PIECEALGO=${PIECEALGO-${TMP_RANDOM}}
|
||||
TMP_aptfast_prefix="${aptfast_prefix-${TMP_RANDOM}}"
|
||||
TMP_APT_FAST_TIMEOUT="${APT_FAST_TIMEOUT-${TMP_RANDOM}}"
|
||||
TMP_APT_FAST_APT_AUTH="${APT_FAST_APT_AUTH-${TMP_RANDOM}}"
|
||||
TMP_VERBOSE_OUTPUT="${VERBOSE_OUTPUT-${TMP_RANDOM}}"
|
||||
TMP_ftp_proxy="${ftp_proxy-${TMP_RANDOM}}"
|
||||
TMP_http_proxy="${http_proxy-${TMP_RANDOM}}"
|
||||
TMP_https_proxy="${https_proxy-${TMP_RANDOM}}"
|
||||
|
||||
# Check for proper privileges.
|
||||
# Call explicitly with environment variables to get them into root conext.
|
||||
if [ "$root" -ne 0 ] && [ "$UID" != 0 ]; then
|
||||
exec sudo DEBUG="$DEBUG" \
|
||||
LCK_FILE="$TMP_LCK_FILE" \
|
||||
DOWNLOADBEFORE="$TMP_DOWNLOADBEFORE" \
|
||||
_APTMGR="$TMP__APTMGR" \
|
||||
APTCACHE="$TMP_APTCACHE" \
|
||||
DLDIR="$TMP_DLDIR" \
|
||||
DLLIST="$TMP_DLLIST" \
|
||||
_MAXNUM="$TMP__MAXNUM" \
|
||||
_MAXCONPERSRV="$TMP__MAXCONPERSRV" \
|
||||
_SPLITCON="$TMP__SPLITCON" \
|
||||
_MINSPLITSZ="$TMP__MINSPLITSZ" \
|
||||
_PIECEALGO="$TMP__PIECEALGO" \
|
||||
aptfast_prefix="$TMP_aptfast_prefix" \
|
||||
APT_FAST_TIMEOUT="$TMP_APT_FAST_TIMEOUT" \
|
||||
APT_FAST_APT_AUTH="$TMP_APT_FAST_APT_AUTH" \
|
||||
VERBOSE_OUTPUT="$TMP_VERBOSE_OUTPUT" \
|
||||
ftp_proxy="$TMP_ftp_proxy" \
|
||||
http_proxy="$TMP_http_proxy" \
|
||||
https_proxy="$TMP_https_proxy" \
|
||||
"$0" "$@"
|
||||
fi
|
||||
|
||||
# Define lockfile.
|
||||
# Use /tmp as directory because everybody (not only root) has to have write
|
||||
# permissions.
|
||||
# We need lock for non-root commands too, because we only have one download
|
||||
# list file.
|
||||
if [ "$IS_ACE_ENV" != "" ];then
|
||||
LCK_FILE="/tmp/apt-fast-in-container.lock"
|
||||
else
|
||||
LCK_FILE="/tmp/apt-fast.lock"
|
||||
fi
|
||||
|
||||
|
||||
# Set default package manager, APT cache, temporary download dir,
|
||||
# temporary download list file, and maximal parallel downloads
|
||||
_APTMGR=apt-get
|
||||
eval "$(apt-config shell APTCACHE Dir::Cache::archives/d)"
|
||||
# Check if APT config option Dir::Cache::archives::apt-fast-partial is set.
|
||||
eval "$(apt-config shell apt_fast_partial Dir::Cache::archives::apt-fast-partial/d)"
|
||||
if [ -z "$apt_fast_partial" ]; then
|
||||
DLDIR="$(realpath "${APTCACHE}/../apt-fast")"
|
||||
else
|
||||
DLDIR="${apt_fast_partial}"
|
||||
fi
|
||||
|
||||
# Check for apt auth files
|
||||
eval "$(apt-config shell NETRC Dir::Etc::netrc/f)"
|
||||
eval "$(apt-config shell NETRCDIR Dir::Etc::netrcparts/d)"
|
||||
APTAUTHFILES=()
|
||||
if [ -f "$NETRC" ]; then
|
||||
APTAUTHFILES=("$NETRC")
|
||||
fi
|
||||
APTAUTHFILES+=("$NETRCDIR"*)
|
||||
|
||||
LISTTEMP=$(mktemp -d)
|
||||
DLLIST="${LISTTEMP}/apt-fast.list"
|
||||
|
||||
|
||||
|
||||
|
||||
_MAXNUM=5
|
||||
_MAXCONPERSRV=10
|
||||
_SPLITCON=8
|
||||
_MINSPLITSZ="1M"
|
||||
_PIECEALGO="default"
|
||||
MIRRORS=()
|
||||
|
||||
# Prefix in front of apt-fast output:
|
||||
aptfast_prefix=
|
||||
# aptfast_prefix="$(date '+%b %_d %T.%N') apt-fast: "
|
||||
|
||||
|
||||
|
||||
# Set timout value for apt-fast download confirmation dialog.
|
||||
# Value is in seconds.
|
||||
APT_FAST_TIMEOUT=60
|
||||
|
||||
# Ask for download confirmation if unset
|
||||
DOWNLOADBEFORE=
|
||||
|
||||
# Enable APT authentication support
|
||||
APT_FAST_APT_AUTH=1
|
||||
|
||||
# Formatted package list in download confirmation if unset
|
||||
VERBOSE_OUTPUT=
|
||||
|
||||
# Download command.
|
||||
_DOWNLOADER='aria2c --no-conf -c -j ${_MAXNUM} -x ${_MAXCONPERSRV} -s ${_SPLITCON} -i ${DLLIST} --min-split-size=${_MINSPLITSZ} --stream-piece-selector=${_PIECEALGO} --connect-timeout=60 --timeout=600 -m0'
|
||||
|
||||
# 定义默认的配置文件列表(按加载顺序排列)
|
||||
CONFIG_FILES=(
|
||||
"/tmp/aptss-conf/apt-fast.conf" # 原始配置文件位置
|
||||
"/etc/aptss/apt-fast.conf" # 系统级配置
|
||||
)
|
||||
|
||||
|
||||
# 按顺序加载所有配置文件
|
||||
for conf_file in "${CONFIG_FILES[@]}"; do
|
||||
if [ -e "$conf_file" ]; then
|
||||
source "$conf_file"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
|
||||
# no proxy as default
|
||||
ftp_proxy=
|
||||
http_proxy=
|
||||
https_proxy=
|
||||
|
||||
# Now overwrite with preserved values if values were set before (compare with
|
||||
# 'random' string).
|
||||
[ "$TMP_LCK_FILE" = "$TMP_RANDOM" ] || LCK_FILE="$TMP_LCK_FILE"
|
||||
[ "$TMP_DOWNLOADBEFORE" = "$TMP_RANDOM" ] || DOWNLOADBEFORE="$TMP_DOWNLOADBEFORE"
|
||||
[ "$TMP__APTMGR" = "$TMP_RANDOM" ] || _APTMGR="$TMP__APTMGR"
|
||||
[ "$TMP_APTCACHE" = "$TMP_RANDOM" ] || APTCACHE="$TMP_APTCACHE"
|
||||
[ "$TMP_DLDIR" = "$TMP_RANDOM" ] || DLDIR="$TMP_DLDIR"
|
||||
[ "$TMP_DLLIST" = "$TMP_RANDOM" ] || DLLIST="$TMP_DLLIST"
|
||||
[ "$TMP__MAXNUM" = "$TMP_RANDOM" ] || _MAXNUM="$TMP__MAXNUM"
|
||||
[ "$TMP__MAXCONPERSRV" = "$TMP_RANDOM" ] || _MAXCONPERSRV="$TMP__MAXCONPERSRV"
|
||||
[ "$TMP__SPLITCON" = "$TMP_RANDOM" ] || _SPLITCON="$TMP__SPLITCON"
|
||||
[ "$TMP__MINSPLITSZ" = "$TMP_RANDOM" ] || _MINSPLITSZ="$TMP__MINSPLITSZ"
|
||||
[ "$TMP__PIECEALGO" = "$TMP_RANDOM" ] || _PIECEALGO="$TMP__PIECEALGO"
|
||||
[ "$TMP_aptfast_prefix" = "$TMP_RANDOM" ] || aptfast_prefix="$TMP_aptfast_prefix"
|
||||
[ "$TMP_APT_FAST_TIMEOUT" = "$TMP_RANDOM" ] || APT_FAST_TIMEOUT="$TMP_APT_FAST_TIMEOUT"
|
||||
[ "$TMP_APT_FAST_APT_AUTH" = "$TMP_RANDOM" ] || APT_FAST_APT_AUTH="$TMP_APT_FAST_APT_AUTH"
|
||||
[ "$TMP_VERBOSE_OUTPUT" = "$TMP_RANDOM" ] || VERBOSE_OUTPUT="$TMP_VERBOSE_OUTPUT"
|
||||
[ "$TMP_ftp_proxy" = "$TMP_RANDOM" ] || ftp_proxy="$TMP_ftp_proxy"
|
||||
[ "$TMP_http_proxy" = "$TMP_RANDOM" ] || http_proxy="$TMP_http_proxy"
|
||||
[ "$TMP_https_proxy" = "$TMP_RANDOM" ] || https_proxy="$TMP_https_proxy"
|
||||
|
||||
|
||||
# Disable colors if not executed in terminal.
|
||||
if [ ! -t 1 ]; then
|
||||
cGreen=
|
||||
cRed=
|
||||
cBlue=
|
||||
endColor=
|
||||
#FIXME: Time not updated.
|
||||
[ -z "$aptfast_prefix" ] && aptfast_prefix="[apt-fast $(date +"%T")]"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# decode url string
|
||||
# translates %xx but must not convert '+' in spaces
|
||||
urldecode()
|
||||
{
|
||||
printf '%b' "${1//%/\\x}"
|
||||
}
|
||||
|
||||
# Check if mirrors are available. And if so add all mirrors to download list.
|
||||
############ SPARK ADJUST: Now we ignore the first config for business request
|
||||
get_mirrors(){
|
||||
# Check all mirror lists.
|
||||
for mirrorstr in "${MIRRORS[@]}"; do
|
||||
# Build mirrors array from comma separated string.
|
||||
IFS=", " read -r -a mirrors <<< "$mirrorstr"
|
||||
# Check for all mirrors if URI of $1 is from mirror. If so add all other
|
||||
# mirrors to (resmirror) list and break all loops.
|
||||
for mirror in "${mirrors[@]}"; do
|
||||
# Real expension.
|
||||
if [[ "$1" == "$mirror"* ]]; then
|
||||
filepath="${1#"${mirror}"}"
|
||||
# Build list for aria download list.
|
||||
list="${mirrors[*]:1}"
|
||||
echo -e "${list// /${filepath}\\t}$filepath\n"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
# No other mirrors found.
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
##########SPARK ADJUST: END
|
||||
|
||||
AUTH_INFO_PARSED=()
|
||||
# Parse apt authentication files.
|
||||
# Undefined behavior on whitespaces in host, username or password.
|
||||
prepare_auth(){
|
||||
if [ "$APT_FAST_APT_AUTH" -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
for auth_file in "${APTAUTHFILES[@]}"; do
|
||||
# auth files have netrc syntax, possible multiline entries starting with "machine"
|
||||
auth_info="$(tr '\n' ' ' < "$auth_file" | sed 's/\(\<machine\>\)/\n\1/g' | sed '1d')"
|
||||
while IFS= read -r auth; do
|
||||
machine="$(echo "$auth" | sed 's/.*\<machine\>[ \t]\+\([^ \t]\+\).*/\1/')"
|
||||
login="$(echo "$auth" | sed 's/.*\<login\>[ \t]\+\([^ \t]\+\).*/\1/')"
|
||||
password="$(echo "$auth" | sed 's/.*\<password\>[ \t]\+\([^ \t]\+\).*/\1/')"
|
||||
# if machine does not have protocol, try https://
|
||||
if ! [[ "$machine" =~ ^.*:// ]]; then
|
||||
machine="https://$machine"
|
||||
fi
|
||||
if [ -z "$machine" ] || [ -z "$login" ] || [ -z "$password" ]; then
|
||||
msg "Could not parse apt authentication (skipping): $auth ($auth_file)" "warning"
|
||||
continue
|
||||
fi
|
||||
# use space separated string to convert back to array later
|
||||
AUTH_INFO_PARSED+=("$machine $login $password")
|
||||
done <<< "$auth_info"
|
||||
done
|
||||
if [ "${#AUTH_INFO_PARSED[@]}" -eq 0 ]; then
|
||||
# acts like auth disabled when no auth info is provided to improve performance
|
||||
APT_FAST_APT_AUTH=0
|
||||
fi
|
||||
}
|
||||
|
||||
# Gets URI as parameter and tries to add basic http credentials. Will fail on
|
||||
# credentials that contain characters that need URL-encoding.
|
||||
get_auth(){
|
||||
for auth_info in "${AUTH_INFO_PARSED[@]}"; do
|
||||
# convert to array, don't escape variable here
|
||||
auth_info_arr=($auth_info)
|
||||
machine="${auth_info_arr[0]}"
|
||||
# takes first match
|
||||
if [[ "$1" == "$machine"* ]]; then
|
||||
login="${auth_info_arr[1]}"
|
||||
password="${auth_info_arr[2]}"
|
||||
uri="$(echo "$1" | sed "s|^\([^:]\+://\)|\1$login:$password@|")"
|
||||
echo "$uri"
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
# Globals to save package name, version, size and overall size.
|
||||
DOWNLOAD_DISPLAY=
|
||||
DOWNLOAD_SIZE=0
|
||||
|
||||
# 获取包的URI
|
||||
# Get the package URLs.
|
||||
get_uris(){
|
||||
if [ ! -d "$(dirname "$DLLIST")" ]
|
||||
then
|
||||
if ! mkdir -p -- "$(dirname "$DLLIST")"
|
||||
then
|
||||
msg "Could not create download file directory." "warning"
|
||||
msg "无法创建下载目录" "warning"
|
||||
CLEANUP_STATE=1
|
||||
exit
|
||||
fi
|
||||
elif [ -f "$DLLIST" ]; then
|
||||
if ! rm -f -- "$DLLIST" 2>/dev/null && ! touch -- "$DLLIST" 2>/dev/null
|
||||
then
|
||||
msg "Unable to write to download file. Try restarting with root permissions or run 'apt-fast clean' first." "warning"
|
||||
msg "无法下载文件。尝试使用root权限,或者运行 'aptss clean'" "warning"
|
||||
CLEANUP_STATE=1
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add header to overwrite file.
|
||||
echo "# apt-fast mirror list: $(date)" > "$DLLIST"
|
||||
# NOTE: "aptitude" doesn't have this functionality
|
||||
# so we use "${_APTMGR}" to get package URI's
|
||||
case "$(basename "${_APTMGR}")" in
|
||||
'apt'|'apt-get') uri_mgr="${_APTMGR}";;
|
||||
*) uri_mgr='apt-get';;
|
||||
esac
|
||||
uris_full="$("$uri_mgr" "${APT_SCRIPT_WARNING[@]}" -y --print-uris "$@")"
|
||||
CLEANUP_STATE="$?"
|
||||
if [ "$CLEANUP_STATE" -ne 0 ]
|
||||
then
|
||||
msg "Package manager quit with exit code. Here is the log" "warning"
|
||||
msg "包管理器以错误代码退出.日志如下" "warning"
|
||||
msg "${uris_full}"
|
||||
exit "$CLEANUP_STATE"
|
||||
fi
|
||||
prepare_auth
|
||||
local tmpdir
|
||||
tmpdir=$(mktemp -d) || {
|
||||
msg "Failed to create tmp dir" "warning"
|
||||
msg "无法创建临时目录" "warning"
|
||||
exit 1
|
||||
|
||||
|
||||
}
|
||||
|
||||
cleanup_tmpdir() {
|
||||
if [ -n "$tmpdir" ] && [ -d "$tmpdir" ]; then
|
||||
rm -rf "$tmpdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup_tmpdir EXIT
|
||||
|
||||
## --print-uris format is:
|
||||
# 'fileurl' filename filesize checksum_hint:filechecksum
|
||||
# 修改:process_package函数增加第二个参数表示当前线程的临时输出文件
|
||||
process_package() {
|
||||
local pkg_uri_info="$1"
|
||||
local thread_file="$2"
|
||||
local display_line="" # 初始化显示信息为空
|
||||
IFS=' ' read -r uri filename filesize checksum_string _ <<<"$pkg_uri_info"
|
||||
[ -z "$uri" ] && return
|
||||
uri="${uri//"'"/}"
|
||||
[ "$APT_FAST_APT_AUTH" -ne 0 ] && uri="$(get_auth "$uri")"
|
||||
IFS=':' read -r hash_algo checksum _ <<<"$checksum_string"
|
||||
|
||||
if [[ "$filename" == *%* ]]; then
|
||||
# decode url string
|
||||
filename_decoded="$(printf '%b' "${filename//%/\\x}")"
|
||||
else
|
||||
filename_decoded="$filename"
|
||||
fi
|
||||
IFS='_' read -r pkg_name_decoded pkg_version_decoded _ <<<"$filename_decoded"
|
||||
|
||||
display_line+="$pkg_name_decoded $pkg_version_decoded $filesize\n"
|
||||
if [ -n "$HASH_SUPPORTED" ]; then
|
||||
case "$hash_algo" in
|
||||
SHA512) [ -z "$SHA512_SUPPORTED" ] && hash_algo= || hash_algo=sha-512 ;;
|
||||
SHA256) [ -z "$SHA256_SUPPORTED" ] && hash_algo= || hash_algo=sha-256 ;;
|
||||
SHA1) [ -z "$SHA1_SUPPORTED" ] && hash_algo= || hash_algo=sha-1 ;;
|
||||
MD5Sum) [ -z "$MD5sum_SUPPORTED" ] && hash_algo= || hash_algo=md5 ;;
|
||||
*) hash_algo=
|
||||
esac
|
||||
|
||||
|
||||
# Using apt-cache show package=version to ensure recover single and
|
||||
# correct package version.
|
||||
# Warning: assuming that package naming uses '_' as field separator.
|
||||
# Therefore, this code expects package-name_version_arch.deb Otherwise
|
||||
# below code will fail resoundingly
|
||||
if [ -z "$hash_algo" ]; then
|
||||
IFS='_' read -r pkg_name _ <<<"$filename"
|
||||
pkg_version="$pkg_version_decoded"
|
||||
# Transform multi-line field output from apt-cache to single line and sort checksums, strongest first
|
||||
package_info="$(apt-cache show "$pkg_name=$pkg_version" | sed ':r;$!{N;br};s/\n / /g' | sort -r)"
|
||||
|
||||
while IFS=': ' read -r field checksum _
|
||||
do
|
||||
case "$field" in
|
||||
SHA512)
|
||||
[ -n "$SHA512_SUPPORTED" ] || continue
|
||||
hash_algo="sha-512"
|
||||
break ;;
|
||||
SHA256)
|
||||
[ -n "$SHA256_SUPPORTED" ] || continue
|
||||
hash_algo="sha-256"
|
||||
break ;;
|
||||
SHA1)
|
||||
[ -n "$SHA1_SUPPORTED" ] || continue
|
||||
hash_algo="sha-1"
|
||||
break ;;
|
||||
MD5sum)
|
||||
[ -n "$MD5sum_SUPPORTED" ] || continue
|
||||
hash_algo="md5"
|
||||
break ;;
|
||||
esac
|
||||
done <<<"$package_info"
|
||||
|
||||
if [ -z "$hash_algo" ]; then
|
||||
checksum=
|
||||
msg "Couldn't get supported checksum for $pkg_name ($pkg_version)." "warning"
|
||||
msg "无法获得 $pkg_name ($pkg_version) 版本受到支持的散列验证值" "warning"
|
||||
REMOVE_WORKING_MESSAGE=
|
||||
fi
|
||||
fi
|
||||
else
|
||||
hash_algo=
|
||||
fi
|
||||
|
||||
# 原来利用文件锁写入,现在改为写入当前线程的临时文件
|
||||
{
|
||||
get_mirrors "$uri"
|
||||
[ -n "$hash_algo" ] && echo " checksum=$hash_algo=$checksum"
|
||||
echo " out=$filename"
|
||||
} >> "$thread_file"
|
||||
|
||||
echo -e "$display_line" >> "$tmpdir/display"
|
||||
echo "$filesize" >> "$tmpdir/sizes"
|
||||
}
|
||||
|
||||
# 主并行处理逻辑
|
||||
mapfile -t pkg_uri_list < <(echo "$uris_full" | grep -E "^'(http(s|)|(s|)ftp)://")
|
||||
total_pkgs=${#pkg_uri_list[@]}
|
||||
threads=${THREADS:-4} # 默认4线程
|
||||
per_thread=$(( (total_pkgs + threads - 1) / threads )) # 向上取整
|
||||
|
||||
# 分配任务到不同线程,每个线程使用自己的临时文件
|
||||
for ((i=0; i<threads; i++)); do
|
||||
thread_file="${DLLIST}.thread.${i}"
|
||||
> "$thread_file" # 清空或创建临时文件
|
||||
start=$((i * per_thread))
|
||||
end=$((start + per_thread -1))
|
||||
[ $end -ge $total_pkgs ] && end=$((total_pkgs -1))
|
||||
|
||||
# 启动后台线程处理任务块
|
||||
(
|
||||
for ((j=start; j<=end; j++)); do
|
||||
[ -z "${pkg_uri_list[j]}" ] && continue
|
||||
process_package "${pkg_uri_list[j]}" "$thread_file"
|
||||
done
|
||||
) &
|
||||
done
|
||||
|
||||
# 等待所有后台任务完成
|
||||
wait
|
||||
|
||||
# 合并所有线程的临时文件到最终的 $DLLIST 中(保留之前添加的 header)
|
||||
for ((i=0; i<threads; i++)); do
|
||||
thread_file="${DLLIST}.thread.${i}"
|
||||
if [ -f "$thread_file" ]; then
|
||||
cat "$thread_file" >> "$DLLIST"
|
||||
rm -f "$thread_file"
|
||||
fi
|
||||
done
|
||||
# 合并显示信息
|
||||
if [ -f "$tmpdir/display" ]; then
|
||||
DOWNLOAD_DISPLAY+="\n$(cat "$tmpdir/display")"
|
||||
fi
|
||||
|
||||
# 计算总下载大小
|
||||
if [ -f "$tmpdir/sizes" ]; then
|
||||
DOWNLOAD_SIZE=$(awk '{sum+=$1} END{print sum}' "$tmpdir/sizes")
|
||||
fi
|
||||
|
||||
# 清理临时目录
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
|
||||
|
||||
display_downloadfile(){
|
||||
if [ -n "$VERBOSE_OUTPUT" ]; then
|
||||
cat "$DLLIST"
|
||||
else
|
||||
DISPLAY_SORT_OPTIONS=(-k 1,1)
|
||||
# Sort output after package download size (decreasing):
|
||||
#DISPLAY_SORT_OPTIONS=(-k 3,3 -hr)
|
||||
while IFS=' ' read -r pkg ver size _; do
|
||||
[ -z "$pkg" ] && continue
|
||||
printf '%s%-40s %-20s %10s\n' "$aptfast_prefix" "$pkg" "$ver" "$size"
|
||||
done <<<"$(echo -e "$DOWNLOAD_DISPLAY" | sort "${DISPLAY_SORT_OPTIONS[@]}" | numfmt --to=iec-i --suffix=B --field=3)"
|
||||
fi
|
||||
msg "Download size: $(echo "$DOWNLOAD_SIZE" | numfmt --to=iec-i --suffix=B)" "normal"
|
||||
msg "下载大小: $(echo "$DOWNLOAD_SIZE" | numfmt --to=iec-i --suffix=B)" "normal"
|
||||
}
|
||||
|
||||
|
||||
# Create and insert a PID number to lockfile.
|
||||
|
||||
|
||||
|
||||
# Make sure aria2c (in general first parameter from _DOWNLOADER) is available.
|
||||
CMD="$(echo "$_DOWNLOADER" | sed 's/^\s*\([^ ]\+\).*$/\1/')"
|
||||
if [ ! "$(command -v "$CMD")" ]; then
|
||||
msg "Command not found: $CMD" "normal" "err"
|
||||
msg "You must configure $CONFFILE to use aria2c or another supported download manager" "normal" "err"
|
||||
CLEANUP_STATE=1
|
||||
exit
|
||||
fi
|
||||
|
||||
# Make sure package manager is available.
|
||||
if [ ! "$(command -v "$_APTMGR")" ]; then
|
||||
msg "\`$_APTMGR\` command not available." "warning"
|
||||
msg "You must configure $CONFFILE to use either apt-get or aptitude." "normal" "err"
|
||||
CLEANUP_STATE=1
|
||||
exit
|
||||
fi
|
||||
|
||||
# Disable script warning if apt is used.
|
||||
APT_SCRIPT_WARNING=()
|
||||
if [ "$(basename "${_APTMGR}")" == 'apt' ]; then
|
||||
APT_SCRIPT_WARNING=(-o "Apt::Cmd::Disable-Script-Warning=true")
|
||||
fi
|
||||
|
||||
# Set supported hash algorithms by aria2c (and also by Debian repository).
|
||||
SHA512_SUPPORTED=
|
||||
SHA256_SUPPORTED=
|
||||
SHA1_SUPPORTED=
|
||||
MD5sum_SUPPORTED=
|
||||
HASH_SUPPORTED=
|
||||
if [ "$CMD" == "aria2c" ]; then
|
||||
for supported_hash in $(LC_ALL=C aria2c -v | sed '/^Hash Algorithms:/!d; s/\(^Hash Algorithms: \|,\)\+//g'); do
|
||||
case "$supported_hash" in
|
||||
sha-512) SHA512_SUPPORTED=y; HASH_SUPPORTED=y ;;
|
||||
sha-256) SHA256_SUPPORTED=y; HASH_SUPPORTED=y ;;
|
||||
sha-1) SHA1_SUPPORTED=y; HASH_SUPPORTED=y ;;
|
||||
md5) MD5sum_SUPPORTED=y; HASH_SUPPORTED=y ;;
|
||||
esac
|
||||
done
|
||||
if [ -z "$HASH_SUPPORTED" ]; then
|
||||
msg "Couldn't find supported checksum algorithm from aria2c. Checksums disabled." "warning"
|
||||
msg "无法找到aria2c支持的散列验证算法. 散列验证已被禁用." "warning"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if "assume yes" switch is enabled and if yes enable $DOWNLOADBEFORE.
|
||||
# Also check if "download only" switch is enabled.
|
||||
#TODO: Get real value over APT items APT::Get::Assume-Yes and
|
||||
# APT::Get::Assume-No .
|
||||
# Respectively Aptitude::CmdLine::Download-Only and APT::Get::Download-Only.
|
||||
DOWNLOAD_ONLY=
|
||||
while true; do
|
||||
while getopts ":dy-:" optchar; do
|
||||
case "${optchar}" in
|
||||
-)
|
||||
case "${OPTARG}" in
|
||||
yes | assume-yes) DOWNLOADBEFORE=true ;;
|
||||
assume-no) DOWNLOADBEFORE= ;;
|
||||
download-only) DOWNLOAD_ONLY=true ;;
|
||||
esac
|
||||
;;
|
||||
y)
|
||||
DOWNLOADBEFORE=true
|
||||
;;
|
||||
d)
|
||||
DOWNLOAD_ONLY=true
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
((OPTIND++))
|
||||
[ $OPTIND -gt $# ] && break
|
||||
done
|
||||
|
||||
# Configure proxies. Use apt values over environment variables.
|
||||
# Note: If proxy setting is not set, there is no apt-config output.
|
||||
# Therefore variable doesn't get overriden, which is intended.
|
||||
# Export the variables to make them available in subshells (aka the
|
||||
# downloader command).
|
||||
eval "$(apt-config shell ftp_proxy Acquire::ftp::proxy)"
|
||||
export ftp_proxy
|
||||
eval "$(apt-config shell http_proxy Acquire::http::proxy)"
|
||||
export http_proxy
|
||||
eval "$(apt-config shell https_proxy Acquire::https::proxy)"
|
||||
export https_proxy
|
||||
|
||||
# aria2 has no socks support (see https://github.com/aria2/aria2/issues/153)
|
||||
if echo "$http_proxy" | grep -q "^socks5h://" || echo "$https_proxy" | grep -q "^socks5h://"; then
|
||||
msg "Socks proxy detected. Falling back to ${_APTMGR}" "hint"
|
||||
"${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Run actions.
|
||||
if [ "$option" == "install" ]; then
|
||||
msg
|
||||
msg "Working... this may take a while." "normal"
|
||||
msg "正在工作中,请稍等" "normal"
|
||||
REMOVE_WORKING_MESSAGE=y
|
||||
|
||||
get_uris "$@"
|
||||
[ -t 1 ] && [ -n "$REMOVE_WORKING_MESSAGE" ] && tput cuu 1 && tput el && tput cuu 1
|
||||
# Test /tmp/apt-fast.list file exists and not just the apt-fast comment line.
|
||||
# Then download all files from the list.
|
||||
if [ -f "$DLLIST" ] && [ "$(wc -l "$DLLIST" | cut -d' ' -f1)" -gt 1 ] && [ ! "$DOWNLOADBEFORE" ]; then
|
||||
display_downloadfile
|
||||
msg
|
||||
msg "Do you want to download the packages? [Y/n] " "question"
|
||||
|
||||
while ((!updsys)); do
|
||||
read -r -sn1 -t "$APT_FAST_TIMEOUT" answer || { msg; msg "Timed out." "warning"; CLEANUP_STATE=1; exit; }
|
||||
case "$answer" in
|
||||
[JjYy]) result=1; updsys=1 ;;
|
||||
[Nn]) result=0; updsys=1 ;;
|
||||
"") result=1; updsys=1 ;;
|
||||
*) updsys=0 ;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
result=1
|
||||
fi
|
||||
|
||||
if ((DOWNLOAD_SIZE)); then
|
||||
msg
|
||||
# Continue if answer was right or DOWNLOADBEFORE is enabled.
|
||||
if ((result)); then
|
||||
if [ -s "$DLLIST" ]; then
|
||||
# Test if apt-fast directory is present where we put packages.
|
||||
if [ ! -d "$DLDIR" ]; then
|
||||
mkdir -p -- "$DLDIR"
|
||||
fi
|
||||
|
||||
cd "$DLDIR" &>/dev/null || { msg; msg "Not able to change into download directory." "warning"; CLEANUP_STATE=1; exit; }
|
||||
|
||||
eval "${_DOWNLOADER}" # execute downloadhelper command
|
||||
if [ "$(find "$DLDIR" -printf . | wc -c)" -gt 1 ]; then
|
||||
|
||||
# Delete incomplete/corrupted downloaded files, if any: Not recursive, as we don't expect any dirs to exist within $DLDIR.
|
||||
|
||||
# When Aria2c downloads a file and detects it is corrupted, its filename won't be renamed back to its actual name,
|
||||
# preserving .aria2 file extension, which also indicates when a file hasn't been completely downloaded.
|
||||
for x in *.aria2; do
|
||||
rm -f "$x" "${x%.aria2}"
|
||||
done
|
||||
|
||||
# Move all packages to the apt install directory by force to ensure
|
||||
# already existing debs which may be incomplete are replaced
|
||||
find . -type f \( -name '*.deb' -o -name '*.ddeb' \) -execdir mv -ft "$APTCACHE" {} \+
|
||||
fi
|
||||
cd - &>/dev/null || msg "Failed to change back directory" "warning"
|
||||
fi
|
||||
else
|
||||
CLEANUP_STATE=1
|
||||
exit
|
||||
fi
|
||||
else
|
||||
[ -t 1 ] && tput el
|
||||
fi
|
||||
|
||||
# different problem resolving for aptitude
|
||||
if [ -z "$DOWNLOAD_ONLY" ] || [ "$(basename "${_APTMGR}")" == 'aptitude' ]; then
|
||||
"${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
|
||||
fi
|
||||
|
||||
|
||||
elif [ "$option" == "clean" ]; then
|
||||
"${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@" && {
|
||||
if [ -d "$DLDIR" ]; then
|
||||
find "$DLDIR" -maxdepth 1 -type f -delete
|
||||
CLEANUP_STATE="$?"
|
||||
[ -f "$DLLIST" ] && rm -f -- "$DLLIST"* || true
|
||||
fi
|
||||
}
|
||||
|
||||
elif [ "$option" == "download" ]; then
|
||||
msg
|
||||
msg "Working... this may take a while." "normal"
|
||||
msg "正在工作中,请稍等" "normal"
|
||||
REMOVE_WORKING_MESSAGE=y
|
||||
|
||||
get_uris "$@"
|
||||
|
||||
[ -t 1 ] && [ -n "$REMOVE_WORKING_MESSAGE" ] && tput cuu 1 && tput el && tput cuu 1
|
||||
|
||||
if [ -f "$DLLIST" ] && [ "$(wc -l "$DLLIST" | cut -d' ' -f1)" -gt 1 ]; then
|
||||
display_downloadfile
|
||||
eval "${_DOWNLOADER}"
|
||||
fi
|
||||
|
||||
# different problem resolving for aptitude
|
||||
if [ "$(basename "${_APTMGR}")" == 'aptitude' ]; then
|
||||
"${_APTMGR}" "$@"
|
||||
fi
|
||||
|
||||
# Clean up temporary directory for download command
|
||||
cleanup_aptfast
|
||||
|
||||
elif [ "$option" == "source" ]; then
|
||||
msg
|
||||
msg "Working... this may take a while." "normal"
|
||||
msg "正在工作中,请稍等" "normal"
|
||||
REMOVE_WORKING_MESSAGE=y
|
||||
|
||||
get_uris "$@"
|
||||
|
||||
[ -t 1 ] && [ -n "$REMOVE_WORKING_MESSAGE" ] && tput cuu 1 && tput el && tput cuu 1
|
||||
|
||||
if [ -f "$DLLIST" ] && [ "$(wc -l "$DLLIST" | cut -d' ' -f1)" -gt 1 ]; then
|
||||
display_downloadfile
|
||||
eval "${_DOWNLOADER}"
|
||||
fi
|
||||
# We use APT manager here to provide more verbose output. This method is
|
||||
# slightly slower then extractiong packages manually after download but also
|
||||
# more hardened (e.g. some options like --compile are available).
|
||||
"${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
|
||||
# Uncomment following snippet to extract source directly and comment
|
||||
# both lines before.
|
||||
#while read srcfile; do
|
||||
# # extract only .dsc files
|
||||
# echo "$srcfile" | grep -q '\.dsc$' || continue
|
||||
# dpkg-source -x "$(basename "$srcfile")"
|
||||
#done < "$DLLIST"
|
||||
|
||||
# Clean up temporary directory for source command
|
||||
cleanup_aptfast
|
||||
|
||||
# Execute package manager directly if unknown options are passed.
|
||||
else
|
||||
"${_APTMGR}" "${APT_SCRIPT_WARNING[@]}" "$@"
|
||||
fi
|
||||
|
||||
# After error or all done remove our lockfile (done with EXIT trap)
|
||||
|
||||
160
tool/aptss
Executable file
160
tool/aptss
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
|
||||
SPARK_DOWNLOAD_SERVER_URL="https://d.spark-app.store/"
|
||||
SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL="d.spark-app.store"
|
||||
|
||||
if [[ "$IS_APM_ENV" = "" ]] ;then
|
||||
UPSTREAM_CATOGARY="sparkstore"
|
||||
else
|
||||
UPSTREAM_CATOGARY="apm"
|
||||
fi
|
||||
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
source /opt/durapps/spark-store/bin/bashimport/log.amber
|
||||
load_transhell
|
||||
|
||||
if [[ "$IS_APM_ENV" = "" ]] ;then
|
||||
case $(arch) in
|
||||
x86_64 | i686 | i386)
|
||||
STORE_URL="store"
|
||||
STORE_LIST_URL=""
|
||||
;;
|
||||
aarch64)
|
||||
STORE_URL="aarch64-store"
|
||||
STORE_LIST_URL="-aarch64"
|
||||
;;
|
||||
loongarch64)
|
||||
STORE_URL="loong64-store"
|
||||
STORE_LIST_URL="-loong64"
|
||||
;;
|
||||
riscv64)
|
||||
STORE_URL="riscv64-store"
|
||||
STORE_LIST_URL="-riscv64"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case $(arch) in
|
||||
x86_64 | i686 | i386)
|
||||
STORE_URL="amd64-apm"
|
||||
STORE_LIST_URL="-amd64"
|
||||
;;
|
||||
aarch64)
|
||||
STORE_URL="arm64-apm"
|
||||
STORE_LIST_URL="-arm64"
|
||||
;;
|
||||
loongarch64)
|
||||
STORE_URL="loong64-apm"
|
||||
STORE_LIST_URL="-loong64"
|
||||
;;
|
||||
riscv64)
|
||||
STORE_URL="riscv64-apm"
|
||||
STORE_LIST_URL="-riscv64"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
SS_APT_FAST="/opt/durapps/spark-store/bin/apt-fast/ss-apt-fast"
|
||||
|
||||
|
||||
is_empty_dir(){
|
||||
return `ls -A $1|wc -w`
|
||||
}
|
||||
|
||||
function update_list(){
|
||||
curl --progress-bar -o /opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d/aptss.list "${SPARK_DOWNLOAD_SERVER_URL}/${UPSTREAM_CATOGARY}${STORE_LIST_URL}.list"
|
||||
log.info "${UPSTREAM_CATOGARY}${STORE_LIST_URL}.list update done"
|
||||
}
|
||||
|
||||
function update_conf(){
|
||||
mkdir -p /tmp/aptss-conf/
|
||||
curl --progress-bar -o /tmp/aptss-conf/apt-fast.conf "${SPARK_DOWNLOAD_SERVER_URL}/apt-fast.conf"
|
||||
log.info "apt-fast.conf update done"
|
||||
chmod -R 755 /tmp/aptss-conf
|
||||
}
|
||||
|
||||
if [ "$(id -u)" != "0" ];then
|
||||
#############################无root权限时
|
||||
echo -e "\e[1;32m${TRANSHELL_CONTENT_RUNNING_IN_NOT_ROOT_USER}\e[0m"
|
||||
|
||||
else
|
||||
|
||||
|
||||
ln -sf /etc/apt/sources.list.d/* /opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d
|
||||
###让这里和系统同步,先链接,然后清除无效链接
|
||||
find /opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d -xtype l -delete
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -e "/tmp/aptss-conf/apt-fast.conf" ];then
|
||||
###刷新apt-fast配置
|
||||
mkdir -p /tmp/aptss-conf/
|
||||
echo -e "\e[1;32m${TRANSHELL_CONTENT_GETTING_SERVER_CONFIG_AND_MIRROR_LIST}\e[0m"
|
||||
echo
|
||||
update_conf
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -e "/var/lib/aptss/lists/${SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL}_${STORE_URL}_Packages" ] && [ ! -e "/var/lib/aptss/lists/d.store.deepinos.org.cn_${STORE_URL}_Packages" ] && [ ! -e "/var/lib/aptss/lists/mirrors.sdu.edu.cn_spark-store-repository_${STORE_URL}_Packages" ];then
|
||||
|
||||
mkdir -p /tmp/aptss-conf/
|
||||
echo -e "\e[1;32m${TRANSHELL_CONTENT_GETTING_SERVER_CONFIG_AND_MIRROR_LIST}\e[0m"
|
||||
echo
|
||||
|
||||
update_list
|
||||
update_conf
|
||||
|
||||
#只更新星火源
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if [ "$1" = "install" ] || [ "$1" = "upgrade" ] || [ "$1" = "full-upgrade" ] || [ "$1" = "reinstall" ] || [ "$1" = "dist-upgrade" ]; then
|
||||
|
||||
|
||||
|
||||
###执行
|
||||
|
||||
${SS_APT_FAST} "$@" --allow-downgrades -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf
|
||||
ret="$?"
|
||||
if [ "$ret" -ne 0 ];then
|
||||
echo -e "\e[1;33m$TRANSHELL_CONTENT_PLEASE_USE_APTSS_INSTEAD_OF_APT\e[0m"
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
elif [ "$1" = "ssupdate" ];then
|
||||
|
||||
mkdir -p /tmp/aptss-conf/
|
||||
echo -e "\e[1;32m${TRANSHELL_CONTENT_GETTING_SERVER_CONFIG_AND_MIRROR_LIST}\e[0m"
|
||||
echo
|
||||
|
||||
|
||||
update_list
|
||||
update_conf
|
||||
|
||||
/usr/bin/apt update -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" -o Dir::Etc::sourcelist="/opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d/aptss.list"
|
||||
|
||||
#只更新星火源
|
||||
|
||||
elif [ "$1" = "update" ];then
|
||||
|
||||
echo -e "\e[1;32m${TRANSHELL_CONTENT_GETTING_SERVER_CONFIG_AND_MIRROR_LIST}\e[0m"
|
||||
echo
|
||||
update_list
|
||||
update_conf
|
||||
### 额外一份拿来给aptss自动补全用
|
||||
|
||||
${SS_APT_FAST} "$@" -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf
|
||||
|
||||
else
|
||||
${SS_APT_FAST} "$@" -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf
|
||||
fi
|
||||
|
||||
5
tool/bashimport/log.amber
Normal file
5
tool/bashimport/log.amber
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
log.warn() { echo -e "[\e[33mWARN\e[0m]: \e[1m$*\e[0m"; }
|
||||
log.error() { echo -e "[\e[31mERROR\e[0m]: \e[1m$*\e[0m"; }
|
||||
log.info() { echo -e "[\e[96mINFO\e[0m]: \e[1m$*\e[0m"; }
|
||||
log.debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; }
|
||||
31
tool/bashimport/transhell.amber
Executable file
31
tool/bashimport/transhell.amber
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
##load transhell
|
||||
function load_transhell_debug()
|
||||
{
|
||||
local WORK_PATH="$(cd "$(dirname "${0}")" && pwd)"
|
||||
local CURRENT_LANG="$(echo ${LANG%.*})"
|
||||
if [ -e "/usr/share/$(basename $0)/transhell/$(basename $0)_en_US.transhell" ]; then source /usr/share/$(basename $0)/transhell/$(basename $0)_en_US.transhell; echo "Loading transhell from /usr/share/$(basename $0)/transhell/$(basename $0)_en_US.transhell ..."; fi
|
||||
if [ -e "/usr/share/$(basename $0)/transhell/$(basename $0)_$CURRENT_LANG.transhell" ]; then source /usr/share/$(basename $0)/transhell/$(basename $0)_$CURRENT_LANG.transhell; echo "Loading transhell from /usr/share/$(basename $0)/transhell/$(basename $0)_$CURRENT_LANG.transhell ..."; fi
|
||||
if [ -e "${WORK_PATH}/transhell/$(basename $0)_en_US.transhell" ]; then source ${WORK_PATH}/transhell/$(basename $0)_en_US.transhell; echo "Loading transhell from ${WORK_PATH}/transhell/$(basename $0)_en_US.transhell ..."; fi
|
||||
if [ -e "${WORK_PATH}/transhell/$(basename $0)_$CURRENT_LANG.transhell" ]; then source ${WORK_PATH}/transhell/$(basename $0)_$CURRENT_LANG.transhell; echo "Loading transhell from ${WORK_PATH}/transhell/$(basename $0)_$CURRENT_LANG.transhell ..."; fi
|
||||
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
function load_transhell()
|
||||
{
|
||||
local WORK_PATH="$(cd "$(dirname "${0}")" && pwd)"
|
||||
local CURRENT_LANG="$(echo ${LANG%.*})"
|
||||
if [ -e "/usr/share/$(basename $0)/transhell/$(basename $0)_en_US.transhell" ]; then source /usr/share/$(basename $0)/transhell/$(basename $0)_en_US.transhell; fi
|
||||
if [ -e "/usr/share/$(basename $0)/transhell/$(basename $0)_$CURRENT_LANG.transhell" ]; then source /usr/share/$(basename $0)/transhell/$(basename $0)_$CURRENT_LANG.transhell; fi
|
||||
if [ -e "${WORK_PATH}/transhell/$(basename $0)_en_US.transhell" ]; then source ${WORK_PATH}/transhell/$(basename $0)_en_US.transhell; fi
|
||||
if [ -e "${WORK_PATH}/transhell/$(basename $0)_$CURRENT_LANG.transhell" ]; then source ${WORK_PATH}/transhell/$(basename $0)_$CURRENT_LANG.transhell; fi
|
||||
|
||||
}
|
||||
|
||||
function update_transhell()
|
||||
{
|
||||
load_transhell $@
|
||||
}
|
||||
|
||||
33
tool/open-in-terminal/open-in-terminal
Executable file
33
tool/open-in-terminal/open-in-terminal
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
load_transhell
|
||||
# 检查是否传入了路径参数
|
||||
if [ -z "$1" ]; then
|
||||
echo "${TRANSHELL_CONTENT_PLEASE_PROVIDE_FILE_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DESKTOP_FILE_PATH=$1
|
||||
|
||||
if [[ $DESKTOP_FILE_PATH == file://* ]]; then
|
||||
# 如果是,移除 'file://' 部分并输出结果
|
||||
DESKTOP_FILE_PATH="${DESKTOP_FILE_PATH#file://}"
|
||||
fi
|
||||
|
||||
# 获取文件内容中第一个 Exec= 后的命令
|
||||
exec_command=$(grep -m 1 -oP "(?<=Exec=).*" "$DESKTOP_FILE_PATH")
|
||||
|
||||
# 删除 exec_command 中最后的 % 及其后面的内容
|
||||
exec_command="${exec_command%\%*}"
|
||||
|
||||
# 打印提取的命令
|
||||
echo "$exec_command"
|
||||
|
||||
# 在默认终端执行命令
|
||||
eval "$exec_command"
|
||||
|
||||
echo --------------------------------------
|
||||
echo "${TRANSHELL_CONTENT_ABOVE_IS_TERMINAL_OUTPUT}"
|
||||
echo "${TRANSHELL_CONTENT_PRESS_ENTER_TO_FINISH}"
|
||||
read
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_PLEASE_PROVIDE_FILE_PATH="Please provide a file path as an argument"
|
||||
TRANSHELL_CONTENT_ABOVE_IS_TERMINAL_OUTPUT="The above is the output executed in the terminal. Please copy and paste it when providing feedback."
|
||||
TRANSHELL_CONTENT_PRESS_ENTER_TO_FINISH="Press Enter to finish"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_PLEASE_PROVIDE_FILE_PATH="请传入文件路径作为参数"
|
||||
TRANSHELL_CONTENT_ABOVE_IS_TERMINAL_OUTPUT="以上是在终端中执行的输出,请在反馈问题的时候完整复制并贴上"
|
||||
TRANSHELL_CONTENT_PRESS_ENTER_TO_FINISH="按回车结束"
|
||||
|
||||
147
tool/spark-dstore-patch
Executable file
147
tool/spark-dstore-patch
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enumAppInfoList() {
|
||||
appInfoList=()
|
||||
apps="/opt/apps"
|
||||
list=$(ls $apps 2>/dev/null)
|
||||
for appID in $list; do
|
||||
appInfoList+=("$appID")
|
||||
done
|
||||
echo "${appInfoList[@]}"
|
||||
}
|
||||
linkDir() {
|
||||
ensureTargetDir() {
|
||||
targetFile=$1
|
||||
t=$(dirname "$targetFile")
|
||||
mkdir -p "$t"
|
||||
}
|
||||
|
||||
source=$1
|
||||
target=$2
|
||||
sourceDir=$(dirname "$source")
|
||||
targetDir=$(dirname "$target")
|
||||
find "$source" -type f | while read sourceFile; do
|
||||
targetFile="$targetDir/${sourceFile#$sourceDir/}"
|
||||
|
||||
|
||||
ensureTargetDir "$targetFile"
|
||||
sourceFile=$(realpath --relative-to="$(dirname $targetFile)" "$sourceFile" )
|
||||
if [ ! -e "${targetFile}" ];then
|
||||
ln -sv "$sourceFile" "$targetFile"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
linkApp() {
|
||||
appID=$1
|
||||
appEntriesDir="/opt/apps/$appID/entries"
|
||||
appLibsDir="/opt/apps/$appID/files/lib"
|
||||
autoStartDir="$appEntriesDir/autostart"
|
||||
|
||||
if [ -d "$autoStartDir" ]; then
|
||||
linkDir "$autoStartDir" "/etc/xdg/autostart"
|
||||
fi
|
||||
|
||||
# link application
|
||||
sysShareDir="/usr/share"
|
||||
for folder in "$appEntriesDir/applications" "$appEntriesDir/icons" "$appEntriesDir/mime" "$appEntriesDir/glib-2.0" "$appEntriesDir/services" "$appEntriesDir/GConf" "$appEntriesDir/help" "$appEntriesDir/locale" "$appEntriesDir/fcitx"; do
|
||||
if [ ! -d "$folder" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$folder" = "$appEntriesDir/polkit" ]; then
|
||||
linkDir "$folder" "/usr/share/polkit-1"
|
||||
elif [ "$folder" = "$appEntriesDir/fonts/conf" ]; then
|
||||
linkDir "$folder" "/etc/fonts/conf.d"
|
||||
else
|
||||
linkDir "$folder" "$sysShareDir/${folder##*/}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function exec_uos_package_link(){
|
||||
|
||||
for app in $(enumAppInfoList); do
|
||||
linkApp "$app" &
|
||||
|
||||
done
|
||||
wait
|
||||
}
|
||||
|
||||
function exec_v23_icon_link(){
|
||||
# Fix v23 broken icon
|
||||
if [ ! -d "/usr/share/icons/hicolor/scalable/apps" ];then
|
||||
mkdir -p /usr/share/icons/hicolor/scalable/apps
|
||||
fi
|
||||
|
||||
for icon_root_icon_path in $(ls /usr/share/icons/*.png /usr/share/icons/*.svg 2>/dev/null)
|
||||
do
|
||||
target_icon_path=/usr/share/icons/hicolor/scalable/apps/$(basename ${icon_root_icon_path})
|
||||
if [ ! -e ${target_icon_path} ];then
|
||||
ln -sv $(realpath --relative-to=/usr/share/icons/hicolor/scalable/apps ${icon_root_icon_path}) /usr/share/icons/hicolor/scalable/apps
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function exec_link_clean(){
|
||||
# remove broken links in /usr/share
|
||||
|
||||
find /usr/share/applications -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/icons -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/mime/packages -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/glib-2.0 -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/dbus-1/services -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/fcitx -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/help -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/locale -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
|
||||
# 根据 uname -m 确定 multiarch 目录名
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
x86_64)
|
||||
multiarch="x86_64-linux-gnu"
|
||||
;;
|
||||
aarch64)
|
||||
multiarch="aarch64-linux-gnu"
|
||||
;;
|
||||
loongarch64|loong64)
|
||||
multiarch="loongarch64-linux-gnu"
|
||||
;;
|
||||
*)
|
||||
multiarch=""
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "$multiarch" ]; then
|
||||
find "/usr/lib/$multiarch/fcitx" -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
fi
|
||||
|
||||
find /usr/lib/mozilla/plugins -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/polkit-1/actions -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /usr/share/fonts -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
find /etc/fonts/conf.d -xtype l -exec echo '{} is invalid now and going to be cleaned' \; -exec unlink {} \; 2>/dev/null &
|
||||
}
|
||||
function exec_uos_package_update(){
|
||||
update-icon-caches /usr/share/icons/* > /dev/null 2>&1 &
|
||||
update-desktop-database -q > /dev/null 2>&1 &
|
||||
update-mime-database -V /usr/share/mime > /dev/null 2>&1 &
|
||||
glib-compile-schemas /usr/share/glib-2.0/schemas/ > /dev/null 2>&1 &
|
||||
|
||||
}
|
||||
|
||||
#########################################################################################
|
||||
echo "----------------Running Spark DStore Patch----------------"
|
||||
if [ ! -e /usr/bin/deepin-app-store-tool ];then
|
||||
# execute linkApp function for each app and print output
|
||||
exec_uos_package_link
|
||||
|
||||
fi
|
||||
#exec_v23_icon_link
|
||||
exec_link_clean
|
||||
wait
|
||||
exec_uos_package_update
|
||||
echo "----------------Finished----------------"
|
||||
41
tool/spark-store.asc
Normal file
41
tool/spark-store.asc
Normal file
@@ -0,0 +1,41 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQGNBF7sGtgBDADKux63RQqGjbilEBErDjbGH+/sya9VjNBZdge1G/kK+8SEU7x9
|
||||
QFkSoprS7MN9qEtLhdN4+jqKDwwwlB0kjOK/L3BTsSjeP1fonY+Foprnc5sBBNDq
|
||||
2g4SQr1joafJq/d/E1GzCFCtUeo1/g8siEB9O2A8LFAqKB0ti6cXFQBc7QrRKNqb
|
||||
mUQYYkva5TeyYXwg8dV/jlQ1HkRftHO+mDOlxhSZxjH8o/3cHpVB/Ef7LUbUfzTL
|
||||
jT4Lxu5k6jFYeNI9EmIl36Nfz6o4T+iG19PQjv0d9aZe+4ceFeRQNPPqeubGJO9Z
|
||||
STNhHBFisgr/NdCKDVimR9wR7NSDceO+NswgMZzzo2xIFCsTB+JrMpTkDEBF1eFC
|
||||
F2RHwi6T4vJmFdt1rHhBfufgHrGNekZytgZw6tL9WDvDCiCKKZSGetfuBfaNYy63
|
||||
QNVszRVT5IOf6Rg2vtBIWM/iiAI6E9RsNhElRQj/cQLriIzuwHfgdHx8gPsRSgVx
|
||||
ZgizW0/2u4ZkrHUAEQEAAbQiRENTdG9yZSA8amlmZW5nc2hlbm1vQG91dGxvb2su
|
||||
Y29tPokBzgQTAQoAOAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBJ2aqFn3
|
||||
UCSxoezhbg5B01SimkQMBQJirsYKAAoJEA5B01SimkQMCx0L/2OvTYmOr4y4wC7i
|
||||
oC/uCZpWt9eCMEkC1kB2a9xjPX2GbxTnzvrdkiqHDD8uR2gfO7NkHyoGies+zeCT
|
||||
LcHH1Li+8KnGy3wye1KWgGTpxS3OV1gHawXi2w6OVhoQvod0y3cbGAOtOWpnbg1n
|
||||
SiJdDy3cjC+BNYSNPuF3qoY6YEdIfE9SaXANxe/57TUbN0TaiQFYdRd7GyyevjtC
|
||||
KNW8R06QKQ/zNqJSaoMHVVtDICXDCR4yvzmqXJppfMJKwHW9sPLC2c1xVx3pmyXc
|
||||
yFzIPOyeu3CDvdbXlh1gfoMTnUfWQyB7oIZxmCfFJGdodZwoxA+pkAcyhx87JYpE
|
||||
L4gy3SERvAog+/dD47gCb5alGYvyk9t7PQAAvwY8yr/6gf7f1U7DzxuT386LefW7
|
||||
6p5ET/R7xcuNLwRH0ZOp/eQECj72A7KXhQ5IL47Rfdh7VzCkf0MGKBFEIET9OV0G
|
||||
zv1q/z281pt08wHPGM3CetPWUFWUD9/H/UvBUSmpoSLgBsMhdbkBjQRe7BrYAQwA
|
||||
mAKDNHieo2P1WGNBMi4pPuhhgv8JyBzk8yrSOU+8s1ZTI4mI82iBEy5zAnAx3W1k
|
||||
unXVlDyq1/LfzL2Nt8Apr5aQdyEqSu4zN/6JBETB0LIkdrwdwBciAHzAKPfJWCR8
|
||||
t+Ox76I2MNeVsVQFAjGeb/7QR1Ge6Sx/sgSG7NTWYD6PmQtqmH0xKJsfXYfgayRG
|
||||
RF1rfu6CV0b2rPFfXOwB+3qQ8YInrPlI/9dswZiVElGGmbQTo3fGqk3T5iShqSnZ
|
||||
wCYDj2ODDknoPrfE1uUkF7CoYEkGrPbrUMwFK/SHvvG6cUz0EFUENPg7nECPmHGm
|
||||
GPWByBx/Yo0Jg68JavIeX7q9mnnlTP/3sp1JFLAQpR8q4S9lFOv6uYKJNUxQeBF+
|
||||
lBUkiafHzeHxJNP3ymDkrRRi640TubEZfVGjp5cskLY+U6KIpAXK/kCp42uPY7ob
|
||||
cuc3vAZ+5EcYCOY+LI80urQ5a+iMqo2ZTxL7C0BAX79QLgTDmH/FW4ejkSbrXH8v
|
||||
ABEBAAGJAbYEGAEKACACGwwWIQSdmqhZ91AksaHs4W4OQdNUoppEDAUCYq7GEwAK
|
||||
CRAOQdNUoppEDOm8C/9w3/Qtd14531O+ZsrQkfQ+ByIvGFKrnz4BIqD/99lR7UXj
|
||||
3Z2/bN7IGbwNUrBpgFqzlWAzpX9tiGhnwDphwSVeYNsvwepKmtmMAaPkP+ujR95E
|
||||
62UKpdVVrHH/VOCT4ZsSddwEVOLeI9LltO6RmPr54e3bpBXv6bijGnjhgRyJU2Jg
|
||||
DVE+UOU3m26fTQZZf3G9W55TBNdtpA1gggppJ7SgbwmuWcFjeF1gaEOeW2P5jaYe
|
||||
+Nx4Xpc4uf341elTfym8NQ/CfEfgAn3zs0ZOmnCX3JlmFh7gPW8fOSIDTC0NkJtU
|
||||
6LlguuprKhAUCSPKDlod7f7SmiwMsqvaAH+6Hi402tFnIwA1zjQk4BoCsUAVXVQx
|
||||
l2LC2UD3zBZw9WO6Y/YDgzM6Q2TlI9l1IjmkMHBWHalZ2afA7Uutv4JeNm0joT1D
|
||||
O5TmDYkkjjfu/+t+QnmBt5KgN2+HwF83ceJOqbPETvEviG5Wh+RXIT5kSgqgRPuV
|
||||
44jA/CTiR2VibEJ22D0=
|
||||
=mGFM
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
17
tool/ss-feedback/sender-d
Executable file
17
tool/ss-feedback/sender-d
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
HERE=$(dirname $0)
|
||||
|
||||
case `uname -m` in
|
||||
x86_64)
|
||||
sender_appendix="amd64"
|
||||
;;
|
||||
aarch64)
|
||||
sender_appendix="arm64"
|
||||
;;
|
||||
loongarch64)
|
||||
sender_appendix="loong64"
|
||||
;;
|
||||
esac
|
||||
|
||||
${HERE}/sender-d-${sender_appendix} $@
|
||||
BIN
tool/ss-feedback/sender-d-amd64
Executable file
BIN
tool/ss-feedback/sender-d-amd64
Executable file
Binary file not shown.
BIN
tool/ss-feedback/sender-d-arm64
Executable file
BIN
tool/ss-feedback/sender-d-arm64
Executable file
Binary file not shown.
BIN
tool/ss-feedback/sender-d-loong64
Executable file
BIN
tool/ss-feedback/sender-d-loong64
Executable file
Binary file not shown.
602
tool/ssaudit
Executable file
602
tool/ssaudit
Executable file
@@ -0,0 +1,602 @@
|
||||
#!/bin/bash
|
||||
# 初始化常量和全局变量
|
||||
readonly SPARK_DOWNLOAD_SERVER_URL="https://d.spark-app.store/"
|
||||
readonly SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL="d.spark-app.store"
|
||||
# ACE环境配置 - 修改此数组即可添加或删除支持的环境——记得修改 store-helper 里的 uninstaller check-is-installed 和 ss-launcher
|
||||
readonly ACE_ENVIRONMENTS=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
"deepin23-run:amber-ce-deepin23"
|
||||
"sid-run:amber-ce-sid"
|
||||
)
|
||||
readonly ACE_ENVIRONMENTS_FOR_AUTOINSTALL=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
)
|
||||
function get_current_user() {
|
||||
# 优先通过 who 命令获取用户
|
||||
local user
|
||||
user=$(who | awk '{print $1}' | head -n 1 2>/dev/null)
|
||||
|
||||
# 如果 who 无输出,则通过 loginctl 获取
|
||||
if [[ -z "$user" ]]; then
|
||||
user=$(loginctl list-sessions --no-legend 2>/dev/null | awk '{print $3}' | head -n 1)
|
||||
fi
|
||||
|
||||
# 返回最终结果(可能为空)
|
||||
echo "${user}"
|
||||
}
|
||||
|
||||
function zenity() {
|
||||
local user=$(get_current_user)
|
||||
local uid=$(id -u "$user")
|
||||
sudo -u "$user" DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/"$uid"/bus zenity "$@"
|
||||
}
|
||||
|
||||
|
||||
# 全局变量初始化(位于 parse_args 前)
|
||||
ACE_PARAMS=()
|
||||
|
||||
# 生成ACE环境参数帮助信息
|
||||
function generate_ace_help() {
|
||||
local help_text=""
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_param="--${ace_entry#*:}"
|
||||
help_text+=" $ace_param 使用${ace_entry%%:*} ACE容器安装\n"
|
||||
done
|
||||
echo -e "$help_text"
|
||||
}
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
# 脚本工作变量
|
||||
DELETE_AFTER_INSTALL="0"
|
||||
DEBPATH=""
|
||||
FORCE_ACE_ENV=""
|
||||
FORCE_NATIVE="0"
|
||||
NO_CREATE_DESKTOP="0"
|
||||
FORCE_CREATE_DESKTOP="0"
|
||||
|
||||
# 加载翻译和调试
|
||||
load_transhell_debug
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
# 根据架构设置仓库URL
|
||||
if [[ "$IS_APM_ENV" = "" ]] ;then
|
||||
case $(arch) in
|
||||
x86_64 | i686 | i386)
|
||||
STORE_URL="store"
|
||||
STORE_LIST_URL=""
|
||||
;;
|
||||
aarch64)
|
||||
STORE_URL="aarch64-store"
|
||||
STORE_LIST_URL="-aarch64"
|
||||
;;
|
||||
loongarch64)
|
||||
STORE_URL="loong64-store"
|
||||
STORE_LIST_URL="-loong64"
|
||||
;;
|
||||
riscv64)
|
||||
STORE_URL="riscv64-store"
|
||||
STORE_LIST_URL="-riscv64"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case $(arch) in
|
||||
x86_64 | i686 | i386)
|
||||
STORE_URL="amd64-apm"
|
||||
STORE_LIST_URL=""
|
||||
;;
|
||||
aarch64)
|
||||
STORE_URL="aarch64-apm"
|
||||
STORE_LIST_URL="-aarch64"
|
||||
;;
|
||||
loongarch64)
|
||||
STORE_URL="loong64-apm"
|
||||
STORE_LIST_URL="-loong64"
|
||||
;;
|
||||
riscv64)
|
||||
STORE_URL="riscv64-apm"
|
||||
STORE_LIST_URL="-riscv64"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# 帮助函数
|
||||
function show_help() {
|
||||
echo "Spark Store Audit script. 星火商店审核脚本"
|
||||
echo "用法: $0 [选项] <deb路径>"
|
||||
echo "选项:"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo " --delete-after-install 安装成功后删除软件包"
|
||||
echo " --no-create-desktop-entry 不创建桌面快捷方式"
|
||||
echo " --force-create-desktop-entry 强制创建桌面快捷方式"
|
||||
echo "$(generate_ace_help)"
|
||||
echo " --native 只在主机安装,不使用ACE容器"
|
||||
}
|
||||
# 参数解析
|
||||
function parse_args() {
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--delete-after-install)
|
||||
DELETE_AFTER_INSTALL="1"
|
||||
shift
|
||||
;;
|
||||
--native)
|
||||
FORCE_NATIVE="1"
|
||||
shift
|
||||
;;
|
||||
--no-create-desktop-entry)
|
||||
NO_CREATE_DESKTOP="1"
|
||||
shift
|
||||
;;
|
||||
--force-create-desktop-entry)
|
||||
FORCE_CREATE_DESKTOP="1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
# 检查是否为ACE环境参数
|
||||
local is_ace_param=0
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_param="--${ace_entry#*:}"
|
||||
if [ "$1" = "$ace_param" ]; then
|
||||
# 将ACE环境命令名加入数组
|
||||
ACE_PARAMS+=("${ace_entry%%:*}")
|
||||
is_ace_param=1
|
||||
shift
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果不是ACE环境参数,则视为DEB路径
|
||||
if [ "$is_ace_param" -eq 0 ]; then
|
||||
DEBPATH="$1"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# 验证当前用户
|
||||
function validate_user() {
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "${TRANSHELL_CONTENT_PLEASE_RUN_AS_ROOT}"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 验证文件存在或尝试下载
|
||||
function validate_or_download_file() {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "${TRANSHELL_CONTENT_FILE_NOT_EXIST},Trying to redownload"
|
||||
aptss update
|
||||
FILEPATH=$(dirname "$1")
|
||||
FILENAME=$(basename "$1")
|
||||
PACKAGE_NAME=$(echo "$FILENAME" | sed -r 's/^([^_]+)_.*$/\1/')
|
||||
VERSION=$(echo "$FILENAME" | sed -r 's/^[^_]+_([^_]+)_.*$/\1/')
|
||||
pushd "${FILEPATH}" >/dev/null || exit 1
|
||||
aptss download "${PACKAGE_NAME}"
|
||||
popd >/dev/null || exit 1
|
||||
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 哈希校验
|
||||
function hash_check() {
|
||||
local PACKAGES_DATA_PATH=""
|
||||
|
||||
# 检查可能的仓库位置
|
||||
if [ -e "/var/lib/aptss/lists/${SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL}_${STORE_URL}_Packages" ]; then
|
||||
PACKAGES_DATA_PATH="/var/lib/aptss/lists/${SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL}_${STORE_URL}_Packages"
|
||||
elif [ -e "/var/lib/aptss/lists/d.store.deepinos.org.cn_${STORE_URL}_Packages" ]; then
|
||||
PACKAGES_DATA_PATH="/var/lib/aptss/lists/d.store.deepinos.org.cn_${STORE_URL}_Packages"
|
||||
else
|
||||
PACKAGES_DATA_PATH="/var/lib/aptss/lists/mirrors.sdu.edu.cn_spark-store-repository_${STORE_URL}_Packages"
|
||||
fi
|
||||
|
||||
echo "正在运行包验证..."
|
||||
echo "Running Spark Package Verify..."
|
||||
|
||||
DEB_SHA512SUM=$(sha512sum "$1" | cut -d ' ' -f 1)
|
||||
unset IS_SHA512SUM_CHECKED
|
||||
IS_SHA512SUM_CHECKED=$(grep -F "$DEB_SHA512SUM" "$PACKAGES_DATA_PATH")
|
||||
}
|
||||
|
||||
# 确保aptss存在
|
||||
function ensure_aptss_exist() {
|
||||
if ! command -v aptss &>/dev/null; then
|
||||
apt update
|
||||
local deb_file="/tmp/spark-store-console-in-container_latest_all.deb"
|
||||
|
||||
if ! wget -O "$deb_file" "https://amber-ce-resource.spark-app.store/store/depends/spark-store-console-in-container_latest_all.deb"; then
|
||||
echo "下载 .deb 安装包失败" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! apt install -y "$deb_file"; then
|
||||
echo "安装 .deb 包失败" >&2
|
||||
rm -f "$deb_file"
|
||||
return 1
|
||||
fi
|
||||
rm -f "$deb_file"
|
||||
|
||||
if ! command -v aptss &>/dev/null; then
|
||||
echo "成功安装但未找到 aptss 命令" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
export -f ensure_aptss_exist
|
||||
|
||||
# 确保ACE环境存在
|
||||
# 确保ACE环境存在
|
||||
function ensure_ace_env() {
|
||||
local ace_env_pkg="${1}"
|
||||
local ace_cmd=""
|
||||
|
||||
# 根据配置找到对应命令
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
if [ "${ace_entry#*:}" = "$ace_env_pkg" ]; then
|
||||
ace_cmd="${ace_entry%%:*}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果命令存在,则说明环境已可用
|
||||
if command -v "$ace_cmd" &>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "ACE环境 $ace_env_pkg 未安装,正在尝试安装..."
|
||||
zenity --info --text="首次使用 $ace_env_pkg 环境,重启或注销桌面后才能在启动器中展示,不影响应用启动。安装将在后台继续。" --title="ACE环境安装" &
|
||||
if ! aptss install -y "$ace_env_pkg"; then
|
||||
echo "安装 $ace_env_pkg 失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 再次确认命令
|
||||
if command -v "$ace_cmd" &>/dev/null; then
|
||||
return 0
|
||||
else
|
||||
echo "ACE环境 $ace_env_pkg 安装后未检测到命令 $ace_cmd"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
export user=$(who | awk '{print $1}' | head -n 1)
|
||||
# 在桌面创建快捷方式
|
||||
function create_desktop_file() {
|
||||
# 如果明确要求不要创建或明确要创建,则跳过配置文件检查
|
||||
if [ "$NO_CREATE_DESKTOP" -eq 1 ]; then
|
||||
echo "根据参数要求,跳过创建桌面快捷方式"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$FORCE_CREATE_DESKTOP" -eq 0 ]; then
|
||||
if [ -e "$(sudo -u "$user" xdg-user-dir)/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop" ]; then
|
||||
echo "根据配置要求,跳过创建桌面快捷方式"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
exec_create_desktop_file
|
||||
}
|
||||
export CURRENT_USER_DIR_DESKTOP=$(sudo -u "$user" xdg-user-dir DESKTOP)
|
||||
function exec_create_desktop_file() {
|
||||
local desktop_files=()
|
||||
local package_name_lower=$(echo "$package_name" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# 只收集指定路径下的桌面文件
|
||||
# 1. /usr/share/applications/ 目录下的 .desktop 文件
|
||||
desktop_files+=($(dpkg -L "$package_name" 2>/dev/null | grep '^/usr/share/applications/.*\.desktop$' || true))
|
||||
|
||||
# 2. /opt/apps/包名/entries/applications/ 目录下的 .desktop 文件
|
||||
# 先尝试精确匹配包名路径
|
||||
desktop_files+=($(dpkg -L "$package_name" 2>/dev/null | grep "^/opt/apps/$package_name/entries/applications/.*\.desktop$" || true))
|
||||
|
||||
# 再尝试小写包名路径(有些包可能使用小写路径)
|
||||
desktop_files+=($(dpkg -L "$package_name" 2>/dev/null | grep "^/opt/apps/$package_name_lower/entries/applications/.*\.desktop$" || true))
|
||||
|
||||
# 如果没有找到任何符合条件的桌面文件,则直接返回
|
||||
if [ ${#desktop_files[@]} -eq 0 ]; then
|
||||
echo "未找到符合条件的桌面快捷方式文件(/usr/share/applications/ 或 /opt/apps/$package_name/entries/applications/)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "找到 ${#desktop_files[@]} 个桌面快捷方式文件:"
|
||||
printf '%s\n' "${desktop_files[@]}"
|
||||
|
||||
for desktop_file_path in "${desktop_files[@]}"; do
|
||||
# 检查文件是否存在
|
||||
if [ ! -f "$desktop_file_path" ]; then
|
||||
echo "文件不存在,跳过: $desktop_file_path"
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查是否是 NoDisplay=true 的桌面文件
|
||||
if [ -z "$(grep -i 'NoDisplay=true' "$desktop_file_path")" ]; then
|
||||
echo "安装桌面快捷方式: $desktop_file_path"
|
||||
chmod +x "$desktop_file_path"
|
||||
sudo -u "$user" cp "$desktop_file_path" "${CURRENT_USER_DIR_DESKTOP}/"
|
||||
else
|
||||
echo "跳过 NoDisplay=true 的桌面文件: $desktop_file_path"
|
||||
fi
|
||||
done
|
||||
}
|
||||
export -f exec_create_desktop_file
|
||||
|
||||
# 在ACE环境中创建桌面快捷方式
|
||||
function create_desktop_in_ace() {
|
||||
local ace_cmd="$1"
|
||||
local package_name="$2"
|
||||
|
||||
# 如果明确要求不要创建,则直接返回
|
||||
if [ "$NO_CREATE_DESKTOP" -eq 1 ]; then
|
||||
echo "根据参数要求,跳过在ACE中创建桌面快捷方式"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 如果是强制创建,或者没有配置禁止创建
|
||||
if [ "$FORCE_CREATE_DESKTOP" -eq 1 ] || ! $ace_cmd "[ -e ~/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop ]"; then
|
||||
echo "在ACE环境中创建桌面快捷方式..."
|
||||
export -f exec_create_desktop_file
|
||||
export package_name
|
||||
export FORCE_CREATE_DESKTOP
|
||||
$ace_cmd "exec_create_desktop_file"
|
||||
else
|
||||
echo "根据ACE环境中的配置,跳过创建桌面快捷方式"
|
||||
fi
|
||||
}
|
||||
|
||||
# 在指定ACE环境中安装
|
||||
function install_in_ace_env() {
|
||||
local ace_cmd="$1"
|
||||
local deb_path="$2"
|
||||
local ace_env_pkg="${3#*:}"
|
||||
|
||||
if [ "$IS_ACE_ENV" != "" ] || command -v termux-chroot; then
|
||||
echo "无法在ACE/termux/小小电脑中安装ACE包"
|
||||
return 1
|
||||
fi
|
||||
if ! ensure_ace_env "$ace_env_pkg"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "----------------------------------------"
|
||||
echo "正在尝试使用 $ace_cmd 环境安装..."
|
||||
echo "----------------------------------------"
|
||||
$ace_cmd "ensure_aptss_exist"
|
||||
|
||||
# 首先尝试dry-run测试
|
||||
if ! $ace_cmd "aptss install --dry-run '$deb_path'"; then
|
||||
echo "初始dry-run测试失败,尝试更新后重试..."
|
||||
$ace_cmd "aptss update"
|
||||
if ! $ace_cmd "aptss install --dry-run '$deb_path'"; then
|
||||
echo "dry-run测试仍然失败,放弃安装"
|
||||
echo "OMG_IT_GOES_WRONG"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# dry-run成功后执行实际安装
|
||||
$ace_cmd "aptss install store.spark-app.app-runtime-base --no-install-recommends -yfq"
|
||||
if $ace_cmd "dpkg -i '$deb_path' || aptss install '$deb_path' -yfq"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 在主机安装
|
||||
function install_in_host() {
|
||||
local deb_path="$1"
|
||||
|
||||
# 首先尝试dry-run测试
|
||||
if ! aptss install --dry-run "$deb_path"; then
|
||||
echo "初始dry-run测试失败,尝试更新后重试..."
|
||||
aptss update
|
||||
if ! aptss install --dry-run "$deb_path"; then
|
||||
echo "dry-run测试仍然失败,放弃安装"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# dry-run成功后执行实际安装
|
||||
if dpkg -i "$deb_path" || aptss install "$deb_path" -yfq; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 自动尝试在各种环境中安装
|
||||
function auto_try_install() {
|
||||
local deb_path="$1"
|
||||
|
||||
# 首先尝试在主机安装
|
||||
if install_in_host "$deb_path"; then
|
||||
create_desktop_file
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 如果主机安装失败,并非在ACE内运行且不在强制本地模式,尝试ACE环境
|
||||
if [ "$FORCE_NATIVE" -eq 0 ] && [ "$IS_ACE_ENV" = "" ] && ! command -v termux-chroot; then
|
||||
for ace_entry in "${ACE_ENVIRONMENTS_FOR_AUTOINSTALL[@]}"; do
|
||||
local ace_cmd=${ace_entry%%:*}
|
||||
local ace_env_pkg=${ace_entry#*:}
|
||||
|
||||
# 确保ACE环境存在
|
||||
if ensure_ace_env "$ace_env_pkg"; then
|
||||
if install_in_ace_env "$ace_cmd" "$deb_path" "$ace_env_pkg"; then
|
||||
# 在ACE环境中创建桌面快捷方式
|
||||
create_desktop_in_ace "$ace_cmd" "$package_name"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
# 清理安装后的文件
|
||||
function post_install_cleanup() {
|
||||
local success=$1
|
||||
local deb_path="$2"
|
||||
local package_name="$3"
|
||||
|
||||
if [ "$success" -eq 0 ] && [ "$DELETE_AFTER_INSTALL" -eq "1" ]; then
|
||||
# 检查是否安装在主机
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] || [ -n "$FORCE_ACE_ENV" ]; then
|
||||
if [ "$FORCE_NATIVE" -eq 1 ]; then
|
||||
if dpkg -s "$package_name" >/dev/null 2>&1; then
|
||||
echo "软件包已在主机安装:$package_name"
|
||||
create_desktop_file
|
||||
unlock_file "$deb_path"
|
||||
rm "$deb_path"
|
||||
echo "${TRANSHELL_CONTENT_DEB_IS_DELETED}"
|
||||
else
|
||||
echo "软件包未在主机安装:$package_name"
|
||||
echo "安装异常!抛出错误"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# ACE环境中安装的情况,不检查主机dpkg数据库
|
||||
echo "软件包已在ACE环境安装:$package_name"
|
||||
unlock_file "$deb_path"
|
||||
rm "$deb_path"
|
||||
echo "${TRANSHELL_CONTENT_DEB_IS_DELETED}"
|
||||
fi
|
||||
else
|
||||
# 自动模式下,如果ACE安装成功也会走到这里
|
||||
echo "软件包已安装:$package_name"
|
||||
unlock_file "$deb_path"
|
||||
rm "$deb_path"
|
||||
echo "${TRANSHELL_CONTENT_DEB_IS_DELETED}"
|
||||
fi
|
||||
else
|
||||
echo "${TRANSHELL_CONTENT_WILL_NOT_DELETE_DEB}"
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] && ! dpkg -s "$package_name" >/dev/null 2>&1; then
|
||||
echo "软件包未在主机安装:$package_name"
|
||||
echo "安装异常!抛出错误"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
elif [ -n "$FORCE_ACE_ENV" ] && ! command -v "$FORCE_ACE_ENV" >/dev/null 2>&1; then
|
||||
echo "指定的ACE环境不可用"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 文件锁定/解锁函数
|
||||
function lock_file() {
|
||||
chattr +i "$1"
|
||||
}
|
||||
|
||||
function unlock_file() {
|
||||
if [ -e "$1" ];then
|
||||
chattr -i "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主安装流程
|
||||
function main_install() {
|
||||
parse_args "$@"
|
||||
|
||||
if [ -z "$DEBPATH" ]; then
|
||||
echo "没有接收到参数,退出"
|
||||
show_help
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 设置退出时的文件解锁
|
||||
trap 'unlock_file $DEBPATH' EXIT
|
||||
validate_user
|
||||
validate_or_download_file "$DEBPATH"
|
||||
|
||||
DEBPATH=$(realpath "$DEBPATH")
|
||||
lock_file "$DEBPATH"
|
||||
|
||||
|
||||
|
||||
package_name=$(dpkg-deb -f "$DEBPATH" Package)
|
||||
local install_success=1
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] || [ "$IS_ACE_ENV" = "1" ]; then
|
||||
# 优先使用主机安装,忽略所有ACE参数
|
||||
echo "忽略ACE,使用主机安装 $package_name"
|
||||
install_in_host "$DEBPATH"
|
||||
install_success=$?
|
||||
# 安装成功后在主机创建桌面快捷方式
|
||||
if [ "$install_success" -eq 0 ]; then
|
||||
create_desktop_file
|
||||
fi
|
||||
|
||||
elif [ ${#ACE_PARAMS[@]} -gt 0 ] && [ "$IS_ACE_ENV" = "" ]; then
|
||||
# 用户指定了一个或多个ACE环境,且未要求原生安装
|
||||
echo "使用ACE环境安装,已指定环境: ${ACE_PARAMS[*]}"
|
||||
|
||||
# 查找第一个已安装的ACE环境
|
||||
chosen_env=""
|
||||
for env_cmd in "${ACE_PARAMS[@]}"; do
|
||||
if command -v "$env_cmd" >/dev/null 2>&1; then
|
||||
chosen_env="$env_cmd"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# 如果没有安装任何环境,则使用第一个指定的环境
|
||||
if [ -z "$chosen_env" ]; then
|
||||
chosen_env="${ACE_PARAMS[0]}"
|
||||
echo "未发现已安装的ACE环境,准备安装 $chosen_env..."
|
||||
# 查找对应的ACE环境软件包名
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
if [ "${ace_entry%%:*}" = "$chosen_env" ]; then
|
||||
ace_pkg="${ace_entry#*:}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# 安装ACE环境(示例使用aptss工具,可根据实际情况调整)
|
||||
ensure_ace_env "$ace_pkg" -y
|
||||
fi
|
||||
|
||||
# 再次确认ACE环境命令是否可用
|
||||
if command -v "$chosen_env" >/dev/null 2>&1; then
|
||||
# 查找软件包名(仅首次查找即可)
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
if [ "${ace_entry%%:*}" = "$chosen_env" ]; then
|
||||
ace_pkg="${ace_entry#*:}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "在 ACE 环境 $chosen_env 中安装 $package_name"
|
||||
install_in_ace_env "$chosen_env" "$DEBPATH" "$ace_pkg"
|
||||
install_success=$?
|
||||
if [ "$install_success" -eq 0 ]; then
|
||||
create_desktop_in_ace "$chosen_env" "$package_name"
|
||||
fi
|
||||
else
|
||||
echo "指定的ACE环境 $chosen_env 不可用"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
# 未指定ACE环境和--native,使用自动安装逻辑(先主机再ACE)
|
||||
echo "自动选择安装方式"
|
||||
auto_try_install "$DEBPATH"
|
||||
install_success=$?
|
||||
fi
|
||||
|
||||
post_install_cleanup "$install_success" "$DEBPATH" "$package_name"
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main_install "$@"
|
||||
615
tool/ssinstall
Executable file
615
tool/ssinstall
Executable file
@@ -0,0 +1,615 @@
|
||||
#!/bin/bash
|
||||
# 初始化常量和全局变量
|
||||
readonly SPARK_DOWNLOAD_SERVER_URL="https://d.spark-app.store/"
|
||||
readonly SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL="d.spark-app.store"
|
||||
# ACE环境配置 - 修改此数组即可添加或删除支持的环境——记得修改 store-helper 里的 uninstaller check-is-installed 和 ss-launcher
|
||||
readonly ACE_ENVIRONMENTS=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
"deepin23-run:amber-ce-deepin23"
|
||||
"sid-run:amber-ce-sid"
|
||||
)
|
||||
readonly ACE_ENVIRONMENTS_FOR_AUTOINSTALL=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
)
|
||||
function get_current_user() {
|
||||
# 优先通过 who 命令获取用户
|
||||
local user
|
||||
user=$(who | awk '{print $1}' | head -n 1 2>/dev/null)
|
||||
|
||||
# 如果 who 无输出,则通过 loginctl 获取
|
||||
if [[ -z "$user" ]]; then
|
||||
user=$(loginctl list-sessions --no-legend 2>/dev/null | awk '{print $3}' | head -n 1)
|
||||
fi
|
||||
|
||||
# 返回最终结果(可能为空)
|
||||
echo "${user}"
|
||||
}
|
||||
|
||||
function zenity() {
|
||||
local user=$(get_current_user)
|
||||
local uid=$(id -u "$user")
|
||||
sudo -u "$user" DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/"$uid"/bus zenity "$@"
|
||||
}
|
||||
|
||||
|
||||
# 全局变量初始化(位于 parse_args 前)
|
||||
ACE_PARAMS=()
|
||||
|
||||
# 生成ACE环境参数帮助信息
|
||||
function generate_ace_help() {
|
||||
local help_text=""
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_param="--${ace_entry#*:}"
|
||||
help_text+=" $ace_param 使用${ace_entry%%:*} ACE容器安装\n"
|
||||
done
|
||||
echo -e "$help_text"
|
||||
}
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
# 脚本工作变量
|
||||
DELETE_AFTER_INSTALL="0"
|
||||
DEBPATH=""
|
||||
FORCE_ACE_ENV=""
|
||||
FORCE_NATIVE="0"
|
||||
NO_CREATE_DESKTOP="0"
|
||||
FORCE_CREATE_DESKTOP="0"
|
||||
|
||||
# 加载翻译和调试
|
||||
load_transhell_debug
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
# 根据架构设置仓库URL
|
||||
if [[ "$IS_APM_ENV" = "" ]] ;then
|
||||
case $(arch) in
|
||||
x86_64 | i686 | i386)
|
||||
STORE_URL="store"
|
||||
STORE_LIST_URL=""
|
||||
;;
|
||||
aarch64)
|
||||
STORE_URL="aarch64-store"
|
||||
STORE_LIST_URL="-aarch64"
|
||||
;;
|
||||
loongarch64)
|
||||
STORE_URL="loong64-store"
|
||||
STORE_LIST_URL="-loong64"
|
||||
;;
|
||||
riscv64)
|
||||
STORE_URL="riscv64-store"
|
||||
STORE_LIST_URL="-riscv64"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case $(arch) in
|
||||
x86_64 | i686 | i386)
|
||||
STORE_URL="amd64-apm"
|
||||
STORE_LIST_URL=""
|
||||
;;
|
||||
aarch64)
|
||||
STORE_URL="arm64-apm"
|
||||
STORE_LIST_URL="-arm64"
|
||||
;;
|
||||
loongarch64)
|
||||
STORE_URL="loong64-apm"
|
||||
STORE_LIST_URL="-loong64"
|
||||
;;
|
||||
riscv64)
|
||||
STORE_URL="riscv64-apm"
|
||||
STORE_LIST_URL="-riscv64"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# 帮助函数
|
||||
function show_help() {
|
||||
echo "Spark Store Install script. 星火商店安装脚本"
|
||||
echo "用法: $0 [选项] <deb路径>"
|
||||
echo "选项:"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo " --delete-after-install 安装成功后删除软件包"
|
||||
echo " --no-create-desktop-entry 不创建桌面快捷方式"
|
||||
echo " --force-create-desktop-entry 强制创建桌面快捷方式"
|
||||
echo "$(generate_ace_help)"
|
||||
echo " --native 只在主机安装,不使用ACE容器"
|
||||
}
|
||||
# 参数解析
|
||||
function parse_args() {
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--delete-after-install)
|
||||
DELETE_AFTER_INSTALL="1"
|
||||
shift
|
||||
;;
|
||||
--native)
|
||||
FORCE_NATIVE="1"
|
||||
shift
|
||||
;;
|
||||
--no-create-desktop-entry)
|
||||
NO_CREATE_DESKTOP="1"
|
||||
shift
|
||||
;;
|
||||
--force-create-desktop-entry)
|
||||
FORCE_CREATE_DESKTOP="1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
# 检查是否为ACE环境参数
|
||||
local is_ace_param=0
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_param="--${ace_entry#*:}"
|
||||
if [ "$1" = "$ace_param" ]; then
|
||||
# 将ACE环境命令名加入数组
|
||||
ACE_PARAMS+=("${ace_entry%%:*}")
|
||||
is_ace_param=1
|
||||
shift
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果不是ACE环境参数,则视为DEB路径
|
||||
if [ "$is_ace_param" -eq 0 ]; then
|
||||
DEBPATH="$1"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# 验证当前用户
|
||||
function validate_user() {
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "${TRANSHELL_CONTENT_PLEASE_RUN_AS_ROOT}"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 验证文件存在或尝试下载
|
||||
function validate_or_download_file() {
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "${TRANSHELL_CONTENT_FILE_NOT_EXIST},Trying to redownload"
|
||||
aptss update
|
||||
FILEPATH=$(dirname "$1")
|
||||
FILENAME=$(basename "$1")
|
||||
PACKAGE_NAME=$(echo "$FILENAME" | sed -r 's/^([^_]+)_.*$/\1/')
|
||||
VERSION=$(echo "$FILENAME" | sed -r 's/^[^_]+_([^_]+)_.*$/\1/')
|
||||
pushd "${FILEPATH}" >/dev/null || exit 1
|
||||
aptss download "${PACKAGE_NAME}"
|
||||
popd >/dev/null || exit 1
|
||||
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 哈希校验
|
||||
function hash_check() {
|
||||
local PACKAGES_DATA_PATH=""
|
||||
|
||||
# 检查可能的仓库位置
|
||||
if [ -e "/var/lib/aptss/lists/${SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL}_${STORE_URL}_Packages" ]; then
|
||||
PACKAGES_DATA_PATH="/var/lib/aptss/lists/${SPARK_DOWNLOAD_SERVER_URL_NO_PROTOCOL}_${STORE_URL}_Packages"
|
||||
elif [ -e "/var/lib/aptss/lists/d.store.deepinos.org.cn_${STORE_URL}_Packages" ]; then
|
||||
PACKAGES_DATA_PATH="/var/lib/aptss/lists/d.store.deepinos.org.cn_${STORE_URL}_Packages"
|
||||
else
|
||||
PACKAGES_DATA_PATH="/var/lib/aptss/lists/mirrors.sdu.edu.cn_spark-store-repository_${STORE_URL}_Packages"
|
||||
fi
|
||||
|
||||
echo "正在运行包验证..."
|
||||
echo "Running Spark Package Verify..."
|
||||
|
||||
DEB_SHA512SUM=$(sha512sum "$1" | cut -d ' ' -f 1)
|
||||
unset IS_SHA512SUM_CHECKED
|
||||
IS_SHA512SUM_CHECKED=$(grep -F "$DEB_SHA512SUM" "$PACKAGES_DATA_PATH")
|
||||
}
|
||||
|
||||
# 确保aptss存在
|
||||
function ensure_aptss_exist() {
|
||||
if ! command -v aptss &>/dev/null; then
|
||||
apt update
|
||||
local deb_file="/tmp/spark-store-console-in-container_latest_all.deb"
|
||||
|
||||
if ! wget -O "$deb_file" "https://amber-ce-resource.spark-app.store/store/depends/spark-store-console-in-container_latest_all.deb"; then
|
||||
echo "下载 .deb 安装包失败" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! apt install -y "$deb_file"; then
|
||||
echo "安装 .deb 包失败" >&2
|
||||
rm -f "$deb_file"
|
||||
return 1
|
||||
fi
|
||||
rm -f "$deb_file"
|
||||
|
||||
if ! command -v aptss &>/dev/null; then
|
||||
echo "成功安装但未找到 aptss 命令" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
export -f ensure_aptss_exist
|
||||
|
||||
# 确保ACE环境存在
|
||||
# 确保ACE环境存在
|
||||
function ensure_ace_env() {
|
||||
local ace_env_pkg="${1}"
|
||||
local ace_cmd=""
|
||||
|
||||
# 根据配置找到对应命令
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
if [ "${ace_entry#*:}" = "$ace_env_pkg" ]; then
|
||||
ace_cmd="${ace_entry%%:*}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果命令存在,则说明环境已可用
|
||||
if command -v "$ace_cmd" &>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "ACE环境 $ace_env_pkg 未安装,正在尝试安装..."
|
||||
zenity --info --text="首次使用 $ace_env_pkg 环境,重启或注销桌面后才能在启动器中展示,不影响应用启动。安装将在后台继续。" --title="ACE环境安装" &
|
||||
if ! aptss install -y "$ace_env_pkg"; then
|
||||
echo "安装 $ace_env_pkg 失败"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 再次确认命令
|
||||
if command -v "$ace_cmd" &>/dev/null; then
|
||||
return 0
|
||||
else
|
||||
echo "ACE环境 $ace_env_pkg 安装后未检测到命令 $ace_cmd"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
export user=$(who | awk '{print $1}' | head -n 1)
|
||||
# 在桌面创建快捷方式
|
||||
function create_desktop_file() {
|
||||
# 如果明确要求不要创建或明确要创建,则跳过配置文件检查
|
||||
if [ "$NO_CREATE_DESKTOP" -eq 1 ]; then
|
||||
echo "根据参数要求,跳过创建桌面快捷方式"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$FORCE_CREATE_DESKTOP" -eq 0 ]; then
|
||||
if [ -e "$(sudo -u "$user" xdg-user-dir)/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop" ]; then
|
||||
echo "根据配置要求,跳过创建桌面快捷方式"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
exec_create_desktop_file
|
||||
}
|
||||
export CURRENT_USER_DIR_DESKTOP=$(sudo -u "$user" xdg-user-dir DESKTOP)
|
||||
function exec_create_desktop_file() {
|
||||
local desktop_files=()
|
||||
local package_name_lower=$(echo "$package_name" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# 只收集指定路径下的桌面文件
|
||||
# 1. /usr/share/applications/ 目录下的 .desktop 文件
|
||||
desktop_files+=($(dpkg -L "$package_name" 2>/dev/null | grep '^/usr/share/applications/.*\.desktop$' || true))
|
||||
|
||||
# 2. /opt/apps/包名/entries/applications/ 目录下的 .desktop 文件
|
||||
# 先尝试精确匹配包名路径
|
||||
desktop_files+=($(dpkg -L "$package_name" 2>/dev/null | grep "^/opt/apps/$package_name/entries/applications/.*\.desktop$" || true))
|
||||
|
||||
# 再尝试小写包名路径(有些包可能使用小写路径)
|
||||
desktop_files+=($(dpkg -L "$package_name" 2>/dev/null | grep "^/opt/apps/$package_name_lower/entries/applications/.*\.desktop$" || true))
|
||||
|
||||
# 如果没有找到任何符合条件的桌面文件,则直接返回
|
||||
if [ ${#desktop_files[@]} -eq 0 ]; then
|
||||
echo "未找到符合条件的桌面快捷方式文件(/usr/share/applications/ 或 /opt/apps/$package_name/entries/applications/)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "找到 ${#desktop_files[@]} 个桌面快捷方式文件:"
|
||||
printf '%s\n' "${desktop_files[@]}"
|
||||
|
||||
for desktop_file_path in "${desktop_files[@]}"; do
|
||||
# 检查文件是否存在
|
||||
if [ ! -f "$desktop_file_path" ]; then
|
||||
echo "文件不存在,跳过: $desktop_file_path"
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查是否是 NoDisplay=true 的桌面文件
|
||||
if [ -z "$(grep -i 'NoDisplay=true' "$desktop_file_path")" ]; then
|
||||
echo "安装桌面快捷方式: $desktop_file_path"
|
||||
chmod +x "$desktop_file_path"
|
||||
sudo -u "$user" cp "$desktop_file_path" "${CURRENT_USER_DIR_DESKTOP}/"
|
||||
else
|
||||
echo "跳过 NoDisplay=true 的桌面文件: $desktop_file_path"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
export -f exec_create_desktop_file
|
||||
|
||||
# 在ACE环境中创建桌面快捷方式
|
||||
function create_desktop_in_ace() {
|
||||
local ace_cmd="$1"
|
||||
local package_name="$2"
|
||||
|
||||
# 如果明确要求不要创建,则直接返回
|
||||
if [ "$NO_CREATE_DESKTOP" -eq 1 ]; then
|
||||
echo "根据参数要求,跳过在ACE中创建桌面快捷方式"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 如果是强制创建,或者没有配置禁止创建
|
||||
if [ "$FORCE_CREATE_DESKTOP" -eq 1 ] || ! [ -e ~/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop ]; then
|
||||
echo "在ACE环境中创建桌面快捷方式..."
|
||||
export -f exec_create_desktop_file
|
||||
export package_name
|
||||
export FORCE_CREATE_DESKTOP
|
||||
$ace_cmd "exec_create_desktop_file"
|
||||
else
|
||||
echo "根据ACE环境中的配置,跳过创建桌面快捷方式"
|
||||
fi
|
||||
}
|
||||
|
||||
# 在指定ACE环境中安装
|
||||
function install_in_ace_env() {
|
||||
local ace_cmd="$1"
|
||||
local deb_path="$2"
|
||||
local ace_env_pkg="${3#*:}"
|
||||
|
||||
if [ "$IS_ACE_ENV" != "" ] || command -v termux-chroot; then
|
||||
echo "无法在ACE/termux/小小电脑中安装ACE包"
|
||||
return 1
|
||||
fi
|
||||
if ! ensure_ace_env "$ace_env_pkg"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "----------------------------------------"
|
||||
echo "正在尝试使用 $ace_cmd 环境安装..."
|
||||
echo "----------------------------------------"
|
||||
$ace_cmd "ensure_aptss_exist"
|
||||
|
||||
# 首先尝试dry-run测试
|
||||
if ! $ace_cmd aptss install --dry-run "$deb_path"; then
|
||||
echo "初始dry-run测试失败,尝试更新后重试..."
|
||||
$ace_cmd aptss update
|
||||
if ! $ace_cmd aptss install --dry-run "$deb_path"; then
|
||||
echo "dry-run测试仍然失败,放弃安装"
|
||||
echo "OMG_IT_GOES_WRONG"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# dry-run成功后执行实际安装
|
||||
$ace_cmd aptss install store.spark-app.app-runtime-base --no-install-recommends -yfq
|
||||
if $ace_cmd dpkg -i "$deb_path" || $ace_cmd aptss install "$deb_path" -yfq; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 在主机安装
|
||||
function install_in_host() {
|
||||
local deb_path="$1"
|
||||
|
||||
# 首先尝试dry-run测试
|
||||
if ! aptss install --dry-run "$deb_path"; then
|
||||
echo "初始dry-run测试失败,尝试更新后重试..."
|
||||
aptss update
|
||||
if ! aptss install --dry-run "$deb_path"; then
|
||||
echo "dry-run测试仍然失败,放弃安装"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# dry-run成功后执行实际安装
|
||||
if dpkg -i "$deb_path" || aptss install "$deb_path" -yfq; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 自动尝试在各种环境中安装
|
||||
function auto_try_install() {
|
||||
local deb_path="$1"
|
||||
|
||||
# 首先尝试在主机安装
|
||||
if install_in_host "$deb_path"; then
|
||||
create_desktop_file
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 如果主机安装失败,并非在ACE内运行且不在强制本地模式,尝试ACE环境
|
||||
if [ "$FORCE_NATIVE" -eq 0 ] && [ "$IS_ACE_ENV" = "" ] && ! command -v termux-chroot; then
|
||||
for ace_entry in "${ACE_ENVIRONMENTS_FOR_AUTOINSTALL[@]}"; do
|
||||
local ace_cmd=${ace_entry%%:*}
|
||||
local ace_env_pkg=${ace_entry#*:}
|
||||
|
||||
# 确保ACE环境存在
|
||||
if ensure_ace_env "$ace_env_pkg"; then
|
||||
if install_in_ace_env "$ace_cmd" "$deb_path" "$ace_env_pkg"; then
|
||||
# 在ACE环境中创建桌面快捷方式
|
||||
create_desktop_in_ace "$ace_cmd" "$package_name"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
# 清理安装后的文件
|
||||
function post_install_cleanup() {
|
||||
local success=$1
|
||||
local deb_path="$2"
|
||||
local package_name="$3"
|
||||
|
||||
if [ "$success" -eq 0 ] && [ "$DELETE_AFTER_INSTALL" -eq "1" ]; then
|
||||
# 检查是否安装在主机
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] || [ -n "$FORCE_ACE_ENV" ]; then
|
||||
if [ "$FORCE_NATIVE" -eq 1 ]; then
|
||||
if dpkg -s "$package_name" >/dev/null 2>&1; then
|
||||
echo "软件包已在主机安装:$package_name"
|
||||
create_desktop_file
|
||||
unlock_file "$deb_path"
|
||||
rm "$deb_path"
|
||||
echo "${TRANSHELL_CONTENT_DEB_IS_DELETED}"
|
||||
else
|
||||
echo "软件包未在主机安装:$package_name"
|
||||
echo "安装异常!抛出错误"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# ACE环境中安装的情况,不检查主机dpkg数据库
|
||||
echo "软件包已在ACE环境安装:$package_name"
|
||||
unlock_file "$deb_path"
|
||||
rm "$deb_path"
|
||||
echo "${TRANSHELL_CONTENT_DEB_IS_DELETED}"
|
||||
fi
|
||||
else
|
||||
# 自动模式下,如果ACE安装成功也会走到这里
|
||||
echo "软件包已安装:$package_name"
|
||||
unlock_file "$deb_path"
|
||||
rm "$deb_path"
|
||||
echo "${TRANSHELL_CONTENT_DEB_IS_DELETED}"
|
||||
fi
|
||||
else
|
||||
echo "${TRANSHELL_CONTENT_WILL_NOT_DELETE_DEB}"
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] && ! dpkg -s "$package_name" >/dev/null 2>&1; then
|
||||
echo "软件包未在主机安装:$package_name"
|
||||
echo "安装异常!抛出错误"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
elif [ -n "$FORCE_ACE_ENV" ] && ! command -v "$FORCE_ACE_ENV" >/dev/null 2>&1; then
|
||||
echo "指定的ACE环境不可用"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 文件锁定/解锁函数
|
||||
function lock_file() {
|
||||
chattr +i "$1"
|
||||
}
|
||||
|
||||
function unlock_file() {
|
||||
if [ -e "$1" ];then
|
||||
chattr -i "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主安装流程
|
||||
function main_install() {
|
||||
parse_args "$@"
|
||||
|
||||
if [ -z "$DEBPATH" ]; then
|
||||
echo "没有接收到参数,退出"
|
||||
show_help
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 设置退出时的文件解锁
|
||||
trap 'unlock_file $DEBPATH' EXIT
|
||||
validate_user
|
||||
validate_or_download_file "$DEBPATH"
|
||||
|
||||
DEBPATH=$(realpath "$DEBPATH")
|
||||
lock_file "$DEBPATH"
|
||||
|
||||
hash_check "$DEBPATH"
|
||||
|
||||
if [ -z "$IS_SHA512SUM_CHECKED" ]; then
|
||||
echo "尝试更新仓库信息重新校验"
|
||||
aptss ssupdate
|
||||
hash_check "$DEBPATH"
|
||||
if [ -z "$IS_SHA512SUM_CHECKED" ]; then
|
||||
echo -e "$TRANSHELL_CONTENT_HASH_CHECK_FAILED"
|
||||
zenity --info --icon-name=spark-store --height 270 --width 500 --text "$TRANSHELL_CONTENT_HASH_CHECK_FAILED"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
package_name=$(dpkg-deb -f "$DEBPATH" Package)
|
||||
local install_success=1
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] || [ "$IS_ACE_ENV" = "1" ]; then
|
||||
# 优先使用主机安装,忽略所有ACE参数
|
||||
echo "忽略ACE,使用主机安装 $package_name"
|
||||
install_in_host "$DEBPATH"
|
||||
install_success=$?
|
||||
# 安装成功后在主机创建桌面快捷方式
|
||||
if [ "$install_success" -eq 0 ]; then
|
||||
create_desktop_file
|
||||
fi
|
||||
|
||||
elif [ ${#ACE_PARAMS[@]} -gt 0 ] && [ "$IS_ACE_ENV" = "" ]; then
|
||||
# 用户指定了一个或多个ACE环境,且未要求原生安装
|
||||
echo "使用ACE环境安装,已指定环境: ${ACE_PARAMS[*]}"
|
||||
|
||||
# 查找第一个已安装的ACE环境
|
||||
chosen_env=""
|
||||
for env_cmd in "${ACE_PARAMS[@]}"; do
|
||||
if command -v "$env_cmd" >/dev/null 2>&1; then
|
||||
chosen_env="$env_cmd"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# 如果没有安装任何环境,则使用第一个指定的环境
|
||||
if [ -z "$chosen_env" ]; then
|
||||
chosen_env="${ACE_PARAMS[0]}"
|
||||
echo "未发现已安装的ACE环境,准备安装 $chosen_env..."
|
||||
# 查找对应的ACE环境软件包名
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
if [ "${ace_entry%%:*}" = "$chosen_env" ]; then
|
||||
ace_pkg="${ace_entry#*:}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# 安装ACE环境(示例使用aptss工具,可根据实际情况调整)
|
||||
ensure_ace_env "$ace_pkg" -y
|
||||
fi
|
||||
|
||||
# 再次确认ACE环境命令是否可用
|
||||
if command -v "$chosen_env" >/dev/null 2>&1; then
|
||||
# 查找软件包名(仅首次查找即可)
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
if [ "${ace_entry%%:*}" = "$chosen_env" ]; then
|
||||
ace_pkg="${ace_entry#*:}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "在 ACE 环境 $chosen_env 中安装 $package_name"
|
||||
install_in_ace_env "$chosen_env" "$DEBPATH" "$ace_pkg"
|
||||
install_success=$?
|
||||
if [ "$install_success" -eq 0 ]; then
|
||||
create_desktop_in_ace "$chosen_env" "$package_name"
|
||||
fi
|
||||
else
|
||||
echo "指定的ACE环境 $chosen_env 不可用"
|
||||
echo "OMG-IT-GOES-WRONG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
# 未指定ACE环境和--native,使用自动安装逻辑(先主机再ACE)
|
||||
echo "自动选择安装方式"
|
||||
auto_try_install "$DEBPATH"
|
||||
install_success=$?
|
||||
fi
|
||||
|
||||
post_install_cleanup "$install_success" "$DEBPATH" "$package_name"
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main_install "$@"
|
||||
43
tool/store-helper/check-is-installed
Executable file
43
tool/store-helper/check-is-installed
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
readonly ACE_ENVIRONMENTS=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
"deepin23-run:amber-ce-deepin23"
|
||||
"sid-run:amber-ce-sid"
|
||||
)
|
||||
dpkg -s '$1' 2>/dev/null | grep -q 'Status: install ok installed' > /dev/null 2>&1
|
||||
RET="$?"
|
||||
if [[ "$RET" != "0" ]] && [[ "$IS_ACE_ENV" == "" ]];then ## 如果未在ACE环境中
|
||||
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
ace_cmd=${ace_entry%%:*}
|
||||
if command -v "$ace_cmd" >/dev/null 2>&1; then
|
||||
echo "----------------------------------------"
|
||||
echo "正在检查 $ace_cmd 环境的安装..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
# 在ACE环境中使用dpkg -s检查安装状态
|
||||
# 使用dpkg -s并检查输出中是否包含"Status: install ok installed"
|
||||
$ace_cmd dpkg -s "$1" 2>/dev/null | grep -q 'Status: install ok installed'
|
||||
try_run_ret="$?"
|
||||
|
||||
# 最终检测结果处理
|
||||
if [ "$try_run_ret" -eq 0 ]; then
|
||||
echo "----------------------------------------"
|
||||
echo "在 $ace_cmd 环境中找到了安装"
|
||||
echo "----------------------------------------"
|
||||
exit $try_run_ret
|
||||
else
|
||||
echo "----------------------------------------"
|
||||
echo "在 $ace_cmd 环境中未能找到安装,继续查找"
|
||||
echo "----------------------------------------"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo "----------------------------------------"
|
||||
echo "所有已安装的 ACE 环境中未能找到安装,退出"
|
||||
echo "----------------------------------------"
|
||||
exit "$RET"
|
||||
fi
|
||||
## 如果在ACE环境中或者未出错
|
||||
exit "$RET"
|
||||
49
tool/store-helper/pass-auth.sh
Executable file
49
tool/store-helper/pass-auth.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
|
||||
#!/bin/bash
|
||||
# We use sudo twice to avoid ACE bug here
|
||||
# https://gitee.com/amber-ce/amber-ce-bookworm/commit/43e1a1599ede474b37e41aa10c53fd8afc4d35a1
|
||||
|
||||
function zenity_prompt() {
|
||||
if [[ -e /usr/bin/garma ]]; then
|
||||
garma "$@"
|
||||
else
|
||||
$(command -v zenity) "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "${IS_ACE_ENV}" = "" ]; then
|
||||
echo "检测为非ACE环境,直接提权"
|
||||
pkexec "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# 检查sudo是否需要密码
|
||||
if sudo -n true 2>/dev/null; then
|
||||
echo "sudo 无需密码,继续执行"
|
||||
else
|
||||
# 循环输入密码直到成功或用户取消
|
||||
while true; do
|
||||
# 使用zenity弹出密码输入框
|
||||
PASSWORD=$(zenity_prompt --password --title="需要sudo权限")
|
||||
|
||||
# 检查用户是否取消输入
|
||||
if [ -z "$PASSWORD" ]; then
|
||||
zenity_prompt --error --text="操作已取消"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 尝试使用输入的密码执行sudo命令
|
||||
echo "$PASSWORD" | sudo -S -v 2>/dev/null
|
||||
|
||||
# 检查sudo是否成功
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "密码正确,继续执行"
|
||||
break
|
||||
else
|
||||
zenity_prompt --error --text="密码错误,请重新输入"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# 使用sudo命令执行目标程序
|
||||
echo "$PASSWORD" | sudo sudo -S "$@"
|
||||
164
tool/store-helper/ss-launcher
Executable file
164
tool/store-helper/ss-launcher
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===== ACE环境配置 =====
|
||||
readonly ACE_ENVIRONMENTS=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
"deepin23-run:amber-ce-deepin23"
|
||||
"sid-run:amber-ce-sid"
|
||||
)
|
||||
|
||||
# ===== 日志和函数 =====
|
||||
[ -f /opt/durapps/spark-store/bin/bashimport/log.amber ] && \
|
||||
source /opt/durapps/spark-store/bin/bashimport/log.amber || {
|
||||
log.info() { echo "INFO: $*"; }
|
||||
log.warn() { echo "WARN: $*"; }
|
||||
log.error() { echo "ERROR: $*"; }
|
||||
log.debug() { echo "DEBUG: $*"; }
|
||||
}
|
||||
|
||||
# ===== 功能函数 =====
|
||||
function scan_desktop_file_log() {
|
||||
unset desktop_file_path
|
||||
local package_name=$1
|
||||
# 标准desktop文件检测
|
||||
while IFS= read -r path; do
|
||||
[ -z "$(grep 'NoDisplay=true' "$path")" ] && {
|
||||
log.info "Found valid desktop file: $path"
|
||||
export desktop_file_path="$path"
|
||||
return 0
|
||||
}
|
||||
done < <(dpkg -L "$package_name" 2>/dev/null | grep -E '/usr/share/applications/.*\.desktop$|/opt/apps/.*/entries/applications/.*\.desktop$')
|
||||
|
||||
# 深度环境特殊处理
|
||||
while IFS= read -r path; do
|
||||
[ -z "$(grep 'NoDisplay=true' "$path")" ] && {
|
||||
log.info "Found deepin desktop file: $path"
|
||||
export desktop_file_path="$path"
|
||||
return 0
|
||||
}
|
||||
done < <(find /opt/apps/$package_name -path '*/entries/applications/*.desktop' 2>/dev/null)
|
||||
return 1
|
||||
}
|
||||
|
||||
function scan_desktop_file() {
|
||||
local package_name=$1 result=""
|
||||
# 标准结果收集
|
||||
while IFS= read -r path; do
|
||||
[ -z "$(grep 'NoDisplay=true' "$path")" ] && result+="$path,"
|
||||
done < <(dpkg -L "$package_name" 2>/dev/null | grep -E '/usr/share/applications/.*\.desktop$|/opt/apps/.*/entries/applications/.*\.desktop$')
|
||||
|
||||
# 深度环境补充扫描
|
||||
while IFS= read -r path; do
|
||||
[ -z "$(grep 'NoDisplay=true' "$path")" ] && result+="$path,"
|
||||
done < <(find /opt/apps/$package_name -path '*/entries/applications/*.desktop' 2>/dev/null)
|
||||
|
||||
echo "${result%,}"
|
||||
}
|
||||
|
||||
function launch_app() {
|
||||
local DESKTOP_FILE_PATH="${1#file://}"
|
||||
# 提取并净化Exec命令
|
||||
exec_command=$(grep -m1 '^Exec=' "$DESKTOP_FILE_PATH" | cut -d= -f2- | sed 's/%.//g')
|
||||
[ -z "$exec_command" ] && return 1
|
||||
[ ! -z "$IS_ACE_ENV" ] && HOST_PREFIX="host-spawn"
|
||||
exec_command="${HOST_PREFIX} $exec_command"
|
||||
log.info "Launching: $exec_command"
|
||||
${SHELL:-bash} -c " $exec_command" &
|
||||
|
||||
}
|
||||
|
||||
# 导出函数以便在ACE环境中使用
|
||||
export -f launch_app scan_desktop_file scan_desktop_file_log log.info log.warn log.debug log.error
|
||||
|
||||
# ===== ACE环境执行器 =====
|
||||
function ace_runner() {
|
||||
local action=$1
|
||||
local target=$2
|
||||
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_cmd=${ace_entry%%:*}
|
||||
local ace_env=${ace_entry#*:}
|
||||
|
||||
if ! command -v "$ace_cmd" >/dev/null; then
|
||||
log.debug "$ace_cmd not found, skipping..."
|
||||
continue
|
||||
fi
|
||||
|
||||
log.info "Attempting in $ace_env environment..."
|
||||
|
||||
case "$action" in
|
||||
check)
|
||||
if "$ace_cmd" scan_desktop_file_log "$target"; then
|
||||
log.info "Found desktop file in $ace_env"
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
list)
|
||||
local result
|
||||
if result=$("$ace_cmd" scan_desktop_file "$target"); then
|
||||
echo "$result"
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
launch|start)
|
||||
"$ace_cmd" scan_desktop_file_log "$target"
|
||||
if desktop_path=$("$ace_cmd" scan_desktop_file_log "$target"); then
|
||||
log.info "Launching from $ace_env..."
|
||||
"$ace_cmd" launch_app $("$ace_cmd" scan_desktop_file "$target")
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
log.debug "Attempt in $ace_env failed"
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# ===== 主逻辑 =====
|
||||
[ $# -lt 2 ] && {
|
||||
log.error "Usage: $0 {check|launch|list|start} package_name/desktop_file"
|
||||
exit 1
|
||||
}
|
||||
|
||||
case $1 in
|
||||
check)
|
||||
# 当前环境检查
|
||||
if scan_desktop_file_log "$2"; then
|
||||
exit 0
|
||||
else
|
||||
# 非ACE环境下执行ACE环境扫描
|
||||
[ -z "$IS_ACE_ENV" ] && ace_runner check "$2"
|
||||
exit $?
|
||||
fi
|
||||
;;
|
||||
|
||||
list)
|
||||
# 当前环境列表
|
||||
if result=$(scan_desktop_file "$2"); then
|
||||
echo "$result"
|
||||
exit 0
|
||||
else
|
||||
# 非ACE环境下执行ACE环境扫描
|
||||
[ -z "$IS_ACE_ENV" ] && ace_runner list "$2"
|
||||
exit $?
|
||||
fi
|
||||
;;
|
||||
|
||||
launch|start)
|
||||
# 当前环境启动
|
||||
if scan_desktop_file_log "$2" && launch_app "$desktop_file_path"; then
|
||||
exit 0
|
||||
else
|
||||
# 非ACE环境下通过ACE环境启动
|
||||
[ -z "$IS_ACE_ENV" ] && ace_runner launch "$2"
|
||||
exit $?
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log.error "Invalid command: $1"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
190
tool/store-helper/uninstaller
Executable file
190
tool/store-helper/uninstaller
Executable file
@@ -0,0 +1,190 @@
|
||||
#!/bin/bash
|
||||
# ===== ACE环境配置 =====
|
||||
|
||||
readonly ACE_ENVIRONMENTS=(
|
||||
"bookworm-run:amber-ce-bookworm"
|
||||
"trixie-run:amber-ce-trixie"
|
||||
"deepin23-run:amber-ce-deepin23"
|
||||
"sid-run:amber-ce-sid"
|
||||
)
|
||||
# 生成ACE环境参数帮助信息
|
||||
function generate_ace_help() {
|
||||
local help_text=""
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_param="--${ace_entry#*:}"
|
||||
help_text+=" $ace_param 使用${ace_entry%%:*} ACE容器卸载\n"
|
||||
done
|
||||
echo -e "$help_text"
|
||||
}
|
||||
# 帮助函数
|
||||
function show_help() {
|
||||
echo "Spark Store Uninstall script. 星火商店卸载脚本"
|
||||
echo "用法: $0 [选项] 包名"
|
||||
echo "选项:"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo " --delete-after-install 安装成功后删除软件包"
|
||||
echo " --no-create-desktop-entry 不创建桌面快捷方式"
|
||||
echo " --force-create-desktop-entry 强制创建桌面快捷方式"
|
||||
echo "$(generate_ace_help)"
|
||||
echo " --native 只在主机卸载,不使用ACE容器"
|
||||
}
|
||||
|
||||
|
||||
# 参数解析
|
||||
function parse_args() {
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--delete-after-install)
|
||||
DELETE_AFTER_INSTALL="1"
|
||||
shift
|
||||
;;
|
||||
--native)
|
||||
FORCE_NATIVE="1"
|
||||
shift
|
||||
;;
|
||||
--no-create-desktop-entry)
|
||||
NO_CREATE_DESKTOP="1"
|
||||
shift
|
||||
;;
|
||||
--force-create-desktop-entry)
|
||||
FORCE_CREATE_DESKTOP="1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
# 检查是否为ACE环境参数
|
||||
local is_ace_param=0
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
local ace_param="--${ace_entry#*:}"
|
||||
if [ "$1" = "$ace_param" ]; then
|
||||
# 将ACE环境命令名加入数组
|
||||
ACE_PARAMS+=("${ace_entry%%:*}")
|
||||
is_ace_param=1
|
||||
shift
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# 如果不是ACE环境参数,则视为包名
|
||||
if [ "$is_ace_param" -eq 0 ]; then
|
||||
PACKAGE_NAME="$1"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# ===== 日志和函数 =====
|
||||
[ -f /opt/durapps/spark-store/bin/bashimport/log.amber ] && \
|
||||
source /opt/durapps/spark-store/bin/bashimport/log.amber || {
|
||||
log.info() { echo "INFO: $*"; }
|
||||
log.warn() { echo "WARN: $*"; }
|
||||
log.error() { echo "ERROR: $*"; }
|
||||
log.debug() { echo "DEBUG: $*"; }
|
||||
}
|
||||
|
||||
# 初始化变量
|
||||
FORCE_NATIVE=0
|
||||
ACE_PARAMS=()
|
||||
PACKAGE_NAME=""
|
||||
uninstall_success=0
|
||||
|
||||
# 解析参数
|
||||
parse_args "$@"
|
||||
|
||||
if [ -z "$PACKAGE_NAME" ]; then
|
||||
log.error "请指定要卸载的包名"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 尝试在本地卸载
|
||||
try_native_uninstall() {
|
||||
if [ "$FORCE_NATIVE" -eq 1 ] || [ ${#ACE_PARAMS[@]} -eq 0 ]; then
|
||||
echo "----------------------------------------"
|
||||
echo "正在检查本地环境中的安装..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
dpkg -s "$PACKAGE_NAME" > /dev/null
|
||||
RET="$?"
|
||||
if [[ "$RET" == "0" ]]; then
|
||||
echo "----------------------------------------"
|
||||
echo "在本地环境中找到了安装"
|
||||
echo "----------------------------------------"
|
||||
apt autopurge "$PACKAGE_NAME" -y
|
||||
uninstall_success=1
|
||||
return 0
|
||||
else
|
||||
echo "----------------------------------------"
|
||||
echo "在本地环境中未能找到安装"
|
||||
echo "----------------------------------------"
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# 尝试在ACE环境中卸载
|
||||
try_ace_uninstall() {
|
||||
local ace_cmd="$1"
|
||||
if command -v "$ace_cmd" >/dev/null 2>&1; then
|
||||
echo "----------------------------------------"
|
||||
echo "正在检查 $ace_cmd 环境的安装..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
$ace_cmd dpkg -l | grep "^ii $PACKAGE_NAME " > /dev/null
|
||||
try_run_ret="$?"
|
||||
|
||||
if [ "$try_run_ret" -eq 0 ]; then
|
||||
echo "----------------------------------------"
|
||||
echo "在 $ace_cmd 环境中找到了安装"
|
||||
echo "----------------------------------------"
|
||||
$ace_cmd apt autopurge "$PACKAGE_NAME" -y
|
||||
uninstall_success=1
|
||||
return 0
|
||||
else
|
||||
echo "----------------------------------------"
|
||||
echo "在 $ace_cmd 环境中未能找到安装"
|
||||
echo "----------------------------------------"
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# 主卸载逻辑
|
||||
if [ $FORCE_NATIVE -eq 1 ] && [ ${#ACE_PARAMS[@]} -eq 0 ]; then
|
||||
# 只有 --native 参数时,只尝试本地卸载
|
||||
try_native_uninstall || exit $?
|
||||
elif [ $FORCE_NATIVE -eq 0 ] && [ ${#ACE_PARAMS[@]} -gt 0 ]; then
|
||||
# 只有 ACE 参数时,只尝试指定的 ACE 环境卸载
|
||||
for ace_param in "${ACE_PARAMS[@]}"; do
|
||||
try_ace_uninstall "$ace_param"
|
||||
done
|
||||
elif [ $FORCE_NATIVE -eq 1 ] && [ ${#ACE_PARAMS[@]} -gt 0 ]; then
|
||||
# 同时有 --native 和 ACE 参数时,先尝试本地卸载,再尝试 ACE 环境卸载
|
||||
try_native_uninstall
|
||||
for ace_param in "${ACE_PARAMS[@]}"; do
|
||||
try_ace_uninstall "$ace_param"
|
||||
done
|
||||
else
|
||||
# 无参数时,先尝试本地卸载,再尝试所有 ACE 环境卸载
|
||||
try_native_uninstall
|
||||
|
||||
for ace_entry in "${ACE_ENVIRONMENTS[@]}"; do
|
||||
ace_cmd=${ace_entry%%:*}
|
||||
if command -v "$ace_cmd" >/dev/null 2>&1; then
|
||||
try_ace_uninstall "$ace_cmd"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $uninstall_success -eq 0 ]; then
|
||||
echo "----------------------------------------"
|
||||
echo "在所有指定的环境中未能找到安装,退出"
|
||||
echo "----------------------------------------"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
84
tool/update-upgrade/ss-do-upgrade-worker.sh
Executable file
84
tool/update-upgrade/ss-do-upgrade-worker.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
export LANGUAGE=en_US
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
case $1 in
|
||||
ssupdate)
|
||||
if [ "$(id -u)" != "0" ] ; then
|
||||
pkexec "$0" "$@"
|
||||
exit
|
||||
fi
|
||||
aptss ssupdate 2>&1 | tee /tmp/spark-store-app-ssupdate-log.txt
|
||||
IS_SSUPDATE_ERROR=`cat /tmp/spark-store-app-ssupdate-log.txt | grep "E: "`
|
||||
echo "$IS_SSUPDATE_ERROR" > /tmp/spark-store-app-ssupdate-status.txt
|
||||
chmod 777 /tmp/spark-store-app-ssupdate-status.txt
|
||||
chmod 777 /tmp/spark-store-app-ssupdate-log.txt
|
||||
;;
|
||||
|
||||
upgradable-list)
|
||||
output=$(env LANGUAGE=en_US /usr/bin/apt -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf list --upgradable -o Dir::Etc::sourcelist="/opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d/aptss.list" -o Dir::Etc::sourceparts="/dev/null" -o APT::Get::List-Cleanup="0" | awk NR\>1)
|
||||
|
||||
IFS_OLD="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
for line in $output ; do
|
||||
PKG_NAME=$(echo $line | awk -F '/' '{print $1}')
|
||||
PKG_NEW_VER=$(echo $line | awk -F ' ' '{print $2}')
|
||||
PKG_CUR_VER=$(echo $line | awk -F ' ' '{print $6}' | awk -F ']' '{print $1}')
|
||||
echo "${PKG_NAME} ${PKG_NEW_VER} ${PKG_CUR_VER}"
|
||||
done
|
||||
|
||||
IFS="$IFS_OLD"
|
||||
;;
|
||||
|
||||
upgrade-app)
|
||||
if [ "$(id -u)" != "0" ] ; then
|
||||
pkexec "$0" "$@"
|
||||
exit
|
||||
fi
|
||||
|
||||
aptss install "${@:2}" --only-upgrade 2>&1 | tee /tmp/spark-store-app-upgrade-log.txt
|
||||
sed -i '1i--------------------------------------------------------------' /tmp/spark-store-app-upgrade-log.txt
|
||||
sed -i '1i更新失败可能是由于系统版本过低,您可先【卸载】此应用后再在商店【安装】此应用来尝试修复此问题,商店会在安装时尝试自动解决问题。若仍无法解决,请按照指引进行反馈' /tmp/spark-store-app-upgrade-log.txt
|
||||
chmod 777 /tmp/spark-store-app-upgrade-log.txt
|
||||
IS_UPGRADE_ERROR=`cat /tmp/spark-store-app-upgrade-log.txt | grep "Package manager quit with exit code."`
|
||||
echo "$IS_UPGRADE_ERROR" > /tmp/spark-store-app-upgrade-status.txt
|
||||
;;
|
||||
test-install-app)
|
||||
if [ "$(id -u)" != "0" ] ; then
|
||||
pkexec "$0" "$@"
|
||||
exit
|
||||
fi
|
||||
|
||||
try_run_output=$(aptss --dry-run install $2)
|
||||
try_run_ret="$?"
|
||||
|
||||
if [ "$try_run_ret" -ne 0 ]
|
||||
then
|
||||
echo "Package manager quit with exit code.Here is the log"
|
||||
echo "包管理器以错误代码退出.日志如下"
|
||||
echo
|
||||
echo -e "${try_run_output}"
|
||||
echo "Will try after run aptss update"
|
||||
echo "将会在aptss update之后再次尝试"
|
||||
aptss update
|
||||
echo ----------------------------------------------------------------------------
|
||||
try_run_output=$(aptss --dry-run install $2)
|
||||
try_run_ret="$?"
|
||||
if [ "$try_run_ret" -ne 0 ]
|
||||
then
|
||||
echo "Package manager quit with exit code.Here is the log"
|
||||
echo "包管理器以错误代码退出.日志如下"
|
||||
echo
|
||||
echo -e "${try_run_output}"
|
||||
exit "$try_run_ret"
|
||||
fi
|
||||
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
|
||||
clean-log)
|
||||
|
||||
rm -f /tmp/spark-store-app-ssupdate-status.txt /tmp/spark-store-app-ssupdate-log.txt /tmp/spark-store-app-upgrade-log.txt /tmp/spark-store-app-upgrade-status.txt
|
||||
;;
|
||||
esac
|
||||
172
tool/update-upgrade/ss-do-upgrade.sh
Executable file
172
tool/update-upgrade/ss-do-upgrade.sh
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$(id -u)" != "0" ] ; then
|
||||
if [ "$IS_ACE_ENV" = "1" ] ; then
|
||||
/opt/durapps/spark-store/bin/store-helper/pass-auth.sh "$0" "$@"
|
||||
else
|
||||
xhost +
|
||||
pkexec "$0" "$@"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
HERE=$(dirname $0)
|
||||
trap "rm -f /tmp/spark-store/upgradeStatus.txt" EXIT
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
load_transhell_debug
|
||||
|
||||
function get_name_from_desktop_file() {
|
||||
local app_name_in_desktop
|
||||
local name_orig
|
||||
local name_i18n
|
||||
local package_name
|
||||
package_name=$1
|
||||
for desktop_file_path in $(dpkg -L "$package_name" |grep /usr/share/applications/ | awk '/\.desktop$/ {print}') ; do
|
||||
if [ "$(grep -m 1 '^NoDisplay=' "$desktop_file_path" | cut -d '=' -f 2)" = "true" ] || [ "$(grep -m 1 '^NoDisplay=' "$desktop_file_path" | cut -d '=' -f 2)" = "True" ] ; then
|
||||
continue
|
||||
else
|
||||
name_orig=$(awk -F= '/^\[Desktop Entry\]$/ {found=1} found && /^Name=/ {print $2; exit} /^\[.*\]$/ && !/\[Desktop Entry\]/ {exit}' "$desktop_file_path")
|
||||
name_i18n=$(awk -v lang="Name[$LANGUAGE]" -F= '/^\[Desktop Entry\]$/ {found=1} found && /^Name\[/ && $1 == lang {print $2; exit} /^\[.*\]$/ && !/\[Desktop Entry\]/ {exit}' "$desktop_file_path")
|
||||
if [ -z "$name_i18n" ] ; then
|
||||
app_name_in_desktop=$name_orig
|
||||
else
|
||||
app_name_in_desktop=$name_i18n
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
for desktop_file_path in $(dpkg -L "$package_name" |grep /opt/apps/$package_name/entries/applications | awk '/\.desktop$/ {print}') ; do
|
||||
if [ "$(grep -m 1 '^NoDisplay=' "$desktop_file_path" | cut -d '=' -f 2)" = "true" ] || [ "$(grep -m 1 '^NoDisplay=' "$desktop_file_path" | cut -d '=' -f 2)" = "True" ] ; then
|
||||
continue
|
||||
else
|
||||
name_orig=$(awk -F= '/^\[Desktop Entry\]$/ {found=1} found && /^Name=/ {print $2; exit} /^\[.*\]$/ && !/\[Desktop Entry\]/ {exit}' "$desktop_file_path")
|
||||
name_i18n=$(awk -v lang="Name[$LANGUAGE]" -F= '/^\[Desktop Entry\]$/ {found=1} found && /^Name\[/ && $1 == lang {print $2; exit} /^\[.*\]$/ && !/\[Desktop Entry\]/ {exit}' "$desktop_file_path")
|
||||
if [ -z "$name_i18n" ] ; then
|
||||
app_name_in_desktop=$name_orig
|
||||
else
|
||||
app_name_in_desktop=$name_i18n
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$app_name_in_desktop" ] ; then
|
||||
app_name_in_desktop=${package_name}
|
||||
fi
|
||||
|
||||
echo ${app_name_in_desktop}
|
||||
}
|
||||
|
||||
touch /tmp/spark-store/upgradeStatus.txt
|
||||
|
||||
# 执行 apt update
|
||||
pkexec ${HERE}/ss-do-upgrade-worker.sh ssupdate 2>&1 > /dev/null | zenity --progress --auto-close --pulsate --no-cancel --text="${TRANSHELL_CONTENT_UPDATE_CHEKING_PLEASE_WAIT}" --height 70 --width 400 --title="${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
|
||||
if [ -z `cat /tmp/spark-store-app-ssupdate-status.txt` ] ; then
|
||||
${HERE}/ss-do-upgrade-worker.sh clean-log
|
||||
else
|
||||
zenity --error --text "${TRANSHELL_CONTENT_CHECK_UPDATE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 200 --width 350 --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
zenity --text-info --filename=/tmp/spark-store-app-ssupdate-log.txt --checkbox="${TRANSHELL_CONTENT_I_ALREDY_COPIED_THE_LOG_HERE_AND_WILL_USE_IT_TO_FEEDBACK}" --title="${TRANSHELL_CONTENT_FEEDBACK_CAN_BE_FOUND_IN_THE_SETTINGS}" --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
${HERE}/ss-do-upgrade-worker.sh clean-log
|
||||
rm -f /tmp/spark-store/upgradeStatus.txt
|
||||
exit
|
||||
fi
|
||||
|
||||
# 获取可更新应用列表
|
||||
PKG_LIST="$(${HERE}/ss-do-upgrade-worker.sh upgradable-list)"
|
||||
## 如果没更新,就弹出不需要更新
|
||||
if [ -z "$PKG_LIST" ] ; then
|
||||
zenity --info --text "${TRANSHELL_CONTENT_NO_NEED_TO_UPGRADE}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 150 --width 300 --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
else
|
||||
## 获取用户选择的要更新的应用
|
||||
### 指定分隔符为 \n
|
||||
IFS_OLD="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
PKG_UPGRADE_LIST=$(for line in $PKG_LIST ; do
|
||||
PKG_NAME=$(echo $line | awk -F ' ' '{print $1}')
|
||||
PKG_NEW_VER=$(echo $line | awk -F ' ' '{print $2}')
|
||||
PKG_CUR_VER=$(echo $line | awk -F ' ' '{print $3}')
|
||||
|
||||
dpkg --compare-versions $PKG_NEW_VER le $PKG_CUR_VER
|
||||
if [ $? -eq 0 ] ; then
|
||||
continue
|
||||
fi
|
||||
APP_NAME=$(get_name_from_desktop_file $PKG_NAME)
|
||||
#### 检测是否是 hold 状态
|
||||
PKG_STA=$(dpkg-query -W -f='${db:Status-Want}' $PKG_NAME)
|
||||
if [ "$PKG_STA" != "hold" ] ; then
|
||||
echo "true"
|
||||
echo "$APP_NAME"
|
||||
echo "$PKG_NEW_VER"
|
||||
echo "$PKG_CUR_VER"
|
||||
echo "$PKG_NAME"
|
||||
else
|
||||
echo "false"
|
||||
echo "$APP_NAME${TRANSHELL_CONTENT_CAN_NOT_UPGRADE_FOR_BEING_HOLD}"
|
||||
echo "$PKG_NEW_VER"
|
||||
echo "$PKG_CUR_VER"
|
||||
echo "$PKG_NAME"
|
||||
fi
|
||||
done)
|
||||
|
||||
### 还原分隔符
|
||||
IFS="$IFS_OLD"
|
||||
|
||||
## 如果没有应用需要更新,则直接退出
|
||||
if [ -z "$PKG_UPGRADE_LIST" ] ; then
|
||||
zenity --info --text "${TRANSHELL_CONTENT_NO_NEED_TO_UPGRADE}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 150 --width 300
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
while true;do
|
||||
PKG_UPGRADE_LIST=$(echo "$PKG_UPGRADE_LIST" | zenity --list --text="${TRANSHELL_CONTENT_CHOOSE_APP_TO_UPGRADE}" --column="${TRANSHELL_CONTENT_CHOOSE}" --column="${TRANSHELL_CONTENT_APP_NAME}" --column="${TRANSHELL_CONTENT_NEW_VERSION}" --column="${TRANSHELL_CONTENT_UPGRADE_FROM}" --column="${TRANSHELL_CONTENT_PKG_NAME}" --separator=" " --checklist --multiple --print-column=5 --height 350 --width 650 )
|
||||
## 如果没有选择,则直接退出
|
||||
if [ -z "$PKG_UPGRADE_LIST" ] ; then
|
||||
zenity --info --text "${TRANSHELL_CONTENT_NO_APP_IS_CHOSEN}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 150 --width 300
|
||||
exit 0
|
||||
fi
|
||||
if [[ "$PKG_UPGRADE_LIST" == *"(null)"* ]]; then
|
||||
zenity --error --text "${TRANSHELL_CONTENT_LIST_NOT_LOADED_PLEASE_WAIT}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 150 --width 300
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
### 更新用户选择的应用
|
||||
# for PKG_UPGRADE in $PKG_UPGRADE_LIST;do
|
||||
# APP_UPGRADE="$(get_name_from_desktop_file $PKG_UPGRADE)"
|
||||
# update_transhell
|
||||
|
||||
(
|
||||
total=$(echo "$PKG_UPGRADE_LIST" | wc -w)
|
||||
count=0
|
||||
|
||||
for PKG_UPGRADE in $PKG_UPGRADE_LIST; do
|
||||
count=$((count + 1))
|
||||
APP_UPGRADE="$(get_name_from_desktop_file $PKG_UPGRADE)"
|
||||
update_transhell
|
||||
|
||||
# 启动升级任务
|
||||
(yes n | pkexec ${HERE}/ss-do-upgrade-worker.sh upgrade-app $PKG_UPGRADE -yfq 2>&1 > /dev/null ) &
|
||||
|
||||
# 计算进度百分比
|
||||
progress=$(( count * 100 / total - 1))
|
||||
|
||||
# 动态修改zenity的文本
|
||||
echo "# ${TRANSHELL_CONTENT_UPGRADING_PLEASE_WAIT}"
|
||||
echo "$progress"
|
||||
wait
|
||||
done
|
||||
) | zenity --progress --auto-close --no-cancel --text="Preparing..." --height 70 --width 400 --title="${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
|
||||
|
||||
#### 更新成功
|
||||
if [ -z "`cat /tmp/spark-store-app-upgrade-status.txt`" ] ; then
|
||||
zenity --info --text "${TRANSHELL_CONTENT_CHOSEN_APP_UPGRADE_FINISHED}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 150 --width 300 --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
else #### 更新异常
|
||||
zenity --error --text "${TRANSHELL_CONTENT_APP_UGRADE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK}" --title "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL}" --height 200 --width 350 --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
zenity --text-info --filename=/tmp/spark-store-app-upgrade-log.txt --checkbox="${TRANSHELL_CONTENT_I_ALREDY_COPIED_THE_LOG_HERE_AND_WILL_USE_IT_TO_FEEDBACK}" --title="${TRANSHELL_CONTENT_FEEDBACK_CAN_BE_FOUND_IN_THE_SETTINGS}" --window-icon=/usr/share/icons/hicolor/scalable/apps/spark-store.svg
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f /tmp/spark-store/upgradeStatus.txt
|
||||
# 从最开头
|
||||
61
tool/update-upgrade/ss-update-controler.sh
Executable file
61
tool/update-upgrade/ss-update-controler.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
load_transhell_debug
|
||||
|
||||
endloop=0
|
||||
|
||||
#####################检测是否启动过了更新检测工具
|
||||
while [ $endloop -eq 0 ] ;do
|
||||
|
||||
if [ ! -e $HOME/.config/spark-union/spark-store/ssshell-config-do-not-show-upgrade-notify ];then
|
||||
text_update_open="${TRANSHELL_CONTENT_CLOSE}"
|
||||
#已经开启了就显示关闭
|
||||
else
|
||||
text_update_open="${TRANSHELL_CONTENT_OPEN}"
|
||||
fi
|
||||
|
||||
if [ ! -e $HOME/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop ];then
|
||||
CONTENT_SET_CREATE_DESKTOP="${TRANSHELL_CONTENT_CLOSE_CREATE_DESKTOP}"
|
||||
#已经开启了就显示关闭
|
||||
else
|
||||
CONTENT_SET_CREATE_DESKTOP="${TRANSHELL_CONTENT_OPEN_CREATE_DESKTOP}"
|
||||
fi
|
||||
|
||||
update_transhell
|
||||
|
||||
option=$(zenity --list --text="${TRANSHELL_CONTENT_WELCOME_AND_CHOOSE_ONE_TO_RUN}" --column 数字 --column=${TRANSHELL_CONTENT_OPTIONS} --print-column=2 --height 350 --width 760 0 "${TRANSHELL_CONTENT_OPEN_OR_CLOSE_UPGRADE_CHECK}" 1 "${CONTENT_SET_CREATE_DESKTOP}" 2 "${TRANSHELL_CONTENT_CHECK_FOR_UPDATE}" 3 "${TRANSHELL_CONTENT_EXIT}" --hide-column=1 --print-column=1)
|
||||
|
||||
case $option in
|
||||
0)
|
||||
if [ ! -e $HOME/.config/spark-union/spark-store/ssshell-config-do-not-show-upgrade-notify ];then
|
||||
mkdir -p $HOME/.config/spark-union/spark-store/
|
||||
touch $HOME/.config/spark-union/spark-store/ssshell-config-do-not-show-upgrade-notify
|
||||
zenity --info --icon-name=spark-store --height 150 --width 200 --text "${TRANSHELL_CONTENT_CLOSED}" --timeout=2
|
||||
else
|
||||
rm -f $HOME/.config/spark-union/spark-store/ssshell-config-do-not-show-upgrade-notify
|
||||
zenity --info --icon-name=spark-store --height 150 --width 200 --text "${TRANSHELL_CONTENT_OPENED}" --timeout=2
|
||||
fi
|
||||
;;
|
||||
1)
|
||||
if [ ! -e $HOME/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop ];then
|
||||
mkdir -p $HOME/.config/spark-union/spark-store/
|
||||
touch $HOME/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop
|
||||
zenity --info --icon-name=spark-store --height 150 --width 200 --text "${TRANSHELL_CONTENT_CLOSED}" --timeout=2
|
||||
else
|
||||
rm -f $HOME/.config/spark-union/spark-store/ssshell-config-do-not-create-desktop
|
||||
zenity --info --icon-name=spark-store --height 150 --width 200 --text "${TRANSHELL_CONTENT_OPENED}" --timeout=2
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
/opt/durapps/spark-store/bin/update-upgrade/ss-do-upgrade.sh
|
||||
;;
|
||||
|
||||
3)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
esac
|
||||
|
||||
done
|
||||
145
tool/update-upgrade/ss-update-notifier.sh
Executable file
145
tool/update-upgrade/ss-update-notifier.sh
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /opt/durapps/spark-store/bin/bashimport/transhell.amber
|
||||
load_transhell_debug
|
||||
|
||||
#############################################################
|
||||
|
||||
# 发送通知
|
||||
function notify-send() {
|
||||
# Detect user using the display
|
||||
local user=$(who | awk '{print $1}' | head -n 1)
|
||||
|
||||
# Detect uid of the user
|
||||
local uid=$(id -u $user)
|
||||
|
||||
sudo -u $user DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus notify-send "$@"
|
||||
}
|
||||
|
||||
# 检测网络链接畅通
|
||||
function network-check() {
|
||||
# 超时时间
|
||||
local timeout=15
|
||||
|
||||
# 目标网站
|
||||
local target=www.baidu.com
|
||||
|
||||
# 获取响应状态码
|
||||
local ret_code=$(curl -I -s --connect-timeout ${timeout} ${target} -w %{http_code} | tail -n1)
|
||||
|
||||
if [ "$ret_code" = "200" ]; then
|
||||
# 网络畅通
|
||||
return 0
|
||||
else
|
||||
# 网络不畅通
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 初始化等待时间和最大等待时间
|
||||
initial_wait_time=15 # 初始等待时间 15 秒
|
||||
max_wait_time=$((12 * 3600)) # 最大等待时间 12 小时
|
||||
|
||||
# 检测网络,若不通则进行重试,采用指数退避算法
|
||||
wait_time=$initial_wait_time
|
||||
while ! network-check; do
|
||||
echo "$TRANSHELL_CONTENT_NETWORK_FAIL"
|
||||
echo "Waiting for network to recover... Retrying in ${wait_time} seconds."
|
||||
|
||||
sleep $wait_time
|
||||
wait_time=$((wait_time * 2)) # 等待时间翻倍
|
||||
if [ $wait_time -gt $max_wait_time ]; then
|
||||
wait_time=$max_wait_time # 最大等待时间限制为12小时
|
||||
fi
|
||||
done
|
||||
|
||||
# 每日更新星火源文件
|
||||
aptss update
|
||||
|
||||
updatetext=`LANGUAGE=en_US aptss ssupdate 2>&1`
|
||||
|
||||
# 在网络恢复后,继续更新操作
|
||||
retry_count=0
|
||||
max_retries=12 # 最大重试次数,防止死循环
|
||||
|
||||
until ! echo $updatetext | grep -q "E:"; do
|
||||
if [ $retry_count -ge $max_retries ]; then
|
||||
echo "Reached maximum retry limit for aptss ssupdate."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "${TRANSHELL_CONTENT_UPDATE_ERROR_AND_WAIT_15_SEC}"
|
||||
sleep 15
|
||||
updatetext=`LANGUAGE=en_US aptss ssupdate 2>&1`
|
||||
retry_count=$((retry_count + 1))
|
||||
done
|
||||
|
||||
update_app_number=$(env LANGUAGE=en_US /usr/bin/apt -c /opt/durapps/spark-store/bin/apt-fast-conf/aptss-apt.conf list --upgradable -o Dir::Etc::sourcelist="/opt/durapps/spark-store/bin/apt-fast-conf/sources.list.d/aptss.list" -o Dir::Etc::sourceparts="/dev/null" -o APT::Get::List-Cleanup="0" 2>/dev/null | grep -c upgradable)
|
||||
|
||||
if [ "$update_app_number" -le 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 读取忽略列表到数组
|
||||
declare -A ignored_apps
|
||||
if [ -f "/etc/spark-store/ignored_apps.conf" ]; then
|
||||
while IFS='|' read -r pkg_name pkg_version || [ -n "$pkg_name" ]; do
|
||||
# 去除前后空白字符
|
||||
pkg_name=$(echo "$pkg_name" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
if [ -n "$pkg_name" ]; then
|
||||
ignored_apps["$pkg_name"]=1
|
||||
fi
|
||||
done < "/etc/spark-store/ignored_apps.conf"
|
||||
fi
|
||||
|
||||
# 获取用户选择的要更新的应用
|
||||
PKG_LIST="$(/opt/durapps/spark-store/bin/update-upgrade/ss-do-upgrade-worker.sh upgradable-list)"
|
||||
# 指定分隔符为 \n
|
||||
IFS_OLD="$IFS"
|
||||
IFS=$'\n'
|
||||
|
||||
for line in $PKG_LIST; do
|
||||
PKG_NAME=$(echo $line | awk -F ' ' '{print $1}')
|
||||
PKG_NEW_VER=$(echo $line | awk -F ' ' '{print $2}')
|
||||
PKG_CUR_VER=$(echo $line | awk -F ' ' '{print $3}')
|
||||
|
||||
dpkg --compare-versions $PKG_NEW_VER le $PKG_CUR_VER
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
let update_app_number=$update_app_number-1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检测是否是 hold 状态
|
||||
PKG_STA=$(dpkg-query -W -f='${db:Status-Want}' $PKG_NAME)
|
||||
if [ "$PKG_STA" = "hold" ]; then
|
||||
let update_app_number=$update_app_number-1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检测是否在忽略列表中
|
||||
if [ -n "${ignored_apps[$PKG_NAME]}" ]; then
|
||||
let update_app_number=$update_app_number-1
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
# 还原分隔符
|
||||
IFS="$IFS_OLD"
|
||||
if [ $update_app_number -le 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
update_transhell
|
||||
|
||||
# 如果都是hold或者版本一致的那就直接退出,否则把剩余的给提醒了
|
||||
# TODO: 除了apt-mark hold之外额外有一个禁止检查列表
|
||||
# 如果不想提示就不提示
|
||||
|
||||
user=$(who | awk '{print $1}' | head -n 1)
|
||||
if [ -e "/home/$user/.config/spark-union/spark-store/ssshell-config-do-not-show-upgrade-notify" ]; then
|
||||
echo "他不想站在世界之巅,好吧"
|
||||
echo "Okay he don't want to be at the top of the world, okay"
|
||||
exit
|
||||
else
|
||||
notify-send -a spark-store "${TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_NOTIFY}" "${TRANSHELL_CONTENT_THERE_ARE_APPS_TO_UPGRADE}" || true # Some machine don't have bus, or who command just print nothing.
|
||||
fi
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_UPDATE_CHEKING_PLEASE_WAIT="Checking for updates, please wait..."
|
||||
TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL="Spark Store Update Module"
|
||||
TRANSHELL_CONTENT_CHECK_UPDATE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK="An error occurred during the update check process. Click Confirm to view the error log, which can be used for issue reporting."
|
||||
TRANSHELL_CONTENT_I_ALREDY_COPIED_THE_LOG_HERE_AND_WILL_USE_IT_TO_FEEDBACK="I have copied the log in this text box and will attach it when submitting feedback. The feedback option can be found in the Settings menu at the top-right corner of the main interface."
|
||||
TRANSHELL_CONTENT_FEEDBACK_CAN_BE_FOUND_IN_THE_SETTINGS="The feedback option can be found in the Settings menu at the top-right corner of the main interface."
|
||||
TRANSHELL_CONTENT_NO_NEED_TO_UPGRADE="All packages are already up to date."
|
||||
TRANSHELL_CONTENT_CAN_NOT_UPGRADE_FOR_BEING_HOLD="Unable to update: the current package status is marked as Hold."
|
||||
TRANSHELL_CONTENT_CHOOSE_APP_TO_UPGRADE="Please select the application you want to update."
|
||||
TRANSHELL_CONTENT_CHOOSE="Select"
|
||||
TRANSHELL_CONTENT_APP_NAME="Application Name"
|
||||
TRANSHELL_CONTENT_PKG_NAME="Package Name"
|
||||
TRANSHELL_CONTENT_NEW_VERSION="New Version"
|
||||
TRANSHELL_CONTENT_UPGRADE_FROM="Updating from this version"
|
||||
TRANSHELL_CONTENT_NO_APP_IS_CHOSEN="You have not selected any application."
|
||||
TRANSHELL_CONTENT_UPGRADING_PLEASE_WAIT="Updating $APP_UPGRADE, please wait..."
|
||||
TRANSHELL_CONTENT_CHOSEN_APP_UPGRADE_FINISHED="The selected application has been successfully updated."
|
||||
TRANSHELL_CONTENT_APP_UGRADE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK="An error occurred during the update process. Click Confirm to view the error log, which can be used for issue reporting."
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_UPDATE_CHEKING_PLEASE_WAIT="正在检查更新,请稍候……"
|
||||
TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL="星火应用商店更新模块"
|
||||
TRANSHELL_CONTENT_CHECK_UPDATE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK="检查更新进程出现错误。单击“确定”查看错误日志,可用于问题反馈。"
|
||||
TRANSHELL_CONTENT_I_ALREDY_COPIED_THE_LOG_HERE_AND_WILL_USE_IT_TO_FEEDBACK="我已复制且将会在反馈时附上此文本框中的日志,反馈渠道位于软件主界面右上角菜单的设置中。"
|
||||
TRANSHELL_CONTENT_FEEDBACK_CAN_BE_FOUND_IN_THE_SETTINGS="反馈渠道位于软件主界面右上角菜单的设置中。"
|
||||
TRANSHELL_CONTENT_NO_NEED_TO_UPGRADE="所有软件包版本已是最新。"
|
||||
TRANSHELL_CONTENT_CAN_NOT_UPGRADE_FOR_BEING_HOLD="无法更新:当前软件包状态已被标记为“保留”。"
|
||||
TRANSHELL_CONTENT_CHOOSE_APP_TO_UPGRADE="请选择您需要更新的软件。"
|
||||
TRANSHELL_CONTENT_CHOOSE="选择"
|
||||
TRANSHELL_CONTENT_APP_NAME="应用名"
|
||||
TRANSHELL_CONTENT_PKG_NAME="软件包名"
|
||||
TRANSHELL_CONTENT_NEW_VERSION="新版本"
|
||||
TRANSHELL_CONTENT_UPGRADE_FROM="将从该版本更新"
|
||||
TRANSHELL_CONTENT_NO_APP_IS_CHOSEN="您没有选中任何软件。"
|
||||
TRANSHELL_CONTENT_UPGRADING_PLEASE_WAIT="正在更新 $APP_UPGRADE,请稍候……"
|
||||
TRANSHELL_CONTENT_CHOSEN_APP_UPGRADE_FINISHED="选中的软件已更新完毕。"
|
||||
TRANSHELL_CONTENT_APP_UGRADE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK="更新进程出现错误。单击“确定”查看错误日志,可用于问题反馈。"
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_UPDATE_CHEKING_PLEASE_WAIT="正在檢查更新,請稍候……"
|
||||
TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_MODEL="星火應用商店更新模組"
|
||||
TRANSHELL_CONTENT_CHECK_UPDATE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK="檢查更新行程出現錯誤。點擊「確定」查看錯誤日誌,可用於問題回饋。"
|
||||
TRANSHELL_CONTENT_I_ALREDY_COPIED_THE_LOG_HERE_AND_WILL_USE_IT_TO_FEEDBACK="我已複製且將會在回饋時附上此文字框中的日誌,回饋渠道位於軟體主介面右上角選單的設定中。"
|
||||
TRANSHELL_CONTENT_FEEDBACK_CAN_BE_FOUND_IN_THE_SETTINGS="回饋渠道位於軟體主介面右上角選單的設定中。"
|
||||
TRANSHELL_CONTENT_NO_NEED_TO_UPGRADE="所有軟體包版本已是最新。"
|
||||
TRANSHELL_CONTENT_CAN_NOT_UPGRADE_FOR_BEING_HOLD="無法更新:當前軟體包狀態已被標記為「保留」。"
|
||||
TRANSHELL_CONTENT_CHOOSE_APP_TO_UPGRADE="請選擇您需要更新的軟體。"
|
||||
TRANSHELL_CONTENT_CHOOSE="選擇"
|
||||
TRANSHELL_CONTENT_APP_NAME="應用名稱"
|
||||
TRANSHELL_CONTENT_PKG_NAME="軟體包名稱"
|
||||
TRANSHELL_CONTENT_NEW_VERSION="新版本"
|
||||
TRANSHELL_CONTENT_UPGRADE_FROM="將從該版本更新"
|
||||
TRANSHELL_CONTENT_NO_APP_IS_CHOSEN="您沒有選中任何軟體。"
|
||||
TRANSHELL_CONTENT_UPGRADING_PLEASE_WAIT="正在更新 $APP_UPGRADE,請稍候……"
|
||||
TRANSHELL_CONTENT_CHOSEN_APP_UPGRADE_FINISHED="選中的軟體已更新完畢。"
|
||||
TRANSHELL_CONTENT_APP_UGRADE_PROCESS_ERROR_PRESS_CONFIRM_TO_CHECK="更新行程出現錯誤。點擊「確定」查看錯誤日誌,可用於問題回饋。"
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_CLOSE="Disable"
|
||||
TRANSHELL_CONTENT_OPEN="Enable"
|
||||
TRANSHELL_CONTENT_WELCOME_AND_CHOOSE_ONE_TO_RUN="Welcome to the Spark App Store update and installation settings tool. Please choose one of the following options to continue."
|
||||
TRANSHELL_CONTENT_OPTIONS="Options"
|
||||
TRANSHELL_CONTENT_OPEN_OR_CLOSE_UPGRADE_CHECK="$text_update_open Spark Store Update Check Tool (When enabled, this tool will automatically check for updates after system startup and display a notification if updates are available)"
|
||||
TRANSHELL_CONTENT_CHECK_FOR_UPDATE="View the list of upgradable packages"
|
||||
TRANSHELL_CONTENT_EXIT="Exit"
|
||||
TRANSHELL_CONTENT_CLOSING_UPGRADE_CHECK="Please authorize to disable automatic update check."
|
||||
TRANSHELL_CONTENT_CLOSED="Disabled"
|
||||
TRANSHELL_CONTENT_OPENING_UPGRADE_CHECK="Please authorize to enable automatic update check."
|
||||
TRANSHELL_CONTENT_OPENED="Enabled"
|
||||
TRANSHELL_CONTENT_CLOSE_CREATE_DESKTOP="Disable automatic creation of desktop launcher"
|
||||
TRANSHELL_CONTENT_OPEN_CREATE_DESKTOP="Enable automatic creation of desktop launcher"
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_CLOSE="关闭"
|
||||
TRANSHELL_CONTENT_OPEN="开启"
|
||||
TRANSHELL_CONTENT_WELCOME_AND_CHOOSE_ONE_TO_RUN="欢迎使用星火应用商店更新与安装设置工具,请在以下选项中选择一个以继续。"
|
||||
TRANSHELL_CONTENT_OPTIONS="操作选项"
|
||||
TRANSHELL_CONTENT_OPEN_OR_CLOSE_UPGRADE_CHECK="$text_update_open星火更新检测工具(此工具于开启状态下将在系统启动后自动检测更新,如有更新则会弹出通知)"
|
||||
TRANSHELL_CONTENT_CHECK_FOR_UPDATE="查看可更新软件包列表"
|
||||
TRANSHELL_CONTENT_EXIT="退出"
|
||||
TRANSHELL_CONTENT_CLOSING_UPGRADE_CHECK="执行“关闭自动更新检测”,请授权。"
|
||||
TRANSHELL_CONTENT_CLOSED="已关闭"
|
||||
TRANSHELL_CONTENT_OPENING_UPGRADE_CHECK="执行“开启自动更新检测”,请授权。"
|
||||
TRANSHELL_CONTENT_OPENED="已开启"
|
||||
TRANSHELL_CONTENT_CLOSE_CREATE_DESKTOP="关闭自动创建桌面启动器"
|
||||
TRANSHELL_CONTENT_OPEN_CREATE_DESKTOP="开启自动创建桌面启动器"
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_CLOSE="關閉"
|
||||
TRANSHELL_CONTENT_OPEN="開啟"
|
||||
TRANSHELL_CONTENT_WELCOME_AND_CHOOSE_ONE_TO_RUN="歡迎使用星火應用商店更新與安裝設定工具,請在以下選項中選擇一個以繼續。"
|
||||
TRANSHELL_CONTENT_OPTIONS="操作選項"
|
||||
TRANSHELL_CONTENT_OPEN_OR_CLOSE_UPGRADE_CHECK="$text_update_open星火更新檢測工具(此工具於開啟狀態下將在系統啟動後自動檢測更新,如有更新則會彈出通知)"
|
||||
TRANSHELL_CONTENT_CHECK_FOR_UPDATE="查看可更新軟體包清單"
|
||||
TRANSHELL_CONTENT_EXIT="退出"
|
||||
TRANSHELL_CONTENT_CLOSING_UPGRADE_CHECK="執行「關閉自動更新檢測」,請授權。"
|
||||
TRANSHELL_CONTENT_CLOSED="已關閉"
|
||||
TRANSHELL_CONTENT_OPENING_UPGRADE_CHECK="執行「開啟自動更新檢測」,請授權。"
|
||||
TRANSHELL_CONTENT_OPENED="已開啟"
|
||||
TRANSHELL_CONTENT_CLOSE_CREATE_DESKTOP="關閉自動建立桌面啟動器"
|
||||
TRANSHELL_CONTENT_OPEN_CREATE_DESKTOP="開啟自動建立桌面啟動器"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_NETWORK_FAIL="The current network is abnormal. To prevent blocking the dpkg process, the update has been paused."
|
||||
TRANSHELL_CONTENT_UPDATE_ERROR_AND_WAIT_15_SEC="An error occurred during the update process. It will automatically retry in 15 seconds."
|
||||
TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_NOTIFY="Spark Store Update Notifier"
|
||||
TRANSHELL_CONTENT_THERE_ARE_APPS_TO_UPGRADE="There are ${update_app_number} packages available for update in the repository. Click to open the Spark Store menu for details."
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_NETWORK_FAIL="当前网络异常,为防止阻塞 dpkg 进程,已暂停更新。"
|
||||
TRANSHELL_CONTENT_UPDATE_ERROR_AND_WAIT_15_SEC="更新进程发生异常,将在 15 秒后自动重试。"
|
||||
TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_NOTIFY="星火应用商店更新提醒"
|
||||
TRANSHELL_CONTENT_THERE_ARE_APPS_TO_UPGRADE="软件仓库中有 $update_app_number 个软件包可供更新,点击前往星火应用商店菜单查看详情。"
|
||||
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
TRANSHELL_CONTENT_NETWORK_FAIL="當前網路異常,為防止阻塞 dpkg 行程,已暫停更新。"
|
||||
TRANSHELL_CONTENT_UPDATE_ERROR_AND_WAIT_15_SEC="更新行程發生異常,將在 15 秒後自動重試。"
|
||||
TRANSHELL_CONTENT_SPARK_STORE_UPGRADE_NOTIFY="星火應用商店更新提醒"
|
||||
TRANSHELL_CONTENT_THERE_ARE_APPS_TO_UPGRADE="軟體倉庫中有 $update_app_number 個軟體包可供更新,點擊前往星火應用商店選單查看詳情。"
|
||||
Reference in New Issue
Block a user