Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,31 @@ nodes:
role: control-plane
```

TOPF generates the installer image from `talosVersion` (and the optional `schematicId`) in `topf.yaml`. Create a patch to specify the install disk:
TOPF generates the installer image from `talosVersion` (and the optional `schematicId`) in `topf.yaml`. Create a patch to specify the install disk.

`all/00-installation.yaml`:
For Talos >= 1.14, `all/00-installation.yaml`:

```yaml
apiVersion: v1alpha1
kind: UnattendedInstallConfig
provisioning:
diskSelector:
match: disk.dev_path == "/dev/sda"
wipe: false
```

For Talos < 1.14:

```yaml
machine:
install:
disk: /dev/sda
```

> Talos v1.14 deprecated `.machine.install` in favor of the
> `UnattendedInstallConfig` multi-document config; the two are mutually
> exclusive — a node rejects a config containing both.

### Set the node hostname

By default, Talos generates hostnames automatically (e.g. `talos-XXX-XXX`). The `host` value in `topf.yaml` is used by TOPF for display, logging, and node selection — it is **not** automatically applied as the Talos hostname.
Expand Down
6 changes: 4 additions & 2 deletions cmd/topf/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ func newApplyCmd() *cli.Command {

// applyModes maps user-facing mode names to their protobuf values.
// https://github.com/siderolabs/talos/blob/main/cmd/talosctl/pkg/talos/helpers/mode.go
var applyModes = map[string]machine.ApplyConfigurationRequest_Mode{ //nolint:gochecknoglobals // read-only lookup table
"reboot": machine.ApplyConfigurationRequest_REBOOT,
//
//nolint:gochecknoglobals // read-only lookup table
var applyModes = map[string]machine.ApplyConfigurationRequest_Mode{
"reboot": machine.ApplyConfigurationRequest_REBOOT, //nolint:staticcheck // backwards compatibility
"auto": machine.ApplyConfigurationRequest_AUTO,
"no-reboot": machine.ApplyConfigurationRequest_NO_REBOOT,
"staged": machine.ApplyConfigurationRequest_STAGED,
Expand Down
2 changes: 1 addition & 1 deletion cmd/topf/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func main() {
&cli.BoolFlag{
Name: "redact",
Value: true,
Usage: "redact sensitive values (secrets, certificates) from output",
Usage: "redact sensitive values (secrets, private keys) from output",
Sources: cli.EnvVars("TOPF_REDACT"),
DefaultText: defaultTextTrue,
},
Expand Down
2 changes: 1 addition & 1 deletion docs/commands/apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ All flags can also be set via environment variables using the `TOPF_` prefix and
| `--stabilization-duration` | `30s` | How long a node must stay ready after applying before it is considered stable |
| `--allow-not-ready` | `false` | Allow applying to nodes that are not ready (have unmet conditions) |
| [`--nodes-filter`](../configuration.md#filtering-nodes) | - | Regex pattern to filter which nodes to operate on (global flag) |
| [`--redact`](../configuration.md#redacting-sensitive-output) | `true` | Redact Talos secrets, certificates, SOPS-encrypted values, and vals-resolved values from output (global flag) |
| [`--redact`](../configuration.md#redacting-sensitive-output) | `true` | Redact Talos secrets, private keys, SOPS-encrypted values, and vals-resolved values from output (global flag) |

## Example Usage

Expand Down
30 changes: 24 additions & 6 deletions docs/commands/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,29 @@ talosVersion: 1.12.7
schematicId: 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba
```

This generates `factory.talos.dev/metal-installer/<schematicId>:v<talosVersion>` as the base installer image. Since this patch is applied first, any subsequent `machine.install.image` patch (shared or node-level) will override it. The factory and platform can be customized via `factory` and `platform` in `topf.yaml` (or per node).
This generates `factory.talos.dev/metal-installer/<schematicId>:v<talosVersion>` as the base installer image. Since this patch is applied first, any subsequent installer image patch (shared or node-level) will override it. The factory and platform can be customized via `factory` and `platform` in `topf.yaml` (or per node).

> **Talos >= 1.14**: the installer image is injected as an
> `UnattendedInstallConfig` document (`.machine.install` is deprecated and
> mutually exclusive with it). For older nodes it is still injected as
> `machine.install.image`. Override patches must use the matching form for
> the node's version.

### Manual installer image patch

Alternatively, manage the installer image explicitly via a patch. The target image for each node comes from the `machine.install.image` field in the assembled node configuration (i.e. the last patch takes precedence). The patch looks like:
Alternatively, manage the installer image explicitly via a patch. The target image for each node comes from the installer image field in the assembled node configuration (i.e. the last patch takes precedence). For Talos >= 1.14 the patch looks like:

`all/00-install.yaml`:

```yaml
apiVersion: v1alpha1
kind: UnattendedInstallConfig
installer:
image: factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.0
```

For Talos < 1.14, use the legacy form:

```yaml
machine:
install:
Expand All @@ -114,16 +129,19 @@ machine:

### Per-node override

To upgrade a single node to a different version or schematic, add a node-specific patch that overrides the image:
To upgrade a single node to a different version or schematic, add a node-specific patch that overrides the image. For Talos >= 1.14:

`node/node1/installer.yaml`:

```yaml
machine:
install:
image: factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.13.0
apiVersion: v1alpha1
kind: UnattendedInstallConfig
installer:
image: factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.0
```

For Talos < 1.14, use the legacy `machine.install.image` form instead.

Because node-level patches are merged last (see [Configuration Model](../configuration-model.md)), this override applies only to that host.

## Example Usage
Expand Down
25 changes: 25 additions & 0 deletions docs/configuration-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ Patches ending with `.yaml.tpl` support [Go templating](https://pkg.go.dev/text/
| `.Node.Role` | Node role (`control-plane` or `worker`) |
| `.Node.IP` | Node IP address (if set) |
| `.Node.Data.<key>` | Per-node data (if set) |
| `.Node.RuntimeData.TalosVersion` | Talos version reported by the **live node** (no `v` prefix; empty when rendering offline or before the node was contacted) |
| `.Node.RuntimeData.SchematicID` | Schematic ID reported by the live node |
| `.Node.RuntimeData.Stage` | Machine stage reported by the live node (`booting`, `installing`, `maintenance`, `running`, `rebooting`, `shutting down`, `resetting`, `upgrading`) |

Runtime data is collected from live nodes by `apply`, `upgrade`, `reset`, and `render --online`. When rendering offline (`render` without `--online`), all runtime fields are empty.

### Template Functions

Expand All @@ -89,6 +94,7 @@ A few commonly used functions:
| `env "VAR"` | Returns the value of the environment variable `VAR`, or an empty string if unset |
| `default "x" .Val` | Returns `.Val`, falling back to `"x"` if `.Val` is empty |
| `b64enc` / `b64dec` | Base64 encode / decode |
| `semverCompare "<constraint>" <version>` | [Semver constraint comparison](https://masterminds.github.io/sprig/semver.html); use a prerelease floor like `">= 1.14.0-0"` to also match RCs |

### Examples

Expand All @@ -112,3 +118,22 @@ endpoints:
- url: {{ env "REGISTRY_MIRROR" }}
{{- end }}
```

Branch on the node's **running** Talos version — useful for mixed-version clusters during the Talos 1.13 → 1.14 transition, where the install disk is configured via `UnattendedInstallConfig` on >= 1.14 and via the deprecated `.machine.install` on older nodes:

```yaml
{{ if semverCompare ">= 1.14.0-0" .Node.RuntimeData.TalosVersion -}}
apiVersion: v1alpha1
kind: UnattendedInstallConfig
provisioning:
diskSelector:
match: disk.dev_path == "/dev/vda"
wipe: false
{{ else -}}
machine:
install:
disk: /dev/vda
{{ end -}}
```

> **Note:** `UnattendedInstallConfig` and `.machine.install` are mutually exclusive — Talos >= 1.14 rejects a config containing both, and `.machine.install` is deprecated. Branching templates like the one above are the recommended way to express the install disk while a cluster straddles versions.
6 changes: 3 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ TOPF supports the following global flags that can be used with any command:
| `--nodes-filter` | `TOPF_NODES_FILTER` | - | Regex pattern to filter which nodes to operate on |
| `--log-level` | `LOG_LEVEL` | `info` | Logging level (debug, info, warn, error) |
| `--confirm` | `TOPF_CONFIRM` | `true` | Confirm any changes before applying them |
| `--redact` | `TOPF_REDACT` | `true` | Redact secrets and certificates from output |
| `--redact` | `TOPF_REDACT` | `true` | Redact secrets and private keys from output |
| `--submit-to-factory` | `TOPF_SUBMIT_TO_FACTORY` | `false` | Submit schematics to the image factory API (default: compute IDs locally) |

### Filtering Nodes
Expand Down Expand Up @@ -190,9 +190,9 @@ topf apply

### Redacting Sensitive Output

When `--redact` is enabled (the default), topf replaces secrets and certificate data with `*** redacted ***` in any command output. The following values are redacted:
When `--redact` is enabled (the default), topf replaces secrets and private keys with `*** redacted ***` in any command output. The following values are redacted:

- **Talos secrets bundle**: private keys, CA certificates, bootstrap tokens, encryption secrets, and trustd tokens from `secrets.yaml`
- **Talos secrets bundle**: private keys, bootstrap tokens, encryption secrets, and trustd tokens from `secrets.yaml`
- **SOPS-encrypted values**: any value that was encrypted with SOPS in `topf.yaml` or in patch files is decrypted internally and its plaintext is redacted from output
- **vals-resolved values**: any value that was resolved from a [vals](https://github.com/helmfile/vals) reference (e.g. `ref+vault://`, `ref+file://`) has its plaintext redacted from output

Expand Down
19 changes: 17 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,31 @@ nodes:
role: control-plane
```

Create a new patch to specify the install disk:
Create a new patch to specify the install disk.

`all/00-installation.yaml`:
For Talos >= 1.14, `all/00-installation.yaml`:

```yaml
apiVersion: v1alpha1
kind: UnattendedInstallConfig
provisioning:
diskSelector:
match: disk.dev_path == "/dev/vda"
wipe: false
```

For Talos < 1.14:

```yaml
machine:
install:
disk: /dev/vda
```

> Talos v1.14 deprecated `.machine.install` in favor of the
> `UnattendedInstallConfig` multi-document config; the two are mutually
> exclusive — a node rejects a config containing both.

### Set the node hostname

By default, Talos generates hostnames automatically (e.g. `talos-XXX-XXX`). The `host` value in `topf.yaml` is used by TOPF for display, logging, and node selection — it is **not** automatically applied as the Talos hostname.
Expand Down
Loading