update store

This commit is contained in:
YGAS 2022-03-03 14:38:35 +08:00
parent e139d0f798
commit 3300cccf50
5 changed files with 871 additions and 20 deletions

View File

@ -7,19 +7,19 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI based ipk store
LUCI_DESCRIPTION:=luci-app-store is a ipk store developed by LinkEase team
LUCI_DEPENDS:=+curl +opkg +luci-lib-ipkg
LUCI_DEPENDS:=+tar +coreutils +coreutils-stat +luci-lib-ipkg +curl +opkg +libuci-lua +mount-utils
LUCI_PKGARCH:=all
PKG_VERSION:=0.1.7
PKG_RELEASE:=2
PKG_RELEASE:=1
ISTORE_UI_VERSION:=1.0
ISTORE_UI_RELEASE:=7
ISTORE_UI_RELEASE:=8
PKG_HASH:=395936ef07403674068a7719c9fcbad59dafa0f2b39d6da05d9eae0b5a7050a6
PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz
PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE)
PKG_SOURCE_URL:=https://github.com/linkease/istore-ui/archive/refs/tags
PKG_SOURCE_URL:=https://github.com/YGAS/istore-ui/archive/refs/tags
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>

View File

@ -23,6 +23,19 @@ function index()
entry({"admin", "store", "upload"}, post("store_upload"))
entry({"admin", "store", "check_self_upgrade"}, call("check_self_upgrade"))
entry({"admin", "store", "do_self_upgrade"}, post("do_self_upgrade"))
entry({"admin", "store", "get_support_backup_features"}, call("get_support_backup_features"))
entry({"admin", "store", "light_backup"}, post("light_backup"))
entry({"admin", "store", "get_light_backup_file"}, call("get_light_backup_file"))
entry({"admin", "store", "local_backup"}, post("local_backup"))
entry({"admin", "store", "light_restore"}, post("light_restore"))
entry({"admin", "store", "local_restore"}, post("local_restore"))
entry({"admin", "store", "get_backup_app_list_file_path"}, call("get_backup_app_list_file_path"))
entry({"admin", "store", "get_backup_app_list"}, call("get_backup_app_list"))
entry({"admin", "store", "get_available_backup_file_list"}, call("get_available_backup_file_list"))
entry({"admin", "store", "set_local_backup_dir_path"}, post("set_local_backup_dir_path"))
entry({"admin", "store", "get_local_backup_dir_path"}, call("get_local_backup_dir_path"))
for _, action in ipairs({"update", "install", "upgrade", "remove"}) do
store_api(action, true)
end
@ -289,3 +302,325 @@ function store_upload()
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
local function split(str,reps)
local resultStrList = {}
string.gsub(str,'[^'..reps..']+',function (w)
table.insert(resultStrList,w)
end)
return resultStrList
end
local function ltn12_popen(command)
local fdi, fdo = nixio.pipe()
local pid = nixio.fork()
if pid > 0 then
fdo:close()
local close
return function()
local buffer = fdi:read(2048)
local wpid, stat = nixio.waitpid(pid, "nohang")
if not close and wpid and stat == "exited" then
close = true
end
if buffer and #buffer > 0 then
return buffer
elseif close then
fdi:close()
return nil
end
end
elseif pid == 0 then
nixio.dup(fdo, nixio.stdout)
fdi:close()
fdo:close()
nixio.exec("/bin/sh", "-c", command)
end
end
-- call get_support_backup_features
function get_support_backup_features()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(myopkg .. " get_support_backup_features")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = jsonc.stringify(split(o,'\n'))
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- post light_backup
function light_backup()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(myopkg .. " backup")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = o:gsub("[\r\n]", "")
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- call get_light_backup_file
function get_light_backup_file()
local light_backup_cmd = "tar -c %s | gzip 2>/dev/null"
local loght_backup_filelist = "/etc/istore/app.list"
local reader = ltn12_popen(light_backup_cmd:format(loght_backup_filelist))
luci.http.header('Content-Disposition', 'attachment; filename="light-backup-%s-%s.tar.gz"' % {
luci.sys.hostname(), os.date("%Y-%m-%d")})
luci.http.prepare_content("application/x-targz")
luci.ltn12.pump.all(reader, luci.http.write)
end
local function update_local_backup_path(path)
local uci = require "uci"
local fs = require "nixio.fs"
local x = uci.cursor()
local local_backup_path
if fs.access("/etc/config/istore") then
local_backup_path = x:get("istore","istore","local_backup_path")
else
--create config file
local f=io.open("/etc/config/istore","a+")
f:write("config istore \'istore\'\n\toption local_backup_path \'\'")
f:flush()
f:close()
end
if path ~= local_backup_path then
-- set uci config
x:set("istore","istore","local_backup_path",path)
x:commit("istore")
end
end
-- post local_backup
function local_backup()
local code, out, err, ret
local error_ret
local path = luci.http.formvalue("path")
if path ~= "" then
-- judge path
code,out,err = is_exec("findmnt -T " .. path .. " -o TARGET|sed -n 2p")
if out:gsub("[\r\n]", "") == "/" or out:gsub("[\r\n]", "") == "/tmp" then
-- error
error_ret = {code = 500, msg = "Path Error,Can not be / or tmp."}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
-- update local backup path
update_local_backup_path(path)
code,out,err = is_exec(myopkg .. " backup " .. path)
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
else
-- error
error_ret = {code = 500, msg = "Path Unknown"}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- post light_restore
function light_restore()
local fd
local path
local finished = false
local tmpdir = "/tmp/"
luci.http.setfilehandler(
function(meta, chunk, eof)
if not fd then
path = tmpdir .. "/" .. meta.file
fd = io.open(path, "w")
end
if chunk then
fd:write(chunk)
end
if eof then
fd:close()
finished = true
end
end
)
local code, out, err, ret
if finished then
is_exec("rm /etc/istore/app.list;tar -xzf " .. path .. " -C /")
if nixio.fs.access("/etc/istore/app.list") then
code,out,err = is_exec(myopkg .. " restore")
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
else
local error_ret = {code = 500, msg = "File is error!"}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
-- remove file
is_exec("rm " .. path)
else
ret = {code = 500, msg = "upload failed!"}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
end
-- post local_restore
function local_restore()
local path = luci.http.formvalue("path")
local code, out, err, ret
if path ~= "" then
code,out,err = is_exec(myopkg .. " restore " .. path)
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
else
-- error
error_ret = {code = 500, msg = "Path Unknown"}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- call get_backup_app_list_file_path
function get_backup_app_list_file_path()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(myopkg .. " get_backup_app_list_file_path")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = o:gsub("[\r\n]", "")
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- call get_backup_app_list
function get_backup_app_list()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(myopkg .. " get_backup_app_list")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = jsonc.stringify(split(o,'\n'))
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- call get_available_backup_file_list
function get_available_backup_file_list()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local path = luci.http.formvalue("path")
local r,o,e
if path ~= "" then
-- update local backup path
update_local_backup_path(path)
r,o,e = is_exec(myopkg .. " get_available_backup_file_list " .. path)
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = jsonc.stringify(split(o,'\n'))
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
else
-- set error code
error_ret.msg = "Path Unknown"
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- post set_local_backup_dir_path
function set_local_backup_dir_path()
local path = luci.http.formvalue("path")
local success_ret = {code = 200,msg = "Success"}
local error_ret = {code = 500, msg = "Unknown"}
if path ~= "" then
-- update local backup path
update_local_backup_path(path)
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
else
-- set error code
error_ret.msg = "Path Unknown"
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- call get_local_backup_dir_path
function get_local_backup_dir_path()
local uci = require "uci"
local fs = require "nixio.fs"
local x = uci.cursor()
local local_backup_path = nil
local success_ret = {code = 200,msg = "Unknown"}
local error_ret = {code = 500, msg = "Path Unknown"}
if fs.access("/etc/config/istore") then
local_backup_path = x:get("istore","istore","local_backup_path")
if local_backup_path == nil then
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.msg = local_backup_path:gsub("[\r\n]", "")
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
else
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end

