Skip to main content
Solved

Progress bar of cached package using CocoaDialog


Did this topic help you find an answer to your question?
Show first post

35 replies

Forum|alt.badge.img+14
  • Author
  • Valued Contributor
  • 296 replies
  • January 22, 2016

@iJake nope, % still stays at 0 and progress bar doesn't move.


iJake
Forum|alt.badge.img+21
  • Contributor
  • 279 replies
  • January 22, 2016

Okay, not sure what the deal is. Let's pick this up on Monday where we can jump on a WebEx and look at it live.


Forum|alt.badge.img+14
  • Author
  • Valued Contributor
  • 296 replies
  • January 22, 2016

@iJake Ok sounds good, thanks for all your help so far.


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • 7880 replies
  • January 22, 2016

Wow, @iJake's script is pretty advanced. Lots of neat stuff going on in there that I'll need to study on the side :)
Thanks for posting your version.

I don't know if this helps or if I'm just muddying the waters at this point, but just in case it helps, here is a version I came up with. Its much simpler - no advanced error state checking or log functions happening, although that could be incorporated. The only reason I'm posting it is because I'm using Casper script parameters for the relevant bits, like the package name, total file size and the policy custom trigger that does the caching.

#!/bin/bash

cdPath="/Library/Application Support/JAMF/bin/cocoaDialog.app/Contents/MacOS/cocoaDialog"
DownloadDir="/Library/Application Support/JAMF/Downloads"
WaitingRoomDir="/Library/Application Support/JAMF/Waiting Room"

if [ "$4" != "" ]; then
    PackageName="$4"
else
    echo "Paramater 4 was empty. This needs to contain the full file name of the package that will download. Exiting..."
    exit 1
fi

if [ "$5" != "" ]; then
    ## To get the correct size to use, run a `du /path/to/package.pkg` command
    ## and copy the first column's integers and use them as the string for parameter 5
    RawFileSize="$5"
else
    echo "Paramater 5 was empty. This needs to contain the raw file size of the package that will download in bytes. Exiting..."
    exit 2
fi

if [ "$6" != "" ]; then
    PolicyTrigger="$6"
else
    echo "Paramater 6 was empty. This needs to contain the caching policy trigger string. Exiting..."
    exit 3
fi



function showProgress ()
{

echo "Starting showProgress function..."

exec 20>&-
rm -f /tmp/prog
mkfifo /tmp/prog
sleep 0.2

"$cdPath" progressbar --title "" --text " Please wait. Beginning cache for "${PackageName}"..." --width 500 --icon info --posY top < /tmp/prog &

## Wait just a half sec
sleep 0.5

## Send progress through the named pipe
exec 20<> /tmp/prog


pct=0
while [[ "$pct" -lt 100 ]]; do
    sleep 0.2
    if [ ! -e "${DownloadDir}/${PackageName}" ]; then
        exec 20>&-
        rm -f /tmp/prog
    else
        dlSize=$(du "${DownloadDir}/${PackageName}" | awk '{print $1}' 2>/dev/null)
        if [ "$dlSize" != "" ]; then
            pct=$((dlSize*100/RawFileSize))
            echo "$pct ${pct}% Now caching "${PackageName}"..." >&20
        fi
    fi
done

}


function showError ()
{

"$cdPath" msgbox 
    --title "" 
    --text "There was a problem" 
    --informative-text "The caching policy could not be started. Please check with your administrator for more information." 
    --button1 "  OK  " 
    --icon caution 
    --width 400 
    --posY top 
    --quiet

exit 1

}


## Start off the caching policy, place into background
jamf policy -event "$PolicyTrigger" &>/dev/null &

## Wait until we see the package begin to show up in the Waiting Room before showing a progress bar.
## Wait up to 20 seconds before finally canceling

maxTries=20

x=1
until [[ $(ls "$DownloadDir" | grep "$PackageName") != "" ]]; do
    if [[ "$x" -lt "$maxTries" ]]; then
        sleep 1
        let x=$((x+1))
    else
        break
        showError
    fi  
done

echo "Package is there. We can start"

showProgress &

I'm sure there's like 10 scenarios that could happen during this that I'm not accounting for that @iJake is checking for with his script, so by no means is this better. Just an alternative.

Incidentally, going back to what @alexjdale wrote, for some reason I didn't need to spin off the policy stuff into a LaunchDaemon or other process. I did need to call the progress function in the background though or the script wouldn't exit, despite having exit calls within it. I'm pretty certain its related to calling a policy within a script called by a policy, but I didn't really dig into it much.

