update 2026-09-26 11:07:27

This commit is contained in:
action committed 2026-09-26 11:07:27 +08:00
1 parent 7b88b273d0
commit 97ae9f68da
4898 files changed
-1712274

No files matched your search

-564
View File
@@ -1,564 +0,0 @@
#!/bin/sh
# this script MUST supports executting without luci-app-store installed,
# so we can use this script to install luci-app-store itself
action=${1}
shift
if [ "${action:0:9}" = "AUTOCONF=" ]; then
export "ISTORE_${action}"
exec "$0" "$@"
fi
IS_ROOT=/tmp/is-root
TMP_SELF_COPY=/var/run/cloned-is-opkg
USE_APK=false
DISABLE_MIRROR=false
if [[ -s /etc/apk/arch ]]; then
USE_APK=true
fi
if $USE_APK; then
LISTS_DIR=${IS_ROOT}/apk
APK_CONF=${IS_ROOT}/etc/apk.conf
FEEDS_SERVER=https://istore.istoreos.com/repo-apk
FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo-apk"
ISTORE_INDEX=$FEEDS_SERVER/all/store/packages.adb
META_DIR=/lib/apk
ARCH=`cat /rom/etc/apk/arch /etc/apk/arch 2>/dev/null | head -1`
else
LISTS_DIR_O=/tmp/opkg-lists
LISTS_DIR=${IS_ROOT}${LISTS_DIR_O}
OPKG_CONF_DIR=${IS_ROOT}/etc/opkg
OPKG_CONF_DIR_M=${IS_ROOT}/etc/opkg_m
FEEDS_SERVER=https://istore.istoreos.com/repo
FEEDS_SERVER_MIRRORS="https://repo.istoreos.com/repo"
ISTORE_INDEX=$FEEDS_SERVER/all/store/Packages.gz
META_DIR=/usr/lib/opkg
ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1`
fi
# for istore self upgrade
ISTORE_PKG=luci-app-store
ISTORE_DEP_PKGS="luci-lib-taskd luci-lib-xterm taskd"
NEWLINE=$'\n'
is_init() {
mkdir -p ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var
if $USE_APK; then
return 0
fi
cat /etc/opkg.conf | grep -Fv lists_dir | grep -Fv check_signature > ${IS_ROOT}/etc/opkg.conf
cp ${IS_ROOT}/etc/opkg.conf ${IS_ROOT}/etc/opkg_o.conf
echo >> ${IS_ROOT}/etc/opkg.conf
echo "lists_dir ext ${LISTS_DIR}" >> ${IS_ROOT}/etc/opkg.conf
# create opkg_o.conf for executting 'opkg update' with offline-root, so we don't overwrite system opkg list
echo >> ${IS_ROOT}/etc/opkg_o.conf
echo "lists_dir ext ${LISTS_DIR_O}" >> ${IS_ROOT}/etc/opkg_o.conf
cp -au /etc/opkg ${IS_ROOT}/etc/
[ -e ${IS_ROOT}/var/lock ] || ln -s /var/lock ${IS_ROOT}/var/lock
}
apk_wrap() {
APK_CONFIG=${APK_CONF} apk "$@"
}
opkg_wrap() {
OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@"
}
simple_apk_opkg() {
local action="$1"
shift
if $USE_APK; then
case "$action" in
"install")
action=add
;;
"remove")
action=del
;;
esac
apk_wrap "$action" "$@"
else
opkg_wrap "$action" "$@"
fi
}
do_in_mirrors() {
local server
if ! $DISABLE_MIRROR; then
local newpath="/usr/libexec/istore/mirror-bin:$PATH"
for server in $FEEDS_SERVER_MIRRORS ; do
echo "Try mirror server $server"
PATH="$newpath" IS_ORIG_SERVER=$FEEDS_SERVER IS_MIRROR_SERVER=$server "$@" && return 0
done
DISABLE_MIRROR=true
fi
echo "Try origin server $FEEDS_SERVER"
"$@"
}
apk_wrap_mirrors() {
do_in_mirrors apk_wrap "$@"
}
opkg_wrap_mirrors() {
do_in_mirrors opkg_wrap "$@"
}
do_install_in_mirrors() {
if $USE_APK; then
apk_wrap_mirrors add "$@"
else
opkg_wrap_mirrors install "$@"
fi
}
do_upgrade_in_mirrors() {
if $USE_APK; then
apk_wrap_mirrors upgrade "$@"
else
opkg_wrap_mirrors upgrade "$@"
fi
}
alias fcurl='curl -L --fail --show-error'
check_space() {
local free="$((`df -kP / | awk 'NR==2 {print $4}'` >> 10 ))"
if [ "$free" -lt 1 ]; then
echo "Root disk full!" >&2
exit 1
fi
return 0
}
update() {
if [ -z "${ARCH}" ]; then
echo "Get architecture failed" >&2
return 1
fi
echo "Fetch feed list for ${ARCH}"
if $USE_APK; then
rm -rf ${IS_ROOT}/var/tmp ${IS_ROOT}/etc/arch ${IS_ROOT}/etc/istore.pem
mkdir -p ${IS_ROOT}/var/tmp
fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \
fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \
fcurl --no-progress-meter -o ${IS_ROOT}/var/tmp/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" && \
fcurl --no-progress-meter -o ${IS_ROOT}/etc/arch "${FEEDS_SERVER}/${ARCH}/archlist.conf" || \
return 1
echo "cache-dir $LISTS_DIR" > ${APK_CONF}
cat ${IS_ROOT}/var/tmp/arch.conf ${IS_ROOT}/var/tmp/all.conf ${IS_ROOT}/var/tmp/meta.conf >> ${APK_CONF}
local line
while read -r line; do
if [[ -n "$line" ]]; then
grep -Fxq "$line" /etc/apk/arch || echo "$line" >> /etc/apk/arch
fi
done < ${IS_ROOT}/etc/arch
sync /etc/apk/arch
if [[ ! -s /etc/apk/keys/istore.pem && ! -s /etc/apk/keys/istore-tmp.pem ]]; then
fcurl --no-progress-meter -o ${IS_ROOT}/etc/istore.pem "${FEEDS_SERVER}/istore-apk.pem" && \
cp -a ${IS_ROOT}/etc/istore.pem /etc/apk/keys/istore-tmp.pem || \
return 1
fi
else
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \
fcurl --no-progress-meter -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \
return 1
fi
echo "Update feeds index"
if $USE_APK; then
apk_wrap update
else
opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update
fi
return 0
}
update_if_outdate() {
local idle_t=$((`date '+%s'` - `date -r ${IS_ROOT}/.last_force_ts '+%s' 2>/dev/null || echo '0'`))
[ $idle_t -gt ${1:-120} ] || return 2
update || return 1
touch ${IS_ROOT}/.last_force_ts
return 0
}
get_online_version() {
local index="$1"
local pkg="$2"
if $USE_APK; then
apk --cache-dir $LISTS_DIR --cache-max-age 0 --repositories-file /dev/null --repository "$index" update >/dev/null 2>&1
apk --cache-dir $LISTS_DIR --cache-max-age 0 --repositories-file /dev/null --repository "$index" query --available --fields version "$pkg" 2>/dev/null | grep -Fm1 'Version: ' | sed 's/^Version: //'
else
curl --connect-timeout 2 --max-time 5 -s "$index" | gunzip | grep -FA10 "Package: $pkg" | grep -Fm1 'Version: ' | sed 's/^Version: //'
fi
}
get_local_version() {
local pkg="$1"
if $USE_APK; then
apk query --installed --fields version "$pkg" 2>/dev/null | grep -Fm1 'Version: ' | sed 's/^Version: //'
else
grep -Fm1 'Version: ' /usr/lib/opkg/info/$pkg.control 2>/dev/null | sed 's/^Version: //'
fi
}
check_self_upgrade() {
local newest=`get_online_version "$ISTORE_INDEX" "$ISTORE_PKG"`
local current=`get_local_version "$ISTORE_PKG"`
if [ "v$newest" = "v" -o "v$current" = "v" ]; then
echo "Check version failed!" >&2
exit 255
fi
if [ "$newest" != "$current" ]; then
echo "$newest"
fi
return 0
}
do_self_upgrade_0() {
simple_apk_opkg upgrade ${ISTORE_DEP_PKGS} && simple_apk_opkg upgrade ${ISTORE_PKG}
}
do_self_upgrade() {
check_mtime || return 1
local newest=`get_online_version "$ISTORE_INDEX" "$ISTORE_PKG"`
local current=`get_local_version "$ISTORE_PKG"`
if [ "v$newest" = "v" -o "v$current" = "v" ]; then
echo "Check version failed!" >&2
return 1
fi
if [ "$newest" = "$current" ]; then
echo "Already the latest version!" >&2
return 1
fi
if $USE_APK || opkg_wrap info ${ISTORE_PKG} | grep -qFm1 "Version: $newest"; then
do_self_upgrade_0 && return 0
update_if_outdate || return 1
do_self_upgrade_0
else
update_if_outdate || return 1
do_self_upgrade_0
fi
}
check_mtime() {
local file
if $USE_APK; then
file=${APK_CONF}
else
file=${OPKG_CONF_DIR}/arch.conf
fi
find "$file" -mtime -1 2>/dev/null | grep -q . || update
}
wrapped_in_update() {
check_mtime || return 1
eval "$@" && return 0
update_if_outdate || return 1
eval "$@"
}
refresh_installed() {
local pkg
for pkg in $@; do
[[ $pkg == app-meta-* ]] || continue
pkg="$META_DIR/meta/${pkg#app-meta-}.json"
[[ -f "$pkg" ]] && touch "$pkg"
done
return 0
}
step_upgrade() {
local pkg
local pkgs=""
local metapkg=""
for pkg in $@; do
if [[ $pkg == app-meta-* ]]; then
metapkg="$metapkg $pkg"
else
pkgs="$pkgs $pkg"
fi
done
if [ -n "$pkgs" ]; then
do_upgrade_in_mirrors $pkgs || return 1
fi
if [ -n "$metapkg" ]; then
do_upgrade_in_mirrors $metapkg || return 1
refresh_installed $metapkg
fi
return 0
}
new_upgrade() {
check_mtime || return 1
local metapkg=`echo "$@" | sed 's/ /\n/g' | grep -F app-meta-`
if [[ -z "$metapkg" ]] || [[ -z "$(get_local_version $metapkg)" ]]; then
true
else
update_if_outdate
fi
wrapped_in_update step_upgrade "$@"
}
remove() {
if $USE_APK; then
apk_wrap del -r "$@"
else
opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@"
fi
}
autoconf_to_env() {
local autoconf path enable
eval "local autoconf=$ISTORE_AUTOCONF"
export -n ISTORE_AUTOCONF
export -n ISTORE_DONT_START
export -n ISTORE_CONF_DIR
export -n ISTORE_CACHE_DIR
export -n ISTORE_PUBLIC_DIR
export -n ISTORE_DL_DIR
ISTORE_AUTOCONF=$autoconf
if [ -n "$path" ]; then
export ISTORE_CONF_DIR="$path/Configs"
export ISTORE_CACHE_DIR="$path/Caches"
export ISTORE_PUBLIC_DIR="$path/Public"
export ISTORE_DL_DIR="$ISTORE_PUBLIC_DIR/Downloads"
fi
[ "$enable" = 0 ] && export ISTORE_DONT_START="1"
}
try_autoconf() {
[ -n "$ISTORE_AUTOCONF" ] || return 0
autoconf_to_env
[ -n "$ISTORE_AUTOCONF" ] || return 1
echo "Auto configure $ISTORE_AUTOCONF"
PATH="$CLEANPATH" /usr/libexec/istorea/${ISTORE_AUTOCONF}.sh
}
try_upgrade_depends() {
local pkg="$1"
if [[ $pkg == app-meta-* ]]; then
local deps
if $USE_APK; then
deps=$(apk --repositories-file /dev/null info -R "$pkg" | tail +2 | grep -vFw libc | xargs echo)
else
deps=$(grep '^Depends: ' "/usr/lib/opkg/info/$pkg.control" | busybox sed -e 's/^Depends: //' -e 's/,/\n/g' -e 's/ //g' | grep -vFw libc | xargs echo)
fi
[ -z "$deps" ] || do_install_in_mirrors $deps
fi
return 0
}
if $USE_APK; then
CMD_INSTALLED="apk --repositories-file /dev/null info | cut -d' ' -f1 | sort -u"
CMD_INSTALL="apk add --allow-untrusted"
else
CMD_INSTALLED="opkg list-installed | cut -d' ' -f1 | sort -u"
CMD_INSTALL="opkg install"
fi
dotrun() {
local path="$1"
[ -f "$path" ] || { echo "file not found: $path" >&2; return 1; }
ls -l "$path"
local md5=$(md5sum "$path" 2>/dev/null | cut -d' ' -f1)
local ts=$(date '+%s')
#local date=$(date '+%Y-%m-%d_%H-%M-%S')
echo "MD5: $md5"
echo "Save installed pkg list before installing"
sh -c "$CMD_INSTALLED" > "/tmp/is-root/tmp/pre_$md5.txt"
if echo "$path" | grep -q '\.run$'; then
echo "Executing .run file"
chmod 0755 "$path" && "$path"
else
echo "Installing pkg file"
$CMD_INSTALL "$path"
fi
local RET=$?
rm -f "$path"
if [ -s "/tmp/is-root/tmp/pre_$md5.txt" ]; then
echo "Save installed pkg list after installing"
sh -c "$CMD_INSTALLED" > "/tmp/is-root/tmp/post_$md5.txt"
grep -Fxf "/tmp/is-root/tmp/pre_$md5.txt" -v "/tmp/is-root/tmp/post_$md5.txt" > "/tmp/is-root/tmp/added_$md5.txt"
if [ -s "/tmp/is-root/tmp/added_$md5.txt" ]; then
echo "The following packages were added:"
cat "/tmp/is-root/tmp/added_$md5.txt"
mkdir -p /usr/share/istore/run-records
path="${path##*/}"
path="${path//\\/\\\\}" #\
path="${path//\"/\\\"}" #"
path="${path//$NEWLINE/\\n}" # \n
path="${path//^M/\\r}" # \r
echo "{\"id\":\"$ts-$md5\",\"ts\":$ts,\"md5\":\"$md5\",\"file\":\"$path\"}" > /usr/share/istore/run-records/$ts-$md5.txt
cat "/tmp/is-root/tmp/added_$md5.txt" >> /usr/share/istore/run-records/$ts-$md5.txt
fi
fi
rm -f "/tmp/is-root/tmp/pre_$md5.txt" "/tmp/is-root/tmp/post_$md5.txt" "/tmp/is-root/tmp/added_$md5.txt"
return $RET
}
run_records() {
local record
local file
echo "["
for record in /usr/share/istore/run-records/*.txt; do
[ -f "$record" ] || continue
echo "`head -1 "$record"`,"
done | head -c -2
echo ""
echo "]"
}
if $USE_APK; then
CMD_REMOVE="apk del"
else
CMD_REMOVE="opkg --autoremove remove"
fi
unrun() {
local id="$1"
[ -s "/usr/share/istore/run-records/$id.txt" ] || { echo "record not found: $id" >&2; return 1; }
mkdir -p /tmp/is-root/tmp
echo "The following packages will be removed:"
tail -n +2 "/usr/share/istore/run-records/$id.txt" > "/tmp/is-root/tmp/to_unrun_$id.txt"
cat "/tmp/is-root/tmp/to_unrun_$id.txt"
local round max_round=6
for round in `seq 1 $max_round`; do
if [ $round == $max_round ]; then
$CMD_REMOVE `cat "/tmp/is-root/tmp/to_unrun_$id.txt"`
else
$CMD_REMOVE `cat "/tmp/is-root/tmp/to_unrun_$id.txt"` 2>/dev/null && break
fi
done
sh -c "$CMD_INSTALLED" > "/tmp/is-root/tmp/post_unrun_$id.txt"
grep -Fxf "/tmp/is-root/tmp/post_unrun_$id.txt" "/tmp/is-root/tmp/to_unrun_$id.txt" > "/tmp/is-root/tmp/remain_unrun_$id.txt"
if [ -s "/tmp/is-root/tmp/remain_unrun_$id.txt" ]; then
echo "The following packages failed to be removed:"
cat "/tmp/is-root/tmp/remain_unrun_$id.txt"
else
echo "All packages removed successfully."
rm -f "/usr/share/istore/run-records/$id.txt"
fi
rm -f "/tmp/is-root/tmp/to_unrun_$id.txt" "/tmp/is-root/tmp/post_unrun_$id.txt" "/tmp/is-root/tmp/remain_unrun_$id.txt"
return 0
}
usage() {
echo "usage: is-opkg sub-command [arguments...]"
echo "where sub-command is one of:"
echo " update Update list of available packages"
echo " upgrade <pkgs> Upgrade package(s)"
echo " install <pkgs> Install package(s)"
echo " remove <pkgs|regexp> Remove package(s)"
echo " info [pkg|regexp] Display all info for <pkg>"
echo " list-upgradable List installed and upgradable packages"
echo " check_self_upgrade Check iStore upgrade"
echo " do_self_upgrade Upgrade iStore"
echo " arch Show libc architecture"
echo " opkg sys opkg wrap"
echo " dotrun {path} install .run/.ipk/.apk"
echo " run_records list .run/.ipk/.apk install records"
echo " del_record {id} delete .run/.ipk/.apk install record"
echo " unrun {id} Remove installed packages by .run/.ipk/.apk"
exit 1
}
if [[ "$action" = "do_self_upgrade" && "$0" != "$TMP_SELF_COPY" ]]; then
echo "copy self $0 to $TMP_SELF_COPY when self upgrade"
cp -af "$0" "$TMP_SELF_COPY" || exit 1
exec "$TMP_SELF_COPY" do_self_upgrade "$@" || exit 1
fi
is_init >/dev/null 2>&1
CLEANPATH="$PATH"
case $action in
"update"|"install"|"upgrade"|"opkg"|"check_self_upgrade"|"do_self_upgrade"|"dotrun")
if [[ "`uci -q get istore.istore.ipv4`" = "1" ]]; then
export PATH="/usr/libexec/istore/ipv4-bin:$CLEANPATH"
fi
;;
esac
case $action in
"update")
update
;;
"install")
check_space
wrapped_in_update do_install_in_mirrors "$@" && refresh_installed "$1" && try_upgrade_depends "$1" && try_autoconf
;;
"autoconf")
try_autoconf
;;
"upgrade")
new_upgrade "$@"
;;
"remove")
remove "$@" || remove "$@"
;;
"info")
if $USE_APK; then
apk_wrap query "$@"
else
opkg_wrap info "$@"
fi
;;
"list-upgradable")
if $USE_APK; then
apk_wrap query --upgradable --summarize package '*'
else
opkg_wrap list-upgradable
fi
;;
"check_self_upgrade")
check_self_upgrade
;;
"do_self_upgrade")
check_space
do_self_upgrade
;;
"arch")
echo "$ARCH"
;;
"opkg")
opkg_wrap "$@"
;;
"dotrun")
dotrun "$@"
;;
"run_records")
run_records
;;
"del_record")
rm -f "/usr/share/istore/run-records/$1.txt"
;;
"unrun")
unrun "$1"
;;
"link_meta")
[[ -d "$META_DIR/meta" ]] || mkdir -p "$META_DIR/meta"
[ -e /tmp/run/istore-meta ] || ln -sf "$META_DIR" /tmp/run/istore-meta
;;
*)
usage
;;
esac
-8
View File
@@ -1,8 +0,0 @@
config istore 'istore'
# option hide_docker '0'
# option ignore_arch '0'
# option last_path '/mnt/nvme'
# option channel 'istore'
# option super_arch 'x86_64'
# option super_arch 'aarch64'
# option ipv4 '0'
-55
View File
@@ -1,55 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2016 OpenWrt.org
START=45
boot() {
local ARCH=`/bin/is-opkg arch`
generate_store_id $ARCH
generate_super_arch $ARCH
/bin/is-opkg link_meta
}
generate_store_id() {
[ -s /etc/.app_store.id ] && return 0
local ARCH=$1
local iface HASH
for iface in eth0 br-lan; do
if [ -e /sys/class/net/$iface/address ]; then
HASH=`md5sum /sys/class/net/$iface/address | cut -d ' ' -f1`
break
fi
done
if [ -z "$HASH" ]; then
HASH=`dd if=/dev/urandom bs=512 count=1 2>/dev/null | md5sum | cut -d ' ' -f1`
fi
echo "{\"arch\":\"${ARCH}\", \"uid\":\"${HASH}\"}" > /etc/.app_store.id
}
generate_super_arch() {
local ARCH=$1
local super_arch
case "$ARCH" in
arm*)
super_arch="arm"
;;
i386)
super_arch="x86"
;;
x86_64)
super_arch="x86_64"
;;
*)
super_arch="${ARCH%%_*}"
;;
esac
local old=`uci -q get istore.istore.super_arch`
[ "$old" = "$super_arch" ] && return 0
uci -q batch <<-EOF >/dev/null
set istore.istore.super_arch=$super_arch
commit istore
EOF
}
@@ -1,15 +0,0 @@
#!/bin/sh
/etc/init.d/istore boot
if [ -z "`uci -q get istore.istore.hide_docker`" ] && ! which docker >/dev/null; then
uci -q batch <<-EOF >/dev/null
set istore.istore.hide_docker=1
commit istore
EOF
fi
# remove tmp keys that used for self-installation, which is not needed after installation
rm -f /etc/apk/keys/istore-tmp.pem
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
@@ -1,305 +0,0 @@
#!/bin/sh
#set -x
#IS_DEBUG=1
IS_ROOT=/tmp/is-backup
APP_LIST_FILE=/etc/istore/app.list
BACKUP_CONFIG_FILE=/etc/config/istore
USE_APK=false
[[ -s /etc/apk/arch ]] && USE_APK=true
action=${1}
shift
is_init() {
mkdir -p ${IS_ROOT}
}
opkg_list_installed_packages() {
local target=$1
local dir
local OPKG_INFO_DIR
case $target in
"preinstalled")
OPKG_INFO_DIR="/rom/usr/lib/opkg/info"
;;
"userinstalled")
OPKG_INFO_DIR="/overlay/upper/usr/lib/opkg/info /ext_overlay/upper/usr/lib/opkg/info"
;;
"allinstalled")
OPKG_INFO_DIR="/usr/lib/opkg/info"
;;
*)
echo "invalid target"
exit
;;
esac
for dir in $OPKG_INFO_DIR ; do
[ -d "$dir" ] || continue
(cd "$dir" && find . -depth -maxdepth 1 -name "*.list" -type f | sed 's#^\./\(.*\)\.list$#\1#g')
done
}
ipk_build() {
PKG_NAME_TEMP=$1
IPK_OUTPUT_DIR=$2
UCI_BAK_DIR="/etc/istore/uci-defaults_bak/"
UCI_DEF_DIR="etc/uci-defaults"
local OPKG_INFO_DIR="/usr/lib/opkg/info/"
[ -n "${PKG_NAME_TEMP}" ] || exit 1
#get real pkg name in opkg
PKG_NAME_TEMP=`cat ${IS_ROOT}/all_installed_package.list | sort -u | grep "^${PKG_NAME_TEMP}" | head -n 1`
[ -n "${PKG_NAME_TEMP}" ] || exit 1
PKG_NAME=`cat ${OPKG_INFO_DIR}${PKG_NAME_TEMP}.control | grep "^Package: " | cut -d ' ' -f2`
PKG_VER=`cat ${OPKG_INFO_DIR}${PKG_NAME}.control | grep "^Version: " | cut -d ' ' -f2`
PKG_ARCH=`cat ${OPKG_INFO_DIR}${PKG_NAME}.control | grep "^Architecture: " | cut -d ' ' -f2`
IPK_FILE_NAME="${PKG_NAME}_${PKG_VER}_${PKG_ARCH}"
rm -rf ${IS_ROOT}/${IPK_FILE_NAME}
mkdir -p ${IS_ROOT}/${IPK_FILE_NAME}
#(1)make CONTROL dir; (2)copy control file to dir
cd ${IS_ROOT}/${IPK_FILE_NAME}
mkdir -p CONTROL
for control_file in `ls ${OPKG_INFO_DIR}${PKG_NAME}.* | grep -v ".list$"`; do
file=${control_file##*/}
suffix=${file##*.}
cp ${control_file} CONTROL/${suffix}
done
#(1)make DATA depend dir; (2)copy uci-defaults_bak file to dir; (3)copy other file to dir
for pkgfile in `cat ${OPKG_INFO_DIR}${PKG_NAME}.list | cut -b 2-`; do
file=${pkgfile##*/}
path=${pkgfile%/*}
mkdir -p ${path}
if [ `echo "${path}" | grep "^${UCI_DEF_DIR}"` ]; then
cp "${UCI_BAK_DIR}${file}" "${pkgfile}"
else
cp "/${pkgfile}" "${pkgfile}"
fi
done
#call ipkg-build script to build ipk
/usr/libexec/istore/ipkg-build ${IS_ROOT}/${IPK_FILE_NAME} ${IPK_OUTPUT_DIR}
echo "${IPK_FILE_NAME}.ipk" >> ${IPK_OUTPUT_DIR}/appdepipk.list
[ -n "${IS_DEBUG}" ] || rm -rf ${IS_ROOT}/${IPK_FILE_NAME}
}
# if arg is NULL, use light backup, otherwise use local backup
backup() {
if [ -n "$1" ]; then
if $USE_APK; then
echo "does not support apk package manager" >&2
exit 1
fi
BACKUP_PATH=$1
fi
if $USE_APK; then
( cd /lib/apk/packages && ls *.list ) | grep '^app-meta-' | sed 's/.list$//' | sort -u > ${IS_ROOT}/istore_installed_package.list
else
#write user installed package list to file
opkg_list_installed_packages "userinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/user_installed_package.list
#write installed package list by istore feed to file
cat ${IS_ROOT}/user_installed_package.list | \
grep '^app-meta-' > ${IS_ROOT}/istore_installed_package.list
fi
#if no input backup path, only back app.list
mkdir -p /etc/istore
cp ${IS_ROOT}/istore_installed_package.list ${APP_LIST_FILE}
echo "backup installed package list to ${APP_LIST_FILE}"
if [ ! -n "${BACKUP_PATH}" ]; then
echo "backup success"
exit 0
fi
if [ ! -d "${BACKUP_PATH}" ] && ! mkdir -p "${BACKUP_PATH}" ; then
echo "invalid backup path, can not backup ipk"
exit 1
fi
#write all installed package list to file
opkg_list_installed_packages "allinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/all_installed_package.list
#write system pre installed package list to file
opkg_list_installed_packages "preinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/pre_installed_package.list
#write installed packages and depends list by istore feed to file by depend sequence
appdep_list=""
temp_list=`cat ${IS_ROOT}/istore_installed_package.list | sed 's/^/\t/'`
while [ -n "${temp_list}" ]
do
#get real pkg name
for PKG_NAME_TEMP in ${temp_list}; do
REAL_PKG_NAME=`cat ${IS_ROOT}/all_installed_package.list | sort -u | grep "^${PKG_NAME_TEMP}" | head -n 1`
if [ "${REAL_PKG_NAME}" != "${PKG_NAME_TEMP}" ]; then
temp_list=`echo "${temp_list}" | sed 's/^\t'"${PKG_NAME_TEMP}"'$/\t'"${REAL_PKG_NAME}"'/'`
fi
done
appdep_list=`echo -e "${temp_list}\n${appdep_list}"`
[ -n "${IS_DEBUG}" ] && echo -e "temp_list:\n""${temp_list}"
[ -n "${IS_DEBUG}" ] && echo -e "appdep_list:\n""${appdep_list}"
temp_list=`echo "${temp_list}" | xargs opkg depends | grep -v "depends on:" | grep -v " (>= " | grep -v " (= " | sort -u`
done
appdep_list_all=`echo "${appdep_list}" | cut -f2 | grep -v "^$" | awk '!seen[$0]++'`
[ -n "${IS_DEBUG}" ] && echo -e "appdep_list_all:\n""${appdep_list_all}"
echo "${appdep_list_all}" > ${IS_ROOT}/appdep.list
#3.rebuild all istore installed package to ipk and backup to userdata partation
# 4. create dir
date=$(date +%Y-%m%d-%H%M)
if [ ! -d "$BACKUP_PATH/backup_istore_$date" ];then
mkdir $BACKUP_PATH/backup_istore_$date
fi
cp ${IS_ROOT}/istore_installed_package.list $BACKUP_PATH/backup_istore_$date/app.list
cp ${IS_ROOT}/appdep.list $BACKUP_PATH/backup_istore_$date/appdep.list
#only backup non pre installed ipk
cp ${IS_ROOT}/appdep.list ${IS_ROOT}/appdep_strip.list
for pre_installed_pkg in `cat ${IS_ROOT}/appdep.list ${IS_ROOT}/pre_installed_package.list | sort -n | uniq -d`; do
sed -i '/^'"$pre_installed_pkg"'$/d' ${IS_ROOT}/appdep_strip.list
done
rm -f $BACKUP_PATH/backup_istore_$date/appdepipk.list
echo "build ipk"
for pkg_name in `cat ${IS_ROOT}/appdep_strip.list`; do
ipk_build ${pkg_name} $BACKUP_PATH/backup_istore_$date
done
# 5. create tar.gz file,and remove dir
cd $BACKUP_PATH
echo "write backup file to $BACKUP_PATH/backup_istore_$date.backup.tar.gz"
tar -czf $BACKUP_PATH/backup_istore_$date.backup.tar.gz backup_istore_$date
rm -rf $BACKUP_PATH/backup_istore_$date
echo "backup success"
}
# if arg is NULL, use light backup, otherwise use local backup
restore() {
if [ -n "$1" ]; then
if $USE_APK; then
echo "does not support apk package manager" >&2
exit 1
fi
BACKUP_PATH_FILE=$1
else
echo "install package by ${APP_LIST_FILE}"
is-opkg update
for app in `cat ${APP_LIST_FILE}`; do
#skip resotre istore self
[ "A${app}" == "A""luci-app-store" ] && continue
is-opkg install ${app}
done
exit 0
fi
if [ ! -f "${BACKUP_PATH_FILE}" ];then
echo "invalid backup file, can not restore ipk"
exit 1
fi
#1. Unzip file to dir
BACKUP_PATH_FILE_NAME=${BACKUP_PATH_FILE##*/}
BACKUP_PATH=/tmp/${BACKUP_PATH_FILE_NAME%.backup.tar.gz*}
if [ -d "$BACKUP_PATH" ];then
rm -rf $BACKUP_PATH
fi
mkdir -p $BACKUP_PATH
echo "unpack input file..."
# fix tar path error
tar -zxf ${BACKUP_PATH_FILE} -C /tmp/
echo "check file"
if [ ! -f "${BACKUP_PATH}/appdep.list" ];then
echo "no available appdep.list, can not restore ipk"
exit 1
fi
echo "check success"
#2. install ipk by backup path
echo "restore begin"
( cd ${BACKUP_PATH}; opkg install `cat ${BACKUP_PATH}/appdepipk.list` )
#3. rm dir
rm -rf ${BACKUP_PATH}
echo "restore success"
}
get_support_backup_features() {
echo "light_backup"
#istore custom img mean support local_backup
if ! $USE_APK; then
echo "local_backup"
fi
}
get_backup_app_list_file_path() {
echo "${APP_LIST_FILE}"
}
get_backup_app_list() {
if [ ! -f "${APP_LIST_FILE}" ];then
echo "no app.list, can not get backup app list"
exit 1
fi
cat ${APP_LIST_FILE}
}
get_available_backup_file_list() {
local backup_file
if [ -n "$1" ]; then
for backup_file in `cd $1 && ls backup_istore_*.backup.tar.gz`; do
echo "${backup_file}"
done
else
echo "input backup path is null"
exit 1
fi
}
usage() {
echo "usage: backup sub-command [arguments...]"
echo "where sub-command is one of:"
echo " backup [dir] Backup all installed package(s) to [directory]"
echo " restore [dir] Restore package(s) by [directory]"
echo " get_support_backup_features get device support backup features"
echo " get_backup_app_list_file_path get light backup app list file path"
echo " get_backup_app_list get light backup app list"
echo " get_available_backup_file_list get local available backup file list"
}
is_init >/dev/null 2>&1
case $action in
"get_support_backup_features")
get_support_backup_features
;;
"backup")
backup "$@"
;;
"restore")
restore "$@"
;;
"get_backup_app_list_file_path")
get_backup_app_list_file_path
;;
"get_backup_app_list")
get_backup_app_list
;;
"get_available_backup_file_list")
get_available_backup_file_list "$@"
;;
*)
usage
;;
esac
@@ -1,114 +0,0 @@
#!/bin/sh
handle_part() {
case "$MOUNT" in
"/overlay")
return 1
;;
esac
return 0
}
check_dir() {
local data_root=$(uci -q get dockerd.globals.data_root)
[ -n "$data_root" ] || return 0
local block_dev=$(findmnt -T "$data_root" -v -o SOURCE | sed -n 2p)
[ -n "$block_dev" ] || return 0
[ "overlayfs:/overlay" = "$block_dev" ] && return 1
local line=$(block info "$block_dev" 2>/dev/null)
[ -n "$line" ] || return 0
eval "${line##*: } handle_part ${line%%: *}"
}
migrate_check(){
local dest="$1"
[ -n "$dest" ] || {
echo "dest dir not specified!" >&2
return 1
}
local data_root="$2"
[ -n "$data_root" ] || data_root=$(uci -q get dockerd.globals.data_root)
[ -n "$data_root" ] || {
echo "get docker data_root failed!" >&2
return 1
}
[ "$data_root" = "/" ] || data_root="${data_root%%/}"
[ "$dest" = "/" ] || dest="${dest%%/}"
[ "$data_root" = "$dest" ] && {
echo "dest dir is the same as data_root!" >&2
return 1
}
[ 1 = "$FORCE" ] && return 0
[ -e "$dest" ] || return 0
[ -d "$dest" ] || {
echo "$dest is existed and it's not a dir, use FORCE=1 to overwrite it" >&2
return 2
}
[ 0 = "$(ls -A "$dest" | head -1 | wc -l)" ] || {
echo "$dest is existed and it's not empty, use FORCE=1 to overwrite it" >&2
return 2
}
return 0
}
migrate() {
local dest="$1"
local data_root=$(uci -q get dockerd.globals.data_root)
[ -n "$data_root" ] || {
echo "get docker data_root failed!" >&2
return 1
}
[ "$data_root" = "/" ] || data_root="${data_root%%/}"
[ "$dest" = "/" ] || dest="${dest%%/}"
FORCE=1 migrate_check "$dest" "$data_root"
local check_result=$?
[ 0 = $check_result ] || return $check_result
if [ "$UCI_ONLY" != 1 ]; then
rm -rf "$dest"
mkdir -p "$dest"
echo "Copy $data_root to $dest ..."
cp -a "$data_root/." "$dest/" || return 1
fi
echo "Change dockerd data_root to $dest and restart"
uci set dockerd.globals.data_root="$dest"
uci commit dockerd
/etc/init.d/dockerd restart
echo "Done"
}
action=${1}
shift
usage() {
echo "usage: $1 sub-command [arguments...]"
echo "where sub-command is one of:"
echo " check_dir Check docker data_root is on extrnal disk"
echo " migrate_check {target_dir} Check target_dir is valid for migration, return 2 if target_dir existed and not empty"
echo " migrate {target_dir} Migrate docker data_root to target_dir"
echo " change_dir {target_dir} Migrate docker data_root to target_dir but change dir only (no data copy)"
}
case $action in
"check_dir")
check_dir
;;
"migrate")
migrate "$@"
;;
"migrate_check")
migrate_check "$@"
;;
"change_dir")
UCI_ONLY=1 migrate "$@"
;;
*)
usage "$0"
;;
esac
@@ -1,8 +0,0 @@
#!/bin/sh
newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/ipv4-bin:#:#g' -e 's/^:*//' -e 's/:*$//')
[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH="$newpath"
exec curl --ipv4 "$@"
@@ -1,8 +0,0 @@
#!/bin/sh
newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/ipv4-bin:#:#g' -e 's/^:*//' -e 's/:*$//')
[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH="$newpath"
exec wget -4 "$@"
@@ -1,26 +0,0 @@
#!/bin/sh
newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/mirror-bin:#:#g' -e 's/^:*//' -e 's/:*$//')
[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH="$newpath"
# if url starts with $IS_ORIG_SERVER, replace it with $IS_MIRROR_SERVER
if [ -n "$IS_ORIG_SERVER" ] && [ -n "$IS_MIRROR_SERVER" ]; then
n=$#
while [ "$n" -gt 0 ]; do
i="$1"
shift
case "$i" in
"$IS_ORIG_SERVER"/*.apk|\
"$IS_ORIG_SERVER"/*.ipk)
i="$IS_MIRROR_SERVER/${i#$IS_ORIG_SERVER/}"
;;
esac
set -- "$@" "$i"
n=$((n - 1))
done
fi
export -n IS_ORIG_SERVER IS_MIRROR_SERVER
exec curl "$@"
@@ -1,26 +0,0 @@
#!/bin/sh
newpath=$(echo ":$PATH:" | sed -e 's#:/usr/libexec/istore/mirror-bin:#:#g' -e 's/^:*//' -e 's/:*$//')
[ -z "$newpath" ] && newpath="/usr/sbin:/usr/bin:/sbin:/bin"
export PATH="$newpath"
# if url starts with $IS_ORIG_SERVER, replace it with $IS_MIRROR_SERVER
if [ -n "$IS_ORIG_SERVER" ] && [ -n "$IS_MIRROR_SERVER" ]; then
n=$#
while [ "$n" -gt 0 ]; do
i="$1"
shift
case "$i" in
"$IS_ORIG_SERVER"/*.apk|\
"$IS_ORIG_SERVER"/*.ipk)
i="$IS_MIRROR_SERVER/${i#$IS_ORIG_SERVER/}"
;;
esac
set -- "$@" "$i"
n=$((n - 1))
done
fi
export -n IS_ORIG_SERVER IS_MIRROR_SERVER
exec wget "$@"
@@ -1,237 +0,0 @@
#!/bin/sh
TMP_SELF_COPY=/var/run/cloned-overlay-backup
action=${1}
shift
has_overlay() {
[ -d "/overlay/upper" ] || return 1
[ "overlay" = "$(/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }')" ] || return 1
return 0
}
has_ext_overlay() {
[ -d "/ext_overlay/upper" ] || return 1
grep '^overlayfs:/overlay / ' /proc/mounts | grep -Fq 'upperdir=/ext_overlay/upper' || return 1
return 0
}
backup() {
if ! has_overlay; then
echo "only supports squashfs firmware"
exit 1
fi
if [ -z "$1" ]; then
echo "input backup path is null"
exit 1
fi
local BACKUP_PATH="$1"
if echo "$BACKUP_PATH" | grep -q -e '^/overlay/upper' -e '^/ext_overlay/upper' ; then
echo "can not backup to /overlay/upper, /ext_overlay/upper"
exit 1
fi
if [ ! -d "${BACKUP_PATH}" ] && ! mkdir -p "${BACKUP_PATH}" ; then
echo "backup path does not exist and can not be create"
exit 1
fi
local realpath="$(cd "${BACKUP_PATH}"; pwd -P)"
if [ -z "$realpath" ]; then
echo "cannot get absolute path of ${BACKUP_PATH}"
exit 1
fi
local mountpoint=$(findmnt -T $realpath -o TARGET | sed -n 2p)
# while read -r; do
# if [[ "x$realpath" == "x$REPLY" || "x${realpath#$REPLY/}" != "x$realpath" ]]; then
# mountpoint="$REPLY"
# break
# fi
# done < <(
# cat /proc/mounts | grep -v '^overlay ' | awk 'NR>1 {print $2}' | grep -v '^/$' | \
# sort -u | \
# while read -r; do printf "%b\n" "$REPLY" ; done | \
# awk '{print length, $0}' | sort -nr | cut -d' ' -f2-
# )
if [ "/" = "$mountpoint" ]; then
echo "can not backup to /"
exit 1
else
echo "found mount point $mountpoint"
fi
local filename_suffix=
local tar_extra_args=
if has_ext_overlay; then
tar_extra_args="$tar_extra_args ext_overlay/upper"
filename_suffix="${filename_suffix}.s"
fi
local hostname=$(cat /proc/sys/kernel/hostname)
local fwver=$(. /etc/openwrt_release; echo $DISTRIB_ID-$DISTRIB_RELEASE)
local date=$(date +%Y-%m%d-%H%M)
local backup_name="backup_overlay_${hostname}_${fwver}_${date}${filename_suffix}.overlay.tar.gz"
local backup_full_path="$BACKUP_PATH/$backup_name"
echo "writing backup to $backup_full_path"
if tar -C / -cz overlay/upper $tar_extra_args > "$backup_full_path" ; then
sync "$BACKUP_PATH"
echo "backup success"
return 0
else
rm -f "$backup_full_path"
echo "backup failed"
exit 1
fi
}
patch_sandbox_device() {
local overlay="$1"
local ucidir="$overlay/upper/etc/config"
local uci_section=$(uci -c "$ucidir" -q show fstab | grep '^fstab\.@mount\[[0-9]*\]\.target='"'/overlay'\$" | head -1 | grep -o '^fstab\.@mount\[[0-9]*\]')
if [ -n "$uci_section" ]; then
if [ "x1" = "x$(uci -c "$ucidir" get "$uci_section.enabled")" ]; then
uci -c "$ucidir" -q delete "$uci_section.uuid"
uci -c "$ucidir" -q delete "$uci_section.label"
uci -c "$ucidir" -q delete "$uci_section.device"
if [ -n "$SANDBOX_UUID" ]; then
uci -c "$ucidir" set "$uci_section.uuid=$SANDBOX_UUID"
elif [ -n "$SANDBOX_LABEL" ]; then
uci -c "$ucidir" set "$uci_section.label=$SANDBOX_LABEL"
else
uci -c "$ucidir" set "$uci_section.device=$SANDBOX_DEVICE"
fi
uci -c "$ucidir" commit fstab
echo "found and patched $overlay"
return 0
fi
fi
return 1
}
restore() {
if ! has_overlay; then
echo "only supports squashfs firmware"
exit 1
fi
if [ -z "$1" ]; then
echo "input backup path is null"
exit 1
fi
local BACKUP_PATH_FILE="$1"
if [ ! -f "${BACKUP_PATH_FILE}" ]; then
echo "invalid backup file, can not restore"
exit 1
fi
# prevent uci cache
rm -rf /var/run/uci
SANDBOX_UUID=
SANDBOX_LABEL=
SANDBOX_DEVICE=
local tar_extra_args=overlay/upper
if has_ext_overlay; then
tar_extra_args=
if echo "${BACKUP_PATH_FILE}" | grep -q '\.s\.overlay\.tar\.gz$' ; then
local uuid label device line
local uci_section=$(uci -c /overlay/upper/etc/config show fstab | grep '^fstab\.@mount\[[0-9]*\]\.target='"'/overlay'\$" | head -1 | grep -o '^fstab\.@mount\[[0-9]*\]')
if [ -z "$uci_section" ]; then
echo "failed to find sandbox config, there is debug info:"
uci -c /overlay/upper/etc/config show fstab | grep '^fstab\.[^.]*\.target='"'/overlay'\$"
exit 1
fi
while read line; do
export -n "$line"
done <<EOF
$(uci -c /overlay/upper/etc/config show "$uci_section" | sed -e '/^fstab\.[^\.]*=/d' -e 's/^fstab\.[^\.]*\.//g' | grep -e '^uuid=' -e '^label=' -e '^device=' | sed "s/'//g")
EOF
SANDBOX_UUID=$uuid
SANDBOX_LABEL=$label
SANDBOX_DEVICE=$device
fi
fi
sync /
echo "restoring from ${BACKUP_PATH_FILE}"
if tar -C / -xz $tar_extra_args < "${BACKUP_PATH_FILE}" ; then
if [ -n "$SANDBOX_UUID" -o -n "$SANDBOX_LABEL" -o -n "$SANDBOX_DEVICE" ]; then
echo "patch sandbox device ${SANDBOX_UUID}${SANDBOX_LABEL}${SANDBOX_DEVICE}"
patch_sandbox_device /overlay && patch_sandbox_device /ext_overlay
fi
sync /overlay /ext_overlay
echo "restore success"
echo "schedule to restart after 5 seconds!"
/etc/init.d/tasks task_add reboot 'reboot -d 5'
return 0
else
echo "restore failed"
exit 1
fi
}
supports_overlay_backup() {
has_overlay || return 1
echo "overlay"
has_ext_overlay && echo "ext_overlay"
return 0
}
filter_backups() {
if has_ext_overlay; then
cat
else
# do not support restoring sandbox backup on non sandbox env
grep -v '\.s\.overlay\.tar\.gz$'
fi
}
get_backup_file_list() {
if [ -n "$1" ]; then
( cd "$1" && ls backup_overlay_*.overlay.tar.gz | filter_backups )
return 0
else
echo "input backup path is null"
exit 1
fi
}
usage() {
echo "usage: overlay-backup sub-command [arguments...]"
echo "where sub-command is one of:"
echo " backup [dir] Backup all installed package(s) to [directory]"
echo " restore [dir] Restore package(s) by [directory]"
echo " supports_overlay_backup check system supports overlay backup"
echo " get_backup_file_list [dir] get local available backup file list in [dir]"
}
case $action in
"supports_overlay_backup")
supports_overlay_backup
;;
"backup")
backup "$@"
;;
"restore")
if [ "$0" = "$TMP_SELF_COPY" ]; then
restore "$@"
else
echo "copy self $0 to $TMP_SELF_COPY when restore"
cp -af "$0" "$TMP_SELF_COPY"
exec "$TMP_SELF_COPY" restore "$@"
fi
;;
"get_available_backup_file_list")
get_backup_file_list "$@"
;;
*)
usage
;;
esac