View File

@ -0,0 +1,200 @@
#!/bin/sh
# ipkg-build -- construct a .ipk from a directory
# Carl Worth <cworth@east.isi.edu>
# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
# 2003-04-25 rea@sr.unh.edu
# Updated to work on Familiar Pre0.7rc1, with busybox tar.
# Note it Requires: binutils-ar (since the busybox ar can't create)
# For UID debugging it needs a better "find".
set -e
version=1.0
FIND="$(command -v find)"
FIND="${FIND:-$(command -v gfind)}"
TAR="${TAR:-$(command -v tar)}"
GZIP="$(command -v gzip)"
# try to use fixed source epoch
if [ -n "$PKG_SOURCE_DATE_EPOCH" ]; then
TIMESTAMP=$(date --date="@$PKG_SOURCE_DATE_EPOCH")
elif [ -n "$SOURCE_DATE_EPOCH" ]; then
TIMESTAMP=$(date --date="@$SOURCE_DATE_EPOCH")
else
TIMESTAMP=$(date)
fi
ipkg_extract_value() {
sed -e "s/^[^:]*:[[:space:]]*//"
}
required_field() {
field=$1
grep "^$field:" < $CONTROL/control | ipkg_extract_value
}
pkg_appears_sane() {
local pkg_dir=$1
local owd=$PWD
cd $pkg_dir
PKG_ERROR=0
pkg=`required_field Package`
version=`required_field Version | sed 's/Version://; s/^.://g;'`
arch=`required_field Architecture`
if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then
echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
PKG_ERROR=1;
fi
if [ -f $CONTROL/conffiles ]; then
rm -f $CONTROL/conffiles.resolved
for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do
echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved
done
rm $CONTROL/conffiles
if [ -f $CONTROL/conffiles.resolved ]; then
mv $CONTROL/conffiles.resolved $CONTROL/conffiles
chmod 0644 $CONTROL/conffiles
fi
fi
cd $owd
return $PKG_ERROR
}
resolve_file_mode_id() {
local var=$1 type=$2 name=$3 id
case "$name" in
root)
id=0
;;
*[!0-9]*)
id=$(sed -ne "s#^$type $name \\([0-9]\\+\\)\\b.*\$#\\1#p" "$TOPDIR/tmp/.packageusergroup" 2>/dev/null)
;;
*)
id=$name
;;
esac
export "$var=$id"
[ -n "$id" ]
}
###
# ipkg-build "main"
###
file_modes=""
usage="Usage: $0 [-v] [-h] [-m] <pkg_directory> [<destination_directory>]"
while getopts "hvm:" opt; do
case $opt in
v ) echo $version
exit 0
;;
h ) echo $usage >&2 ;;
m ) file_modes=$OPTARG ;;
\? ) echo $usage >&2
esac
done
shift $(($OPTIND - 1))
# continue on to process additional arguments
case $# in
1)
dest_dir=$PWD
;;
2)
dest_dir=$2
if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
dest_dir=$PWD
fi
;;
*)
echo $usage >&2
exit 1
;;
esac
pkg_dir=$1
if [ ! -d $pkg_dir ]; then
echo "*** Error: Directory $pkg_dir does not exist" >&2
exit 1
fi
# CONTROL is second so that it takes precedence
CONTROL=
[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
if [ -z "$CONTROL" ]; then
echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
exit 1
fi
if ! pkg_appears_sane $pkg_dir; then
echo >&2
echo "ipkg-build: Please fix the above errors and try again." >&2
exit 1
fi
tmp_dir=$dest_dir/IPKG_BUILD.$$
mkdir $tmp_dir
echo $CONTROL > $tmp_dir/tarX
cd $pkg_dir
for file_mode in $file_modes; do
case $file_mode in
/*:*:*:*)
;;
*)
echo "ERROR: file modes must use absolute path and contain user:group:mode"
echo "$file_mode"
exit 1
;;
esac
mode=${file_mode##*:}; path=${file_mode%:*}
group=${path##*:}; path=${path%:*}
user=${path##*:}; path=${path%:*}
if ! resolve_file_mode_id uid user "$user"; then
echo "ERROR: unable to resolve uid of $user" >&2
exit 1
fi
if ! resolve_file_mode_id gid group "$group"; then
echo "ERROR: unable to resolve gid of $group" >&2
exit 1
fi
chown "$uid:$gid" "$pkg_dir/$path"
chmod "$mode" "$pkg_dir/$path"
done
$TAR -X $tmp_dir/tarX --format=gnu --sort=name -cpf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/data.tar.gz
installed_size=`stat -c "%s" $tmp_dir/data.tar.gz`
sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
$pkg_dir/$CONTROL/control
( cd $pkg_dir/$CONTROL && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/control.tar.gz )
rm $tmp_dir/tarX
echo "2.0" > $tmp_dir/debian-binary
pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
rm -f $pkg_file
( cd $tmp_dir && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | $GZIP -n - > $pkg_file )
rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
rmdir $tmp_dir
echo "Packaged contents of $pkg_dir into $pkg_file"

View File

@ -1,10 +1,14 @@
#!/bin/sh
#set -x
#IS_DEBUG=1
IS_ROOT=/tmp/is-root
DL_DIR=${IS_ROOT}/tmp/dl
LISTS_DIR_O=/tmp/opkg-lists
LISTS_DIR=${IS_ROOT}${LISTS_DIR_O}
OPKG_CONF_DIR=${IS_ROOT}/etc/opkg
APP_LIST_FILE=/etc/istore/app.list
BACKUP_CONFIG_FILE=/etc/config/istore
FEEDS_SERVER=https://istore.linkease.com/repo
ARCH=`jsonfilter -i /etc/.app_store.id -e '$.arch'`
@ -59,7 +63,7 @@ update() {
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
[ $idle_t -gt ${1:-120} ] || return 1
update || return 1
touch ${IS_ROOT}/.last_force_ts
return 0
@ -83,13 +87,7 @@ do_self_upgrade() {
if opkg_wrap info ${ISTORE_PKG} | grep -qF not-installed ; then
true
else
update_if_outdate
local code=$?
[ "$code" = 1 ] && return 1
if [ "$code" = 2 ] || ! opkg_wrap info ${ISTORE_PKG} | grep -qF not-installed; then
echo "already the latest version!" >&2
return 1
fi
update_if_outdate || return 1
fi
opkg_wrap upgrade ${ISTORE_PKG}
}
@ -116,17 +114,306 @@ new_upgrade() {
wrapped_in_update upgrade "$@"
}
opkg_list_installed_packages() {
target=$1
case $target in
"preinstalled")
OPKG_INFO_DIR="/rom/usr/lib/opkg/info"
;;
"userinstalled")
OPKG_INFO_DIR="/overlay/upper/usr/lib/opkg/info"
;;
"allinstalled")
OPKG_INFO_DIR="/usr/lib/opkg/info"
;;
*)
echo "invalid target"
exit
;;
esac
awk -v D="cd $OPKG_INFO_DIR &&" 'BEGIN {
C=D"ls *.list"
S="sort -n"
while(C|getline>0) {
P=substr(F=$1,1,length($1)-5)
J=D"du -sk $(cat "F")"
s=0
while(J|getline>0) s+=$1
close(J)
t+=s
print s" "P|S
}
close(S)
}'
}
ipk_build() {
PKG_NAME_TEMP=$1
IPK_OUTPUT_DIR=$2
UCI_BAK_DIR="/etc/istore/uci-defaults_bak/"
UCI_DEF_DIR="etc/uci-defaults"
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
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() {
[ -n "$1" ] && BACKUP_PATH=$1
#1.add all istore self data to sysupgrade config file,
#sysupgrade will backup/restore it auto when flash new firmware
echo "/etc/.app_store.id" > /lib/upgrade/keep.d/luci-app-store
cat /usr/lib/opkg/info/luci-app-store.list >> /lib/upgrade/keep.d/luci-app-store
echo "/etc/rc.d/S45istore" >> /lib/upgrade/keep.d/luci-app-store
echo "/etc/istore/uci-defaults_bak" >> /lib/upgrade/keep.d/luci-app-store
echo "${APP_LIST_FILE}" >> /lib/upgrade/keep.d/luci-app-store
echo "${BACKUP_CONFIG_FILE}" >> /lib/upgrade/keep.d/luci-app-store
#2.backup all installed package lists to config file
update #if want not depend this, need record package list by istore to file when is-opkg update
#get feed list
opkg_conf_list="meta all arch"
feed_name_list=""
for conf in ${opkg_conf_list}; do
feed_name=`cat ${OPKG_CONF_DIR}/${conf}.conf | cut -d ' ' -f2`
feed_name_list="${feed_name} ${feed_name_list}"
done
[ -n "${IS_DEBUG}" ] && echo ${feed_name_list}
istore_package_list=""
#get istore package list
for feed_name in ${feed_name_list}; do
package_list=`cat ${LISTS_DIR}/${feed_name} | gunzip | grep "^Package: " | cut -d ' ' -f2`
istore_package_list="${package_list} ${istore_package_list}"
done
[ -n "${IS_DEBUG}" ] && echo ${istore_package_list}
#write istore package list to file
echo ${istore_package_list} | tr " " "\n" | sort -n | uniq > ${IS_ROOT}/istore_support_package.list
#write all installed package list to file
opkg_list_installed_packages "allinstalled" 2>/dev/null | cut -d ' ' -f2 | sort -u > ${IS_ROOT}/all_installed_package.list
#write user installed package list to file
opkg_list_installed_packages "userinstalled" 2>/dev/null | cut -d ' ' -f2 | sort -u > ${IS_ROOT}/user_installed_package.list
#write system pre installed package list to file
opkg_list_installed_packages "preinstalled" 2>/dev/null | cut -d ' ' -f2 | sort -u > ${IS_ROOT}/pre_installed_package.list
#write installed package list by istore feed to file
cat ${IS_ROOT}/istore_support_package.list ${IS_ROOT}/user_installed_package.list | \
sort -n | uniq -d > ${IS_ROOT}/istore_installed_package.list
#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
#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
if [ ! -d "${BACKUP_PATH}" ];then
echo "invalid backup path, can not backup ipk"
exit 1
fi
# 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 fir
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
BACKUP_PATH_FILE=$1
else
echo "install package by ${APP_LIST_FILE}"
update
for app in `cat ${APP_LIST_FILE}`; do
#skip resotre istore self
[ "A${app}" == "A""luci-app-store" ] && continue
opkg_wrap 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"
for app in `cat ${BACKUP_PATH}/appdepipk.list`; do
opkg_wrap install ${BACKUP_PATH}/${app}
done
#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 [ -f /etc/istore_img_flag ];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() {
if [ -n "$1" ]; then
for backup_file in `ls $1/*.backup.tar.gz`; do
filename=${backup_file##*/}
echo "${filename}"
done
else
echo "input backup path is null"
exit 1
fi
}
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 " 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 " 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"
echo " opkg sys opkg wrap"
}
is_init >/dev/null 2>&1
@ -156,6 +443,28 @@ case $action in
"do_self_upgrade")
do_self_upgrade
;;
"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 "$@"
;;
"opkg")
opkg_wrap "$@"
;;
*)
usage
;;

View File

@ -0,0 +1,7 @@
#!/bin/sh
for i in "$@"; do
echo "$i" | grep -s -q "/etc/uci-defaults/" \
&& mkdir -p /etc/istore/uci-defaults_bak \
&& cp -f "$i" /etc/istore/uci-defaults_bak/
done
/bin/rm "$@"