Also, you could run an "After" script that uses some of the same script parameters like file name and file size to check if the download was completed and pop up a message to that effect so the user knows everything was OK, or even call Management Action.app for a simple Notification Center message stating the same.


Forum|alt.badge.img+14
  • Author
  • Valued Contributor
  • 296 replies
  • January 22, 2016

@mm2270 Thanks for info. And sorry if you've gotten 38472947298342 notifications from this thread ha.

So I tried out your script and it works, however same thing happens. It sits at 0% and at least for me, our cached package doesn't move into Waiting Room until it's done. It downloads in entirety in the JAMF/Downloads folder and then moves to the Waiting Room. I suspect that's why I only see 0% with your script since it comments to not show a progress bar until it's in the waiting room.


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • 7880 replies
  • January 23, 2016

@perrycj Hmm, well, it sounds like there is something being configured wrong. I have a hard time believing that both of our scripts work for us, but just won't for you. I don't doubt what you're saying, but we're overlooking something here.

So let's back up a moment. I can't really help with Jacob's script, so I'll focus on mine for a moment. You set up a policy using this? If so, did you set up the correct parameters. Here's an example of how I have my test policy set up.

Parameter 4: Microsoft_Office_2016_Volume_Installer.pkg
Parameter 5: 2314016
Parameter 6: CacheMyFiles

So, respectively, I've assigned the package name, the package size as seen from du, and the custom trigger that runs the policy which caches the package. So I have 2 policies. One that runs the above script using those parameters, and then a second policy using only the custom trigger also scoped to my Mac. That second policy is only doing the caching of the package. The script then calls that policy by its trigger, which begins the download and the script continues on, looks for the download and begins showing progress by calculating the file size on disk.

As for it moving from Downloads into Waiting Room, that is expected and is what happens. Downloads is a sort of temporary location. Typically items that are downloaded and installed immediately like in regular policies may use that directory, but are cleaned up afterwards. Waiting Room is used for cached items, but it won't move the download there until its complete. My script is only looking for the file in Downloads. Once its then gone, moved to Waiting Room, it shuts the progress bar down.

Anyway, can you verify all your settings are correct, that you have 2 policies set up like above and they are correctly scoped to the test Mac?

EDIT: I just re-read what you said above, and that was a typo on my part in the comments of my script. Originally I was having it watch in Waiting Room, but then realized I was looking in the wrong spot. I just forgot to edit the comment in the script. My bad. I'll change that. Its in fact looking for the file in "Downloads" If you look at the until line, its using "$DownloadDir" to look for the file to begin the progress bar.


Forum|alt.badge.img+14
  • Author
  • Valued Contributor
  • 296 replies
  • January 23, 2016

@mm2270 So I'm an idiot. I had the wrong file size. I had everything else correct in terms of parameters, policies set up correctly, etc. Just had the wrong file size. I changed the file size to the correct value and I am seeing the percentage increase as it downloads. Both of your workflows are working now.

It is very much appreciated for all your help, both @iJake and @mm2270


iJake
Forum|alt.badge.img+21
  • Contributor
  • 279 replies
  • January 23, 2016

Glad to help. I need to look over the script @mm2270 wrote to see what he did better. The parameters is a good idea. I never took mine past the one scenarios but that's certainly the more extensible way to go.


Forum|alt.badge.img+20
  • Valued Contributor
  • 193 replies
  • May 10, 2018

@mm2270

Thank you for putting this together as I have been looking for something like this for a long time!

Everything was working except for the actual dialog box would never show up. The policy would work and the file would get cached using the 2 polices. I can not figure out why it is not working.

I then tested it on 10.12.6 and it worked great!!! So something is not mixing right with 10.13.x or 10.13.4.

Any ideas or have you updated the script for 10.13 ?

EDIT: it worked on a different 10.13 machine! please go back to your regular scheduled program. ;)
P.S. Thanks again for putting this together!


Forum|alt.badge.img+1
  • New Contributor
  • 3 replies
  • December 8, 2021
iJake wrote:

CocoaDialog can be finicky and you have to use the beta of version 3 for progress to work but here is code to show progress of caching a package. I have a function for when I call the installer too if you need that. You have to tell it the size of the package since it can't be determined dynamically with the way packages ae cached currently.

