Pull an image using Casper?

andyinindy
Contributor II

All:

I am trying to come up with a way to pull an image using Casper Imaging while netbooted. Obviously there is no prebuilt script/task for this, but I didn't want to spend a bunch of time reinventing the wheel if someone else has already figured this out.

So, has anyone managed to script an image pull job in Casper Imaging?

Thx!

-Andy

1 ACCEPTED SOLUTION

stevewood
Honored Contributor II
Honored Contributor II

It is the "wait" command that is killing you, not jamfHelper. The "wait" command, when not passed a process ID, will wait for all background tasks to complete. Since jamfHelper is technically a running app that never quits, the "wait" process will just sit there.

So, to get around this, grab the PID of hdiutil and use that with the wait command. I tested this script on my system and it worked fine:

#!/bin/bash

function imageBackup
{

    imageName="test"
    hdiutil create -srcfolder "/Volumes/Macintosh HD/Users/swood/Desktop/" -format SPARSE "/Volumes/Macintosh HD/$imageName" &
    pid=`ps -xa | grep hdiutil | awk '{ print $1 }'`
    wait $pid

}
if [ -f "/Volumes/Macintosh HD/Users/Shared/backup" ]; 

then

/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "Performing Full Disk Backup" -description "A full backup is being taken of this machine. Do not interrupt or power off." -icon /Applications/Utilities/Disk Utility.app/Contents/Resources/DFA.icns &
imageBackup

killall jamfHelper

else



    exit 0

fi

I moved the backup processes into a function just for testing, but you could put it back to the if/then format you had it in.

View solution in original post

24 REPLIES 24

andyinindy
Contributor II

Nevermind, I think I have an answer.

I copied Carbon Copy Cloner to met Casper Netboot image, and I was able to mount some afp storage (only from the command line, strangely) and am now cloning to a disk image on the file share.

Not exactly the most straightforward approach, but it seems like it might work...

tlarkin
Honored Contributor

I have an asr script that can be used with Casper imaging to image a client Mac over net boot.

https://jamfnation.jamfsoftware.com/discussion.html?id=65

-Tom

andyinindy
Contributor II

Thanks, Tom, but I am looking to do the opposite of this: take an image/snapshot of the internal disk of a netbooted Mac, not apply an image as you discuss in your post.

The method I describe using CCC while netbooted worked, but it is pretty labor intensive for our low-level techs. I would prefer a pre-baked job or script that they could call from within Casper Imaging. I guess I will have to whip one up :)

--Andy

tlarkin
Honored Contributor

If I recall, disk utility will do this, and it uses asr under-the-hood but you cannot do it from the boot disk.

acdesigntech
Contributor II

you can use hdiutil to pull a dmg from a netbooted mac. If you script it and run it automatically on login it shouldn't be as labor intensive.

Of course this doesn't utilize Casper imaging, but you CAN have it run via Remote. I have a remote job that uses the bless command to netboot the mac. Then you can just have the netboot image run the script to pull the DMG and then reboot the mac when it's done.

Be careful if the macs are on the same subnet as the NB server though, as bless will act funky when used on the same subnet: http://acdesigntech.wordpress.com/2011/10/27/netboot-across-subnets-or-how-to-use-the-bless-command/

chris_kemp
Contributor III

I use CCC regularly to pull images around here, and I don't netboot to do it. I just run it from an external drive on the computer I want to image and image the running system. I then use these images to push out to our client machines with Casper. Works just fine.

andyinindy
Contributor II

Hmm, strangely hdiutil doesn't seem to be working while netbooted. Here is my script:

#!/bin/bash

if [ -f /Volumes/Macintosh HD/Users/Shared/backup ]

then
        killall "Casper Imaging"

        /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "Performing Full Disk Backup" -description "A full backup is being taken of this machine. Do not interrupt or power off." -icon /Applications/Utilities/Disk Utility.app/Contents/Resources/DFA.icns

        imageName=`cat /Volumes/Macintosh HD/Library/Preferences/SystemConfiguration/preferences.plist | grep A2 | sed 's/<string>//g' | sed 's/</string>//g' | tr -d '�11' | uniq`

        mkdir /tmp/mount
        chmod 755 /tmp/mount
        mount_afp "afp://username:password@bertie.butler.edu/RCBackups" /tmp/mount

        hdiutil create -srcfolder /Volumes/Macintosh HD/ -format SPARSEBUNDLE /Volumes/RCBackups/$imageName &

        wait

        rm -f /Volumes/Macintosh HD/Users/Shared/backup

        bless --folder "/Volumes/Macintosh HD/System/Library/CoreServices" --bootinfo --bootefi

        shutdown -r now

