pixop-kvm-pulse

pixop-kvm-pulse

Guest CLI for KVM Pulse credential activation: enrolls the appliance with Pixop Pulse over HTTPS, writes Basic Auth credentials to /etc/pixop-live/pulse.env, and records non-secret metadata under /var/lib/pixop-kvm-pulse/. It does not print license JWTs, Pulse passwords, or private keys.

Installed path: /opt/pixop/bin/pixop-kvm-pulse. KVM QCOW2 images ship with PIXOP_MARKETPLACE_MODE=off so AWS Marketplace activation is skipped; Pulse credentials are provisioned through this tool instead.

For the full KVM licensing workflow (host install, first boot, renewal), see KVM license and Pulse activation. Host-side SSH wrapper: pixop-install license activate.

Usage

pixop-kvm-pulse {activate|repair|retry|status|show-identity} [--json]
pixop-kvm-pulse -h|--help
CommandMutates state?Purpose
activateYesContact Pulse, install or refresh pulse.env, update state.json
repairYesRe-fetch credentials from Pulse and rewrite pulse.env (same HTTPS activate call)
retryYes when activation runsTimer/operator retry after deferred activation; may no-op
statusMay migrate legacy identity paths under /var/lib/pixop-live/ into /var/lib/pixop-kvm-pulse/; no Pulse requestLocal file + container apply hints (no secrets)
show-identityMay initialize/repair local identity; no Pulse requestPublic appliance id and Ed25519 public key for Pixop support / rebind (private key stays on disk only)

--json prints a single JSON object (success or errorCode / message on failure). Human output never includes credentials.

Privileges

If not root, the script re-executes via sudo with its real path (same pattern as other guest tools). Set PIXOP_KVM_PULSE_NOSUDO=1 only in tests. Operators normally run pixop-kvm-pulse without typing sudo.

Paths and permissions

PathRoleTypical mode
/etc/pixop-live/license.jwtCustomer license JWT (bind-mounted into pixop-live)root-readable
/etc/pixop-live/pulse.envPulse Basic Auth (PIXOP_LIVE_PULSE_USER / PIXOP_LIVE_PULSE_PASSWORD)0600 root:root
/var/lib/pixop-kvm-pulse/Appliance identity + activation metadata (not Docker-mounted)0700 root:root
/var/lib/pixop-kvm-pulse/appliance-keyEd25519 private key0600
/var/lib/pixop-kvm-pulse/appliance-idDerived appliance id0600
/var/lib/pixop-kvm-pulse/state.jsonNon-secret activation metadata0640
/run/pixop-live/kvm-pulse.lockSingle-writer lock during activate/repairruntime

Older guests may still hold identity under /var/lib/pixop-live/; the first command moves those files into /var/lib/pixop-kvm-pulse/ when the new directory is empty (enrollment preserved).

Back up /var/lib/pixop-kvm-pulse/ with the VM. Cloning the disk copies identity. Lost keys after enrollment require Pixop support rebind (show-identity output)—do not silently regenerate identity.

License and Pulse configuration

  • The license file must be a compact JWS at /etc/pixop-live/license.jwt.
  • The JWT must carry the signed claim exactly pixop.allowed_deployments: ["kvm"] (Pulse rejects mixed entitlements, case variants, missing or extra array entries). AWS Marketplace license tokens are rejected for KVM activation even when instance limits are high.
  • Pulse base URL must be HTTPS (default https://live-pulse.pixop.com). Overrides: PIXOP_KVM_PULSE_BASE_URL or PIXOP_LIVE_PULSE_URL. Insecure HTTP is test-only on loopback with PIXOP_KVM_PULSE_ALLOW_INSECURE_HTTP.
  • Activation uses POST …/v1/kvm/activate with protocol version 2 (signed requestProof on every request). Customers do not call admin or revoke APIs directly.

Command behavior

activate

  1. Read license JWT and appliance identity.
  2. Call Pulse activate (idempotent for the same license + appliance).
  3. Atomically write pulse.env and merge state.json.

action in JSON:

ValueMeaning
activatedFirst successful enrollment on this appliance
refreshedSame deploymentId as before—credentials rewritten
reinstalledNew deploymentId vs prior local state

Repeat activate with the same license and appliance contacts Pulse every time and reinstalls credentials on disk. It does not restart pixop-live.

Retryable Pulse outages set pendingActivation in state.json and exit 1; first-boot init may enable pixop-kvm-pulse-retry.timer (see KVM license guide).

repair

Same Pulse activate call as activate, always intended to rewrite pulse.env when Pulse still authorizes the deployment. Use after credential rotation or a corrupted pulse.env when the license and appliance binding are still valid.

retry

Used by pixop-kvm-pulse-retry.timer and operators after deferred activation:

  • If activation is no longer pending and deploymentId exists → action: noop, exit 0.
  • If no license file → action: skipped-no-license, exit 1.
  • On retryable Pulse errors → action: pending, exit 1.
  • On success → same outcomes as activate.

status

Reads local state.json and compares on-disk pulse.env to the running pixop-live container environment (via Docker inspect). It does not validate current Pulse authorization, server-side revocation, or JWT expiry. Those conditions are revealed by the next activate / repair request, which may fail (for example errorCode pulse_rejected). For JWT expiry claims on disk, use pixop-license decode—not status.

Common non-secret JSON fields:

FieldMeaning
pendingActivationLast activate failed with a retryable error; timer may be active
deploymentIdPulse deployment id from last successful activation (may be stale if revoked server-side)
pulseEnvConfiguredpulse.env contains both user and password keys
credentialsPendingApplyOn-disk credentials differ from the running container (or inspect unavailable)
restartRequiredtrue when a running container must be restarted to load new credentials; false when not needed; null when inspect could not decide
containerPulseCredentialsmatching, mismatch, missing_in_container, not_running, service_inactive, absent_on_disk, inspect_unavailable, …
containerRunningWhether the pixop-live container is running (when inspect works)
applyCredentialsCommandsudo pixopctl restart (Pixop-only—not pixop-stack restart)
applyCredentialsNoteReminder to restart during a maintenance window

When restartRequired is true, apply credentials with a controlled maintenance restart—never automatic during broadcast:

pixopctl restart

pixop-live loads Pulse env vars only at container create time; updating pulse.env while the container runs does not change in-process credentials.

show-identity

Calls load_identity: on first use when not yet enrolled it may create appliance-key / appliance-id, recreate a missing appliance-id when the private key exists, and fix insecure modes as root. Output is applianceId and base64 publicKey only—the private key is never printed. Provide this output to Pixop support for replacement appliance rebind. After a prior successful enrollment, a missing private key is an error (restore backup or contact support)—identity is not silently regenerated.

Exit codes

CodeWhen
0Success; retry noop; status / show-identity
1KvmPulseError (missing license, Pulse rejection, config error, …); retry pending/skipped
2Unknown subcommand

With --json, failures still return exit 1 and print {"ok": false, "errorCode": "…", "message": "…"}.

Related


Did this page help you?