mirror of
https://github.com/fleetdm/fleet
synced 2026-05-05 06:18:25 +00:00
## Description Moves the enabling of the launch daemon to before trying to launch it, so it doesn't fail if the launch daemon is disabled ## Testing Done launch daemon is enabled ``` launchctl print system | grep fleetdm 78074 - com.fleetdm.orbit "com.fleetdm.orbit" => enabled ``` uninstalling FleetDM via https://github.com/fleetdm/fleet/blob/main/orbit/tools/cleanup/cleanup_macos.sh ``` sudo ~/Desktop/removefleet.sh Removing fleet, system will be unenrolled in 15 seconds... Executing detached child process ``` launch daemon is still enabled: ``` launchctl print system | grep fleetdm 78074 - com.fleetdm.orbit "com.fleetdm.orbit" => enabled ``` If I manually disable the launch daemon... ``` sudo launchctl disable system/com.fleetdm.orbit ``` ``` launchctl print system | grep fleetdm 0 78 com.fleetdm.orbit "com.fleetdm.orbit" => disabled ``` ... then the install will fail: ``` sudo installer -pkg ~/Desktop/fleet-osquery-1.18.3.pkg -target / installer: Package name is Fleet osquery installer: Installing at base path / installer: The install failed. (The Installer encountered an error that caused the installation to fail. Contact the software manufacturer for assistance. An error occurred while running scripts from the package “fleet-osquery-1.18.3.pkg”.) ``` Excerpt from `/var/log/install.log`: ``` 2024-10-08 15:00:57-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:00:57-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:00:58-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:00:58-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:00:59-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:00:59-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:01:00-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:01:00-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:01:01-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:01:01-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:01:02-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:01:02-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:01:03-07 HOSTNAME package_script_service[80350]: ./postinstall: Retrying launchctl bootstrap... 2024-10-08 15:01:03-07 HOSTNAME package_script_service[80350]: ./postinstall: Bootstrap failed: 5: Input/output error 2024-10-08 15:01:04-07 HOSTNAME package_script_service[80350]: ./postinstall: Failed to bootstrap system /Library/LaunchDaemons/com.fleetdm.orbit.plist ``` If I then enable the launch daemon... ``` sudo launchctl enable system/com.fleetdm.orbit ``` ``` launchctl print system | grep fleetdm "com.fleetdm.orbit" => enabled ``` ... then the postinstall in the pkg works fine: ``` sudo installer -pkg ~/Desktop/fleet-osquery-1.18.3.pkg -target / installer: Package name is Fleet osquery installer: Installing at base path / installer: The install was successful. ``` So, yeah, the enabling has to be before the launching of the launch daemon.
188 lines
6.2 KiB
Go
188 lines
6.2 KiB
Go
package packaging
|
|
|
|
import "text/template"
|
|
|
|
// Best reference I could find:
|
|
// http://s.sudre.free.fr/Stuff/Ivanhoe/FLAT.html
|
|
var macosPackageInfoTemplate = template.Must(template.New("").Option("missingkey=error").Parse(
|
|
`<pkg-info format-version="2" identifier="{{.Identifier}}.base.pkg" version="{{.Version}}" install-location="/" auth="root">
|
|
<payload/>
|
|
<scripts>
|
|
<postinstall file="./postinstall"/>
|
|
</scripts>
|
|
<bundle-version>
|
|
</bundle-version>
|
|
</pkg-info>
|
|
`))
|
|
|
|
// This template is used to generate a Distribution Definition file, which
|
|
// controls the experience of the installer (the default dir, what options the
|
|
// user has, etc.)
|
|
//
|
|
// Reference:
|
|
// https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html
|
|
var macosDistributionTemplate = template.Must(template.New("").Option("missingkey=error").Parse(
|
|
`<?xml version="1.0" encoding="utf-8"?>
|
|
<installer-gui-script minSpecVersion="2">
|
|
<title>Fleet osquery</title>
|
|
<choices-outline>
|
|
<line choice="choiceBase"/>
|
|
</choices-outline>
|
|
<choice id="choiceBase" title="Fleet osquery" enabled="false" selected="true" description="Standard installation for Fleet osquery.">
|
|
<pkg-ref id="{{.Identifier}}.base.pkg"/>
|
|
</choice>
|
|
{{/* base.pkg specified here is the foldername that contains the package contents */}}
|
|
<pkg-ref id="{{.Identifier}}.base.pkg" version="{{.Version}}" auth="root">#base.pkg</pkg-ref>
|
|
{{/* this ref is collapsed with the previous, having a bundle version helps our notarization tools */}}
|
|
<pkg-ref id="{{.Identifier}}.base.pkg">
|
|
<bundle-version>
|
|
<bundle id="{{.Identifier}}" path="" />
|
|
</bundle-version>
|
|
</pkg-ref>
|
|
<options customize="never" hostArchitectures="arm64,x86_64" require-scripts="false" allow-external-scripts="false" />
|
|
</installer-gui-script>
|
|
`))
|
|
|
|
var macosPostinstallTemplate = template.Must(template.New("").Option("missingkey=error").Parse(
|
|
`#!/bin/bash
|
|
|
|
ln -sf /opt/orbit/bin/orbit/macos/{{.OrbitChannel}}/orbit /opt/orbit/bin/orbit/orbit
|
|
ln -sf /opt/orbit/bin/orbit/orbit /usr/local/bin/orbit
|
|
{{ if .LegacyVarLibSymlink }}
|
|
# Symlink needed to support old versions of orbit.
|
|
ln -sf /opt/orbit /var/lib/orbit
|
|
{{- end }}
|
|
|
|
{{ if .StartService -}}
|
|
DAEMON_LABEL="com.fleetdm.orbit"
|
|
DAEMON_PLIST="/Library/LaunchDaemons/${DAEMON_LABEL}.plist"
|
|
|
|
# Stop the previous desktop agent
|
|
pkill fleet-desktop || true
|
|
# Remove any pre-existing version of the config
|
|
launchctl bootout "system/${DAEMON_LABEL}"
|
|
|
|
# Make sure the launch daemon is enabled before we try to bootstrap it
|
|
launchctl enable "system/${DAEMON_LABEL}"
|
|
|
|
# Add the daemon to the launchd system.
|
|
#
|
|
# We add retries because we've seen "launchctl bootstrap" fail
|
|
# if the service is still running after bootout (in case the
|
|
# service takes a bit longer to terminate gracefully).
|
|
# We've seen this when deploying the package via an MDM server.
|
|
#
|
|
count=0
|
|
while ! launchctl bootstrap system "${DAEMON_PLIST}"; do
|
|
sleep 1
|
|
((count++))
|
|
if [[ $count -eq 30 ]]; then
|
|
echo "Failed to bootstrap system ${DAEMON_PLIST}"
|
|
exit 1
|
|
fi
|
|
echo "Retrying launchctl bootstrap..."
|
|
done
|
|
echo "Successfully bootstrap system ${DAEMON_PLIST}"
|
|
|
|
# Force the daemon to start
|
|
launchctl kickstart "system/${DAEMON_LABEL}"
|
|
{{- end }}
|
|
`))
|
|
|
|
// Note it's important not to start the orbit binary in
|
|
// `/usr/local/bin/orbit` because this is a path that users usually have write
|
|
// access to, and running that binary with launchd can become a privilege
|
|
// escalation vector.
|
|
var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=error").Parse(
|
|
`<?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>EnvironmentVariables</key>
|
|
<dict>
|
|
{{- if .Debug }}
|
|
<key>ORBIT_DEBUG</key>
|
|
<string>true</string>
|
|
{{- end }}
|
|
{{- if .Insecure }}
|
|
<key>ORBIT_INSECURE</key>
|
|
<string>true</string>
|
|
{{- end }}
|
|
{{- if .FleetCertificate }}
|
|
<key>ORBIT_FLEET_CERTIFICATE</key>
|
|
<string>/opt/orbit/fleet.pem</string>
|
|
{{- end }}
|
|
{{- if .EnrollSecret }}
|
|
<key>ORBIT_ENROLL_SECRET_PATH</key>
|
|
<string>/opt/orbit/secret.txt</string>
|
|
{{- end }}
|
|
{{- if .FleetURL }}
|
|
<key>ORBIT_FLEET_URL</key>
|
|
<string>{{ .FleetURL }}</string>
|
|
{{- end }}
|
|
{{- if .UseSystemConfiguration }}
|
|
<key>ORBIT_USE_SYSTEM_CONFIGURATION</key>
|
|
<string>{{ .UseSystemConfiguration }}</string>
|
|
{{- end }}
|
|
{{- if .EnableScripts }}
|
|
<key>ORBIT_ENABLE_SCRIPTS</key>
|
|
<string>{{ .EnableScripts }}</string>
|
|
{{- end }}
|
|
{{- if .DisableUpdates }}
|
|
<key>ORBIT_DISABLE_UPDATES</key>
|
|
<string>true</string>
|
|
{{- end }}
|
|
<key>ORBIT_ORBIT_CHANNEL</key>
|
|
<string>{{ .OrbitChannel }}</string>
|
|
<key>ORBIT_OSQUERYD_CHANNEL</key>
|
|
<string>{{ .OsquerydChannel }}</string>
|
|
<key>ORBIT_UPDATE_URL</key>
|
|
<string>{{ .UpdateURL }}</string>
|
|
{{- if .UpdateTLSServerCertificate }}
|
|
<key>ORBIT_UPDATE_TLS_CERTIFICATE</key>
|
|
<string>/opt/orbit/update.pem</string>
|
|
{{- end }}
|
|
{{- if .Desktop }}
|
|
<key>ORBIT_FLEET_DESKTOP</key>
|
|
<string>true</string>
|
|
<key>ORBIT_DESKTOP_CHANNEL</key>
|
|
<string>{{ .DesktopChannel }}</string>
|
|
{{- if .FleetDesktopAlternativeBrowserHost }}
|
|
<key>ORBIT_FLEET_DESKTOP_ALTERNATIVE_BROWSER_HOST</key>
|
|
<string>{{ .FleetDesktopAlternativeBrowserHost }}</string>
|
|
{{- end }}
|
|
{{- end }}
|
|
<key>ORBIT_UPDATE_INTERVAL</key>
|
|
<string>{{ .OrbitUpdateInterval }}</string>
|
|
{{- if and (ne .HostIdentifier "") (ne .HostIdentifier "uuid") }}
|
|
<key>ORBIT_HOST_IDENTIFIER</key>
|
|
<string>{{ .HostIdentifier }}</string>
|
|
{{- end }}
|
|
{{- if .DisableKeystore }}
|
|
<key>ORBIT_DISABLE_KEYSTORE</key>
|
|
<string>true</string>
|
|
{{- end }}
|
|
{{- if .OsqueryDB }}
|
|
<key>ORBIT_OSQUERY_DB</key>
|
|
<string>{{ .OsqueryDB }}</string>
|
|
{{- end }}
|
|
</dict>
|
|
<key>KeepAlive</key>
|
|
<true/>
|
|
<key>Label</key>
|
|
<string>com.fleetdm.orbit</string>
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>/opt/orbit/bin/orbit/orbit</string>
|
|
</array>
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
<key>StandardErrorPath</key>
|
|
<string>/var/log/orbit/orbit.stderr.log</string>
|
|
<key>StandardOutPath</key>
|
|
<string>/var/log/orbit/orbit.stdout.log</string>
|
|
<key>ThrottleInterval</key>
|
|
<integer>10</integer>
|
|
</dict>
|
|
</plist>
|
|
`))
|