Simple rsync backup of your remote server w/ crontab

If you have a remote server, e.g. for you website, small business or whatever, it is a good idea to replicate it regularly onto local storage. You at least want /etc, /home, /var/www, /usr/local to be in the backup. Maybe more stuff, depending on what you are doing.

For now I assume you are running the backup on OS X’s user with admin/sudo rights, or some Linux user with sudo rights.

The reason why we want to do this with sudo and root on the remote system is to have a simple way to backup the whole system with all files, users and permissions. If you only want to backup a remote user, you don’t need the whole sudo and root part, but can use the remote user login instead.

First, you need the backup script:

#!/bin/bash

if [ "${UID}" != 0 ]
then
    echo "Must be run as root."
    exit 1
fi

shopt -s nocasematch

pushd `dirname $0` > /dev/null
SCRIPTPATH=`pwd`
popd > /dev/null

if [[ "${PWD}" != "${SCRIPTPATH}" ]]
then
    echo "Wrong path: ${PWD}"
    exit 2
fi

RSYNC_RSH="ssh -C -o IdentitiesOnly=yes -i /Path/to/key/without/password"
RSYNC_CMD='rsync -aP --delete --delete-after'
RSYNC_HOSTNAME='your.server.name'

($RSYNC_CMD -e "${RSYNC_RSH}" root@${RSYNC_HOSTNAME}:/etc :/home :/root :/usr/local :/var/www . > /tmp/rsync.log 2>&1 ) || \
(>&2 echo "An error occured while doing the backup: " ; cat /tmp/rsync.log )

exit $?

Adjust your hostname accordingly and also the directories to be backed up. Use the :/dir notation to reuse the SSH connection. Also make sure to use SSH key authentication, so no password is needed, since this backup is supposed to run via crontab. SSH access as root must only be allowed via key exchange! Make sure to disable password access, or else you are running a security risk! Also, keep the SSH key secret — it is the door to your server!

There are probably more secure ways, but they are more complicated than this.

Next up, put you script somewhere your sudo user can run it, and edit the crontab via “crontab -e”:

MAILTO=user@domain  # or simply your local user, to put it into the local mbox
0 * * * *       cd /Users/youruser/Documents/Backup && sudo /Users/youruser/Documents/Backup/backup.sh

You can make the script runnable with sudo without password by adding the following line to your /etc/sudoers file:

# allow passwordless access to the backup script
youruser ALL = (ALL) NOPASSWD: /Users/youruser/Documents/Backup/backup.sh

The script will only generate output on an error, hence cron will only send an email if there is an error.

If you are now also running TimeMachine, your server will have a nice, hourly history of backups.

Indexed Java 8 enums with gaps

This is an example enum for Java 8 that supports gaps in its indices is relatively fast for enums with a large amount of values:

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

public enum TestEnum {
   VALUE1( 0 ),
   VALUE2( 2 ),
   VALUE3( 50 );
   
   private final Integer id_;
   private static Map< Integer, TestEnum > values_ = 
      Arrays.stream( TestEnum.values() ).collect( Collectors.toMap(e -> e.id_, e -> e) );;
   
   private TestEnum( int i ) { id_ = i; }
   public static TestEnum fromInteger( int i )
   {
      return values_.get( i );
   }
   
}

Where to put a label on a LaTeX figure

I just found out that LaTeX is sensitive as to where you put the label command in a figure environment. For example if you do something like this:

begin{figure}
centering
includegraphics[width=0.95columnwidth]{sompic}
label{fig:some-pic}
caption{Some caption.}
end{figure}

if you now do a ref{fig:some-pic}, the reference will point to the parent element of the figure environment. For me, I got a reference to the subsection enclosing the figure. This was very irritating, because the text then said “see Figure 3.4.2.4 for details.”
Instead you need to place the label in or after the caption command. For some reason the ref will then point to the figure:

begin{figure}
centering
includegraphics[width=0.95columnwidth]{sompic}
caption{Some caption.}
label{fig:some-pic}
end{figure}

Update: And here is also the answer to the question why it is necessary to do it this way.

SD card reading problems

Today I was shooting some pictures using some camera and a cheap 2GB SD card. Upon returning home, I copied the pictures from the SD card to the Mac, using an old 6-in-1 card reader. After about 980 MiB of images, OS X throws a read error. Using cp in terminal yields the same result. Trying to repair the card using the hard disk utility even resulted in the system hanging. No hard freeze, but I had to power cycle it, since I was too lazy to fire up another ssh-capable machine.
After some research, I read on Wikipedia that SD cards over 1 GiB are adressed differently. It seems that older devices, such as my reader may have problems using those cards. This means I have to go buy a new reader tomorrow, I guess! Or be restricted to using only 1 Gig of the SD cards I use… Which is not a good idea for camera producing 37 MiB RAW files.

Update: My suspicion was correct. A new 10 € card reader solved the problem. The 2 GiB are back, I can read all the photos from the card.

Mobile me, Mobile schmu

I am currently trying out Apple’s Mobile Me service, which is free in the first two months. It seems relatively nice, but has some drawbacks. On the plus side, you get 20 GB of storage space, or 40 GB for the family pack. Also you can track your iPhone if you lose it. The mail service is useful, but on the downside: It does not support server side filtering! That’s a great, great bummer. Also it does not seem to support Apple’s notion of filtering, called “intelligent mailboxes”. If that were supported on the server, I would ditch my GMX ProMail account, and switch to using Mobile Me for mail services.

Syncing Google Calendar with the iPhone or iPod Touch

Since several people asked me how to do this, after I twittered about this, here it comes: How to correctly sync the Google Calendar with the iPhone. First step is to create a new calendar account in the iPhone settings (Email, Calendar, Contacts) using the Exchange protocol. The finished account should look something like this:
You can also sync the contacts and emails, if you want, but that’s optional. The second step is to go to http://m.google.com/sync/ to set up which of your google calendars you are going to sync. Beware: on the german iPhones, the page will display an error message, unless you switch to the english page!
That seems to be a bug on google’s page. So after you’ve done this, you get a list of your iPhones and can select for each device which calendars to sync:

Some small iPhone address book nags

I am using the try-out version of Mobile Me for the iPhone. Syncing the device with the Macbook Pro. Whenever I go to my address book, all the contacts appear twice. Very strange, I though, until I noticed that I was in the Group “All contacts”, which will show the contacts synced from the Mac and from Mobile Me. What a stupid way to present things. Right now, I just need to switch to “All contacts from my Mac” to fix this, but when I were to add another address book (say a corporate one or the Google one), I would be in trouble. Not very clever, Apple…

Qt woes on OS X 10.6…

Oh dear, Nokia and Macports do seem to hate me. I’ve spent half a day to get some version of Qt running on OS X 10.6.2. The problem is as follows. Nokia only provides 32 bit builds of their Qt SDK for OS X (universal binaries for PPC and i386) as can be seen here and here. Under OS X 10.5 this was no problem, since the whole system was basically 32 bit. But Snow Leopard now builds for x86_64 per default. Especially when using Macports. So I thought, lets just install the qt4-mac port from Macports. Wrong again! That port is currently broken. So, my project depends half on Qt and half on stuff from Macports. Now neither one is in a usable state. Ok, so I thought maybe I can force Macports to build in i386 mode only, to be compatible again with Qt. So I edited /opt/local/etc/macports.conf, cleaned the whole Macports tree and reinstalled. Fail again. This time, perl5 fails to build. That port is broken on 10.6 for non 64 bit builds. Hooray. Well, I give up for today, but will continue to investigate and will report back, as soon as either Nokia provides a decent 64 bit build, or Macports recovers and fixes any of their build issues.