291 lines
12 KiB
PHP
291 lines
12 KiB
PHP
<?php
|
|
|
|
return [
|
|
'title' => 'Hosts',
|
|
'subtitle' => 'Proxmox hosts and capacity.',
|
|
'add' => 'Add host',
|
|
'empty' => 'No hosts yet. Add your first server.',
|
|
'no_matches' => 'No hosts match these filters.',
|
|
'search_placeholder' => 'Search by name or IP …',
|
|
'all_datacenters' => 'All datacenters',
|
|
'all_statuses' => 'All statuses',
|
|
'clear' => 'Clear',
|
|
'count' => ':shown of :total',
|
|
'col' => [
|
|
'host' => 'Host',
|
|
'datacenter' => 'DC',
|
|
'health' => 'Health',
|
|
'vpn' => 'VPN',
|
|
'instances' => 'Instances',
|
|
'capacity' => 'Capacity',
|
|
'status' => 'Status',
|
|
],
|
|
'health' => [
|
|
'online' => 'Online',
|
|
'stale' => 'Stale',
|
|
'offline' => 'Offline',
|
|
],
|
|
'vpn' => [
|
|
'not_configured' => 'Not configured',
|
|
'connected' => 'Connected',
|
|
'silent' => 'Silent',
|
|
'silent_since' => 'Silent · :time',
|
|
'unknown' => 'Unknown',
|
|
],
|
|
|
|
'create_title' => 'Add host',
|
|
'create_sub' => 'Onboard a fresh server (Debian, root only) as a Proxmox host automatically.',
|
|
'back' => 'Back to hosts',
|
|
'cancel' => 'Cancel',
|
|
'save' => 'Start onboarding',
|
|
|
|
'field' => [
|
|
'name' => 'Name',
|
|
'name_hint' => 'Assigned by CluPilot in sequence. Reachable at :fqdn',
|
|
'datacenter' => 'Datacenter',
|
|
'public_ip' => 'Public IP',
|
|
'root_password' => 'Root password (one-time)',
|
|
'root_password_hint' => 'Used for the first login only. Discarded after the SSH key is deployed — never stored permanently.',
|
|
],
|
|
|
|
'datacenter' => [
|
|
'fsn' => 'Falkenstein',
|
|
'hel' => 'Helsinki',
|
|
],
|
|
|
|
'capacity' => 'Capacity',
|
|
'free' => 'free',
|
|
'unknown' => '—',
|
|
// Short form for rows (host list, capacity page) — same idea as
|
|
// 'detail.reserved_for', just small enough for a table cell.
|
|
'reserved_badge' => 'reserved for :name',
|
|
'meta' => [
|
|
'cores' => 'Cores',
|
|
'ram' => 'RAM',
|
|
'version' => 'Version',
|
|
'wg_ip' => 'Mgmt IP',
|
|
'datacenter' => 'DC',
|
|
],
|
|
|
|
'status' => [
|
|
'pending' => 'Pending',
|
|
'onboarding' => 'Onboarding',
|
|
'active' => 'Active',
|
|
'error' => 'Error',
|
|
'disabled' => 'Disabled',
|
|
],
|
|
|
|
'detail' => [
|
|
'health' => 'Health',
|
|
'load' => 'Load',
|
|
'load_hint' => 'last hour',
|
|
'no_load' => 'No measurements — the host is not answering right now.',
|
|
'no_load_short' => 'no measurements',
|
|
'cpu' => 'CPU',
|
|
'ram' => 'RAM',
|
|
'cpu_load' => 'CPU usage',
|
|
'ram_load' => 'RAM usage',
|
|
'net_in' => 'Inbound',
|
|
'net_out' => 'Outbound',
|
|
'public_ip' => 'Public IP',
|
|
'spec' => 'Specification',
|
|
'build' => 'Build',
|
|
'onboarding_done' => 'Onboarding complete',
|
|
'storage' => 'Storage',
|
|
'compute' => 'Compute',
|
|
'node' => 'Node',
|
|
'fqdn' => 'Address',
|
|
'fqdn_hint' => 'Proxmox web UI — answers from inside the WireGuard tunnel only.',
|
|
'instances' => 'Instances',
|
|
'hosted' => 'Hosted instances',
|
|
'no_instances' => 'No instances running on this host yet.',
|
|
'last_seen' => 'Last seen :time',
|
|
'never_seen' => 'Never seen',
|
|
'committed' => ':gb GB committed',
|
|
'reserve' => ':pct % reserve',
|
|
'reserve_label' => 'Reserve',
|
|
'reserve_hint' => 'Share of storage kept free.',
|
|
'reserve_save' => 'Save',
|
|
'reserve_saved' => 'Reserve updated.',
|
|
'drain' => 'Maintenance',
|
|
'activate' => 'Activate',
|
|
|
|
'reserved_general' => 'General stock.',
|
|
'reserved_for' => 'Reserved for :name.',
|
|
'reserved_pick' => 'Pick a customer …',
|
|
'reserved_save' => 'Reserve',
|
|
'reserved_saved' => 'Reserved for :name.',
|
|
'reserved_release' => 'Release',
|
|
'reserved_released' => 'Reservation released.',
|
|
],
|
|
|
|
'istatus' => [
|
|
'active' => 'Active',
|
|
'provisioning' => 'Provisioning',
|
|
'failed' => 'Failed',
|
|
'suspended' => 'Suspended',
|
|
'cancellation_scheduled' => 'Cancelling',
|
|
],
|
|
|
|
'progress' => 'Progress',
|
|
'events' => 'Events',
|
|
'no_run' => 'No provisioning run for this host.',
|
|
'attempt' => 'Attempt',
|
|
'retry' => 'Retry',
|
|
'error_title' => 'Onboarding failed',
|
|
|
|
'terminal' => [
|
|
'open' => 'Terminal',
|
|
'hint' => 'Opens a separate window with a root session on this host.',
|
|
|
|
// The stage — the panel that sits on top of the terminal. Same panel
|
|
// while connecting, when the session ends and when it breaks; only the
|
|
// words change. The lower four are only ever needed by the browser and
|
|
// travel to it as JSON.
|
|
'stage' => [
|
|
'connecting' => [
|
|
'title' => 'Connecting to :host',
|
|
'note' => 'Redeeming the one-time ticket and opening the session.',
|
|
],
|
|
'ended' => [
|
|
'title' => 'Session ended',
|
|
'note' => 'The connection to :host was closed. Another attempt opens a fresh session.',
|
|
],
|
|
'lost' => [
|
|
'title' => 'No connection',
|
|
'note' => 'No session came up on :host. Is the terminal service running, and is the tunnel up?',
|
|
],
|
|
'rejected' => [
|
|
'title' => 'Ticket no longer valid',
|
|
'note' => 'A ticket lasts thirty seconds and works exactly once. This one had expired or was already redeemed — another attempt issues a fresh one.',
|
|
],
|
|
// Deliberately non-committal: the bridge sends 4502 for EVERY failed
|
|
// sign-in — machine silent, fingerprint mismatch, key refused,
|
|
// timeout. "Not answering" would be plain wrong in the likeliest
|
|
// case: after a host is rebuilt it answers and refuses.
|
|
'unreachable' => [
|
|
'title' => 'No session on :host',
|
|
'note' => 'The bridge never reached a command line: the machine is not answering, its fingerprint differs from the one on file, or it refused the fleet key — the last is the likeliest once a host has been rebuilt. Which of them is in the terminal service log; this window is deliberately not told.',
|
|
],
|
|
'retry' => 'Reconnect',
|
|
],
|
|
|
|
// Reasons the server already knows. They appear straight away instead
|
|
// of a window that opens and waits for a connection that cannot happen.
|
|
'problem' => [
|
|
'no_key' => [
|
|
'title' => 'No SSH key on file',
|
|
'note' => 'Without the fleet key nobody can sign in to a host. It is stored under credentials.',
|
|
],
|
|
'not_ready' => [
|
|
'title' => 'This host is not ready yet',
|
|
'note' => 'The tunnel address or the verified fingerprint is missing. Both appear during takeover — until that is through, no secure session can exist.',
|
|
],
|
|
'unknown' => [
|
|
'title' => 'The terminal cannot be opened right now',
|
|
'note' => 'Something went wrong issuing the ticket. The incident is in the log; another attempt is worth a try.',
|
|
],
|
|
],
|
|
],
|
|
|
|
'remove' => 'Remove host',
|
|
'remove_title' => 'Remove host?',
|
|
'remove_body' => 'Removes only the CluPilot record for :name. The physical server is NOT deleted or wiped.',
|
|
'remove_confirm' => 'Remove',
|
|
|
|
'outcome' => [
|
|
'advanced' => 'Advanced',
|
|
'retry' => 'Retry',
|
|
'failed' => 'Failed',
|
|
'info' => 'Info',
|
|
],
|
|
|
|
'step' => [
|
|
'validate_host_input' => 'Validate input',
|
|
'establish_ssh_trust' => 'Establish SSH trust',
|
|
'prepare_base_system' => 'Prepare base system',
|
|
'configure_wireguard' => 'Configure WireGuard',
|
|
'install_proxmox_ve' => 'Install Proxmox VE',
|
|
'reboot_into_pve_kernel' => 'Reboot into Proxmox kernel',
|
|
'ensure_network_bridge' => 'Build the vmbr0 network bridge',
|
|
'configure_proxmox' => 'Configure Proxmox',
|
|
'create_automation_token' => 'Create automation token',
|
|
'verify_proxmox_api' => 'Verify Proxmox API',
|
|
'build_vm_template' => 'Build VM template',
|
|
'verify_vm_template' => 'Verify VM template',
|
|
'register_host_dns' => 'Register internal DNS name',
|
|
'register_capacity' => 'Register capacity',
|
|
'secure_host_firewall' => 'Secure host firewall',
|
|
'complete_host_onboarding' => 'Complete onboarding',
|
|
],
|
|
'release_reservation' => [
|
|
'title' => 'Release the reservation?',
|
|
'body' => ':host becomes general stock again — previously reserved for :customer. The next new customer could land on it.',
|
|
'confirm' => 'Release',
|
|
],
|
|
|
|
'reissue' => [
|
|
'action' => 'Re-issue the command line',
|
|
'title' => 'Issue a new command line?',
|
|
'body' => 'A new one-time code and a new key pair are created for :name. The line is then shown once.',
|
|
'invalidates' => 'Any code handed out so far becomes worthless. If a takeover is running on the machine right now, it loses its credentials mid-run — and then it is reinstalled rather than repaired.',
|
|
'confirm' => 'Re-issue',
|
|
'done' => 'Done',
|
|
'not_eligible' => 'This host is already running. A new command line would reinstall the machine — for that, remove the host and create it again.',
|
|
],
|
|
|
|
'takeover' => [
|
|
'eyebrow' => 'Host takeover',
|
|
'how_title' => 'How a host takeover works',
|
|
'how_sub' => 'Three steps. Only the first happens at the provider.',
|
|
|
|
'rail_title' => 'Procedure',
|
|
'badge_before' => 'first',
|
|
|
|
// There were SIX steps here, two of them named "rescue system": boot the
|
|
// rescue system, copy the command line, paste it there. That described
|
|
// the bootstrap route. Saving actually starts the provisioning pipeline
|
|
// — EstablishSshTrust simply signs in with the root password on a
|
|
// RUNNING Debian machine, and Proxmox arrives as a package after that.
|
|
// The page described one route and took the other.
|
|
's1_label' => 'Order server',
|
|
's2_label' => 'Add host',
|
|
's3_label' => 'Watch',
|
|
|
|
's1_title' => 'Order the server',
|
|
's1_body' => 'Dedicated, not cloud, with Debian 13 preinstalled and root access. Without /dev/kvm no guest will start later on.',
|
|
|
|
's2_title' => 'Add the host',
|
|
's2_body' => 'Datacenter, public IP, root password. The password is only for the first sign-in and is discarded once the key is in place.',
|
|
|
|
's3_title' => 'Watch',
|
|
's3_body' => 'CluPilot signs in by itself, installs Proxmox, reboots into its kernel and builds the bridge, the tunnel and the template. Progress appears on the host page.',
|
|
|
|
'requirements_title' => 'At the provider, first',
|
|
'requirements_sub' => 'This has to be in place before you save below — CluPilot signs in to the machine straight after.',
|
|
|
|
'form_title' => 'The host',
|
|
'form_sub' => 'Three fields. The server works out the rest itself.',
|
|
|
|
'command_title' => 'The command line',
|
|
'command_sub' => 'Paste into the rescue system as root. It carries everything the server needs before the tunnel.',
|
|
|
|
'after_title' => 'Then',
|
|
|
|
'missing_title' => 'The tunnel is not set up yet',
|
|
'missing_body' => 'Missing: :settings. Without these the line runs and ends in a tunnel that never handshakes — and that only shows up on the machine.',
|
|
|
|
'title' => ':name is created',
|
|
'subtitle' => 'Three steps left, then the server does the rest on its own.',
|
|
|
|
'once_title' => 'This line exists only now',
|
|
'once_body' => 'The database holds only the hash of the code, and not the WireGuard key at all. Reloading does not bring it back — it mints a new code, and the old one becomes worthless.',
|
|
|
|
'watch' => 'Watch progress',
|
|
'copy' => 'Copy',
|
|
'copied' => 'Copied',
|
|
|
|
'footnote' => 'The code is valid for 24 hours and can be redeemed once. If the takeover stops, the machine is reinstalled rather than repaired — see docs/runbooks/host-bootstrap.md.',
|
|
],
|
|
];
|