mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-19 10:33:29 +00:00
Explain stopped agent commands without credential or state churn
Distinguish private prompt preparation, preflight and read-only profile inspection from installation and destructive removal. Keep existing unavailable-agent and automatic-update investigations separate, and route FAQ and troubleshooting readers to the existing private-file and recovery guides. Contract-Neutral: Help copy and rendered-document regression checks only; installer, credential, lifecycle and monitoring contracts are unchanged. Change-source: pulse-maintainer
This commit is contained in:
parent
e241788c38
commit
ed2107bee0
7 changed files with 218 additions and 6 deletions
17
docs/FAQ.md
17
docs/FAQ.md
|
|
@ -15,11 +15,26 @@ See [INSTALL.md](INSTALL.md) for all options (Docker Compose, Kubernetes, system
|
|||
Go to **Settings → Infrastructure → Install on a host** for systems that should
|
||||
run the unified agent directly.
|
||||
|
||||
- **Recommended (agent setup)**: copy the generated install command and run it on the target host.
|
||||
- **Agent setup**: use the generated command on the target host, entering the
|
||||
token only at its private prompt, never in the command itself. Alternatively,
|
||||
follow the [private-file preparation](UNIFIED_AGENT.md#private-file-installation-linux-macos-and-nas).
|
||||
- **Manual/API-backed platforms**: use **Settings → Infrastructure** (**Add infrastructure**) for systems such as Proxmox, PBS, PMG, or TrueNAS that connect over an API instead of running the agent locally.
|
||||
|
||||
If you want Pulse to find servers automatically, open **Settings → Infrastructure**, select **Configure discovery** (it reads **Settings** once discovery is on), turn on **Automatic scanning** in the Discovery settings dialog, and then review discovered servers in the same section.
|
||||
|
||||
### Why does the copied agent command say no installation was attempted?
|
||||
|
||||
That message describes a stopped preparation step, not the health of an agent
|
||||
already installed. If it follows `stty: command not found`, the private token
|
||||
prompt cannot prepare the terminal; having an interactive shell does not supply
|
||||
the missing tool. Do not remove the privacy check, put a token in the command,
|
||||
generate another token or uninstall the existing agent to get past it.
|
||||
|
||||
Use the [agent command failure guide](UNIFIED_AGENT.md#copied-agent-command-fails-before-installation)
|
||||
to distinguish the prompt, preflight and removal paths. Keep the original error
|
||||
and existing state; a failed new command does not explain an earlier outage or
|
||||
automatic-update failure.
|
||||
|
||||
### How do I change the port?
|
||||
|
||||
Distinguish Pulse's web listener from a container's published host port.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ establish safe recovery.
|
|||
[agent authentication and reporting evidence](UNIFIED_AGENT.md#agent-lookup-returns-http-401-or-403)
|
||||
before replacing a token or reinstalling. Installer success is not an accepted
|
||||
report.
|
||||
- **Copied agent install or removal command failed:** distinguish its
|
||||
[preparation, private prompt and lifecycle action](UNIFIED_AGENT.md#copied-agent-command-fails-before-installation).
|
||||
A stopped new command does not diagnose the existing agent. Keep state and
|
||||
credentials; do not repeat removal or installation to obtain an error.
|
||||
- **Guest readings are missing or disagree:** distinguish
|
||||
[current, retained and unavailable disks](VM_DISK_MONITORING.md#current-retained-and-unavailable-disk-readings)
|
||||
from [guest memory pressure](TROUBLESHOOTING.md#guest-memory-is-high-but-available-memory-is-plentiful).
|
||||
|
|
|
|||
|
|
@ -1040,6 +1040,49 @@ Set `--health-addr=""` or `PULSE_HEALTH_ADDR=off` to disable the health/metrics
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Copied agent command fails before installation
|
||||
|
||||
The copied Unix command prepares a download and, for installation, runs a
|
||||
`--preflight-only` check before entering a private token prompt. Passing
|
||||
preflight is **not installation** or accepted reporting. Read the original
|
||||
error to identify which step stopped; do not run the command again to find out.
|
||||
|
||||
- **`stty: command not found`, followed by a terminal-required message:** the
|
||||
command's environment cannot run the tool used to prepare the private prompt.
|
||||
A real terminal can still produce this error. It does not establish that the
|
||||
token is invalid, that the target platform cannot run an agent, or that an
|
||||
existing agent was removed.
|
||||
- **A terminal-required or interrupted-input message without that error:**
|
||||
token entry did not complete safely. Keep it separate from an installer's
|
||||
later result; do not assume a missing tool from the terminal message alone.
|
||||
- **`Safe-profile migration is unsupported on this platform`:** this concerns
|
||||
the Linux safe-profile migration path. `--safe-profile-inspect` is a
|
||||
standalone **read-only** action, not removal; `--uninstall` is a separate,
|
||||
destructive action. The inspection can produce this error on an unsupported
|
||||
platform such as QNAP. The error alone does not prove that removal ran. Do
|
||||
not combine those flags or request a broader-privilege fallback.
|
||||
|
||||
**Stop rather than bypass the private prompt.** Do not enable token echo, put a
|
||||
secret in command arguments or an environment assignment, weaken TLS, generate
|
||||
a replacement token or delete installed identity, connection files or logs.
|
||||
For a planned first installation where the prompt is unavailable, the
|
||||
[private-file installation](#private-file-installation-linux-macos-and-nas)
|
||||
uses a private editor and `--token-file`, with the same download trust and
|
||||
collector choices. It is not an instruction to repeat a failed recovery attempt.
|
||||
|
||||
For an existing unavailable or outdated agent, retain that original failure
|
||||
separately and use [reporting checks](#agent-lookup-returns-http-401-or-403) or
|
||||
[update guidance](#auto-update). If removal was intentional, read its
|
||||
[state-preservation and result checks](#uninstall) before another action. A
|
||||
failed new command does not establish the cause of the earlier outage or
|
||||
automatic-update failure.
|
||||
|
||||
When reporting a command failure, share only the original failure stage and
|
||||
manually redacted error. If the action is consequential, name only the flag
|
||||
already used (`--safe-profile-inspect` or `--uninstall`), or say **unknown**.
|
||||
Do not post the full copied command, a token, its file contents or service
|
||||
configuration, and do not repeat installation or removal to complete a report.
|
||||
|
||||
### Collect agent logs safely
|
||||
|
||||
Prefer existing observations from the original failure. On a **Linux systemd
|
||||
|
|
|
|||
|
|
@ -15,11 +15,26 @@ See [INSTALL.md](INSTALL.md) for all options (Docker Compose, Kubernetes, system
|
|||
Go to **Settings → Infrastructure → Install on a host** for systems that should
|
||||
run the unified agent directly.
|
||||
|
||||
- **Recommended (agent setup)**: copy the generated install command and run it on the target host.
|
||||
- **Agent setup**: use the generated command on the target host, entering the
|
||||
token only at its private prompt, never in the command itself. Alternatively,
|
||||
follow the [private-file preparation](UNIFIED_AGENT.md#private-file-installation-linux-macos-and-nas).
|
||||
- **Manual/API-backed platforms**: use **Settings → Infrastructure** (**Add infrastructure**) for systems such as Proxmox, PBS, PMG, or TrueNAS that connect over an API instead of running the agent locally.
|
||||
|
||||
If you want Pulse to find servers automatically, open **Settings → Infrastructure**, select **Configure discovery** (it reads **Settings** once discovery is on), turn on **Automatic scanning** in the Discovery settings dialog, and then review discovered servers in the same section.
|
||||
|
||||
### Why does the copied agent command say no installation was attempted?
|
||||
|
||||
That message describes a stopped preparation step, not the health of an agent
|
||||
already installed. If it follows `stty: command not found`, the private token
|
||||
prompt cannot prepare the terminal; having an interactive shell does not supply
|
||||
the missing tool. Do not remove the privacy check, put a token in the command,
|
||||
generate another token or uninstall the existing agent to get past it.
|
||||
|
||||
Use the [agent command failure guide](UNIFIED_AGENT.md#copied-agent-command-fails-before-installation)
|
||||
to distinguish the prompt, preflight and removal paths. Keep the original error
|
||||
and existing state; a failed new command does not explain an earlier outage or
|
||||
automatic-update failure.
|
||||
|
||||
### How do I change the port?
|
||||
|
||||
Distinguish Pulse's web listener from a container's published host port.
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ establish safe recovery.
|
|||
[agent authentication and reporting evidence](UNIFIED_AGENT.md#agent-lookup-returns-http-401-or-403)
|
||||
before replacing a token or reinstalling. Installer success is not an accepted
|
||||
report.
|
||||
- **Copied agent install or removal command failed:** distinguish its
|
||||
[preparation, private prompt and lifecycle action](UNIFIED_AGENT.md#copied-agent-command-fails-before-installation).
|
||||
A stopped new command does not diagnose the existing agent. Keep state and
|
||||
credentials; do not repeat removal or installation to obtain an error.
|
||||
- **Guest readings are missing or disagree:** distinguish
|
||||
[current, retained and unavailable disks](VM_DISK_MONITORING.md#current-retained-and-unavailable-disk-readings)
|
||||
from [guest memory pressure](TROUBLESHOOTING.md#guest-memory-is-high-but-available-memory-is-plentiful).
|
||||
|
|
|
|||
|
|
@ -1040,6 +1040,49 @@ Set `--health-addr=""` or `PULSE_HEALTH_ADDR=off` to disable the health/metrics
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Copied agent command fails before installation
|
||||
|
||||
The copied Unix command prepares a download and, for installation, runs a
|
||||
`--preflight-only` check before entering a private token prompt. Passing
|
||||
preflight is **not installation** or accepted reporting. Read the original
|
||||
error to identify which step stopped; do not run the command again to find out.
|
||||
|
||||
- **`stty: command not found`, followed by a terminal-required message:** the
|
||||
command's environment cannot run the tool used to prepare the private prompt.
|
||||
A real terminal can still produce this error. It does not establish that the
|
||||
token is invalid, that the target platform cannot run an agent, or that an
|
||||
existing agent was removed.
|
||||
- **A terminal-required or interrupted-input message without that error:**
|
||||
token entry did not complete safely. Keep it separate from an installer's
|
||||
later result; do not assume a missing tool from the terminal message alone.
|
||||
- **`Safe-profile migration is unsupported on this platform`:** this concerns
|
||||
the Linux safe-profile migration path. `--safe-profile-inspect` is a
|
||||
standalone **read-only** action, not removal; `--uninstall` is a separate,
|
||||
destructive action. The inspection can produce this error on an unsupported
|
||||
platform such as QNAP. The error alone does not prove that removal ran. Do
|
||||
not combine those flags or request a broader-privilege fallback.
|
||||
|
||||
**Stop rather than bypass the private prompt.** Do not enable token echo, put a
|
||||
secret in command arguments or an environment assignment, weaken TLS, generate
|
||||
a replacement token or delete installed identity, connection files or logs.
|
||||
For a planned first installation where the prompt is unavailable, the
|
||||
[private-file installation](#private-file-installation-linux-macos-and-nas)
|
||||
uses a private editor and `--token-file`, with the same download trust and
|
||||
collector choices. It is not an instruction to repeat a failed recovery attempt.
|
||||
|
||||
For an existing unavailable or outdated agent, retain that original failure
|
||||
separately and use [reporting checks](#agent-lookup-returns-http-401-or-403) or
|
||||
[update guidance](#auto-update). If removal was intentional, read its
|
||||
[state-preservation and result checks](#uninstall) before another action. A
|
||||
failed new command does not establish the cause of the earlier outage or
|
||||
automatic-update failure.
|
||||
|
||||
When reporting a command failure, share only the original failure stage and
|
||||
manually redacted error. If the action is consequential, name only the flag
|
||||
already used (`--safe-profile-inspect` or `--uninstall`), or say **unknown**.
|
||||
Do not post the full copied command, a token, its file contents or service
|
||||
configuration, and do not repeat installation or removal to complete a report.
|
||||
|
||||
### Collect agent logs safely
|
||||
|
||||
Prefer existing observations from the original failure. On a **Linux systemd
|
||||
|
|
|
|||
|
|
@ -7,13 +7,14 @@ import { renderDocMarkdown } from '../docMarkdown';
|
|||
const frontendRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
|
||||
const source = readFileSync(path.join(frontendRoot, '../docs/UNIFIED_AGENT.md'), 'utf8');
|
||||
|
||||
function setupSection() {
|
||||
function docSection(markdown: string, docPath: string, id: string) {
|
||||
const article = document.createElement('article');
|
||||
article.innerHTML = renderDocMarkdown(source, 'UNIFIED_AGENT');
|
||||
const heading = article.querySelector('#private-file-installation-linux-macos-and-nas')!;
|
||||
article.innerHTML = renderDocMarkdown(markdown, docPath);
|
||||
const heading = article.querySelector(`#${id}`);
|
||||
expect(heading, `${docPath}#${id} must be a real rendered destination`).not.toBeNull();
|
||||
const section = document.createElement('section');
|
||||
for (
|
||||
let node = heading.nextElementSibling;
|
||||
let node = heading!.nextElementSibling;
|
||||
node && !/^H[23]$/.test(node.tagName);
|
||||
node = node.nextElementSibling
|
||||
) {
|
||||
|
|
@ -22,6 +23,10 @@ function setupSection() {
|
|||
return section;
|
||||
}
|
||||
|
||||
function setupSection() {
|
||||
return docSection(source, 'UNIFIED_AGENT', 'private-file-installation-linux-macos-and-nas');
|
||||
}
|
||||
|
||||
describe('Unified Agent private-file setup help', () => {
|
||||
it('renders preparation and download as self-contained fences before installation', () => {
|
||||
const section = setupSection();
|
||||
|
|
@ -61,3 +66,86 @@ describe('Unified Agent private-file setup help', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Stopped agent-command help', () => {
|
||||
const failureId = 'copied-agent-command-fails-before-installation';
|
||||
const faq = readFileSync(path.join(frontendRoot, '../docs/FAQ.md'), 'utf8');
|
||||
const troubleshooting = readFileSync(
|
||||
path.join(frontendRoot, '../docs/TROUBLESHOOTING.md'),
|
||||
'utf8',
|
||||
);
|
||||
const normalizedText = (section: HTMLElement) => section.textContent!.replace(/\s+/g, ' ');
|
||||
|
||||
it('makes the same failure destination reachable from setup and troubleshooting', () => {
|
||||
for (const [name, markdown] of [
|
||||
['FAQ', faq],
|
||||
['TROUBLESHOOTING', troubleshooting],
|
||||
]) {
|
||||
const article = document.createElement('article');
|
||||
article.innerHTML = renderDocMarkdown(markdown, name);
|
||||
expect(
|
||||
article.querySelector(`a[data-doc-link][href="/docs/UNIFIED_AGENT#${failureId}"]`),
|
||||
).not.toBeNull();
|
||||
expect(readFileSync(path.join(frontendRoot, `public/docs/${name}.md`), 'utf8')).toBe(
|
||||
markdown,
|
||||
);
|
||||
}
|
||||
const setup = docSection(faq, 'FAQ', 'how-do-i-add-a-node');
|
||||
expect(
|
||||
setup.querySelector(
|
||||
'a[href="/docs/UNIFIED_AGENT#private-file-installation-linux-macos-and-nas"]',
|
||||
),
|
||||
).not.toBeNull();
|
||||
expect(normalizedText(setup)).toContain('token only at its private prompt');
|
||||
});
|
||||
|
||||
it('distinguishes stopped prompt, read-only inspection and destructive removal', () => {
|
||||
const section = docSection(source, 'UNIFIED_AGENT', failureId);
|
||||
const text = normalizedText(section);
|
||||
expect(section.querySelectorAll(':scope > ul > li')).toHaveLength(3);
|
||||
for (const fact of [
|
||||
'Passing preflight is not installation',
|
||||
'A real terminal can still produce this error',
|
||||
'do not assume a missing tool from the terminal message alone',
|
||||
'standalone read-only action, not removal',
|
||||
'The error alone does not prove that removal ran',
|
||||
'failed new command does not establish the cause of the earlier outage',
|
||||
]) {
|
||||
expect(text).toContain(fact);
|
||||
}
|
||||
const producer = readFileSync(
|
||||
path.join(frontendRoot, 'src/utils/agentInstallCommand.ts'),
|
||||
'utf8',
|
||||
);
|
||||
expect(producer).toContain('--preflight-only');
|
||||
expect(producer).toContain('--token-file "$token_file"');
|
||||
const installer = readFileSync(path.join(frontendRoot, '../scripts/install.sh'), 'utf8');
|
||||
expect(installer).toContain('--safe-profile-inspect is a standalone read-only action');
|
||||
expect(installer).toContain('Safe-profile migration is unsupported on this platform');
|
||||
});
|
||||
|
||||
it('links to existing private preparation and recovery without another executable recipe', () => {
|
||||
const section = docSection(source, 'UNIFIED_AGENT', failureId);
|
||||
const article = document.createElement('article');
|
||||
article.innerHTML = renderDocMarkdown(source, 'UNIFIED_AGENT');
|
||||
for (const id of [
|
||||
'private-file-installation-linux-macos-and-nas',
|
||||
'agent-lookup-returns-http-401-or-403',
|
||||
'auto-update',
|
||||
'uninstall',
|
||||
]) {
|
||||
expect(section.querySelector(`a[href="#${id}"]`)).not.toBeNull();
|
||||
expect(article.querySelector(`#${id}`)).not.toBeNull();
|
||||
}
|
||||
expect(section.querySelector('pre')).toBeNull();
|
||||
for (const boundary of [
|
||||
'Stop rather than bypass the private prompt',
|
||||
'not an instruction to repeat a failed recovery attempt',
|
||||
'name only the flag already used',
|
||||
'Do not post the full copied command',
|
||||
'do not repeat installation or removal to complete a report',
|
||||
]) {
|
||||
expect(normalizedText(section)).toContain(boundary);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue