Skip to content

Commit

Permalink
Merge pull request #53 from macadmins/dev_4.1.2
Browse files Browse the repository at this point in the history
Outset 4.1.2
  • Loading branch information
bartreardon committed Apr 18, 2024
2 parents 457c116 + 45d9bfc commit e1b64f1
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 78 deletions.
24 changes: 24 additions & 0 deletions MDM/Jamf Pro/service-status-ea.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/zsh

# Indicate if all the Outset daemons are enabled or not.

outsetStatusRaw=$(/usr/local/outset/outset --service-status)
enabledDaemons=$(echo $outsetStatusRaw | grep -c 'Enabled$')

# If there is no user logged in, none of the 3 agents will be active, only the daemons.

expectedServices=6

currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )

if [ -z "$currentUser" -o "$currentUser" = "loginwindow" ]; then
expectedServices=3
fi

healthyStatus="Not Healthy"

if [ $enabledDaemons -eq $expectedServices ]; then
healthyStatus="Healthy"
fi

echo "<result>$healthyStatus</result>"
8 changes: 4 additions & 4 deletions Outset.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 4.1.1;
MARKETING_VERSION = 4.1.2;
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -549,7 +549,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 4.1.1;
MARKETING_VERSION = 4.1.2;
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -587,7 +587,7 @@
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 4.1.1;
MARKETING_VERSION = 4.1.2;
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -629,7 +629,7 @@
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 4.1.1;
MARKETING_VERSION = 4.1.2;
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
4 changes: 2 additions & 2 deletions Outset/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>4.1.1</string>
<string>4.1.2</string>
<key>CFBundleVersion</key>
<string>4.1.1</string>
<string>4.1.2</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
Expand Down
27 changes: 11 additions & 16 deletions Outset/Outset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ struct Outset: ParsableCommand {
// perform log file rotation
performLogRotation(logFolderPath: logDirectory, logFileBaseName: logFileName, maxLogFiles: logFileMaxCount)

writeLog("Processing scheduled runs for boot", logLevel: .debug)
writeLog("Processing scheduled runs for boot", logLevel: .info)
ensureWorkingFolders()

writeOutsetPreferences(prefs: prefs)
Expand Down Expand Up @@ -190,15 +190,15 @@ struct Outset: ParsableCommand {
}

if loginWindow {
writeLog("Processing scheduled runs for login window", logLevel: .debug)
writeLog("Processing scheduled runs for login window", logLevel: .info)

if !folderContents(path: loginWindowDir).isEmpty {
processItems(loginWindowDir)
}
}

if login {
writeLog("Processing scheduled runs for login", logLevel: .debug)
writeLog("Processing scheduled runs for login", logLevel: .info)
if !prefs.ignoredUsers.contains(consoleUser) {
if !folderContents(path: loginOnceDir).isEmpty {
processItems(loginOnceDir, once: true, override: prefs.overrideLoginOnce)
Expand All @@ -207,14 +207,14 @@ struct Outset: ParsableCommand {
processItems(loginEveryDir)
}
if !folderContents(path: loginOncePrivilegedDir).isEmpty || !folderContents(path: loginEveryPrivilegedDir).isEmpty {
FileManager.default.createFile(atPath: loginPrivilegedTrigger, contents: nil)
createTrigger(loginPrivilegedTrigger)
}
}

}

if loginPrivileged {
writeLog("Processing scheduled runs for privileged login", logLevel: .debug)
writeLog("Processing scheduled runs for privileged login", logLevel: .info)
if checkFileExists(path: loginPrivilegedTrigger) {
pathCleanup(pathname: loginPrivilegedTrigger)
}
Expand All @@ -231,29 +231,24 @@ struct Outset: ParsableCommand {
}

if onDemand {
writeLog("Processing on-demand", logLevel: .debug)
writeLog("Processing on-demand", logLevel: .info)
if !folderContents(path: onDemandDir).isEmpty {
if !["root", "loginwindow"].contains(consoleUser) {
let currentUser = NSUserName()
if consoleUser == currentUser {
processItems(onDemandDir)
createTrigger(cleanupTrigger)
} else {
writeLog("User \(currentUser) is not the current console user. Skipping on-demand run.")
}
} else {
writeLog("No current user session. Skipping on-demand run.")
}
FileManager.default.createFile(atPath: cleanupTrigger, contents: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if checkFileExists(path: cleanupTrigger) {
pathCleanup(pathname: cleanupTrigger)
}
}
}
}

if loginEvery {
writeLog("Processing scripts in login-every", logLevel: .debug)
writeLog("Processing scripts in login-every", logLevel: .info)
if !prefs.ignoredUsers.contains(consoleUser) {
if !folderContents(path: loginEveryDir).isEmpty {
processItems(loginEveryDir)
Expand All @@ -262,7 +257,7 @@ struct Outset: ParsableCommand {
}

if loginOnce {
writeLog("Processing scripts in login-once", logLevel: .debug)
writeLog("Processing scripts in login-once", logLevel: .info)
if !prefs.ignoredUsers.contains(consoleUser) {
if !folderContents(path: loginOnceDir).isEmpty {
processItems(loginOnceDir, once: true, override: prefs.overrideLoginOnce)
Expand All @@ -273,7 +268,7 @@ struct Outset: ParsableCommand {
}

if cleanup {
writeLog("Cleaning up on-demand directory.", logLevel: .debug)
writeLog("Cleaning up on-demand directory.", logLevel: .info)
if checkFileExists(path: onDemandTrigger) { pathCleanup(pathname: onDemandTrigger) }
if checkFileExists(path: cleanupTrigger) { pathCleanup(pathname: cleanupTrigger) }
if !folderContents(path: onDemandDir).isEmpty { pathCleanup(pathname: onDemandDir) }
Expand Down Expand Up @@ -309,7 +304,7 @@ struct Outset: ParsableCommand {
ensureRoot("add scripts to override list")

for var override in addOverride {
if !override.contains(loginOnceDir) {
if !override.contains(loginOnceDir) && !override.contains(loginOncePrivilegedDir) {
override = "\(loginOnceDir)/\(override)"
}
writeLog("Adding \(override) to override list", logLevel: .debug)
Expand Down
4 changes: 4 additions & 0 deletions Outset/Utils/FileUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ func deletePath(_ path: String) {
}
}

func createTrigger(_ path: String) {
FileManager.default.createFile(atPath: path, contents: nil)
}

func mountDmg(dmg: String) -> String {
// Attaches dmg and returns the path
let cmd = "/usr/bin/hdiutil attach -nobrowse -noverify -noautoopen \(dmg)"
Expand Down
4 changes: 2 additions & 2 deletions Outset/Utils/ItemProcessing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func processItems(_ path: String, deleteItems: Bool=false, once: Bool=false, ove
}

if once {
writeLog("Processing run-once \(script)", logLevel: .debug)
writeLog("Processing run-once \(script)", logLevel: .info)
// If this is supposed to be a runonce item then we want to check to see if has an existing runonce entry
// looks for a key with the full script path. Writes the full path and run date when done
if !runOnceDict.contains(where: {$0.key == script}) {
Expand Down Expand Up @@ -119,7 +119,7 @@ func processItems(_ path: String, deleteItems: Bool=false, once: Bool=false, ove
}
}
} else {
writeLog("Processing script \(script)", logLevel: .debug)
writeLog("Processing script \(script)", logLevel: .info)
let (_, error, status) = runShellCommand(script, args: [consoleUser], verbose: true)
if status != 0 {
writeLog(error, logLevel: .error)
Expand Down
19 changes: 10 additions & 9 deletions Outset/Utils/Preferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,17 @@ func migrateLegacyPreferences() {
deletePath(newoldRootUserDefaults)
}
case legacyOutsetPreferencesFile:
writeLog("\(legacyOutsetPreferencesFile) migration", logLevel: .debug)
do {
let legacyPreferences = try PropertyListDecoder().decode(OutsetPreferences.self, from: data)
writeOutsetPreferences(prefs: legacyPreferences)
writeLog("Migrated Legacy Outset Preferences", logLevel: .debug)
deletePath(legacyOutsetPreferencesFile)
} catch {
writeLog("legacy Preferences migration failed", logLevel: .error)
if isRoot() {
writeLog("\(legacyOutsetPreferencesFile) migration", logLevel: .debug)
do {
let legacyPreferences = try PropertyListDecoder().decode(OutsetPreferences.self, from: data)
writeOutsetPreferences(prefs: legacyPreferences)
writeLog("Migrated Legacy Outset Preferences", logLevel: .debug)
deletePath(legacyOutsetPreferencesFile)
} catch {
writeLog("legacy Preferences migration failed", logLevel: .error)
}
}

case legacyRootRunOncePlistFile, legacyUserRunOncePlistFile:
writeLog("\(legacyRootRunOncePlistFile) and \(legacyUserRunOncePlistFile) migration", logLevel: .debug)
do {
Expand Down
51 changes: 49 additions & 2 deletions Package/outset-pkg
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# AUTHOR: Bart Reardon
# ORGANIZATION: Macadmins Open Source
# CREATED: 2023-03-23
# REVISION: 1.0.1
# REVISION: 1.0.2
#
# COPYRIGHT: (C) Macadmins Open Source 2023. All rights reserved.
#
Expand All @@ -21,6 +21,9 @@
FILE_TO_PACKAGE=""
FILE_TARGET="login-once"
BUILD_ALL=false
POSTINSTALL_SCRIPT=false
MAKE_EXECUTABLE=false
POSTINSTALL_SCRIPT_FILE=""
BUILD_DIRECTORY="/var/tmp/outset"

PKGTITLE="Outset Custom Content"
Expand All @@ -30,7 +33,16 @@ PKGID="${PKG_DOMAIN}.custom-content"

OUTSET_ROOT="/usr/local/outset"
PGKROOT="${BUILD_DIRECTORY}/PGKROOT"
SCRIPT_DIR="${PGKROOT}/scripts"
PKGNAME="outset-custom-content"
ONDEMAND_POSTINSTALL=$(cat <<EOF
#!/bin/bash
trigger="/private/tmp/.io.macadmins.outset.ondemand.launchd"
[[ \$3 != "/" ]] && exit 0
/usr/bin/touch "\${trigger}"
exit 0
EOF
)

printUsage() {
echo "OVERVIEW: ${0##*/} is a utility that packages files for use in outset workflows."
Expand All @@ -40,7 +52,11 @@ printUsage() {
echo "OPTIONS:"
echo " -a, --all Package all scripts from outset processing directories into one package"
echo " -f, --file <filename> Package the selected file"
echo " -x, --make-executable Ensure the selected file executable bit is set (only applies to script files)"
echo " -t, --target <directory> Target processing directory (default 'login-once')"
echo " -s, --postinstall-script [<filename>]"
echo " Include a postinstall script. If no argument is given, a standard postinstall"
echo " script to trigger on-demand will be included."
echo " -v, --version, <number> Set package version to the selected number (default is '1.0')"
echo " -p, --build-path, <path> Path to use as the build location (default ${BUILD_DIRECTORY})"
echo " -h, --help Print this message"
Expand Down Expand Up @@ -95,8 +111,17 @@ fi
while [[ "$#" -gt 0 ]]; do
case $1 in
--file|-f) FILE_TO_PACKAGE="$2"; shift ;;
--make-executable|-x) MAKE_EXECUTABLE=true ;;
--target|-t) FILE_TARGET=$(validateTarget "$2") || printValidTargets "$2"; shift ;;
--version|-v) PKGVERSION=$(validateVersion "$2") || exitWithError "invalid version number $2"; shift ;;
--postinstall-script|-s) POSTINSTALL_SCRIPT_FILE="$2" && POSTINSTALL_SCRIPT=true
# if the first character is a hyphen, then no argument was passed
if [[ -z $POSTINSTALL_SCRIPT_FILE ]] || [[ "${POSTINSTALL_SCRIPT_FILE:0:1}" == "-" ]]; then
POSTINSTALL_SCRIPT_FILE=""
else
shift
fi
;;
--build-path|-p)
if [[ -e "$2" ]]; then
BUILD_DIRECTORY="${2%/}"
Expand All @@ -116,6 +141,20 @@ done
# create PGKROOT structure
mkdir -p "${PGKROOT}${OUTSET_ROOT}"

if $POSTINSTALL_SCRIPT; then
mkdir -p "${SCRIPT_DIR}"
if [[ -n $POSTINSTALL_SCRIPT_FILE ]]; then
if [[ -e "${POSTINSTALL_SCRIPT_FILE}" ]]; then
cp "${POSTINSTALL_SCRIPT_FILE}" "${SCRIPT_DIR}/postinstall"
else
exitWithError "${POSTINSTALL_SCRIPT_FILE} doesn't exist"
fi
else
echo "${ONDEMAND_POSTINSTALL}" > "${SCRIPT_DIR}/postinstall"
fi
chmod 755 "${SCRIPT_DIR}/postinstall"
fi

if [[ -n $FILE_TO_PACKAGE ]]; then
PKGID="${PKG_DOMAIN}.${FILE_TARGET}-${FILE_TO_PACKAGE##*/}"
PKGNAME="outset-${FILE_TARGET}-${FILE_TO_PACKAGE##*/}_v${PKGVERSION}"
Expand All @@ -125,6 +164,10 @@ if [[ -n $FILE_TO_PACKAGE ]]; then

if [[ -e "${FILE_TO_PACKAGE}" ]]; then
cp "${FILE_TO_PACKAGE}" "${TARGET_DIR}"
# if the file is not a pkg or dmg, make it executable
if $MAKE_EXECUTABLE && [[ "${FILE_TO_PACKAGE##*.}" != "pkg" ]] && [[ "${FILE_TO_PACKAGE##*.}" != "dmg" ]]; then
chmod 755 "${TARGET_DIR}/${FILE_TO_PACKAGE##*/}"
fi
else
exitWithError "${FILE_TO_PACKAGE} doesn't exist"
fi
Expand All @@ -139,7 +182,11 @@ fi
TMP_PKG="${BUILD_DIRECTORY}/${PKGNAME}.component.pkg"
BUILD_PKG="${BUILD_DIRECTORY}/${PKGNAME}.pkg"

/usr/bin/pkgbuild --root "${PGKROOT}" --identifier ${PKGID} --version ${PKGVERSION} "${TMP_PKG}"
if $POSTINSTALL_SCRIPT; then
/usr/bin/pkgbuild --root "${PGKROOT}" --scripts "${SCRIPT_DIR}" --identifier ${PKGID} --version ${PKGVERSION} "${TMP_PKG}"
else
/usr/bin/pkgbuild --root "${PGKROOT}" --identifier ${PKGID} --version ${PKGVERSION} "${TMP_PKG}"
fi
/usr/bin/productbuild --identifier ${PKGID} --package "${TMP_PKG}" "${BUILD_PKG}"

# clean up
Expand Down

0 comments on commit e1b64f1

Please sign in to comment.