mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-29 19:45:13 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
0d155c70be
commit
32600acc60
14258 files changed
+3954570
No files matched your search
+300
@@ -0,0 +1,300 @@
|
||||
#!/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
|
||||
|
||||
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() {
|
||||
[ -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
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
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 [ -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() {
|
||||
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
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
#!/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
|
||||
+200
@@ -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=`ls -ln $tmp_dir/data.tar.gz | awk 'NR==1 {print $5}'`
|
||||
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"
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/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 "$@"
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/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 "$@"
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
#!/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
|
||||
Reference in new issue
Block a user