else

        exit 0

fi

The full screen message appears, and then... nothing. I don't see a disk image appear on my storage. If I Command+Option+Escape, the full screen message disappears, and the rest of the script runs (internal HD is blessed, backup file removed, machine reboots. But the backup is a no-go.

The afp mount code seems to be sound; I can run it independently and it works. Anyone have an idea of what may be failing here?

Thanks,

--Andy

andyinindy
Contributor II

I think that I figured it out. The hdiutil command was failing because it could not find the /Volumes/HDBackups share. This is because it doesn't exist when I mount the storage via mount_afp! The solution was to replace /Volumes/RCBackups with /tmp/mount. Voila!

tlarkin
Honored Contributor

The only thing I would like to point out when running the `shutdown -r now` command is it sends a killall to everything. I have had this result is improper exit status of a script. I would suggest putting the ampersand (&) after the command to put it in the background and set it to shutdown in 1 minute. So I time it for 1 minute so something like this:

shutdown -r -h 1 &

That will reboot the system in 1 minute and allow enough time for your script to exit properly.

andyinindy
Contributor II

OK, almost have this figured out. Everything is working except for the damned reboot after the hdiutil task completes! Basically, I cannot figure out how to kill the full screen message (jamfHelper). Here is my current script:

#!/bin/bash

if [ -f "/Volumes/Macintosh HD/Users/Shared/backup" ]; 

then

    imageName=`cat /Volumes/Macintosh HD/Library/Preferences/SystemConfiguration/preferences.plist | grep A2 | sed 's/<string>//g' | sed 's/</string>//g' | tr -d '�11' | uniq`

    mkdir /tmp/mount
    chmod 755 /tmp/mount
    mount_afp "afp://acunning:password@bertie.butler.edu/RCBackups" /tmp/mount

    /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "Performing Full Disk Backup" -description "A full backup is being taken of this machine. Do not interrupt or power off." -icon /Applications/Utilities/Disk Utility.app/Contents/Resources/DFA.icns &

    hdiutil create -srcfolder "/Volumes/Macintosh HD/" -format SPARSE "/tmp/mount/$imageName" &

    wait

    killall jamfHelper

    rm -f /Volumes/Macintosh HD/Users/Shared/backup

    shutdown -r now

else

    exit 0

fi

For whatever reason, jamfHelper refuses to quit. I am thinking that this is because it has been backgrounded with the ampersand. There is also the fact that there are two backgrounded processes in my script. I read a bit about killing background processes, and tried changing the 'killall jamfHelper' to 'killall -', thinking that this would kill ALL background processes, but this did not work either.

Incidentally, when I do a command+option+escape, jamfHelper quits immediately and the script continues (machine reboots). So I am VERY close to this working, but just cannot effing tell jamfHelper to quit! ARRGGGGHHH!

HELP ME PLZ!

--Andy

mm2270
Legendary Contributor III

you may need to figure out what the PID of jamfHelper is inside your script and then do a kill -9 PID to kill it properly. Or, I think there is a command to kill the process that's listed in the jamfHelper help text if I'm not mistaken.

This may work, but not sure how well it does with the fs option of jamfHelper-

kill -9 $(ps -axww | awk '/jamfHelper/{ print $1 }')

leslie
Contributor II
Contributor II

I tend to add another kill when invoking jamfhelper in the background.
killall jamfHelper
sleep 2
killall System Events

andyinindy
Contributor II

@Mike: The "kill -9 $(ps -axww | awk '/jamfHelper/{ print $1 }')" didn't work, unfortunately.

Trying @leslie's 1-2 punch: "killall jamfHelper; sleep 2; killall System Events"

mm2270
Legendary Contributor III

I've seen some cases where the jamfHelper can spawn a few different instances, depending on how its being used. It could be the case that the kill command is not catching everything. Leslie's command may then do the trick.
Also, I assume your above script is running as toot, yes? I believe the command I posted would have to be done as sudo to work.

andyinindy
Contributor II

OK, this is getting ridiculous. Leslie's approach did not work either.

WHY IS IT SO DIFFICULT TO TELL JAMFHELPER TO EFFING QUIT???

Please please please help. I am ready to smash things.

