Validate available disk space before installing package

dan-snelson
Valued Contributor II

While testing a Self Service policy to install Adobe Creative Cloud Master Collection 2015, I was greeted by a Finder dialog box informing me I was nearly out of disk space.

The following script leverages JSS Parameter 4 and verifies there is enough available disk space before continuing with the policy. If there is not enough free disk space, a message is displayed to the end-user and Self Service is forcibly quit. (Is there a way to just simply stop the policy and leave Self Service running?)

340e721b27d24e5bade75c4a5567cde9

#!/bin/sh
####################################################################################################
#
# ABOUT
#
#   Check Free Space: Leverages JSS Parameter 4 to verify there is enough available disk space before continuing with the policy. If there is not enough free disk space, a message is displayed to the end-user and Self Service is forcibly quit.
#
####################################################################################################
#
# HISTORY
#
#   Version 1.0, 17-Jun-2015, Dan K. Snelson
#
####################################################################################################
# Import logging functions
source /path/to/logging/script/goes/here/logging.sh
####################################################################################################

# Variables
requiredSpace="$4"            # Available Space Required (in GBs)
availableSpace=`/usr/sbin/diskutil info / | grep "Volume Free Space:" | awk '{print $4}'`
availableSpaceInt=$(/bin/echo "($availableSpace+0.5)/1" | bc)
totalSpace=`/usr/sbin/diskutil info / | grep "Total Size:" | awk '{print $3}'`
/bin/echo "`now` *** Check Free Space ***" >> $logFile
/bin/echo "`now` Required Space: $requiredSpace" >> $logFile
/bin/echo "`now` Available Space: $availableSpaceInt" >> $logFile

if [ "$availableSpaceInt" -lt "$requiredSpace" ]; then
    /usr/sbin/jamf displayMessage -message "Insufficient Free Space Available

This installation requires $requiredSpace GB.
There is $availableSpace GB available.

"
    /usr/bin/killall "Self Service"
    exit 1      ## Failure
else
    /bin/echo "`now` There is enough free space available" >> $logFile
fi


exit 0      ## Success
18 REPLIES 18

nessts
Valued Contributor II

maybe change your policy to two different policies, one that checks for the right amount of free space and if its enough then call the CC install with a custom trigger. if there is not enough space, display the message and quit that script

bpavlov
Honored Contributor

If this is the only instance where you're using a script parameter with space, may I suggest an alternative?
Create an extension attribute that calculates free disk space. Then create a smart group that utilizes that extension attribute where only those that have more than X GB of free space can install the software.

Those that do not meet that criteria will obviously not see the Self Service item. But you could create the same smart group for those that have less than X GB of free space and have some sort of notifier via jamfHelper to let them know they do not have enough free space and need to clear up X GB to proceed. You'll probably need to instruct them to run an inventory check which could be either a separate policy (or maybe included in that same policy that notifies them, but that would probably mean having to run the same policy twice since they won't know they are low on space the first time they run that policy).

mm2270
Legendary Contributor III

The EA capturing free disk space isn't a bad idea @bpavlov. We have one that does that for awhile since we want to keep track of that, but it should just be noted that EAs, like all inventory items are only static values in time. The amount of free disk space can change dramatically in a matter of minutes.
Example: The policy requires 70 GB+ of free disk space. One Mac has 77 GB of free disk space in the AM when their Mac submits inventory, so their Mac lands in the Smart Group scoped to the Self Service policy. A little after, they download some large files that consume ~10 GB of space, they are now at ~66 GB of free disk space, so below the amount necessary to run the policy without causing issues, but of course their Mac has not submitted new inventory since, maybe no new policies have run on it. The Mac will still be in the Smart Group b/c the JSS is unaware that the user just ate up a bunch of available space. What happens now when they run the policy from Self Service?

I'm not saying the above scenario will be very common, but its also quite possible to happen. I do like the idea of doing a dynamic on the fly check for requirements in a script, but, as I and others have noted elsewhere, policies are unfortunately only smart when they are taken as a whole. Individual items within a policy are actually quite dumb and have no knowledge of what has come before them or what comes after them. A script run "before" can't dictate to the package portion of the policy that it should not run the installation, nor vice versa. Its also why both of these feature requests have been made:
https://jamfnation.jamfsoftware.com/featureRequest.html?id=2991
https://jamfnation.jamfsoftware.com/featureRequest.html?id=3669
Its the same general problem, and its really one of my biggest complaints about how policies work. They are disparate items strung together on an assembly line. The assembly line equipment that is supposed to fill the bottle with soda is going to dispense the liquid even if the bottle isn't there! (Note: I do not know if that's actually how modern assembly lines work, so I'm just using it as an example)

