From 6951cde8170be518fd63a53d8284d517305c958c Mon Sep 17 00:00:00 2001 From: Omar Refai Date: Mon, 29 Jun 2026 20:31:39 -0700 Subject: [PATCH 1/2] docs: explain phoneHomeEnabled flag and the phone-home flow The phoneHomeEnabled flag was documented as a one-liner ("Enable phone-home on first boot") with no explanation of what it does, what (if anything) NICo injects, or how the phone-home callback works. Document the mechanism, sourced from the code: - It gates instance readiness: when enabled, the instance is held in a provisioning state and not reported Ready until the booted OS contacts NICo's metadata service (the carbide tenant-state gate in crates/rpc/src/model/instance/status/tenant.rs; proto note on InstanceOperatingSystemConfig.phone_home_enabled). - NICo injects nothing: user-data is served verbatim (crates/agent/src/instance_metadata_endpoint.rs). The OS must include a cloud-init phone_home module posting to the link-local metadata endpoint http://169.254.169.254:7777/latest/meta-data/phone_home, which records the contact timestamp and releases the gate. - Add usage guidance (delay readiness until cloud-init applies SSH keys/passwords) and caveats (no module => never ready; custom-iPXE reboot re-arms the gate). Adds a Phone-home section to docs/configuration/tenant_management.md and links the operating-system create/update CLI reference pages to it. Fixes #2790 Signed-off-by: Omar Refai --- docs/configuration/tenant_management.md | 27 +++++++++++++++++++ .../operating-system-create.md | 8 +++++- .../operating-system-update.md | 8 +++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/docs/configuration/tenant_management.md b/docs/configuration/tenant_management.md index 02d7976c24..7af1613f67 100644 --- a/docs/configuration/tenant_management.md +++ b/docs/configuration/tenant_management.md @@ -589,6 +589,33 @@ nicocli instance status-history The instance detail response is rich -- it includes `interfaces[]` with assigned IP addresses and VPC prefix info, `ipxeScript` showing the live boot script, `serialConsoleUrl` for console access, full machine and SKU metadata, and any active `deprecations[]` warnings. The API uses inline `deprecations[]` arrays to flag fields scheduled for removal -- watch for these in your responses. +### Phone-home + +`phoneHomeEnabled` (`--phone-home-enabled`) controls whether NICo waits for the booted operating system to call back -- to "phone home" -- before it reports the instance as ready. It is a property of the operating-system definition (`operating-system create` / `operating-system update`) and can also be set per instance (`instance create` / `instance update`). + +**What it does.** When phone-home is enabled, NICo does not consider the instance fully provisioned until the booted OS contacts NICo's metadata service from inside the guest. The instance is held in a provisioning state -- the transition to `Ready` is gated -- until that callback arrives. When it is disabled, NICo reports the instance ready as soon as provisioning and config sync finish, without waiting for any signal from the OS. + +**What NICo injects: nothing.** Enabling the flag does *not* add anything to your `userData`. NICo serves your cloud-init user-data to the booting host verbatim. To make the host actually phone home, your user-data must include a cloud-init [`phone_home`](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#phone-home) module that POSTs to NICo's link-local metadata endpoint: + +```yaml +#cloud-config +# ... your first-boot setup (SSH keys, passwords, packages, ...) ... +phone_home: + url: http://169.254.169.254:7777/latest/meta-data/phone_home + post: all +``` + +cloud-init runs the `phone_home` module in its final stage, after the rest of your configuration has been applied, so the callback fires only once your setup has completed. When NICo receives the POST it records the contact and releases the readiness gate, allowing the instance to become `Ready`. + +**When to use it.** Enable phone-home when "ready" must mean "the guest has finished its own first-boot setup" -- for example, to delay readiness until cloud-init has applied SSH keys and passwords, so that automation watching for `Ready` does not connect before the host is fully configured. Leave it disabled when NICo finishing provisioning is a sufficient ready signal and you do not need a callback from inside the guest. + +**Notes and caveats.** + +- Phone-home only gates *status reporting*. It does not change how the host is provisioned or booted -- the reboot into the provisioned OS happens identically whether or not phone-home is enabled. +- If you enable phone-home but never include a `phone_home` module in your user-data, the instance stays in its provisioning state indefinitely and never reports ready. +- The metadata endpoint (`169.254.169.254:7777`) is reachable only from the provisioned host over its link-local metadata link; it is not a tenant-facing API. +- Rebooting the instance with a one-time custom iPXE override (`instance update --reboot-with-custom-ipxe=true`) re-arms the gate when phone-home is enabled: NICo clears the recorded contact, so the OS must phone home again before the instance is reported ready. + ### Batch Instance Creation For creating multiple identical instances at once, use `instance batch-create`. Unlike `create`, batch-create takes a single shared spec plus a count -- it provisions N instances with auto-generated names from the same instance type, tenant, and VPC. `nicocli instance batch-create --help` shows: diff --git a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md index 27aecdb38e..f1eb925e81 100644 --- a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md +++ b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md @@ -48,7 +48,13 @@ Whether this OS definition is active (default: true).\ Allow users to override OS parameters. **--phone-home-enabled** -Enable phone-home on first boot. +Hold the instance in a provisioning state until the booted OS calls back +("phones home") to NICo's metadata service, instead of reporting it ready as +soon as provisioning finishes. NICo does not inject anything into your +user-data -- the OS must include a cloud-init `phone_home` module to make the +callback. See +[Phone-home](../../../../configuration/tenant_management.md#phone-home) for +what it injects, the endpoint, and usage guidance. **--user-data** *\* Optional cloud-init / user-data script. diff --git a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md index 855db6a32e..be3369e94a 100644 --- a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md +++ b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md @@ -49,7 +49,13 @@ Set whether users can override OS parameters.\ - false **--phone-home-enabled** *\* -Set whether phone-home on first boot is enabled.\ +Set whether the instance is held in a provisioning state until the booted OS +calls back ("phones home") to NICo's metadata service, instead of being +reported ready as soon as provisioning finishes. NICo does not inject anything +into your user-data -- the OS must include a cloud-init `phone_home` module to +make the callback. See +[Phone-home](../../../../configuration/tenant_management.md#phone-home) for +what it injects, the endpoint, and usage guidance.\ \ *Possible values:* From 186d596f20c7b22a1f766afbe448dc179f7c2917 Mon Sep 17 00:00:00 2001 From: Omar Refai Date: Thu, 2 Jul 2026 11:31:21 -0700 Subject: [PATCH 2/2] docs: correct phone-home injection behavior NICo injects the cloud-init phone_home block into user-data itself when phoneHomeEnabled is set (util.InsertPhoneHomeIntoUserData, from both the OS and instance paths); it does not serve user-data verbatim. Document the injected site.phoneHomeUrl endpoint and the valid-YAML requirement, and fix the two CLI reference blurbs that repeated the same wrong claim. Co-Authored-By: Claude Opus 4.8 --- docs/configuration/tenant_management.md | 6 ++++-- .../commands/operating-system/operating-system-create.md | 6 +++--- .../commands/operating-system/operating-system-update.md | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/configuration/tenant_management.md b/docs/configuration/tenant_management.md index 7af1613f67..c6260a1849 100644 --- a/docs/configuration/tenant_management.md +++ b/docs/configuration/tenant_management.md @@ -595,7 +595,7 @@ The instance detail response is rich -- it includes `interfaces[]` with assigned **What it does.** When phone-home is enabled, NICo does not consider the instance fully provisioned until the booted OS contacts NICo's metadata service from inside the guest. The instance is held in a provisioning state -- the transition to `Ready` is gated -- until that callback arrives. When it is disabled, NICo reports the instance ready as soon as provisioning and config sync finish, without waiting for any signal from the OS. -**What NICo injects: nothing.** Enabling the flag does *not* add anything to your `userData`. NICo serves your cloud-init user-data to the booting host verbatim. To make the host actually phone home, your user-data must include a cloud-init [`phone_home`](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#phone-home) module that POSTs to NICo's link-local metadata endpoint: +**What NICo injects.** When phone-home is enabled, NICo edits your `userData` for you -- you do *not* add the callback yourself. NICo parses your cloud-init YAML, strips any existing [`phone_home`](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#phone-home) block, and inserts one that POSTs to the site's metadata endpoint: ```yaml #cloud-config @@ -605,6 +605,8 @@ phone_home: post: all ``` +The injected `url` is the site-configured phone-home endpoint (`site.phoneHomeUrl`; default `http://169.254.169.254:7777/latest/meta-data/phone_home`), which the platform operator can override per deployment. If you supply no `userData`, NICo generates a minimal `#cloud-config` containing only the block above. Disabling phone-home reverses this: NICo removes the matching `phone_home` block it manages. Because NICo rewrites your user-data as YAML, **`userData` must be valid cloud-init YAML (a `#cloud-config` mapping) whenever phone-home is enabled** -- the API rejects the request otherwise. + cloud-init runs the `phone_home` module in its final stage, after the rest of your configuration has been applied, so the callback fires only once your setup has completed. When NICo receives the POST it records the contact and releases the readiness gate, allowing the instance to become `Ready`. **When to use it.** Enable phone-home when "ready" must mean "the guest has finished its own first-boot setup" -- for example, to delay readiness until cloud-init has applied SSH keys and passwords, so that automation watching for `Ready` does not connect before the host is fully configured. Leave it disabled when NICo finishing provisioning is a sufficient ready signal and you do not need a callback from inside the guest. @@ -612,7 +614,7 @@ cloud-init runs the `phone_home` module in its final stage, after the rest of yo **Notes and caveats.** - Phone-home only gates *status reporting*. It does not change how the host is provisioned or booted -- the reboot into the provisioned OS happens identically whether or not phone-home is enabled. -- If you enable phone-home but never include a `phone_home` module in your user-data, the instance stays in its provisioning state indefinitely and never reports ready. +- If phone-home is enabled but the booted OS never runs cloud-init -- or the guest cannot reach the metadata endpoint -- the callback never arrives and the instance stays in its provisioning state, never reporting ready. - The metadata endpoint (`169.254.169.254:7777`) is reachable only from the provisioned host over its link-local metadata link; it is not a tenant-facing API. - Rebooting the instance with a one-time custom iPXE override (`instance update --reboot-with-custom-ipxe=true`) re-arms the gate when phone-home is enabled: NICo clears the recorded contact, so the OS must phone home again before the instance is reported ready. diff --git a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md index f1eb925e81..a9d0b56e35 100644 --- a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md +++ b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-create.md @@ -50,9 +50,9 @@ Allow users to override OS parameters. **--phone-home-enabled** Hold the instance in a provisioning state until the booted OS calls back ("phones home") to NICo's metadata service, instead of reporting it ready as -soon as provisioning finishes. NICo does not inject anything into your -user-data -- the OS must include a cloud-init `phone_home` module to make the -callback. See +soon as provisioning finishes. NICo injects the cloud-init `phone_home` block +into your user-data for you, so your `userData` must be valid cloud-init YAML +when this is enabled. See [Phone-home](../../../../configuration/tenant_management.md#phone-home) for what it injects, the endpoint, and usage guidance. diff --git a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md index be3369e94a..f38fe56c86 100644 --- a/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md +++ b/docs/manuals/nico-admin-cli/commands/operating-system/operating-system-update.md @@ -51,9 +51,9 @@ Set whether users can override OS parameters.\ **--phone-home-enabled** *\* Set whether the instance is held in a provisioning state until the booted OS calls back ("phones home") to NICo's metadata service, instead of being -reported ready as soon as provisioning finishes. NICo does not inject anything -into your user-data -- the OS must include a cloud-init `phone_home` module to -make the callback. See +reported ready as soon as provisioning finishes. NICo injects the cloud-init +`phone_home` block into your user-data for you, so your `userData` must be +valid cloud-init YAML when this is enabled. See [Phone-home](../../../../configuration/tenant_management.md#phone-home) for what it injects, the endpoint, and usage guidance.\