June 30, 2009

A Method for Migrating Files and Permissions

I recently had to retire an old Solaris system. It was the one that had a decade-worth of random projects placed on it. This leads to lots of files that can be a headache to handle without a skilled team and ticketing system to back you up. My part of the project was migrating the web content. To follow is a script that automated the copy of the web directory and mapped old UIDs to new UIDs, with non-colliding GIDs preserved. This does not include the 1000 line Apache httpd.conf file I had to audit and update.

Everything went surprisingly smooth, with only a handful of special cases to deal with, and a nice log file to catch those anomalous instances. New accounts were not created, but instead orphaned and chowned to a dummy user account.

Notice that I am using read into a while loop instead of a for loop from find. This is a good way to handle filenames with spaces and special characters.

migrate-www.sh:
#!/bin/bash

### uncomment afterwards and do not re-run
#exit 1

### sync files from old to new host
mkdir /www-old
rsync -aq old_server:/www/data /www-old/

### copy old auth files and manually edit groups
rsync -aq root@old_server:/etc/passwd /www-old/passwd.old
rsync -aq root@old_server:/etc/group /www-old/group.old
cat /www-old/group.old >> /etc/group
#vim /etc/group

### map old UIDs to new UIDs
#for I in `find /www-old/data`; do
find /www-old/data | while read I; do
echo -n "$I"
OUID=`ls -ndl "$I" | cut -d ' ' -f 3`
echo -n " OUID $OUID"
OLOGIN=`grep "\:x\:$OUID\:" /www-old/passwd.old | cut -d ':' -f 1`
echo -n " OLOGIN $OLOGIN"
NUID=`grep ^$OLOGIN\: /etc/passwd | cut -d ':' -f 3`
if grep -q ^$OLOGIN\: /etc/passwd; then
echo " NUID $NUID"
chown $NUID "$I"
else
# chown jack(1209) files to john(3572)
case "$NUID" in
"1209" )
echo " ADOPT 3572"
chown 3572 "$I"
;;
# own jill(921) to jane(372)
"921" )
echo " ADOPT 372"
chown 372 "$I"
;;
*)
echo " ORPHAN 499"
chown 499 "$I"
;;
esac
fi
done

### special case perm changes
# adopt to bob
chown -R 5432 /www-old/data/projectA
# new GID for group 432 is 1487
find /www-old/data -gid 432 -exec chown :1487 {} \;

Execute the scipt and redirect all output to a log file for later analysis:
# chmod +x migrate-www.sh
# ./migrate-www.sh > migrate-www.log 2>&1 &
# tail -F migrate-www.log

0 comments: