Modular backuptool.sh. Executes backup and restore methods defined in arbitrary /system/addon.d/*.sh scripts.
Tips & Tricks ============= * 50-cm.sh contains only a reference implementation. You may customize the methods however you wish. For example, 20-foobar.sh pre-backup can use a loop with conditionals to generate a dynamic backup list in /tmp/foobar_file_list which is later printed by list_files() so the backup method will act on those files. * Optional methods pre-backup, post-backup, pre-restore, or post-restore may be defined for special purposes. * Inject new files into /tmp/addon.d/ prior to backuptool.sh backup if you want to act during the current CM upgrade. * Delete files from /tmp/addon.d/ during post-restore if you want to permanently remove files from /system/addon.d/ Addons may use this approach to run a script only once. * Scripts run in sort -n order. Prefix with numbers 00 through 99 if want to run in a particular order. * You can have two separate scripts, implementing only backup in one, and only restore in the other with a different number prefix of each. This allows even greater control the backup/restore order even further. * You could use pre-backup to generate a one-time use backup script in /tmp/addon.d/ that deletes itself in post-restore. Patch Series ============ http://review.cyanogenmod.com/#change,13265 CyanogenMod/android_build * edify generator http://review.cyanogenmod.com/#change,13266 CyanogenMod/android_system_core * permissions on /system/addon.d http://review.cyanogenmod.com/#change,13267 CyanogenMod/android_vendor_cm * 50-cm.sh reference backup script * modular backuptool.sh * support backuptool.functions used by /system/addon.d/*.sh scripts Change-Id: Ifd5eaf9dcfd68d92e5043c21d1bae1dc0ad54860
This commit is contained in:
parent
ce375df5ab
commit
b1637c8e2b
@ -24,8 +24,11 @@ PRODUCT_PROPERTY_OVERRIDES += \
|
||||
PRODUCT_COPY_FILES += \
|
||||
vendor/cm/CHANGELOG.mkdn:system/etc/CHANGELOG-CM.txt
|
||||
|
||||
# Backup Tool
|
||||
PRODUCT_COPY_FILES += \
|
||||
vendor/cm/prebuilt/common/bin/backuptool.sh:system/bin/backuptool.sh
|
||||
vendor/cm/prebuilt/common/bin/backuptool.sh:system/bin/backuptool.sh \
|
||||
vendor/cm/prebuilt/common/bin/backuptool.functions:system/bin/backuptool.functions \
|
||||
vendor/cm/prebuilt/common/bin/50-cm.sh:system/addon.d/50-cm.sh
|
||||
|
||||
# init.d support
|
||||
PRODUCT_COPY_FILES += \
|
||||
@ -116,4 +119,4 @@ endif
|
||||
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
ro.cm.version=$(CM_VERSION) \
|
||||
ro.modversion=$(CM_VERSION)
|
||||
ro.modversion=$(CM_VERSION)
|
||||
|
41
prebuilt/common/bin/50-cm.sh
Executable file
41
prebuilt/common/bin/50-cm.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/sbin/sh
|
||||
#
|
||||
# /system/addon.d/50-cm.sh
|
||||
# During a CM9 upgrade, this script backs up /system/etc/hosts,
|
||||
# /system is formatted and reinstalled, then the file is restored.
|
||||
#
|
||||
|
||||
. /tmp/backuptool.functions
|
||||
|
||||
list_files() {
|
||||
cat <<EOF
|
||||
etc/hosts
|
||||
EOF
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
backup)
|
||||
list_files | while read FILE DUMMY; do
|
||||
backup_file $S/"$FILE"
|
||||
done
|
||||
;;
|
||||
restore)
|
||||
list_files | while read FILE REPLACEMENT; do
|
||||
R=""
|
||||
[ -n "$REPLACEMENT" ] && R="$S/$REPLACEMENT"
|
||||
[ -f "$C/$S/$FILE" ] && restore_file $S/"$FILE" "$R"
|
||||
done
|
||||
;;
|
||||
pre-backup)
|
||||
# Stub
|
||||
;;
|
||||
post-backup)
|
||||
# Stub
|
||||
;;
|
||||
pre-restore)
|
||||
# Stub
|
||||
;;
|
||||
post-restore)
|
||||
# Stub
|
||||
;;
|
||||
esac
|
37
prebuilt/common/bin/backuptool.functions
Normal file
37
prebuilt/common/bin/backuptool.functions
Normal file
@ -0,0 +1,37 @@
|
||||
#!/sbin/sh
|
||||
#
|
||||
# Functions for backuptool.sh
|
||||
#
|
||||
|
||||
export C=/tmp/backupdir
|
||||
export S=/system
|
||||
export V=9
|
||||
|
||||
backup_file() {
|
||||
if [ -e "$1" ]; then
|
||||
local F=`basename "$1"`
|
||||
local D=`dirname "$1"`
|
||||
# dont backup any apps that have odex files, they are useless
|
||||
if ( echo "$F" | grep -q "\.apk$" ) && [ -e `echo "$1" | sed -e 's/\.apk$/\.odex/'` ]; then
|
||||
echo "Skipping odexed apk $1";
|
||||
else
|
||||
mkdir -p "$C/$D"
|
||||
cp -p $1 "$C/$D/$F"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
restore_file() {
|
||||
local FILE=`basename "$1"`
|
||||
local DIR=`dirname "$1"`
|
||||
if [ -e "$C/$DIR/$FILE" ]; then
|
||||
if [ ! -d "$DIR" ]; then
|
||||
mkdir -p "$DIR";
|
||||
fi
|
||||
cp -p "$C/$DIR/$FILE" "$1";
|
||||
if [ -n "$2" ]; then
|
||||
echo "Deleting obsolete file $2"
|
||||
rm "$2";
|
||||
fi
|
||||
fi
|
||||
}
|
@ -1,215 +1,80 @@
|
||||
#!/sbin/sh
|
||||
#
|
||||
# Backup and restore proprietary Android system files
|
||||
# Backup and restore addon /system files
|
||||
#
|
||||
|
||||
C=/tmp/backupdir
|
||||
S=/system
|
||||
V=9
|
||||
export C=/tmp/backupdir
|
||||
export S=/system
|
||||
export V=9
|
||||
|
||||
PROCEED=1;
|
||||
# Mount /system if it is not already mounted
|
||||
mount_system() {
|
||||
if [ ! -f "$S/build.prop" ]; then
|
||||
mount $S
|
||||
fi
|
||||
}
|
||||
|
||||
# Unmount /system unless it is already unmounted
|
||||
umount_system() {
|
||||
if [ -f "$S/build.prop" ]; then
|
||||
umount $S
|
||||
fi
|
||||
}
|
||||
|
||||
# Preserve /system/addon.d in /tmp/addon.d
|
||||
preserve_addon_d() {
|
||||
mkdir -p /tmp/addon.d/
|
||||
cp -a /system/addon.d/* /tmp/addon.d/
|
||||
chmod 755 /tmp/addon.d/*.sh
|
||||
}
|
||||
|
||||
# Restore /system/addon.d in /tmp/addon.d
|
||||
restore_addon_d() {
|
||||
cp -a /tmp/addon.d/* /system/addon.d/
|
||||
rm -rf /tmp/addon.d/
|
||||
}
|
||||
|
||||
# Proceed only if /system is the expected major version
|
||||
check_prereq() {
|
||||
if ( ! grep -q "^ro.cm.version=$V.*" /system/build.prop );
|
||||
then
|
||||
echo "Not backing up files from incompatible version.";
|
||||
PROCEED=0;
|
||||
fi
|
||||
if ( ! grep -q "^ro.cm.version=$V.*" /system/build.prop ); then
|
||||
echo "Not backing up files from incompatible version."
|
||||
umount_system
|
||||
exit 127
|
||||
fi
|
||||
}
|
||||
|
||||
check_installscript() {
|
||||
if [ -f "/tmp/.installscript" ] && [ $PROCEED -ne 0 ];
|
||||
then
|
||||
# We have an install script, and ROM versions match!
|
||||
# We now need to check and see if we have force_backup
|
||||
# in either /etc or /tmp/backupdir
|
||||
if [ -f "$S/etc/force_backuptool" ] || [ -f "$C/force_backuptool" ];
|
||||
then
|
||||
echo "force_backuptool file found, Forcing backuptool."
|
||||
else
|
||||
echo "/tmp/.installscript found. Skipping backuptool."
|
||||
PROCEED=0;
|
||||
fi
|
||||
fi
|
||||
# Execute /system/addon.d/*.sh scripts with $1 parameter
|
||||
run_stage() {
|
||||
for script in $(find /tmp/addon.d/ -name '*.sh' |sort -n); do
|
||||
$script $1
|
||||
done
|
||||
}
|
||||
|
||||
get_files() {
|
||||
cat <<EOF
|
||||
vendor/pittpatt/models/recognition/face.face.y0-y0-22-b-N/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/left_eye-y0-yi45-p0-pi45-rn7-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/nose_base-y0-yi45-p0-pi45-r0-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/right_eye-y0-yi45-p0-pi45-rp7-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/nose_base-y0-yi45-p0-pi45-rp7-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/left_eye-y0-yi45-p0-pi45-rp7-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/right_eye-y0-yi45-p0-pi45-rn7-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/nose_base-y0-yi45-p0-pi45-rn7-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/right_eye-y0-yi45-p0-pi45-r0-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/multi_pose_face_landmark_detectors.3/left_eye-y0-yi45-p0-pi45-r0-ri20.2d_n2/full_model.bin
|
||||
vendor/pittpatt/models/detection/yaw_roll_face_detectors.3/head-y0-yi45-p0-pi45-rn30-ri30.5/full_model.bin
|
||||
vendor/pittpatt/models/detection/yaw_roll_face_detectors.3/head-y0-yi45-p0-pi45-rp30-ri30.5/full_model.bin
|
||||
vendor/pittpatt/models/detection/yaw_roll_face_detectors.3/head-y0-yi45-p0-pi45-r0-ri30.4a/full_model.bin
|
||||
framework/com.android.nfc_extras.jar
|
||||
framework/com.google.widevine.software.drm.jar
|
||||
framework/com.google.android.maps.jar
|
||||
framework/com.google.android.media.effects.jar
|
||||
lib/libfacelock_jni.so
|
||||
lib/libfilterpack_facedetect.so
|
||||
lib/libflint_engine_jni_api.so
|
||||
lib/libfrsdk.so
|
||||
lib/libgcomm_jni.so
|
||||
lib/libpicowrapper.so
|
||||
lib/libspeexresampler.so
|
||||
lib/libspeexwrapper.so
|
||||
lib/libvideochat_jni.so
|
||||
lib/libvideochat_stabilize.so
|
||||
lib/libvoicesearch.so
|
||||
etc/permissions/com.google.android.nfc_extras.xml
|
||||
etc/permissions/com.google.android.media.effects.xml
|
||||
etc/permissions/com.google.android.maps.xml
|
||||
etc/permissions/com.google.widevine.software.drm.xml
|
||||
etc/permissions/features.xml
|
||||
app/MediaUploader.apk
|
||||
app/GoogleFeedback.apk
|
||||
app/GoogleTTS.apk
|
||||
app/MarketUpdater.apk
|
||||
app/GoogleServicesFramework.apk
|
||||
app/YouTube.apk
|
||||
app/GenieWidget.apk
|
||||
app/GooglePackageVerifierUpdater.apk
|
||||
app/SetupWizard.apk app/Provision.apk
|
||||
app/GoogleEarth.apk
|
||||
app/ChromeBookmarksSyncAdapter.apk
|
||||
app/GoogleQuickSearchBox.apk app/QuickSearchBox.apk
|
||||
app/GoogleLoginService.apk
|
||||
app/Talk.apk
|
||||
app/Maps.apk
|
||||
app/GooglePackageVerifier.apk
|
||||
app/GoogleBackupTransport.apk
|
||||
app/GalleryGoogle.apk app/Gallery2.apk
|
||||
app/FaceLock.apk
|
||||
app/Vending.apk
|
||||
app/GoogleContactsSyncAdapter.apk
|
||||
app/GoogleCalendarSyncAdapter.apk
|
||||
app/Gmail.apk
|
||||
app/OneTimeInitializer.apk
|
||||
app/NetworkLocation.apk
|
||||
app/GooglePartnerSetup.apk
|
||||
app/Phonesky.apk
|
||||
app/VoiceSearch.apk
|
||||
etc/hosts
|
||||
etc/custom_backup_list.txt
|
||||
etc/force_backuptool
|
||||
EOF
|
||||
}
|
||||
|
||||
get_custom_files() {
|
||||
local L
|
||||
if [ -f "$C/custom_backup_list.txt" ];
|
||||
then
|
||||
[ ! -f $C/fixed_custom_backup_list.txt ] && tr -d '\r' < $C/custom_backup_list.txt \
|
||||
> $C/fixed_custom_backup_list.txt
|
||||
L=`cat $C/fixed_custom_backup_list.txt`
|
||||
cat <<EOF
|
||||
$L
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
backup_file() {
|
||||
if [ -e "$1" ];
|
||||
then
|
||||
if [ -n "$2" ];
|
||||
then
|
||||
echo "$2 $1" | md5sum -c -
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
echo "MD5Sum check for $1 failed!";
|
||||
exit $?;
|
||||
fi
|
||||
fi
|
||||
|
||||
local F=`basename $1`
|
||||
local D=`dirname $1`
|
||||
|
||||
# dont backup any apps that have odex files, they are useless
|
||||
if ( echo $F | grep -q "\.apk$" ) && [ -e `echo $1 | sed -e 's/\.apk$/\.odex/'` ];
|
||||
then
|
||||
echo "Skipping odexed apk $1";
|
||||
else
|
||||
mkdir -p $C/bak/$D
|
||||
cp -p $1 $C/bak/$D/$F
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
restore_file() {
|
||||
local FILE=`basename $1`
|
||||
local DIR=`dirname $1`
|
||||
if [ -e "$C/bak/$DIR/$FILE" ];
|
||||
then
|
||||
if [ ! -d "$DIR" ];
|
||||
then
|
||||
mkdir -p $DIR;
|
||||
fi
|
||||
cp -p $C/bak/$DIR/$FILE $1;
|
||||
if [ -n "$2" ];
|
||||
then
|
||||
rm $2;
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# don't (u)mount system if already done
|
||||
UMOUNT=0
|
||||
|
||||
case "$1" in
|
||||
backup)
|
||||
if [ ! -f "$S/build.prop" ]; then
|
||||
mount $S
|
||||
UMOUNT=1
|
||||
fi
|
||||
check_prereq;
|
||||
check_installscript;
|
||||
if [ $PROCEED -ne 0 ];
|
||||
then
|
||||
rm -rf $C
|
||||
mkdir -p $C
|
||||
for file_list in get_files get_custom_files; do
|
||||
$file_list | while read FILE REPLACEMENT; do
|
||||
backup_file $S/$FILE
|
||||
done
|
||||
done
|
||||
fi
|
||||
if [ $UMOUNT -ne 0 ]; then
|
||||
umount $S
|
||||
fi
|
||||
;;
|
||||
restore)
|
||||
if [ ! -f "$S/build.prop" ]; then
|
||||
mount $S
|
||||
UMOUNT=1
|
||||
fi
|
||||
check_prereq;
|
||||
check_installscript;
|
||||
if [ $PROCEED -ne 0 ];
|
||||
then
|
||||
for file_list in get_files get_custom_files; do
|
||||
$file_list | while read FILE REPLACEMENT; do
|
||||
R=""
|
||||
[ -n "$REPLACEMENT" ] && R="$S/$REPLACEMENT"
|
||||
restore_file $S/$FILE $R
|
||||
done
|
||||
done
|
||||
rm -rf $C
|
||||
fi
|
||||
if [ $UMOUNT -ne 0 ]; then
|
||||
umount $S
|
||||
fi
|
||||
sync
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {backup|restore}"
|
||||
exit 1
|
||||
backup)
|
||||
mkdir -p $C
|
||||
mount_system
|
||||
check_prereq
|
||||
preserve_addon_d
|
||||
run_stage pre-backup
|
||||
run_stage backup
|
||||
run_stage post-backup
|
||||
umount_system
|
||||
;;
|
||||
restore)
|
||||
mount_system
|
||||
check_prereq
|
||||
run_stage pre-restore
|
||||
run_stage restore
|
||||
run_stage post-restore
|
||||
restore_addon_d
|
||||
umount_system
|
||||
rm -rf $C
|
||||
sync
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {backup|restore}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
Loading…
Reference in New Issue
Block a user