DeployStudio ForumThe best location to share your DeployStudio experiences... |
You are not logged in.
ok, I am jumping on board the Deploy Studio train and with multiple sites to support I came to the issue of how to use 1 master Deploy Studio server but host the images at each of the sites (especially the WAN locations).
The solution I came up with was simple. When Deploy Studio wants to mount the images volume (via AFP) I just have a preflight script that mounts the volume based on which location (based on subnet) the computer is being imaged at.
I.E. Our Deploy Studio is on our fiber network, but our satellite site is on cable. When the computer netboots and DeployStudio Runtime is launched, it connects up to the Deploy Studio server (again, hosted on the fiber network).
- A preflight script will mount the correct AFP mount prior to imaging the computer. We are basing this on our subnets, but your mileage may vary.
Hope this helps those other network administrators going through the same struggles. I have other thoughts on using one image name (with multiple images) but I'll save that for another hint.
And now for a quick plug: This hint brought to you by the makers of Seize The ARD @ [url]http://jenniferandjon.com/software/[/url]
[url]http://jenniferandjon.com/software/[/url]
Offline
one thing to add. Our images on our DS server are on the "images" mount. The servers that you host the images need the same share name ("images" for us) and of course need the same images as what is on the DS server itself.
[url]http://jenniferandjon.com/software/[/url]
Offline
I discovered something that makes my above solution better. Make a login hook instead that mounts the path.
I made a login hook that mounts the image volume based on subnet. Subnets that fall into WAN locations mount the image path at that site. Otherwise, all our fiber locations mount to 1 of 5 servers. It picks 1 of the five based on what second it is (I.E. at 01 second, the first server, at 02 seconds, the second server, rotating all the way to 60)
[url]http://jenniferandjon.com/software/[/url]
Offline
I came up with a similar solution as a workaround for another post I just created ([url]http://www.deploystudio.com/Forums/viewtopic.php?id=659[/url]).
My idea was to set the image as /tmp/myimg.dmg or something and during the pre-flight script, make a symbolic link to the actual image stored in the Images share. The preflight would do something like this:
mkdir /tmp/ImgShare (create the mount point)
mount_afp afp://user:password@host/Images /tmp/ImgShare (mount the share)
ln -s /tmp/ImgShare/ActualImage.dmg /tmp/myimg.dmg (link the actual image to /tmp/myimg.dmg)
You could set in your workflow to restore /tmp/myimg.dmg. This way you can have multiple images with different names but still dynamically set which one during a preflight script.
Last edited by wollarintj (2009-03-03 04:18:21)
Offline
very nice solution! I'll add to that!
[url]http://jenniferandjon.com/software/[/url]
Offline
The script below selects a server based on subnet. Also, with certain subnets, it will select 1 of 4 image servers (based off of the second) to load balance image servers.
Next it will select what image the machine runs based on processor. We use 10.4 where we can, and 10.5 only on machines that require 10.5. You will of course have to modify the code to work with your environment.
Run this as a login hook for best results (as I have designed this to run as root)
#!/bin/sh
set -xv; exec 1>/Library/Logs/in.log 2>&1
#preferredserverusername='deploystudio'
#preferredserverpassword='d3p!0y$tuDi0'
allservers="serverFQDN1.org serverFQDN2.org serverFQDN3.org serverFQDN4.org serverFQDN5.org serverFQDN6.org serverFQDN7.org serverFQDN8.org"
#rm -rf /Volumes/images/Masters/HFS/
rm -f /Volumes/images/Masters/HFS/image.dmg
rmdir /Volumes/images/Masters/HFS/
rmdir /Volumes/images/Masters/
rmdir /Volumes/images/
mkdir -p /Volumes/images/Masters/HFS/
/usr/bin/osascript -e "set volume 7"
# set the screensaver
defaults -currentHost write com.apple.screensaver idleTime 300
# add 'dstudio' user to list of administrators
dscl . append /Groups/admin users dstudio
#mount images volume
SubNet=$(/sbin/ifconfig | /usr/bin/grep "inet 10." | /usr/bin/sed "s/\./ \. /g" | /usr/bin/awk {'print $4'})
case "$SubNet" in
108)
preferredserver=serverFQDN1.org;;
110)
preferredserver=serverFQDN2.org;;
111)
preferredserver=serverFQDN3.org;;
*)
sec=$(date +%S)
if [[ "$(echo 00,01,05,09,13,17,21,25,29,33,37,41,45,49,53,57 | grep $sec)" != "" ]]; then preferredserver=serverFQDN4.org
elif [[ "$(echo 02,06,10,14,18,22,26,30,34,38,42,46,50,54,58 | grep $sec)" != "" ]]; then preferredserver=serverFQDN5.org
elif [[ "$(echo 03,07,11,15,19,23,27,31,35,39,43,47,51,55,59 | grep $sec)" != "" ]]; then preferredserver=serverFQDN6.org
elif [[ "$(echo 04,08,12,16,20,24,28,32,36,40,44,48,52,56,60 | grep $sec)" != "" ]]; then preferredserver=serverFQDN7.org
fi
echo $preferredserver;;
esac
if [[ "$preferredserverusername" != "" ]]; then
preferredserverauthentication="$preferredserverusername:$preferredserverpassword@"
fi
allservers="$preferredserver $(echo $allservers | sed "s/$preferredserver//g")"
mountsuccess=1
for selectserver in $allservers; do
if [[ "$mountsuccess" != "0" ]]; then
/sbin/umount /Volumes/real_images/
/bin/rmdir /Volumes/real_images/
/sbin/umount /Volumes/images/
/bin/rmdir /Volumes/images/
sudo mkdir /Volumes/real_images && sudo /sbin/mount_afp -o nobrowse afp://$preferredserverauthentication$selectserver/images /Volumes/real_images
mountsuccess=$? # once it has mounted a good volume, exit out of the loop (only mount first volume it can)
if [[ "$mountsuccess" == "0" ]]; then
mountedserver=$selectserver
fi
fi
done
if [ ! -e /Volumes/real_images/Masters/ ]; then
/usr/bin/osascript -e 'tell application "System Events"' -e 'activate' -e "display alert \"\nNo image servers could be mounted.\n\n\nPlease contact District Technology to resolve this issue.\n\n\" giving up after 90" -e 'end tell'
else
# This will set the appropriate image to restore from based on computer
if [[ "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | grep 'PowerMac')" != "" ]]; then # this is a Power PC Computer
ln -s /Volumes/real_images/Masters/HFS/Standard-10.4-PPC.dmg /Volumes/images/Masters/HFS/image.dmg
else
# the is an intel machine - see if this is a computer that can run 10.4 and if so, set it to do so
machinemodel=$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk {'print $3'})
for fn in "MacPro2,1" "MacPro1,1,Quad" "MacPro1,1" "iMac6,1" "iMac5,1" "iMac5,2" "MacBookPro2,1" "MacBookPro2,2" "MacBookPro3,1" "Macmini1,1" "Macmini2,1" "MacBook1,1" "MacBookPro1,2" "MacBookPro1,1" "iMac4,2" "iMac4,1" "MacBook2,1"; do
if [[ "$fn" == "$machinemodel" ]]; then
ln -s /Volumes/real_images/Masters/HFS/Standard-10.4-x86.dmg /Volumes/images/Masters/HFS/image.dmg
else
ln -s /Volumes/real_images/Masters/HFS/Standard-10.5.dmg /Volumes/images/Masters/HFS/image.dmg
fi
done
fi
# /usr/bin/osascript -e 'tell application "System Events"' -e 'activate' -e "display alert \"\n$mountedserver server mounted.\n\n\" giving up after 90" -e 'end tell' &
fi
[url]http://jenniferandjon.com/software/[/url]
Offline
We're still using the old name_table.csv file from NetRestore, only with a bunch of extra fields. This data contains the final config information for each workstation, as well as the type of image that should be applied, based on MAC address. We also have 44 file servers in different locations, and don't want to image over the WAN, but do want to pull config info from one central source.
This thread gave me the clues to how to implement what we want using DeployStudio: NetBoot, mount the local server's DiskImages volume, read the config info from the central DeployStudio volume, create a symbolic link to the disk image we want to use, and then have DeployStudio proceed with imaging (workflow: initialize drive, run mount-local-diskimages script, image, etc.). First off, create a symbolic link to a file called /tmp/Images/image.dmg in DeployStudio/Masters/HFS/image.dmg -- this will be a link to a link, and we'll substitute another /tmp/Images/image.dmg later, based on our name_table.csv file. Here's my pre-imaging script:
#!/bin/tcsh -f
set scriptname = "mount_local_diskimages.sh 1.0"
echo "SCRIPT START: ${scriptname} ("`date`")"
### Path to DeployStudio's data
set dipath = "/tmp/DSNetworkRepository"
### Set the path to the local server's DiskImages folder
set dipathlocal = "/Volumes/LocalDiskImages"
### Set the path to the name table file (on our master DeployStudio server, we have
### DeployStudio data located in /DiskImages/DeployStudio and name_table.csv
### at the same level
set nameTable = "${dipath}/name_table.csv"
### hwAddress is the automatically-determined MAC address of built-in ethernet
set hwAddress = `/sbin/ifconfig en0 | awk '/ether/ { gsub(":", ""); print $2 }'`
### Check to see whether a record exists for this MAC in name_table.csv
set settingsRecord = `cat "$nameTable" | awk -F, "/$hwAddress/ "'{ print $1 }'`
if ( $settingsRecord == "" ) then
echo "FATAL ERROR: ${scriptname}: No settings record exists in name_table.csv for this hardware address. Exiting..."
exit 1
endif
### Our configname is the 30th field in the record
set configname = `cat $nameTable | /usr/bin/awk -F, "/$hwAddress/ "'{ print $30 }'`
### Get IP address of server (in this case, we're assuming server = DNS, since
### our DHCP, DNS, and NetBoot servers are running on the same local machine)
### you could work out another method for determining the server.
set serverip = "`/usr/sbin/ipconfig getoption en0 domain_name_server`"
### Mount the local server's DiskImages volume.
mkdir "$dipathlocal"
mount_afp afp://username:password@"$serverip"/DiskImages/ "$dipathlocal"
echo "INFO: ${scriptname}: Mounted afp://$serverip/DiskImages/ as /Volumes/LocalDiskImages"
### Wait for the server volume to mount...there must be a better way to do this!
sleep 8
### If configname.dmg doesn't exist, then generate an error...this isn't handled well
### by DeployStudio, and there must be a better way of doing this
if ( ! -e "${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg" ) then
echo "FATAL ERROR: ${scriptname}: The disk image ${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg does not exist!"
exit 1
else
### It exists, so create a generic symbolic link to the image file specified by
### configname in /tmp/Images
echo "INFO: ${scriptname}: Using ${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg"
mkdir -p /tmp/Images
ln -s "${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg" /tmp/Images/image.dmg
endif
echo "SCRIPT END: ${scriptname} ("`date`")"You'd have to customize this script to suit your network, of course, and the same type of script could be used to image off a pocket drive's local images, yet still grab config data from a central server (we have some locations with outbuildings serviced by a slow wireless connection, so the workstation has ethernet but the local server is deathly slow compared to accessing it within the main building).
If anyone has any suggestions on how to clean up this script, I'd appreciate the input!
Julian
Last edited by jdaniel (2009-03-19 16:42:48)
Offline
And here's the slightly revamped script which also looks for /DiskImages or /Volumes/External_HD/DiskImages on a connected USB or FireWire hard drive.
#!/bin/tcsh -f
set scriptname = "mount_local_diskimages.sh 2.0"
echo "SCRIPT START: ${scriptname} ("`date`")"
### Path to DeployStudio's data
set dipath = "/tmp/DSNetworkRepository"
### DiskImage volume/folder name
set divol = "DiskImages"
### Extra external USB/FireWire drive name
set extradrive = "/Volumes/External_HD"
### Set the default path to the local server's DiskImages folder
set dipathlocal = "/Volumes/LocalDiskImages"
### Set the path to the name table file (on our master DeployStudio server, we have
### DeployStudio data located in /DiskImages/DeployStudio and name_table.csv
### at the same level
set nameTable = "${dipath}/name_table.csv"
### hwAddress is the automatically-determined MAC address of built-in ethernet
set hwAddress = `/sbin/ifconfig en0 | awk '/ether/ { gsub(":", ""); print $2 }'`
### Check to see whether a record exists for this MAC in name_table.csv
set settingsRecord = `cat "$nameTable" | awk -F, "/$hwAddress/ "'{ print $1 }'`
if ( $settingsRecord == "" ) then
echo "FATAL ERROR: ${scriptname}: No settings record exists in name_table.csv for this hardware address. Exiting..."
exit 1
endif
### Our configname (disk image name) is the 30th field in the record
set configname = `cat $nameTable | /usr/bin/awk -F, "/$hwAddress/ "'{ print $30 }'`
### Check to see where we're going to get out disk images from.
### If /DiskImages or /Volumes/External_HD/DiskImages exists,
### it's coming from an external FireWire/USB drive
if ( -d "/${divol}" ) then
set dipathlocal = "/${divol}"
echo "INFO: ${scriptname}: Using /${divol} from an external FireWire or USB drive"
else if ( -d "${extradrive}/${divol}" ) then
set dipathlocal = "${extradrive}/${divol}"
echo "INFO: ${scriptname}: Using ${extradrive}/${divol} from an external FireWire or USB drive"
else
### Otherwise, we're using the local file server
### Get IP address of server (in this case, we're assuming server = DNS, since
### our DHCP, DNS, and NetBoot servers are running on the same local machine)
### you could work out another method for determining the server.
set serverip = "`/usr/sbin/ipconfig getoption en0 domain_name_server`"
### Mount the server volume
mkdir "$dipathlocal"
mount_afp afp://image:image@"$serverip"/"$divol"/ "$dipathlocal"
echo "INFO: ${scriptname}: Mounted afp://${serverip}/DiskImages/ as ${dipathlocal}"
### Wait for the server volume to mount...there must be a better way to do this!
sleep 8
endif
### If configname.dmg doesn't exist, then generate an error...this isn't handled well
### by DeployStudio, and there must be a better way of doing this
if ( ! -e "${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg" ) then
echo "FATAL ERROR: ${scriptname}: The disk image ${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg does not exist!"
exit 1
else
### It exists, so create a generic symbolic link to the image file specified by
### configname in /tmp/Images
echo "INFO: ${scriptname}: Using ${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg"
mkdir -p /tmp/Images
ln -s "${dipathlocal}/DeployStudio/Masters/HFS/${configname}.dmg" /tmp/Images/image.dmg
endif
echo "SCRIPT END: ${scriptname} ("`date`")"I still could use some assistance with how to clean up the script to deal with mounting server volumes (instead of sleep 8) and how to make DeployStudio happier with an exit 1.
Julian
Offline
i'm just getting into DS so I'm not sure i've got this right.
if i've a client netbooted from the DS nbi, how can i get a preflight script in there to step in and mount a chosen (site-specific) repository before/instead of the one wired into the nbi
Offline
alantrewartha:
Click the +, under General Tasks add "Run a script", and choose the mount-local-diskimages script from the popup menu on this task. Move this step to the very beginning -- before the Restore task.
I separated all the pre- and post-restore tasks into separate scripts, so my workflow looks like this:
Script: Mount Local DiskImages
Partition
Restore
Script: Set Apple Remote Desktop field contents
Script: Set Computer and Bonjour names
Script: Create Shared Files afploc files
Script: Personalize local login account
Firmware Security
We're still not using network logins, so the last two scripts set up a local user account by adding dock items that provide easy access to sharepoints, and customize the name and password of a generic local account.
Julian
Offline
*FACEPALM* sorry so obvious. i get it now.
i wonder if there is a way to fake it entirely - fool DS into thinking that the afp mount your script has provided is the real repository.
has anyone tried a script like this that just umounts the repository and re-mounts a new location on the same mountpoint!?
so long as the different network volumes are mirrored from the REAL repository (script and all) I don't see why DS should skip a beat, unless it tried to log something while the switching script does the trick.
hmm....
Offline
Why not just mount your local "Masters" image folder on top of the non-local one?
ie: mount_afp afp://${DS_USER_LOGIN}:password@localserver/localDSRepoMasters ${DS_REPOSITORY_PATH}/Masters
That way, you don't need to create any symlinks, and you can just unmount ${DS_REPOSITORY_PATH}/Masters and your original network Masters folder will be back.
Also, instead of waiting for x seconds for the afp mount to work, you can use something like the following:
result=`/sbin/mount | grep ${DS_REPOSITORY_PATH}/Masters`
count=0;
while [ -z "$result" ]
do
result=`/sbin/mount | grep ${DS_REPOSITORY_PATH}/Masters`
echo "INFO: waiting for mount..."
count=$[$count+1]
if [ "$count" -gt 8 ]
then
echo "RuntimeAbortWorkflow: Unable to mount Local DS Repository"
exit 1
fi
sleep 1
done
echo "Info: Successfull mounted Local DS Repo"
Offline
ie: mount_afp afp://${DS_USER_LOGIN}:password@localserver/localDSRepoMasters ${DS_REPOSITORY_PATH}/Masters
Will this work with a local afp repository? Can a client machine mount an afp share from itself?
Offline
I don't think the idea is too run the dsruntime on the local repository server. When I say localserver, I am referring to the server in your local subnet (area) not the master repository server. Ie if you have 3 sites, then you would have 1 master DS repository and 2 'local' ones. The local servers would ideally be file servers, not client machines.
Offline