I really hope JAMF is working on making this all more intelligent, because right now its kind of impossible to use some items in a policy (like Scripts) to dictate how the remainder of the policy should run, or not run as it were.

bpavlov
Honored Contributor

Indeed @mm2270 that is a very good point. I suppose depending on how often you have inventory take place the extension attribute will hopefully be usually accurate. However if policies had logic built into them then it would make things a lot easier to manage for sure. I can't recall right now but I do remember seeing a feature request that asked for it that was different from the one you linked that may have had a few more votes but would probably better address the issue at hand. The request was for policies to stop and not proceed if a certain step in the policy failed. If I can find it, I'll link it here.

gregneagle
Valued Contributor

If it doesn't already, Casper should do this automatically without the admin having to re-invent the wheel. Casper should track the size of the item and the space needed for its install and not attempt download or install if there is not enough free space. There should be no need for the admin to reinvent this logic over and over for each software item.

Creating Extension Attributes and Smart Groups is a very powerful feature of Casper, but an admin should not have to do this for every single software package just to ensure there is enough free space to install.

bpavlov
Honored Contributor

dan-snelson
Valued Contributor II

May
Contributor III

Thanks @dan.snelson for the script,
I'm looking for a similar solution the only difference is i'm caching rather than installing the Adobe packages in the policy.

Did you come up with a solution ?

I'm testing the approach suggested by @nessts (thank you also!) where the script in the first policy then triggers the cache policy if there's enough disk space.

This is working well apart from when the first policy runs in Self Service the progress bar states that it's running the script but it remains on that progress bar until the second policy has completed, does anyone know how this could be avoided ?

I was considering re-naming the script to something like "bepatientyourstuffisdownloadinggomakesometea.sh" to hopefully keep the downloader from panicking and force quiiting Self Service during their 8GB download.

512e621b1fb54441b2b9f8589d1ac817

#Trigger part of the script

else
    echo "triggering cache policy"
    jamf policy -trigger cachetestpolicy

fi

exit 0      ## Success

nessts
Valued Contributor II

I guess it makes sense that it would sit there and wait. You could use a Cocoa Dialog to put up a notice or a progress bar before the trigger that notifies the user that they have enough disk space and tell them to be patient.

May
Contributor III

@nessts

I imagined that it should complete the first policy that contains the trigger script
then once the triggered policy is running then show the progress for that policy
"i imagine" many things....

I like the idea of a notification, thanks! It should be simple to add jamfhelper to the script

nessts
Valued Contributor II

if you add a

&

after the cachetestpolicy it would likely finish the script.

May
Contributor III

@nessts Thank you, simple and effective!!

It now finishes the Self Service policy and runs the triggered policy in the background so i just need to add a notification to that policy.

dan-snelson
Valued Contributor II

Updates for macOS 10.12 (i.e., "Volume Free Space:" vs. "Volume Available Space:")

#!/bin/sh
####################################################################################################
#
# ABOUT
#
#   Check Free Space
#
####################################################################################################
#
# HISTORY
#
#   Version 1.0, 17-Jun-2015, Dan K. Snelson
#   Version 2.0, 28-Oct-2015, Dan K. Snelson
#       Stops Self Service by calling a policy which runs a script.
#   Version 2.1, 04-Jan-2017, Dan K. Snelson
#       Updated for macOS 10.12
#
####################################################################################################
# Import logging functions
source /path/to/client-side/logging/script/logging.sh
####################################################################################################

## Variables
requiredSpace="$4"            # Availble Space Required (in GBs)


osMinorVersion=$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d. -f2)

    if [[ "$osMinorVersion" -lt 12 ]]; then

        availableSpace=$(/usr/sbin/diskutil info / | grep "Volume Free Space:" | awk '{print $4}')
        availableSpaceInt=$(/bin/echo "($availableSpace+0.5)/1" | bc)
        totalSpace=$(/usr/sbin/diskutil info / | grep "Total Size:" | awk '{print $3}')

    else

        availableSpace=$(/usr/sbin/diskutil info / | grep "Volume Available Space:" | awk '{print $4}')
        availableSpaceInt=$(/bin/echo "($availableSpace+0.5)/1" | bc)
        totalSpace=$(/usr/sbin/diskutil info / | grep "Volume Total Space:" | awk '{print $4}')

    fi



ScriptLog "*** Check Free Space ***"
ScriptLog "Required Space: $requiredSpace"
ScriptLog "Available Space:    $availableSpaceInt"

if [ "$availableSpaceInt" -lt "$requiredSpace" ]; then
    /usr/local/jamf/bin/jamf displayMessage -message "Insufficient Free Space Available

This installation requires $requiredSpace GB.
There is $availableSpace GB available.

"

    /bin/sleep 2

    jssLog "Error: Insufficient Free Space Available: This installation requires $requiredSpace GB; There is $availableSpace GB available."

    ## Call policy to kill download
    /usr/local/jamf/bin/jamf policy -trigger stopSelfService
    exit 1      ## Failure

else

    jssLog "There is enough free space available: This installation requires $requiredSpace GB; There is $availableSpace GB available."

fi


exit 0      ## Success

seann
Contributor

Another way to do this. The benefit being not having to account for multiple OSes, or have to deal with TB or GB being returned

df -g / | tail -n +2 | awk '{print $4}'

EdLuo
Contributor II

@seann Thanks for your command. I made it a bit simpler.

df -g / | awk 'FNR==2{print $4}'

KRIECCO
Contributor

Quite old this post - but tried it, but seems to be issues with Catalina.

Scriptlog command cannot be found when I execute this one

#!/bin/sh
####################################################################################################
#
# ABOUT
#
#   Check Free Space
#
####################################################################################################
#
# HISTORY
#
#   Version 1.0, 17-Jun-2015, Dan K. Snelson
#   Version 2.0, 28-Oct-2015, Dan K. Snelson
#       Stops Self Service by calling a policy which runs a script.
#   Version 2.1, 04-Jan-2017, Dan K. Snelson
#       Updated for macOS 10.12
#
####################################################################################################
# Import logging functions
source /path/to/client-side/logging/script/logging.sh
####################################################################################################

## Variables
requiredSpace="$4"            # Availble Space Required (in GBs)


osMinorVersion=$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d. -f2)

    if [[ "$osMinorVersion" -lt 15 ]]; then

        availableSpace=$(/usr/sbin/diskutil info / | grep "Volume Free Space:" | awk '{print $4}')
        availableSpaceInt=$(/bin/echo "($availableSpace+0.5)/1" | bc)
        totalSpace=$(/usr/sbin/diskutil info / | grep "Total Size:" | awk '{print $3}')

    else

        availableSpace=$(/usr/sbin/diskutil info / | grep "Volume Available Space:" | awk '{print $4}')
        availableSpaceInt=$(/bin/echo "($availableSpace+0.5)/1" | bc)
        totalSpace=$(/usr/sbin/diskutil info / | grep "Volume Total Space:" | awk '{print $4}')

    fi



ScriptLog "*** Check Free Space ***"
ScriptLog "Required Space: $requiredSpace"
ScriptLog "Available Space:    $availableSpaceInt"

if [ "$availableSpaceInt" -lt "$requiredSpace" ]; then
    /usr/local/jamf/bin/jamf displayMessage -message "Insufficient Free Space Available

This installation requires $requiredSpace GB.
There is $availableSpace GB available.

"

    /bin/sleep 2

    jssLog "Error: Insufficient Free Space Available: This installation requires $requiredSpace GB; There is $availableSpace GB available."

    ## Call policy to kill download
    /usr/local/jamf/bin/jamf policy -trigger stopSelfService
    exit 1      ## Failure

else

    jssLog "There is enough free space available: This installation requires $requiredSpace GB; There is $availableSpace GB available."

fi


exit 0      ## Success

walt
Contributor III

only compatible version or method with Catalina? this would be extremely useful. initially, i was considering using smart groups to scope out insufficient disk space but that would not be necessarily clear to the user, unless they were scoped out and a jamfhelper prompt notified them to clean up space to install future applications...

Captainamerica
Contributor II

Seems like the script above is 1 part of it, while the scriptlog part is missing. It is quite old, but maybe someone can show a working example, could be usefull for me as I am not a script guy