« March 2008 | Main | May 2008 »

April 29, 2008

Using Chroot to Update the Kernel

One of the biggest problems with using Radmind to manage your systems instead of an imaging utility, despite all of Radmind’s advantages, is updating the kernel. You can’t just update the kernel and reboot; trying to reboot will result in a “Bad system call” error. In fact, trying to do anything after updating the kernel will result in an error. So how can you go from, say, Tiger to Leopard without hand-rebooting the computer once lapply finishes? The answer lies in the chroot utility. Using chroot, you can make a copy of your system's kernel and run from that instead of the regular kernel. Here’s how to set it up:

  1. Create a directory for the chroot “jail” in some directory that’s in your Radmind negative so it doesn’t get overwritten. I recommend creating a subdirectory of /tmp for this.
  2. Determine which tools you need to copy to the fake kernel system. For our script, we use the following:
    • /bin/bash
    • /bin/sh
    • /bin/ps
    • /sbin/reboot
    • /usr/bin/grep
  3. Using otool, figure out which dependencies these tools have. otool requires Apple's Developer Tools to be installed.
  4. Recreate the directory structure in your chroot jail folder for all the tools and their libraries and copy them into it. You will also need these system components:
    • /usr/lib/dyld
    • /usr/lib/system/libMathCommon.A.dylib
  5. Now that you’ve gotten the chroot jail set up, you can use it to watch lapply. Run lapply as usual after running ktcheck and fsdiff, but run it as a background process (e.g. lapply -your -options -here &).
  6. Use chroot to change your root directory to your chroot jail. From the jail, you can use ps to view the running processes (use ps -A to view all users’ processes).
  7. Once lapply is done, use your protected copy of reboot to reboot the system, and you're all set to run with the new version of the kernel.

Note: You need to be careful with your negative transcripts when you go from OS to OS. If something in the operating system needs to be in the negative (such as /dev or, in Leopard, /Network) isn’t in the new negative, you can run into errors in either your fsdiff or lapply steps.

Scripting examples of this after the jump.

So let’s say you want to add something into your Radmind scripts to automatically set up a chroot space when your system needs to be updated. The ideal script will have the following attributes:

To do this, we added a preapply script to run on the transcript that fsdiff creates:

#!/bin/sh

# chroot logic for kernel updates
# requires script to test passed as $1

# uses the following tools:
#  /bin/bash
#  /bin/sh
#  /bin/ps
#  /sbin/reboot
#  /usr/bin/grep

# and the following for chroot:
#  /usr/lib/dyld
#  /usr/lib/system/libmathCommon.A.dylib

# declarations
toolList="/bin/bash /bin/sh /bin/ps /sbin/reboot /usr/bin/grep /bin/sleep /bin/t
est"
dependencyList="/usr/lib/dyld /usr/lib/system/libmathCommon.A.dylib"
markerFile="/tmp/.chrootlogicneeded"
searchList="/mach_kernel"
chrootJailLocation="/tmp/chrootjail"

# if otool exists, use that to dynamically generate a list of dependencies
# use a pre-made list if it doesn't
if [ -x "/usr/bin/otool" ]; then
   for x in ${toolList}; do 
      for y in `otool -LX $x | awk '{ print $1 }'`; do 
         dependencyList="${dependencyList} $y"; 
      done; 
   done
else
   dependencyList="/usr/lib/dyld /usr/lib/libgcc_s.1.dylib /usr/lib/libiconv.2.d
ylib /usr/lib/libncurses.5.4.dylib /usr/lib/libSystem.B.dylib /usr/lib/system/li
bmathCommon.A.dylib"
fi

for x in `for y in ${toolList} ${dependencyList}; do echo $y; done | sort -fu`; 
do 
   searchList="${searchList} $x"; 
done

if [ "`for x in ${searchList}; do grep "$x" "$1"; done`" != "" ]; then 
   touch "${markerFile}"; 

   mkdir -p ${chrootJailLocation}/usr/lib/system
   mkdir -p ${chrootJailLocation}/bin
   mkdir -p ${chrootJailLocation}/sbin
   mkdir -p ${chrootJailLocation}/usr/bin

   for x in ${searchList}; do
      ditto $x ${chrootJailLocation}$x
   done
fi

Now, all you need is a portion of your Radmind script that looks for the marker file and, if it exists, runs lapply in the background. Set up another script to reboot the computer when lapply finishes:

#!/bin/sh

# reboots the system from a protected location after lapply finishes

while [ "`ps -A | grep lapply | grep -v grep`" != "" ]; do
   sleep 60
done

/sbin/reboot

After you run lapply in the background, run this script from your chroot space with the following command: “chroot /path/to/chroot/space /bin/sh path/to/command.” Note that the path to the script is relative to the location of your chroot jail, so you’ll have to copy it into the folder.

Posted by slauncha at 09:59 AM | Comments (0) | TrackBack

April 24, 2008

Using dscl to Create New Users and Groups in Leopard

It's of course possible to create a new user in Apple's System Preferences (under the "Accounts" pane), but if you want more control over your new user, the dscl command comes in handy. Under Leopard, here is the code to create a new user:

dscl . -create /Users/newusername (This creates the user's entry in the local database)
dscl . -create /Users/newusername UserShell /bin/bash
dscl . -create /Users/newusername RealName "New User's Real Name"
(This is the user's full name for display at login, etc.)
dscl . -create /Users/newusername UniqueID 503 (The standard behavior is to use number 50X, where X is the lowest available number. The account you create when you set up a new Mac is always user 501.)
dscl . -create /Users/newusername PrimaryGroupID 20
dscl . -create /Users/newusername NFSHomeDirectory /path/to/user/folder
(Apple's Tiger documentation explains that though this is named NFSHomeDirectory, it can be used for local folders.)
passwd newusername (This sets the password).

Now your new user should be all set up.

If you're using Radmind, you'll want to include these files in a transcript:

Posted by slauncha at 10:55 AM | Comments (0) | TrackBack