cdPath="/Path/To/cocoaDialog.app/Contents/MacOS/cocoaDialog"
cdIcon="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ApplicationsFolderIcon.icns"
cdTitle="Dialog Title"
pkgTotal=12064712 #Must know the size of the package
pkgPartial=0
downloadFolder="/Library/Application Support/JAMF/Downloads"
waitingRoomFolder="/Library/Application Support/JAMF/Waiting Room"
dmgName="Package.dmg"

## CocoaDialog Function
dialogDownload()
{
## Create the name pipe input for the progressbar & set brief pause
rm -f /tmp/hpipe
mkfifo /tmp/hpipe
sleep 0.2

## Display progress bar with initial text settings
"$cdPath" progressbar --stoppable --title "Upgrade Package Download Progress" --text "Downloading..." --float < /tmp/hpipe > /tmp/_out &

exec 3< <(yes)

## Send progress through the named pipe
exec 3<> /tmp/hpipe

if { >&3; } 2> /dev/null
    then
        writeLog "Pipe RW verified"
    else
        writeLog "Pipe RW failed"
fi

#Determine PID of jamf process so it can be killed.
trap : SIGTERM SIGINT

echo $$

(jamf policy -event PayloadName ) > /tmp/_out2 &

jamfPID=$!

## Give the policy time to start
sleep 5

#Initialize error counter
counter=0
#While loop to generate package download percent
while [[ $pkgPartial != $pkgTotal ]]
    do
        #Watches for the output of CocoaDialog to equal stopped if "Stop" button is clicked. Cancels install.
        dialogStopCheck=`cat /tmp/_out`
        if [[ "$dialogStopCheck" = "stopped" ]]
            then
                kill $jamfPID
                rm -f /tmp/_out
                rm -f /tmp/_out2
                writeLog "Upgrade cancelled by user."
                exit
        fi
        #Watches for possible jamf binary being upgraded which will fail download of package.
        binaryUpgradeCheck=`cat /private/tmp/_out2 | grep "Upgrading jamf binary..."`
        if [[ "$binaryUpgradeCheck" != "" ]]
            then
                kill $jamfPID
                rm -f /tmp/_out
                rm -f /tmp/_out2
                writeLog "jamf binary upgrade detected. Fixing..."
                jamf policy -event PayloadName >> "$logFile"
                sleep 20
                dialogDownload
        fi
        #Error counter check. Die at 10 errors.
        if [[ $counter -gt 9 ]]
            then
                echo "Package Download failed..." >&3
                sleep 5
                kill $jamfPID
                writeLog "Package download failed."
                exit
            else
                #If the package exists in the download folder determine percentage downloaded.
                if [[ -f  "$downloadFolder"/"$dmgName" ]]
                    then
                        pkgPartial=`du "$downloadFolder"/"$dmgName" | awk '{print $1}'`
                        modifiedTime=`stat -s "$downloadFolder"/"$dmgName" | awk '{print $10}' | sed 's/.*=//'`
                        currentTime=`date +%s`
                        timeDifference=`expr $currentTime - $modifiedTime`
                        #If the downloading file has not been updated in the 10 seconds relative to the current time download may have stalled. Increment error counter.
                        if [[ $timeDifference -gt 10 ]]
                            then
                                echo "$xferPercentage Download may have stalled... ${xferPercentage}%" >&3
                                sleep 5 
                                counter=$(expr $counter + 1)
                            else
                                #Calculate percentage
                                if [[ $pkgPartial =~ ^-?[0-9]+$ ]]
                                    then
                                        xferPercentage=`echo "scale=0; $pkgPartial*100/$pkgTotal" | bc`
                                        echo "$xferPercentage Downloading... ${xferPercentage}%" >&3
                                fi
                        fi
                    #Determine if the file has been moved to the JAMF Waiting room. Exit loop if so to begin install.
                    elif [[ -f "$waitingRoomFolder"/"$dmgName" ]]
                        then
                            writeLog "$dmgName downloaded to $waitingRoomFolder"
                            break
                    else
                        counter=$(expr $counter + 1)
                fi
        fi      
done

## Turn off progress bar by closing file descriptor 3 and removing the named pipe
echo "Closing progress bar."
exec 3>&-
rm -f /tmp/hpipe
}

Hello @iJake ; I know it's a very old thread, but would you have a functioning script with progress Bar for when actually calling the installer? Perhaps with Number of Files processed?

Thanks!


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings