/dev/trouble
Eric Roller's Development Blog

Similar to what I have been doing with subversion, I now also create backups for my git repositories.

Note that the git repositories on the backup host are local repositories (not cloned ones) and that they are named ".git".

From /etc/periodic/monthly/mine.monthly:

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  for i in *.git ; do
    # Not a local git repository? Ignore it.
    if [ ! -f "$i/HEAD" ]; then
        continue
    fi
    line="/tmp/monthly-$i.out"
    # File: /Volumes/Backups/Attic/git-file-2016-08-10.bundle
    name="git-`basename $i`-`date +%F`.bundle"
    dump="/Volumes/Backups/Attic/$name"
    if [ ! -f "$dump" ]; then
      echo "Bundling git repository: $name"
      { cd "$i"; git bundle create "$dump" --all; } >& "$line"
      # Change the user for the dump file.
      chown gollum:gollum "$dump"
      # Only output the last stderr line then delete the file.
      tail -1 "$line"
      rm "$line"
    else
      echo "Warning: Dump already exists: $name"
    fi
  done
else
  echo "Error: Repositories directory not found."
fi

The weekly backups are much the same, except that only the three most recent repositories are backed up. Thus, the for loop in /etc/periodic/weekly/mine.weekly changes to:

  for i in `ls -1t *.git | sed '3 q'` ; do
    [...]
    line="/tmp/weekly-$i.out"
    [...]

N.B. I still use TrashLater to keep files for only 6 months in the Attic folder.

Just added a new section to /etc/periodic/monthly/mine.monthly in the attempt to create monthly backups of my subversion repositories, using compressed dump files:

[Update: Now using quoted variable names.] [Update: Now checking "format" file.]

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  for i in * ; do
    # Not a subversion repository? Ignore it.
    if [ ! -f "$i/format" ]; then
        continue
    fi
    line="/tmp/monthly-$i.out"
    # File: /Volumes/Backups/Attic/svn-file-2014-01-17.dump.gz
    name="svn-$i-`date +%F`.dump.gz"
    dump="/Volumes/Backups/Attic/$name"
    if [ ! -f "$dump" ]; then
      echo "Dumping subversion repository: $name"
      # Dump into a gzipped file; "Dumped revision n" into temp file.
      { /usr/bin/svnadmin dump "$i" | gzip -c -9 > "$dump"; } >& "$line"
      # Change the user for the dump file.
      chown gollum:gollum "$dump"
      # Only output the last stderr line then delete the file.
      tail -1 "$line"
      rm "$line"
    else
      echo "Warning: Dump already exists: $name"
    fi
  done
else
  echo "Error: Repositories directory not found."
fi

N.B. I also use TrashLater to keep files for only 6 months in the Attic folder.

For /etc/periodic/weekly/mine.weekly I only dump the most recently modified repository since I don't normally work on multiple projects. This is done with a different foreach loop, where we get just one repository file name:

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  # List the dir by last modified and get the first entry only.
  for i in `ls -1t | sed '1 q'` ; do
    line="/tmp/weekly-$i.out"
    # [...as above...]
  done
else
  echo "Error: Subversion repositories not found."
fi

Symptoms: When 'mounting' the external disk, shared over the AirPort Extreme WiFi network, it is not added to the Finder's sidebar; instead, you get an error like this:

The alias can't be opened because the original item can't be found.

Also, dragging the disk icon from the SHARED section in Finder's sidebar to the DEVICES section is not possibe; the Finder just displays a "can't drop it here" icon.

Searching online, I found a discussion on Apple's forums which contained the solution.

Fixing permissions with Disk Utility was not an option since a network-shared disk is not accessible within the app.

Apparently, the disk acquired an "alias" attribute by mistake. This can be checked in the Terminal, where the alias attribute is the capital 'A':

% /usr/bin/GetFileInfo /Volumes/AirDisk
directory: "/Volumes/AirDisk"
attributes: Avbstclinmedz

You can use the following command to turn the alias attribute off (then check again with the above GetFileInfo command and look for a lowercase 'a'):

% /usr/bin/SetFile -a a /Volumes/AirDisk

After that, the mounting problem disappeared.

Following the instructions on DroboShare, the Drobo disk must be reformatted as "MacOS Extended", i.e. not journalled. Furthermore, to prevent Time Machine from filling up the Drobo indefinitely, one may like to partitioned it:

Partition 1: Tardis (500GB) ... for Time Machine Partition 2: Dalek (1.5TB) ... for general use

Next problem was to copy the previous Time Machine image onto the new partition. For better performance, we did this with both the old backup disk (Diskus) and the Drobo (Tardis & Dalek) connected. This suggestion from an arstechnica forum appeared to do the trick:

sudo /usr/local/rsync/bin/rsync -aNHAXx --protect-args --fileflags \
    --force-change /Volumes/Diskus/Backups.backupdb /Volumes/Tardis

NB. that this is not the rsync that came with Mac OS X, but version 3.0.1 that we have compiled with support for extended attributes.

Splitting Disk Images

- Posted in General by

This has been bugging me for a while: How do you split large .dmg files such that you can save them onto multiple CDs (as opposed to an expensive DVD). It turns out, there is no special tool required (although it would be nice if Disk Utility would do the job). No, the functionality is already built-in in the Mac OS. All you need to do is to use the hdiutil in the Terminal to create your partitions:

% cd Downloads
% mkdir parts
% hdiutil segment -o ./parts/large_image.dmg \
    -segmentSize 100m large_image.dmg

Of the resulting files in the parts directory, one can simply double-click the first one in the Finder to mount the entire image:

large_image.dmg
large_image.002.dmgpart
[...]
large_image.010.dmgpart