Add probo-agent binary, installer, and CI

Signed-off-by: Ludovic Vielle <ludovic@probo.com>
This commit is contained in:
Ludovic Vielle
2026-07-14 20:40:18 +02:00
parent b442e1ed76
commit d0dd87c6c7
24 changed files with 1597 additions and 75 deletions

View File

@@ -12,14 +12,17 @@
#
# We intentionally do not abort the install if enrollment fails:
# the binary is laid down regardless, and the operator can finish
# enrollment with `sudo probo-agent install ...` from Terminal.
# enrollment from the menu bar helper.
set -u
LOG_FILE="/var/log/probo-agent-install.log"
BINARY="/usr/local/bin/probo-agent"
STATE_DIR="/var/lib/probo-agent"
RUN_DIR="/var/run/probo-agent"
CONF_FILE="/tmp/probo-agent.conf"
TRAY_LABEL="com.probo.agent.tray"
TRAY_PLIST_NAME="${TRAY_LABEL}.plist"
# Mirror everything to the install log. We keep stdout/stderr open
# too so failures still surface in macOS Installer.app's log pane.
@@ -39,11 +42,123 @@ mkdir -p "${STATE_DIR}"
chown root:wheel "${STATE_DIR}"
chmod 0700 "${STATE_DIR}"
mkdir -p "${RUN_DIR}"
chown root:wheel "${RUN_DIR}"
chmod 0755 "${RUN_DIR}"
register_tray_launchagent() {
local current_user user_uid agents_dir plist_path
agents_dir="/Library/LaunchAgents"
plist_path="${agents_dir}/${TRAY_PLIST_NAME}"
mkdir -p "${agents_dir}"
cat > "${plist_path}" <<EOF
<?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>${TRAY_LABEL}</string>
<key>ProgramArguments</key>
<array>
<string>${BINARY}</string>
<string>tray</string>
<string>--run-dir</string>
<string>${RUN_DIR}</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
EOF
chmod 0644 "${plist_path}"
echo "Installed tray LaunchAgent at ${plist_path}."
bootstrap_tray_for_user() {
local username="$1"
local user_uid
if [ -z "${username}" ] || \
[ "${username}" = "root" ] || \
[ "${username}" = "loginwindow" ]; then
return 1
fi
user_uid="$(id -u "${username}" 2>/dev/null || true)"
if [ -z "${user_uid}" ]; then
echo "warning: cannot resolve uid for ${username}; skipping tray bootstrap."
return 1
fi
launchctl bootout "gui/${user_uid}/${TRAY_LABEL}" 2>/dev/null || true
if ! launchctl bootstrap "gui/${user_uid}" "${plist_path}"; then
echo "warning: could not start tray helper for ${username}; it will start at next GUI login."
return 1
fi
echo "Started tray LaunchAgent for ${username}."
return 0
}
started_any=false
seen_users=" "
for username in $(users 2>/dev/null || true); do
case "${seen_users}" in
*" ${username} "*) continue ;;
esac
seen_users="${seen_users}${username} "
if bootstrap_tray_for_user "${username}"; then
started_any=true
fi
done
if [ "${started_any}" = false ]; then
current_user=$(stat -f "%Su" /dev/console 2>/dev/null || true)
if bootstrap_tray_for_user "${current_user}"; then
started_any=true
fi
fi
if [ "${started_any}" = false ]; then
echo "No active GUI session found; tray helper will start at next GUI login."
fi
}
register_enrollment_url_scheme() {
local app_path lsregister
app_path="/Applications/Probo Agent.app"
if [ ! -d "${app_path}" ]; then
echo "warning: ${app_path} not found; cannot register probo:// URL scheme."
return 0
fi
lsregister="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister"
if [ ! -x "${lsregister}" ]; then
echo "warning: lsregister is unavailable; URL scheme registration skipped."
return 0
fi
if ! "${lsregister}" -f "${app_path}"; then
echo "warning: failed to register probo:// URL scheme."
return 0
fi
echo "Registered probo:// URL scheme."
}
# An admin (or MDM) may stage /tmp/probo-agent.conf to drive an
# unattended enrollment. Recognized keys (shell-style):
#
# PROBO_SERVER_URL=https://app.getprobo.com
# PROBO_ENROLLMENT_TOKEN=<token>
# PROBO_SERVER_URL=https://your-probo-host.example.com
# PROBO_ENROLLMENT_TOKEN=<enrollment-token>
# PROBO_NO_AUTO_UPDATE=true
#
# Parse KEY=VALUE lines without sourcing or eval so a crafted conf
@@ -61,7 +176,7 @@ if [ -f "${CONF_FILE}" ]; then
echo "Found ${CONF_FILE}, attempting unattended enrollment."
CONF_SERVER=""
CONF_TOKEN=""
CONF_ENROLLMENT_TOKEN=""
CONF_NOUPDATE=""
while IFS= read -r line || [ -n "$line" ]; do
line="${line%%#*}"
@@ -74,7 +189,7 @@ if [ -f "${CONF_FILE}" ]; then
CONF_SERVER="$(strip_conf_value "${line#PROBO_SERVER_URL=}")"
;;
PROBO_ENROLLMENT_TOKEN=*)
CONF_TOKEN="$(strip_conf_value "${line#PROBO_ENROLLMENT_TOKEN=}")"
CONF_ENROLLMENT_TOKEN="$(strip_conf_value "${line#PROBO_ENROLLMENT_TOKEN=}")"
;;
PROBO_NO_AUTO_UPDATE=*)
CONF_NOUPDATE="$(strip_conf_value "${line#PROBO_NO_AUTO_UPDATE=}")"
@@ -82,32 +197,38 @@ if [ -f "${CONF_FILE}" ]; then
esac
done < "${CONF_FILE}"
if [ -z "${CONF_SERVER}" ] || [ -z "${CONF_TOKEN}" ]; then
if [ -z "${CONF_SERVER}" ] || [ -z "${CONF_ENROLLMENT_TOKEN}" ]; then
echo "warning: ${CONF_FILE} is missing PROBO_SERVER_URL or PROBO_ENROLLMENT_TOKEN; skipping enrollment."
else
EXTRA_FLAGS=()
# Build argv from the first element so "${INSTALL_ARGS[@]}"
# is never empty — macOS /bin/bash 3.2 treats an unset empty
# array as unbound under `set -u`.
INSTALL_ARGS=(
install
--server "${CONF_SERVER}"
--enrollment-token "${CONF_ENROLLMENT_TOKEN}"
)
case "${CONF_NOUPDATE}" in
1|true|TRUE|yes|YES) EXTRA_FLAGS+=("--no-auto-update") ;;
1|true|TRUE|yes|YES) INSTALL_ARGS+=(--no-auto-update) ;;
esac
if "${BINARY}" install \
--server "${CONF_SERVER}" \
--enrollment-token "${CONF_TOKEN}" \
"${EXTRA_FLAGS[@]}"; then
if "${BINARY}" "${INSTALL_ARGS[@]}"; then
echo "Device enrolled and service installed."
else
echo "warning: probo-agent install failed; the binary is in place and can be re-run by an admin."
fi
fi
# The token in the conf file is sensitive; clear it whatever
# The enrollment token in the conf file is sensitive; clear it
# the outcome so a successful install does not leave secrets
# in /tmp.
rm -f "${CONF_FILE}"
else
echo "No ${CONF_FILE} found; skipping automatic enrollment."
echo "Finish setup with: sudo ${BINARY} install --server <URL> --enrollment-token <TOKEN>"
echo "No ${CONF_FILE} found; enrollment can be completed from the menu bar icon."
fi
register_tray_launchagent
register_enrollment_url_scheme
echo "=== postinstall done ==="
exit 0

View File

@@ -0,0 +1,9 @@
#!/bin/bash
#
# probo-agent macOS PKG preinstall script.
#
# Enrollment is handled by the menu bar helper after installation.
# MDM may still pre-stage /tmp/probo-agent.conf for unattended
# enrollment in postinstall.
exit 0