Skip to content

Commit e1b64f1

Browse files
authored
Merge pull request #53 from macadmins/dev_4.1.2
Outset 4.1.2
2 parents 457c116 + 45d9bfc commit e1b64f1

File tree

9 files changed

+109
-78
lines changed

9 files changed

+109
-78
lines changed

MDM/Jamf Pro/service-status-ea.sh

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/zsh
2+
3+
# Indicate if all the Outset daemons are enabled or not.
4+
5+
outsetStatusRaw=$(/usr/local/outset/outset --service-status)
6+
enabledDaemons=$(echo $outsetStatusRaw | grep -c 'Enabled$')
7+
8+
# If there is no user logged in, none of the 3 agents will be active, only the daemons.
9+
10+
expectedServices=6
11+
12+
currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )
13+
14+
if [ -z "$currentUser" -o "$currentUser" = "loginwindow" ]; then
15+
expectedServices=3
16+
fi
17+
18+
healthyStatus="Not Healthy"
19+
20+
if [ $enabledDaemons -eq $expectedServices ]; then
21+
healthyStatus="Healthy"
22+
fi
23+
24+
echo "<result>$healthyStatus</result>"

Outset.xcodeproj/project.pbxproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@
512512
"@executable_path/../Frameworks",
513513
);
514514
MACOSX_DEPLOYMENT_TARGET = 10.15;
515-
MARKETING_VERSION = 4.1.1;
515+
MARKETING_VERSION = 4.1.2;
516516
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
517517
PRODUCT_NAME = "$(TARGET_NAME)";
518518
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -549,7 +549,7 @@
549549
"@executable_path/../Frameworks",
550550
);
551551
MACOSX_DEPLOYMENT_TARGET = 10.15;
552-
MARKETING_VERSION = 4.1.1;
552+
MARKETING_VERSION = 4.1.2;
553553
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
554554
PRODUCT_NAME = "$(TARGET_NAME)";
555555
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -587,7 +587,7 @@
587587
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
588588
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
589589
MACOSX_DEPLOYMENT_TARGET = 10.15;
590-
MARKETING_VERSION = 4.1.1;
590+
MARKETING_VERSION = 4.1.2;
591591
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
592592
PRODUCT_NAME = "$(TARGET_NAME)";
593593
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -629,7 +629,7 @@
629629
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
630630
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
631631
MACOSX_DEPLOYMENT_TARGET = 10.15;
632-
MARKETING_VERSION = 4.1.1;
632+
MARKETING_VERSION = 4.1.2;
633633
PRODUCT_BUNDLE_IDENTIFIER = io.macadmins.Outset;
634634
PRODUCT_NAME = "$(TARGET_NAME)";
635635
PROVISIONING_PROFILE_SPECIFIER = "";

Outset/Info.plist

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<key>CFBundlePackageType</key>
1616
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>4.1.1</string>
18+
<string>4.1.2</string>
1919
<key>CFBundleVersion</key>
20-
<string>4.1.1</string>
20+
<string>4.1.2</string>
2121
<key>LSApplicationCategoryType</key>
2222
<string>public.app-category.utilities</string>
2323
<key>LSMinimumSystemVersion</key>

Outset/Outset.swift

+11-16
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ struct Outset: ParsableCommand {
161161
// perform log file rotation
162162
performLogRotation(logFolderPath: logDirectory, logFileBaseName: logFileName, maxLogFiles: logFileMaxCount)
163163

164-
writeLog("Processing scheduled runs for boot", logLevel: .debug)
164+
writeLog("Processing scheduled runs for boot", logLevel: .info)
165165
ensureWorkingFolders()
166166

167167
writeOutsetPreferences(prefs: prefs)
@@ -190,15 +190,15 @@ struct Outset: ParsableCommand {
190190
}
191191

192192
if loginWindow {
193-
writeLog("Processing scheduled runs for login window", logLevel: .debug)
193+
writeLog("Processing scheduled runs for login window", logLevel: .info)
194194

195195
if !folderContents(path: loginWindowDir).isEmpty {
196196
processItems(loginWindowDir)
197197
}
198198
}
199199

200200
if login {
201-
writeLog("Processing scheduled runs for login", logLevel: .debug)
201+
writeLog("Processing scheduled runs for login", logLevel: .info)
202202
if !prefs.ignoredUsers.contains(consoleUser) {
203203
if !folderContents(path: loginOnceDir).isEmpty {
204204
processItems(loginOnceDir, once: true, override: prefs.overrideLoginOnce)
@@ -207,14 +207,14 @@ struct Outset: ParsableCommand {
207207
processItems(loginEveryDir)
208208
}
209209
if !folderContents(path: loginOncePrivilegedDir).isEmpty || !folderContents(path: loginEveryPrivilegedDir).isEmpty {
210-
FileManager.default.createFile(atPath: loginPrivilegedTrigger, contents: nil)
210+
createTrigger(loginPrivilegedTrigger)
211211
}
212212
}
213213

214214
}
215215

216216
if loginPrivileged {
217-
writeLog("Processing scheduled runs for privileged login", logLevel: .debug)
217+
writeLog("Processing scheduled runs for privileged login", logLevel: .info)
218218
if checkFileExists(path: loginPrivilegedTrigger) {
219219
pathCleanup(pathname: loginPrivilegedTrigger)
220220
}
@@ -231,29 +231,24 @@ struct Outset: ParsableCommand {
231231
}
232232

233233
if onDemand {
234-
writeLog("Processing on-demand", logLevel: .debug)
234+
writeLog("Processing on-demand", logLevel: .info)
235235
if !folderContents(path: onDemandDir).isEmpty {
236236
if !["root", "loginwindow"].contains(consoleUser) {
237237
let currentUser = NSUserName()
238238
if consoleUser == currentUser {
239239
processItems(onDemandDir)
240+
createTrigger(cleanupTrigger)
240241
} else {
241242
writeLog("User \(currentUser) is not the current console user. Skipping on-demand run.")
242243
}
243244
} else {
244245
writeLog("No current user session. Skipping on-demand run.")
245246
}
246-
FileManager.default.createFile(atPath: cleanupTrigger, contents: nil)
247-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
248-
if checkFileExists(path: cleanupTrigger) {
249-
pathCleanup(pathname: cleanupTrigger)
250-
}
251-
}
252247
}
253248
}
254249

255250
if loginEvery {
256-
writeLog("Processing scripts in login-every", logLevel: .debug)
251+
writeLog("Processing scripts in login-every", logLevel: .info)
257252
if !prefs.ignoredUsers.contains(consoleUser) {
258253
if !folderContents(path: loginEveryDir).isEmpty {
259254
processItems(loginEveryDir)
@@ -262,7 +257,7 @@ struct Outset: ParsableCommand {
262257
}
263258

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

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

311306
for var override in addOverride {
312-
if !override.contains(loginOnceDir) {
307+
if !override.contains(loginOnceDir) && !override.contains(loginOncePrivilegedDir) {
313308
override = "\(loginOnceDir)/\(override)"
314309
}
315310
writeLog("Adding \(override) to override list", logLevel: .debug)

Outset/Utils/FileUtils.swift

+4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ func deletePath(_ path: String) {
169169
}
170170
}
171171

172+
func createTrigger(_ path: String) {
173+
FileManager.default.createFile(atPath: path, contents: nil)
174+
}
175+
172176
func mountDmg(dmg: String) -> String {
173177
// Attaches dmg and returns the path
174178
let cmd = "/usr/bin/hdiutil attach -nobrowse -noverify -noautoopen \(dmg)"

Outset/Utils/ItemProcessing.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func processItems(_ path: String, deleteItems: Bool=false, once: Bool=false, ove
8585
}
8686

8787
if once {
88-
writeLog("Processing run-once \(script)", logLevel: .debug)
88+
writeLog("Processing run-once \(script)", logLevel: .info)
8989
// If this is supposed to be a runonce item then we want to check to see if has an existing runonce entry
9090
// looks for a key with the full script path. Writes the full path and run date when done
9191
if !runOnceDict.contains(where: {$0.key == script}) {
@@ -119,7 +119,7 @@ func processItems(_ path: String, deleteItems: Bool=false, once: Bool=false, ove
119119
}
120120
}
121121
} else {
122-
writeLog("Processing script \(script)", logLevel: .debug)
122+
writeLog("Processing script \(script)", logLevel: .info)
123123
let (_, error, status) = runShellCommand(script, args: [consoleUser], verbose: true)
124124
if status != 0 {
125125
writeLog(error, logLevel: .error)

Outset/Utils/Preferences.swift

+10-9
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,17 @@ func migrateLegacyPreferences() {
153153
deletePath(newoldRootUserDefaults)
154154
}
155155
case legacyOutsetPreferencesFile:
156-
writeLog("\(legacyOutsetPreferencesFile) migration", logLevel: .debug)
157-
do {
158-
let legacyPreferences = try PropertyListDecoder().decode(OutsetPreferences.self, from: data)
159-
writeOutsetPreferences(prefs: legacyPreferences)
160-
writeLog("Migrated Legacy Outset Preferences", logLevel: .debug)
161-
deletePath(legacyOutsetPreferencesFile)
162-
} catch {
163-
writeLog("legacy Preferences migration failed", logLevel: .error)
156+
if isRoot() {
157+
writeLog("\(legacyOutsetPreferencesFile) migration", logLevel: .debug)
158+
do {
159+
let legacyPreferences = try PropertyListDecoder().decode(OutsetPreferences.self, from: data)
160+
writeOutsetPreferences(prefs: legacyPreferences)
161+
writeLog("Migrated Legacy Outset Preferences", logLevel: .debug)
162+
deletePath(legacyOutsetPreferencesFile)
163+
} catch {
164+
writeLog("legacy Preferences migration failed", logLevel: .error)
165+
}
164166
}
165-
166167
case legacyRootRunOncePlistFile, legacyUserRunOncePlistFile:
167168
writeLog("\(legacyRootRunOncePlistFile) and \(legacyUserRunOncePlistFile) migration", logLevel: .debug)
168169
do {

Package/outset-pkg

+49-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# AUTHOR: Bart Reardon
1313
# ORGANIZATION: Macadmins Open Source
1414
# CREATED: 2023-03-23
15-
# REVISION: 1.0.1
15+
# REVISION: 1.0.2
1616
#
1717
# COPYRIGHT: (C) Macadmins Open Source 2023. All rights reserved.
1818
#
@@ -21,6 +21,9 @@
2121
FILE_TO_PACKAGE=""
2222
FILE_TARGET="login-once"
2323
BUILD_ALL=false
24+
POSTINSTALL_SCRIPT=false
25+
MAKE_EXECUTABLE=false
26+
POSTINSTALL_SCRIPT_FILE=""
2427
BUILD_DIRECTORY="/var/tmp/outset"
2528

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

3134
OUTSET_ROOT="/usr/local/outset"
3235
PGKROOT="${BUILD_DIRECTORY}/PGKROOT"
36+
SCRIPT_DIR="${PGKROOT}/scripts"
3337
PKGNAME="outset-custom-content"
38+
ONDEMAND_POSTINSTALL=$(cat <<EOF
39+
#!/bin/bash
40+
trigger="/private/tmp/.io.macadmins.outset.ondemand.launchd"
41+
[[ \$3 != "/" ]] && exit 0
42+
/usr/bin/touch "\${trigger}"
43+
exit 0
44+
EOF
45+
)
3446

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

144+
if $POSTINSTALL_SCRIPT; then
145+
mkdir -p "${SCRIPT_DIR}"
146+
if [[ -n $POSTINSTALL_SCRIPT_FILE ]]; then
147+
if [[ -e "${POSTINSTALL_SCRIPT_FILE}" ]]; then
148+
cp "${POSTINSTALL_SCRIPT_FILE}" "${SCRIPT_DIR}/postinstall"
149+
else
150+
exitWithError "${POSTINSTALL_SCRIPT_FILE} doesn't exist"
151+
fi
152+
else
153+
echo "${ONDEMAND_POSTINSTALL}" > "${SCRIPT_DIR}/postinstall"
154+
fi
155+
chmod 755 "${SCRIPT_DIR}/postinstall"
156+
fi
157+
119158
if [[ -n $FILE_TO_PACKAGE ]]; then
120159
PKGID="${PKG_DOMAIN}.${FILE_TARGET}-${FILE_TO_PACKAGE##*/}"
121160
PKGNAME="outset-${FILE_TARGET}-${FILE_TO_PACKAGE##*/}_v${PKGVERSION}"
@@ -125,6 +164,10 @@ if [[ -n $FILE_TO_PACKAGE ]]; then
125164

126165
if [[ -e "${FILE_TO_PACKAGE}" ]]; then
127166
cp "${FILE_TO_PACKAGE}" "${TARGET_DIR}"
167+
# if the file is not a pkg or dmg, make it executable
168+
if $MAKE_EXECUTABLE && [[ "${FILE_TO_PACKAGE##*.}" != "pkg" ]] && [[ "${FILE_TO_PACKAGE##*.}" != "dmg" ]]; then
169+
chmod 755 "${TARGET_DIR}/${FILE_TO_PACKAGE##*/}"
170+
fi
128171
else
129172
exitWithError "${FILE_TO_PACKAGE} doesn't exist"
130173
fi
@@ -139,7 +182,11 @@ fi
139182
TMP_PKG="${BUILD_DIRECTORY}/${PKGNAME}.component.pkg"
140183
BUILD_PKG="${BUILD_DIRECTORY}/${PKGNAME}.pkg"
141184

142-
/usr/bin/pkgbuild --root "${PGKROOT}" --identifier ${PKGID} --version ${PKGVERSION} "${TMP_PKG}"
185+
if $POSTINSTALL_SCRIPT; then
186+
/usr/bin/pkgbuild --root "${PGKROOT}" --scripts "${SCRIPT_DIR}" --identifier ${PKGID} --version ${PKGVERSION} "${TMP_PKG}"
187+
else
188+
/usr/bin/pkgbuild --root "${PGKROOT}" --identifier ${PKGID} --version ${PKGVERSION} "${TMP_PKG}"
189+
fi
143190
/usr/bin/productbuild --identifier ${PKGID} --package "${TMP_PKG}" "${BUILD_PKG}"
144191

145192
# clean up

0 commit comments

Comments
 (0)