nessts
Valued Contributor II

we run this perl script as a post script in the policy, we found it did not always die on the first kiallall, so it loops until they are gone

#!/usr/bin/perl -w

use strict;
use Sys::Syslog;

(my $progname =$0) =~ s#.*/##;

$ENV{PATH} = '/bin:/usr/bin:/usr/sbin:/sbin:/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources:/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/';
umask 0022;

# generic variables
my $time = 1;
my @checkfor = ("jamfHelper", "System Events");
my $waitfor = 1;
my @running;

main:
openlog $progname, undef, 'user';
while ($waitfor) { $waitfor = 0; open PS, "ps -e -w -O comm= |" or die "$progname: ps: $! "; @running = <PS>; close PS; for my $dut (@checkfor) { if (grep /$dut/, @running) { syslog('notice', "$dut found, killing ", $dut); system("killall "$dut""); $waitfor = 1; } else { syslog('notice', "process %s has completed ", $dut); } }
sleep $time if ($waitfor);
}

closelog;
exit 0;

stevewood
Honored Contributor II
Honored Contributor II

Have you verified the script behaves as expected without the jamfHelper lines? Personally I've never used the wait command in a bash script. Generally I use sleep to sit for a period of time. I understand wait is waiting for the background processes to complete, but I'm wondering if that is causing the problem and that the "killall" line is not ever running.

I've rarely had problems killing jamfHelper with a "killall" statement like you have. And the few times I have had problems, it's been because the previous executions were not completing.

andyinindy
Contributor II

@steve: I think you may be on to something. It seems that wait will not exit until ALL backgrounded tasks have completed. Since jamfHelper will never exit on its own, the script will never exit. I moved the jamfHelper line so that it is called after the hdiutil job, and set it not to background (removed the ampersand). Hopefully this will allow the wait to end, and the subsequent killall command to complete.

Really hope this works! Thanks for the advice.

--Andy

stevewood
Honored Contributor II
Honored Contributor II

You'll still need the & after jamfHelper. If you don't put that in there, the script will stall waiting for jamfHelper to quit.

I would just take the wait out and try running it that way.

andyinindy
Contributor II

Steve:

Unfortunately, the 'wait' is necessary. Without it, the script completes almost instantly, and the backup is not created.

Incidentally, my theory about removing the '&' from the jamfHelper command was incorrect. The script still stalled.

Looks like I am going to have to get creative, along the lines of nessts' looping approach. Again, JAMF has made it ridiculously difficult to programmatically kill their fullscreen prompt!

--Andy

stevewood
Honored Contributor II
Honored Contributor II

It is the "wait" command that is killing you, not jamfHelper. The "wait" command, when not passed a process ID, will wait for all background tasks to complete. Since jamfHelper is technically a running app that never quits, the "wait" process will just sit there.

So, to get around this, grab the PID of hdiutil and use that with the wait command. I tested this script on my system and it worked fine:

#!/bin/bash

function imageBackup
{

    imageName="test"
    hdiutil create -srcfolder "/Volumes/Macintosh HD/Users/swood/Desktop/" -format SPARSE "/Volumes/Macintosh HD/$imageName" &
    pid=`ps -xa | grep hdiutil | awk '{ print $1 }'`
    wait $pid

}
if [ -f "/Volumes/Macintosh HD/Users/Shared/backup" ]; 

then

/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType fs -title "Performing Full Disk Backup" -description "A full backup is being taken of this machine. Do not interrupt or power off." -icon /Applications/Utilities/Disk Utility.app/Contents/Resources/DFA.icns &
imageBackup

killall jamfHelper

else



    exit 0

fi

I moved the backup processes into a function just for testing, but you could put it back to the if/then format you had it in.

andyinindy
Contributor II

Steve! Yes! That did it! Thanks very much for the primer on 'wait' usage! I owe you many beers, my friend.

arekdreyer
Contributor

Can you use Casper Admin from your NetBooted Mac and drag the image to Casper Admin?

andyinindy
Contributor II

Arek:

I don't know, I haven't tried that. I created this process so that we could backup peoples' machines prior to upgrading them to Lion, not for creating master images (that's what InstaDMG is for!).

The cool thing about the process is that you end up with a disk image that can be used with Apple's Migration Assistant. So, we could use this to automate the data migration process (instead of having to go retrieve someones machine and physically plug in firewire/ethernet/thunderbolt to migrate data).

--Andy