mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-23 20:25:56 +00:00
Merge reviewed candidate 20260923T004045Z-core-runtime (pulse 922626418c)
Integrate the exact reviewed FreeBSD/pfSense agent log-capture repair for #2123. The rc.d service now receives the agent's installer-owned rotating --log-file on both the pfSense/OPNsense/vanilla-FreeBSD and TrueNAS CORE branches, and the completion hints name that file instead of the absent /var/log/messages. Includes the installtests coverage and the agent-lifecycle and deployment-installability contract updates. Change-source: pulse-maintainer
This commit is contained in:
@@ -1168,6 +1168,12 @@ update, profile rollout, command reachability, or fleet-control authority.
|
||||
`shasum`, so checksum verification must fall back through the digest tools
|
||||
actually present on the target platform rather than failing a valid agent
|
||||
download when coreutils is absent.
|
||||
FreeBSD-family diagnostics are part of that lifecycle too. The rc.d service
|
||||
has no journal and `daemon(8)` does not capture the child's stdout, so the
|
||||
rendered service must pass an installer-owned rotating `--log-file` and the
|
||||
installer's completion hint must name that file. A platform system log is
|
||||
not a substitute: pfSense ships no `/var/log/messages`, and repointing the
|
||||
hint at a log that receives no agent output would still strand the operator.
|
||||
|
||||
Server update planning is part of the same lifecycle contract. The System
|
||||
Updates plan must surface a structured upgrade-readiness verdict before an
|
||||
|
||||
@@ -1078,8 +1078,13 @@ artifact-selection behaviour.
|
||||
platform. FreeBSD base ships `sha256(1)` and neither GNU `sha256sum` nor
|
||||
Perl `shasum`, so the unified installer and the MCP installer must fall back
|
||||
through the available digest tool instead of refusing an otherwise correct
|
||||
download. The shared installer helper owns that fallback so every download
|
||||
(agent, typed helper, action runner) is verified consistently.
|
||||
download. The shared installer helper owns that fallback so every download
|
||||
(agent, typed helper, action runner) is verified consistently.
|
||||
FreeBSD and pfSense installs must likewise leave the agent with a durable,
|
||||
installer-owned rotating log. rc.d has no journal and `daemon(8)` discards
|
||||
the child's stdout, so the rendered rc.d service must carry the agent's
|
||||
`--log-file` and the install summary must point at that file rather than
|
||||
`/var/log/messages`, which pfSense does not ship.
|
||||
The shell installer must disclose `--enable-commands` as Pulse command
|
||||
execution, disabled by default, and must name both Patrol actions and
|
||||
Proxmox LXC Docker inventory as the operator-visible reasons to enable it.
|
||||
|
||||
+16
-3
@@ -6821,6 +6821,13 @@ if [[ "$TRUENAS" == true ]]; then
|
||||
mkdir -p "$TRUENAS_STATE_DIR"
|
||||
mkdir -p "$TRUENAS_LOG_DIR"
|
||||
|
||||
# FreeBSD rc.d has no journal and daemon(8) does not capture the child's
|
||||
# stdout, so the agent's own rotating writer must own its log. On Linux the
|
||||
# systemd unit captures stdout via journald instead.
|
||||
if [[ "$(uname -s)" == "FreeBSD" ]]; then
|
||||
AGENT_LOG_FILE="${TRUENAS_LOG_DIR}/${AGENT_NAME}.log"
|
||||
fi
|
||||
|
||||
TRUENAS_STORED_BINARY="$TRUENAS_STATE_DIR/${BINARY_NAME}"
|
||||
|
||||
# Move binary to persistent storage location
|
||||
@@ -6958,7 +6965,7 @@ EOF
|
||||
log_info "Logs: tail -f ${TRUENAS_LOG_FILE}"
|
||||
elif [[ "$(uname -s)" == "FreeBSD" ]]; then
|
||||
log_info "Service: $TRUENAS_SERVICE_STORAGE (symlinked to rc.d)"
|
||||
log_info "Logs: tail -f /var/log/messages"
|
||||
log_info "Logs: tail -f ${AGENT_LOG_FILE}"
|
||||
fi
|
||||
log_info ""
|
||||
log_info "The Init/Shutdown task ensures the agent survives TrueNAS upgrades."
|
||||
@@ -7023,6 +7030,12 @@ if [[ "$OS" == "freebsd" ]] || [[ -f /etc/rc.subr ]]; then
|
||||
RCSCRIPT="/usr/local/etc/rc.d/${AGENT_NAME}"
|
||||
log_info "Configuring FreeBSD rc.d service at $RCSCRIPT..."
|
||||
|
||||
# FreeBSD rc.d has no journal, and daemon(8) does not capture the child's
|
||||
# stdout, so the agent's own rotating writer must own its log. Without this
|
||||
# the agent logs are lost and the completion hint below would point at a
|
||||
# system log that never receives them (and that pfSense does not even ship).
|
||||
AGENT_LOG_FILE="${STATE_DIR}/logs/${AGENT_NAME}.log"
|
||||
|
||||
# Build command line args
|
||||
ensure_runtime_token_file "$STATE_DIR"
|
||||
clear_proxmox_state_if_needed
|
||||
@@ -7050,9 +7063,9 @@ BOOTEOF
|
||||
|
||||
# Stop existing agent if running
|
||||
restart_sysv_agent_service "$RCSCRIPT"
|
||||
complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "tail -f /var/log/messages"
|
||||
complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "tail -f ${AGENT_LOG_FILE}"
|
||||
log_info "To check status: $RCSCRIPT status"
|
||||
log_info "To view logs: tail -f /var/log/messages"
|
||||
log_info "To view logs: tail -f ${AGENT_LOG_FILE}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -2658,6 +2658,83 @@ func TestInstallSHFreeBSDRendererUsesDaemonSupervisorPidfile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestInstallSHFreeBSDAgentLogsUseRotatingWriter pins the FreeBSD half of the
|
||||
// log-capture fix for issue #2123: rc.d has no journal and daemon(8) does not
|
||||
// capture the child's stdout, so the agent must own a rotating --log-file and
|
||||
// the completion hint must point at it. pfSense has no /var/log/messages, so
|
||||
// the old system-log hint is removed entirely rather than repointed.
|
||||
func TestInstallSHFreeBSDAgentLogsUseRotatingWriter(t *testing.T) {
|
||||
content, err := os.ReadFile(repoFile("scripts", "install.sh"))
|
||||
if err != nil {
|
||||
t.Fatalf("read install.sh: %v", err)
|
||||
}
|
||||
|
||||
script := string(content)
|
||||
required := []string{
|
||||
`AGENT_LOG_FILE="${STATE_DIR}/logs/${AGENT_NAME}.log"`,
|
||||
`AGENT_LOG_FILE="${TRUENAS_LOG_DIR}/${AGENT_NAME}.log"`,
|
||||
`complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "tail -f ${AGENT_LOG_FILE}"`,
|
||||
`log_info "To view logs: tail -f ${AGENT_LOG_FILE}"`,
|
||||
}
|
||||
for _, needle := range required {
|
||||
if !strings.Contains(script, needle) {
|
||||
t.Fatalf("install.sh missing FreeBSD rotating agent log wiring: %s", needle)
|
||||
}
|
||||
}
|
||||
if strings.Contains(script, "tail -f /var/log/messages") {
|
||||
t.Fatal("install.sh still points FreeBSD/pfSense users at /var/log/messages, which does not exist on pfSense")
|
||||
}
|
||||
}
|
||||
|
||||
// TestInstallSHFreeBSDBuildArgsPassesLogFile verifies the FreeBSD rc.d service
|
||||
// args actually carry --log-file once AGENT_LOG_FILE is set.
|
||||
func TestInstallSHFreeBSDBuildArgsPassesLogFile(t *testing.T) {
|
||||
script := `
|
||||
PULSE_URL="http://pulse.local:7655"
|
||||
PULSE_TOKEN=""
|
||||
INTERVAL="30s"
|
||||
INTERVAL_EXPLICIT="false"
|
||||
ENABLE_HOST="true"
|
||||
HOST_EXPLICIT="false"
|
||||
ENABLE_DOCKER=""
|
||||
DOCKER_EXPLICIT="false"
|
||||
ENABLE_KUBERNETES=""
|
||||
KUBERNETES_EXPLICIT="false"
|
||||
KUBECONFIG_PATH=""
|
||||
ENABLE_PROXMOX=""
|
||||
PROXMOX_EXPLICIT="false"
|
||||
PROXMOX_TYPE=""
|
||||
INSECURE="false"
|
||||
ENABLE_COMMANDS="false"
|
||||
ENROLL="false"
|
||||
HEALTH_ADDR=""
|
||||
HEALTH_ADDR_SET="false"
|
||||
AGENT_ID=""
|
||||
HOSTNAME_OVERRIDE=""
|
||||
STATE_DIR="/var/lib/pulse-agent"
|
||||
CURL_CA_BUNDLE=""
|
||||
KUBE_INCLUDE_ALL_PODS="false"
|
||||
KUBE_INCLUDE_ALL_DEPLOYMENTS="false"
|
||||
DISK_EXCLUDES=()
|
||||
DISK_INCLUDES=()
|
||||
RUNTIME_TOKEN_FILE=""
|
||||
AGENT_LOG_FILE="/var/lib/pulse-agent/logs/pulse-agent.log"
|
||||
` + extractInstallShellFunction(t, "build_exec_arg_items") + `
|
||||
` + extractInstallShellFunction(t, "join_exec_arg_items") + `
|
||||
` + extractInstallShellFunction(t, "build_exec_args") + `
|
||||
build_exec_args
|
||||
printf 'EXEC_ARGS=%s\n' "$EXEC_ARGS"
|
||||
`
|
||||
out, err := exec.Command("bash", "-c", script).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("bash: %v\n%s", err, out)
|
||||
}
|
||||
got := string(out)
|
||||
if !strings.Contains(got, "--log-file /var/lib/pulse-agent/logs/pulse-agent.log") {
|
||||
t.Fatalf("FreeBSD service args missing rotating --log-file:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallSHUsesCanonicalCompletionHelper(t *testing.T) {
|
||||
content, err := os.ReadFile(repoFile("scripts", "install.sh"))
|
||||
if err != nil {
|
||||
@@ -2676,7 +2753,7 @@ func TestInstallSHUsesCanonicalCompletionHelper(t *testing.T) {
|
||||
`complete_installation_flow "$UNRAID_STORAGE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent is running." "tail -f ${AGENT_LOG_FILE}"`,
|
||||
`complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent is running." "tail -f ${AGENT_LOG_FILE}"`,
|
||||
`complete_installation_flow "$TRUENAS_STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent is running." ""`,
|
||||
`complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "tail -f /var/log/messages"`,
|
||||
`complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "tail -f ${AGENT_LOG_FILE}"`,
|
||||
`complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "journalctl -u ${AGENT_NAME} --no-pager -n 20"`,
|
||||
`complete_installation_flow "$STATE_DIR" "Installation complete! Agent is running." "Upgrade complete! Agent restarted with new configuration." "tail -f /var/log/${AGENT_NAME}.log"`,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user