tools/update-packaging/make_incremental_update.sh

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rwxr-xr-x

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 #!/bin/bash
     2 # This Source Code Form is subject to the terms of the Mozilla Public
     3 # License, v. 2.0. If a copy of the MPL was not distributed with this
     4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6 #
     7 # This tool generates incremental update packages for the update system.
     8 # Author: Darin Fisher
     9 #
    11 . $(dirname "$0")/common.sh
    13 # -----------------------------------------------------------------------------
    15 print_usage() {
    16   notice "Usage: $(basename $0) [OPTIONS] ARCHIVE FROMDIR TODIR"
    17   notice ""
    18   notice "The differences between FROMDIR and TODIR will be stored in ARCHIVE."
    19   notice ""
    20   notice "Options:"
    21   notice "  -h  show this help text"
    22   notice "  -f  clobber this file in the installation"
    23   notice "      Must be a path to a file to clobber in the partial update."
    24   notice "  -q  be less verbose"
    25   notice ""
    26 }
    28 check_for_forced_update() {
    29   force_list="$1"
    30   forced_file_chk="$2"
    32   local f
    34   if [ "$forced_file_chk" = "precomplete" ]; then
    35     ## "true" *giggle*
    36     return 0;
    37   fi
    39   if [ "${forced_file_chk##*.}" = "chk" ]
    40   then
    41     ## "true" *giggle*
    42     return 0;
    43   fi
    45   for f in $force_list; do
    46     #echo comparing $forced_file_chk to $f
    47     if [ "$forced_file_chk" = "$f" ]; then
    48       ## "true" *giggle*
    49       return 0;
    50     fi
    52     # If the file in the skip list ends with /*, do a prefix match.
    53     # This allows TorBrowser/Data/Browser/profile.default/extensions/https-everywhere@eff.org/* to be used to force all HTTPS Everywhere files to be updated.
    54     f_suffix=${f##*/}
    55     if [[ $f_suffix = "*" ]]; then
    56       f_prefix="${f%\/\*}";
    57       if [[ $forced_file_chk == $f_prefix* ]]; then
    58         ## 0 means "true"
    59         return 0;
    60       fi
    61     fi
    62   done
    63   ## 'false'... because this is bash. Oh yay!
    64   return 1;
    65 }
    67 if [ $# = 0 ]; then
    68   print_usage
    69   exit 1
    70 fi
    72 # The last .xpi is NoScript.
    73 ext_path='TorBrowser/Data/Browser/profile.default/extensions';
    74 # TODO: it would be better to pass this as a command line option.
    75 exts='https-everywhere@eff.org/* tor-launcher@torproject.org.xpi torbutton@torproject.org.xpi uriloader@pdf.js.xpi {73a6fe31-595d-460b-a920-fcc0f8843232}.xpi'
    76 requested_forced_updates='Contents/MacOS/TorBrowser.app/Contents/MacOS/firefox'
    77 for ext in $exts; do
    78   requested_forced_updates="$requested_forced_updates $ext_path/$ext"
    79 done
    82 # TODO: it would be better to pass this as a command line option.
    83 directories_to_remove='TorBrowser/Data/Browser/profile.default/extensions/https-everywhere@eff.org'
    85 while getopts "hqf:" flag
    86 do
    87    case "$flag" in
    88       h) print_usage; exit 0
    89       ;;
    90       q) QUIET=1
    91       ;;
    92       f) requested_forced_updates="$requested_forced_updates $OPTARG"
    93       ;;
    94       ?) print_usage; exit 1
    95       ;;
    96    esac
    97 done
    99 # -----------------------------------------------------------------------------
   101 let arg_start=$OPTIND-1
   102 shift $arg_start
   104 archive="$1"
   105 olddir="$2"
   106 newdir="$3"
   107 # Prevent the workdir from being inside the targetdir so it isn't included in
   108 # the update mar.
   109 if [ $(echo "$newdir" | grep -c '\/$') = 1 ]; then
   110   # Remove the /
   111   newdir=$(echo "$newdir" | sed -e 's:\/$::')
   112 fi
   113 workdir="$newdir.work"
   114 updatemanifestv2="$workdir/updatev2.manifest"
   115 updatemanifestv3="$workdir/updatev3.manifest"
   116 archivefiles="updatev2.manifest updatev3.manifest"
   118 mkdir -p "$workdir"
   120 # On Mac, the precomplete file added by Bug 386760 will cause OS X to reload the
   121 # Info.plist so it launches the right architecture, bug 600098
   123 # Generate a list of all files in the target directory.
   124 pushd "$olddir"
   125 if test $? -ne 0 ; then
   126   exit 1
   127 fi
   129 list_files oldfiles
   130 list_symlinks oldsymlinks oldsymlink_targets
   131 list_dirs olddirs
   133 popd
   135 pushd "$newdir"
   136 if test $? -ne 0 ; then
   137   exit 1
   138 fi
   140 if [ ! -f "precomplete" ]; then
   141   notice "precomplete file is missing!"
   142   exit 1
   143 fi
   145 list_dirs newdirs
   146 list_files newfiles
   147 list_symlinks newsymlinks newsymlink_targets
   149 popd
   151 # Add the type of update to the beginning of the update manifests.
   152 notice ""
   153 notice "Adding type instruction to update manifests"
   154 > "$updatemanifestv2"
   155 > "$updatemanifestv3"
   156 notice "       type partial"
   157 echo "type \"partial\"" >> "$updatemanifestv2"
   158 echo "type \"partial\"" >> "$updatemanifestv3"
   160 # If removal of any old, existing directories is desired, emit the appropriate
   161 # rmrfdir commands.
   162 notice ""
   163 notice "Adding directory removal instructions to update manifests"
   164 for dir_to_remove in $directories_to_remove; do
   165   # rmrfdir requires a trailing slash, so add one if missing.
   166   if ! [[ "$dir_to_remove" =~ /$ ]]; then
   167     dir_to_remove="${dir_to_remove}/"
   168   fi
   169   echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv2"
   170   echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv3"
   171 done
   173 notice ""
   174 notice "Adding file patch and add instructions to update manifests"
   176 num_oldfiles=${#oldfiles[*]}
   177 remove_array=
   178 num_removes=0
   180 for ((i=0; $i<$num_oldfiles; i=$i+1)); do
   181   f="${oldfiles[$i]}"
   183   # This file is created by Talkback, so we can ignore it
   184   if [ "$f" = "readme.txt" ]; then
   185     continue 1
   186   fi
   188   # removed-files is excluded by make_incremental_updates.py so it is excluded
   189   # here for consistency.
   190   if [ "`basename "$f"`" = "removed-files" ]; then
   191     continue 1
   192   fi
   194   # If this file exists in the new directory as well, then check if it differs.
   195   if [ -f "$newdir/$f" ]; then
   197     if check_for_add_if_not_update "$f"; then
   198       # The full workdir may not exist yet, so create it if necessary.
   199       mkdir -p `dirname "$workdir/$f"`
   200       $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
   201       copy_perm "$newdir/$f" "$workdir/$f"
   202       make_add_if_not_instruction "$f" "$updatemanifestv3"
   203       archivefiles="$archivefiles \"$f\""
   204       continue 1
   205     fi
   207     if check_for_forced_update "$requested_forced_updates" "$f"; then
   208       # The full workdir may not exist yet, so create it if necessary.
   209       mkdir -p `dirname "$workdir/$f"`
   210       $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
   211       copy_perm "$newdir/$f" "$workdir/$f"
   212       make_add_instruction "$f" "$updatemanifestv2" "$updatemanifestv3" 1
   213       archivefiles="$archivefiles \"$f\""
   214       continue 1
   215     fi
   217     if ! diff "$olddir/$f" "$newdir/$f" > /dev/null; then
   218       # Compute both the compressed binary diff and the compressed file, and
   219       # compare the sizes.  Then choose the smaller of the two to package.
   220       dir=$(dirname "$workdir/$f")
   221       mkdir -p "$dir"
   222       notice "diffing \"$f\""
   223       $MBSDIFF "$olddir/$f" "$newdir/$f" "$workdir/$f.patch"
   224       $BZIP2 -z9 "$workdir/$f.patch"
   225       $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
   226       copy_perm "$newdir/$f" "$workdir/$f"
   227       patchfile="$workdir/$f.patch.bz2"
   228       patchsize=$(get_file_size "$patchfile")
   229       fullsize=$(get_file_size "$workdir/$f")
   231       if [ $patchsize -lt $fullsize ]; then
   232         make_patch_instruction "$f" "$updatemanifestv2" "$updatemanifestv3"
   233         mv -f "$patchfile" "$workdir/$f.patch"
   234         rm -f "$workdir/$f"
   235         archivefiles="$archivefiles \"$f.patch\""
   236       else
   237         make_add_instruction "$f" "$updatemanifestv2" "$updatemanifestv3"
   238         rm -f "$patchfile"
   239         archivefiles="$archivefiles \"$f\""
   240       fi
   241     fi
   242   else
   243     # remove instructions are added after add / patch instructions for
   244     # consistency with make_incremental_updates.py
   245     remove_array[$num_removes]=$f
   246     (( num_removes++ ))
   247   fi
   248 done
   250 # Remove and re-add symlinks
   251 notice ""
   252 notice "Adding symlink remove/add instructions to update manifests"
   253 num_oldsymlinks=${#oldsymlinks[*]}
   254 for ((i=0; $i<$num_oldsymlinks; i=$i+1)); do
   255   link="${oldsymlinks[$i]}"
   256   verbose_notice "        remove: $link"
   257   echo "remove \"$link\"" >> "$updatemanifestv2"
   258   echo "remove \"$link\"" >> "$updatemanifestv3"
   259 done
   261 num_newsymlinks=${#newsymlinks[*]}
   262 for ((i=0; $i<$num_newsymlinks; i=$i+1)); do
   263   link="${newsymlinks[$i]}"
   264   target="${newsymlink_targets[$i]}"
   265   make_addsymlink_instruction "$link" "$target" "$updatemanifestv2" "$updatemanifestv3"
   266 done
   268 # Newly added files
   269 notice ""
   270 notice "Adding file add instructions to update manifests"
   271 num_newfiles=${#newfiles[*]}
   273 for ((i=0; $i<$num_newfiles; i=$i+1)); do
   274   f="${newfiles[$i]}"
   276   # removed-files is excluded by make_incremental_updates.py so it is excluded
   277   # here for consistency.
   278   if [ "`basename "$f"`" = "removed-files" ]; then
   279     continue 1
   280   fi
   282   # If we've already tested this file, then skip it
   283   for ((j=0; $j<$num_oldfiles; j=$j+1)); do
   284     if [ "$f" = "${oldfiles[j]}" ]; then
   285       continue 2
   286     fi
   287   done
   289   dir=$(dirname "$workdir/$f")
   290   mkdir -p "$dir"
   292   $BZIP2 -cz9 "$newdir/$f" > "$workdir/$f"
   293   copy_perm "$newdir/$f" "$workdir/$f"
   295   if check_for_add_if_not_update "$f"; then
   296     make_add_if_not_instruction "$f" "$updatemanifestv3"
   297   else
   298     make_add_instruction "$f" "$updatemanifestv2" "$updatemanifestv3"
   299   fi
   302   archivefiles="$archivefiles \"$f\""
   303 done
   305 notice ""
   306 notice "Adding file remove instructions to update manifests"
   307 for ((i=0; $i<$num_removes; i=$i+1)); do
   308   f="${remove_array[$i]}"
   309   notice "     remove \"$f\""
   310   echo "remove \"$f\"" >> "$updatemanifestv2"
   311   echo "remove \"$f\"" >> "$updatemanifestv3"
   312 done
   314 # Add remove instructions for any dead files.
   315 notice ""
   316 notice "Adding file and directory remove instructions from file 'removed-files'"
   317 append_remove_instructions "$newdir" "$updatemanifestv2" "$updatemanifestv3"
   319 notice ""
   320 notice "Adding directory remove instructions for directories that no longer exist"
   321 num_olddirs=${#olddirs[*]}
   323 for ((i=0; $i<$num_olddirs; i=$i+1)); do
   324   f="${olddirs[$i]}"
   325   # If this dir doesn't exist in the new directory remove it.
   326   if [ ! -d "$newdir/$f" ]; then
   327     notice "      rmdir $f/"
   328     echo "rmdir \"$f/\"" >> "$updatemanifestv2"
   329     echo "rmdir \"$f/\"" >> "$updatemanifestv3"
   330   fi
   331 done
   333 $BZIP2 -z9 "$updatemanifestv2" && mv -f "$updatemanifestv2.bz2" "$updatemanifestv2"
   334 $BZIP2 -z9 "$updatemanifestv3" && mv -f "$updatemanifestv3.bz2" "$updatemanifestv3"
   336 eval "$MAR -C \"$workdir\" -c output.mar $archivefiles"
   337 mv -f "$workdir/output.mar" "$archive"
   339 # cleanup
   340 rm -fr "$workdir"
   342 notice ""
   343 notice "Finished"
   344 notice ""

mercurial