Automating Reposado with Slack Notifications

To know when Apple releases new updates that are downloaded by my Reposado server I’ve been depending on random checks via Margarita, emails from the Security-announce list or discussions on the MacAdmins Slack. Automating repo_sync runs is easy enough with a LaunchDaemon or cron job, but I want to automatically be notified whenever a new update is detected.

When searching to see if anyone had already done the work I found a script by Michael Stango on GitHub that sends email notifications when new updates are downloaded. Stango’s script even takes things a step further with the ability to automatically add new products to a testing branch. Awesome!

Since I have all my similar notifications (AutoPkg, MAU, etc.) feeding into Slack I wanted to send Reposado notifications there as well. I’ve been testing the updated bash script for a few weeks and am happy to share it, read on if you are interested in the details.

I started with Stango’s script as a base since he had done most of the hard work already. Additional options have been added to repoutil since he wrote it in 2013 so I was able to simplify several of the commands. Specifically –non-deprecated (Line 22) and –remove-product deprecated (Line 36).

Next I swapped out the email configuration section for Slack variables and reused the curl webhook code from my post on adding Slack notifications to MAUCacheAdmin.

I also added in a call to run repo_sync at the begging of this script so it doesn’t have to be scheduled separately.

UPDATE 6/3/20: Since I store my Reposado files on a second volume, I added a check to make sure this Storage volume is mounted before the script executes.

#!/bin/bash

# Version 1.1

# File locations - Change as needed
LIST="/tmp/ReposadoUpdateList.txt" # List of updates not in any branches
REPO_SYNC="/usr/local/reposado/repo_sync" # Location of the repo_sync binary
REPOUTIL="/usr/local/reposado/repoutil" # Location of the repoutil binary

# Options for automatically adding new updates to a branch - Change as desired
AUTOADD=true
BRANCH="testing"

# Variables for Slack Notifications
SLACK_NOTIFY=true
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/<COMPLETE URL HERE>"
SLACK_ICON_URL="https://raw.githubusercontent.com/wdas/reposado/master/other/reposado.jpg"

# Make sure the Storage volume is mounted before continuing
if
	[ ! -f /Volumes/Storage/reposado/html/index.html ]
	then
	echo "Storage volume does not appear to be mounted, exiting."
	curl -X POST -H 'Content-type: application/json' --data '{"username":"Reposado","icon_url":"'"$SLACK_ICON_URL"'","text":"*WARNING:* The Storage volume is not mounted."}' $SLACK_WEBHOOK_URL
	exit 1
fi

# Run repo_sync to fetch latest updates from Apple
$REPO_SYNC

# List available updates that are not in any branch and are not marked as deprecated
echo "Searching for non-deprecated updates that are not in any branch..."
$REPOUTIL --non-deprecated | grep "\[\]" > $LIST

# Count the new updates
UPDATECOUNT=$(cat $LIST | wc -l | tr -d ' ')
echo "$UPDATECOUNT updates found."

# If updates are available add them to a designated branch and send the Slack notification
if [ "$UPDATECOUNT" -gt 0 ]; then

	# If AUTOADD is enabled then add the updates to the designated branch to mirror Apple's branch
	if [ "$AUTOADD" = true ]; then

		# Remove deprecated updates from the designated branch
		echo "Removing deprecated updates from the $BRANCH branch..."
		$REPOUTIL --remove-product deprecated $BRANCH

		# Add the new updates to the designated branch
		NEWPRODUCTIDS=$(cat $LIST | awk '{ print $1 }' | tr '\n' ' ')
		echo "Adding $NEWPRODUCTIDS to $BRANCH branch..."
		$REPOUTIL --add-product=$NEWPRODUCTIDS $BRANCH
	fi
fi

# Send notification to Slack webhook if needed
if [ $SLACK_NOTIFY = true ]; then
	if [ -s $LIST ]; then
		echo "Sending Slack notification."
		if [ "$AUTOADD" = true ]; then
			curl -X POST -H 'Content-type: application/json' --data '{"username":"Reposado","icon_url":"'"$SLACK_ICON_URL"'","text":"*The following updates were added to the _'"$BRANCH"'_ branch:* \n '"$(cat $LIST)"'"}' $SLACK_WEBHOOK_URL
		else
			curl -X POST -H 'Content-type: application/json' --data '{"username":"Reposado","icon_url":"'"$SLACK_ICON_URL"'","text":"*The following updates are available for addition to a branch:* \n '"$(cat $LIST)"'"}' $SLACK_WEBHOOK_URL
		fi		
	else
	echo "No notification needed."
	fi
fi

When new updates are downloaded you’ll get one of the following notifications depending on wether AUTOADD is set to true or false:

Now you can point your LaunchDaemon or cron job at this script to run a repo_sync on whatever schedule you’d like and receive a notification in Slack anytime a new update is downloaded.

During testing I included an extra Slack notification that triggered even if no updates were downloaded. If you want reassurance that the script it running on schedule simply replace Line 55 with the following:

	curl -X POST -H 'Content-type: application/json' --data '{"username":"Reposado","icon_url":"'"$SLACK_ICON_URL"'","text":"No updates found."}' $SLACK_WEBHOOK_URL

One note is that if you intentionally want to keep deprecated products in your testing branch then this script will not work as-is. By default it will remove any deprecated items from the specified branch anytime it adds newly available packages.

An example LaunchDaemon is included below in case it might be helpful for anyone. Just edit the identifier and script path before loading it. This example runs every 12 hours:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.galvnews.ReposadoNotification</string>
	<key>Program</key>
	<string>/usr/local/reposado/ReposadoNotification.sh</string>
	<key>RunAtLoad</key>
	<true/>
	<key>StartInterval</key>
	<integer>43200</integer>
</dict>
</plist>

1 comment on “Automating Reposado with Slack Notifications

  1. Pingback: Weekly News Summary for Admins — 2019-04-19 – Scripting OS X

Leave a Reply

Your email address will not be published. Required fields are marked *