Posted on 11-29-2022 03:16 PM
No previous experience in scripting or making plist, I was tasked with creating one for setting up an automatic backup using RSync on our Mac minis. Users log in using their AD accounts. The idea is to have three folders to back up for any users that logs into the mini. We are using AD setting for a home folder on a NAS. This part is already tested and works. Now to automating this, I have a
simple script in /Library/Scripts
rsync.sh (name)
#!/bin/bash
rsync -ahP -delete ~/Desktop /Volumes/$USER/BackupData
rsync -ahP -delete ~/Documents /Volumes/$USER/BackupData
rsync -ahP -delete ~/Downloads /Volumes/$USER/BackupData
and a plist in /Library/LaunchAgents
com.backup.rsync.plist (name)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.backup.rsync</string>
<key>ProgramArguments</key>
<string>/Library/Scripts/rsync.sh</string>
<key>StartCalendarInterval</key>
<!-- Weekdays are 1 - 5; Sunday is 0 and 7 -->
<array>
<dict>
<key>Weekday</key>
<integer>1</integer>
<key>Hour</key>
<integer>20</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
<dict>
<key>Weekday</key>
<integer>2</integer>
<key>Hour</key>
<integer>20</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
<dict>
<key>Weekday</key>
<integer>3</integer>
<key>Hour</key>
<integer>20</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
<dict>
<key>Weekday</key>
<integer>4</integer>
<key>Hour</key>
<integer>20</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
<dict>
<key>Weekday</key>
<integer>5</integer>
<key>Hour</key>
<integer>20</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
</array>
</dict>
</plist>
and a permission script
#!/bin/bash
# Set permissions on launchd agent files
chown root:wheel "/Library/LaunchAgents/com.backup.rsync.plist"
chmod 644 "/Library/LaunchAgents/com.backup.rsync.plist"
# Set permissions on launchd agent files
chown root:wheel "/Library/Scripts/rsync.sh"
chmod 755 "/Library/Scripts/rsync.sh"
exit 0
I am trying to create a package in Composer and then push it with a policy. Both a script and a plist make it to correct folders when I run the package. The permissions are showing up correctly when I check. But it does not actually run a backup. When I run the same lines in terminal after I create a test file, I can see it backs it up to correct location. I tried this plist with CalendarInterval and with RunAtStart, tried restarting and manually loading. Is it very possible that I have mistakes within the plist that I just don't see. I would appreciate any help on this issue.
11-30-2022 03:29 AM - edited 11-30-2022 08:25 PM
Same here, I can see it backs it up to correct location. I tried this plist with CalendarInterval and with RunAtStart, tried restarting and manually loading. but nothing happened.
Posted on 11-30-2022 06:04 AM
I've had non running scripts when packaged via Composer. Turned out to be a quarantine flag got set on the script. Make sure your tools (BBEdit, Composer, etc ) aren't tainted with a quarantine flag because they will hand it down.
xattr -c -r <file>
Posted on 11-30-2022 09:25 AM
Taking the sample script at what it is. JAMF does everything as root. If you have ~ in the file path the command will be /users/root/rest_of_path to CLI on the Mac. I suggest putting the full path, and a variable to figure out who the logged in user is. KISS = Keep it Stupid Simple
#!/bin/bash
USER=$(who | awk '/console/{print $1}')
rsync -ahP -delete "/Users/$USER/Desktop" /Volumes/$USER/BackupData
rsync -ahP -delete "/Users/$USER/Documents" /Volumes/$USER/BackupData
rsync -ahP -delete "/Users/$USER/Downloads" /Volumes/$USER/BackupData
The plist and permissions look fine. Though I would probably set the permissions to the source files you are packaging in composer and not with CLI on the destination device. If you intend on the agent to start without needing a reboot you will need to bootstrap it.
Bootstrapping would look something like this
#!/bin/bash
#Load a LaunchAgent
launchctl bootstrap gui/502 /System/Library/LaunchAgents/com.backup.rsync.plist
#Start a loaded LaunchAgent
launchctl start com.backup.rsync.plist
This is probably a bit deep end, but here is JAMF 400's training documentation on LaunchAgents and LaunchDaemons. It can be a beast, but once you understand the basics its really not that bad.
Lesson 3 - Course Resources | Jamf