Tips and pointers for using CFEngine on Mac OS X. The following subsections cover details of CFEngine particular to major Apple releases, and issues with compiling CFEngine manually.
-
Compiling CFEngine on Mac OS X
-
CFEngine on Mac OS X 10.4 (Tiger)
- CFEngine on Mac OS X 10.3 (Panther)
Mac OS X Classes
CFEngine sets a darwin class, but nothing to distinguish Mac OS X 10.2 from 10.3, nor Mac OS X from Darwin. Maintaining a source code patch to do so would be complex and time consuming; the following shows initial work on identifying the operating systems apart.
groups:
darwin::
macosx = ( FileExists(/System/Library/CoreServices/Finder) )
# TODO pipes not supported, so would need wrapper scripts or other
# means of distinguishing 10.x apart
#macosx_10_2 = ( "/usr/bin/sw_vers | fgrep 10.2" )
#macosx_10_3 = ( "/usr/bin/sw_vers | fgrep 10.3" )
# KLUGE 10.3 first with Postfix, 10.2 had Sendmail. Will need to
# reconsider what to do when 10.4 comes out.
macosx_10_2 = ( FileExists(/System/Library/StartupItems/Sendmail) )
macosx_10_3 = ( FileExists(/System/Library/StartupItems/Postfix) )
import:
macosx::
cf.macosx
System Configuration
Useful configuration commands include pmset, nvram, softwareupdate, and diskutil. Install the Apple Remote Desktop Client software to gain access to the systemsetup and networksetup commands.
control:
ard_dir = ( /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Support )
links:
macosx_10_2::
/usr/sbin/networksetup ->! $(ard_dir)/networksetup-jaguar
/usr/sbin/systemsetup ->! $(ard_dir)/systemsetup-jaguar
macosx_10_3::
/usr/sbin/networksetup ->! $(ard_dir)/networksetup-panther
/usr/sbin/systemsetup ->! $(ard_dir)/systemsetup-panther
Mixed directories under /Users.
Another problem is dealing with user home directories; Apple uses /Users instead of the more common /home used on other systems. Also, Apple mixes /Users/Shared in with the other user home directories, which complicates matters, as all directories under /Users are not actually user directories.
The easiest way to deal with this would be to remove /Users/Shared, and recreate it elsewhere if required. Then, for cross platform needs, use a $localhome variable to track where the local system home directory is.
control:
darwin::
localhome = ( /Users )
openbsd::
localhome = ( /home )
tidy:
# r* services insecure, remove configuration for them
/etc pat=hosts.equiv age=0 r=1
$(localhome)/* pat=.rhosts age=0 r=1
Automatic Updates
Use the softwareupdate command to install updates from the command line. Be sure to set the COMMAND_LINE_INSTALL=1 environment variable to avoid any prompts during the run. Older Mac OS X systems (10.1 and below?) may not have the softwareupdate utility.
#!/bin/sh
export COMMAND_LINE_INSTALL=1
if [ -f /var/log/auto-update.log ]; then
/bin/mv -f /var/log/auto-update.log /var/log/auto-update.log.old
fi
(
/usr/sbin/softwareupdate --install --req
/usr/sbin/diskutil repairPermissions /
) >/var/log/auto-update.log 2>&1
if /usr/bin/grep -q restart /var/log/auto-update.log; then
/sbin/shutdown -r now restart required due to system update
fi
Updates could be installed automatically (via a shellcommands in CFEngine or a cron job), though ideally should be tested first on one or more test systems before general distribution. Automatic reboots may cause data loss, if a user with unsaved data is still logged in when the reboot occurs.
To allow non-administrator users to run updates, create a script with the above command, then allow access to it in the sudoers file. Either use visudo, or edit the sudoers file directly via CFEngine.
ALL ALL=NOPASSWD: /usr/local/sbin/run-sw-updates
Either have the users run the update from the command line, or create a wrapper that the users can click on to call the shell command in question:
-- save as AppleScript command via "Script Editor" application
on run
set theResult to display alert ¬
"Check for updates? This may require a reboot!" as warning ¬
buttons {"Cancel", "Restart"} ¬
giving up after 120
if button returned of theResult is "Restart" and ¬
gave up of theResult is false then
do shell script "/usr/bin/sudo /usr/local/sbin/run-sw-updates"
end if
end run