Skip to content

feat: improve talos upgrade command - #12751

Open
pranav767 wants to merge 1 commit into
siderolabs:mainfrom
pranav767:feat/improve-talos-upgrade-command
Open

feat: improve talos upgrade command#12751
pranav767 wants to merge 1 commit into
siderolabs:mainfrom
pranav767:feat/improve-talos-upgrade-command

Conversation

@pranav767

Copy link
Copy Markdown
Contributor

Pull Request

Resolves #12152

What? (description)

  • Remove default --image parameter, keep as legacy
  • Add other parameters like --factory, --platform,--secureBoot,--schematic

Why? (reasoning)

  • Prevents node-bricking by replacing dangerous default --image with component-based flags that create image url from machine state / specified requirements and validate secure-boot/platform transitions.

Acceptance

Please use the following checklist:

  • you linked an issue (if applicable)
  • you included tests (if applicable)
  • you ran conformance (make conformance)
  • you formatted your code (make fmt)
  • you linted your code (make lint)
  • you generated documentation (make docs)
  • you ran unit-tests (make unit-tests)

See make help for a description of the available targets.

Trying this out on a test node:

jinx@jinx:~/siderolabs/talos$ _out/talosctl-linux-amd64 get extensions --nodes 10.5.0.3
WARNING: 10.5.0.3: server version 1.12.0 is older than client version 1.13.0-alpha.0-29-g8e9718be0-dirty
NODE   NAMESPACE   TYPE   ID   VERSION   NAME   VERSION
$ _out/talosctl-linux-amd64 upgrade --nodes 10.5.0.3 \
  --version v1.12.1 \
  --schematic 08ec3d667c94cc858ff2542dc0ae11055004cc6d8338a3d682ea208e7e736be7 

Upgrade Warnings:
  Adding schematic: 08ec3d667c94cc858ff2542dc0ae11055004cc6d8338a3d682ea208e7e736be7


Upgrade Plan:
Version:    v1.12.0 → v1.12.1
Schematic:  08ec3d667c94cc858ff2542dc0ae11055004cc6d8338a3d682ea208e7e736be7 (CHANGED)
SecureBoot: false (unchanged)
Platform:   metal (unchanged)
Factory:    factory.talos.dev
Image:      factory.talos.dev/metal-installer/08ec3d667c94cc858ff2542dc0ae11055004cc6d8338a3d682ea208e7e736be7:v1.12.1

WARNING: 10.5.0.3: server version 1.12.0 is older than client version 1.13.0-alpha.0-29-g8e9718be0-dirty
watching nodes: [10.5.0.3]
    * 10.5.0.3: post check passed

Post upgrade check extensions & upgraded version

$ _out/talosctl-linux-amd64 get extensions --nodes 10.5.0.3
WARNING: 10.5.0.3: server version 1.12.1 is older than client version 1.13.0-alpha.0-29-g8e9718be0-dirty
NODE       NAMESPACE   TYPE              ID            VERSION   NAME              VERSION
10.5.0.3   runtime     ExtensionStatus   0             1         amazon-ena        2.16.0-v1.12.1
10.5.0.3   runtime     ExtensionStatus   1             1         binfmt-misc       v1.12.1
10.5.0.3   runtime     ExtensionStatus   2             1         bnx2-bnx2x        20251125
10.5.0.3   runtime     ExtensionStatus   3             1         chelsio-drivers   v1.12.1
10.5.0.3   runtime     ExtensionStatus   4             1         schematic         08ec3d667c94cc858ff2542dc0ae11055004cc6d8338a3d682ea208e7e736be7
10.5.0.3   runtime     ExtensionStatus   modules.dep   1         modules.dep       6.18.2-talos
jinx@jinx:~/siderolabs/talos$ _out/talosctl-linux-amd64 --nodes 10.5.0.3 version
Client:
	Tag:         v1.13.0-alpha.0-29-g8e9718be0-dirty
	SHA:         8e9718be-dirty
	Built:       
	Go version:  go1.25.5
	OS/Arch:     linux/amd64
Server:
	NODE:        10.5.0.3
	Tag:         v1.12.1
	SHA:         7ea2ef7c
	Built:       
	Go version:  go1.25.5
	OS/Arch:     linux/amd64
	Enabled:     RBAC

@github-project-automation github-project-automation Bot moved this to To Do in Planning Feb 8, 2026
@talos-bot talos-bot moved this from To Do to In Review in Planning Feb 8, 2026
@smira smira self-assigned this Feb 9, 2026
@smira smira moved this from In Review to On Hold in Planning Feb 9, 2026
@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open 45 days with no activity.

@github-actions github-actions Bot added the Stale label Mar 27, 2026
@pranav767
pranav767 marked this pull request as draft June 11, 2026 09:05
@github-actions github-actions Bot removed the Stale label Jun 12, 2026
@pranav767
pranav767 force-pushed the feat/improve-talos-upgrade-command branch from 778fda8 to 8940a40 Compare June 12, 2026 04:42
@pranav767 pranav767 changed the title Feat/improve talos upgrade command feat: improve talos upgrade command Jun 12, 2026
@pranav767
pranav767 force-pushed the feat/improve-talos-upgrade-command branch from 8940a40 to a2f6b9d Compare June 15, 2026 15:09
@pranav767
pranav767 force-pushed the feat/improve-talos-upgrade-command branch 2 times, most recently from 6963da1 to ded09cf Compare July 24, 2026 13:57
@pranav767

Copy link
Copy Markdown
Contributor Author

@smira , Might be a little late to the party
But this is ready for review, few things to note

Per Node Image Resolution involves

  1. Created 2 helper files to query machine context and build upgrade image url for upgrades.
  2. I've changed the definition of imagePullInternal it now requires imageRefs as a dict which maps nodes with their images.
  3. Image pull and debug used this function so had to create 2 ways of doing things.
    • uniformImageRefs maps all nodes to the same image reference, same node image ref is used for debugs & pulls.
    • resolveUpgradeImages is used for referencing each target node using nodeFromContext.

As a basic criteria new flags created --factory, --schematic, --talos-version, --secure-boot, --platform,

  • if all flags are mentioned create url fast and upgrade
  • if any one of the given flag is missing, we create a new upgrade url first via querying machine current state, with buit-in fallbacks.
    Also legacy --image legacy flag still exits which overrides any other flag if mentioned.

@pranav767
pranav767 marked this pull request as ready for review July 26, 2026 09:53
…per-node image resolution for building upgrade url
@pranav767

pranav767 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Dropping in test upgrade logs
upgrade from v1.13.0 -> v1.14.0-alpha.2

jinx@jinx:~/siderolabs/talos$ sudo --preserve-env=HOME $TALOSCTL upgrade   -c talos-default   -n 172.20.0.2,172.20.0.3   --talos-version v1.14.0-alpha.2
172.20.0.2: upgrade image: factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.0-alpha.2
172.20.0.3: upgrade image: factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.0-alpha.2
172.20.0.2: pulled image factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba@sha256:339e901906ca4eb1b3f28b6ca3815195843c1dfa178dc69c929040f63b9fc655
172.20.0.3: pulled image factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba@sha256:339e901906ca4eb1b3f28b6ca3815195843c1dfa178dc69c929040f63b9fc655
◰ 172.20.0.2: 2026/07/26 09:27:43 running Talos installer v1.14.0-alpha.2
◳ 172.20.0.2: 2026/07/26 09:27:43 running Talos installer v1.14.0-alpha.2
◲ 172.20.0.2: 2026/07/26 09:27:43 running pre-flight checks
◱ 172.20.0.2: 2026/07/26 09:27:43 host Talos version: v1.14.0-alpha.1
◰ 172.20.0.2: 2026/07/26 09:27:43 all pre-flight checks successful
◳ 172.20.0.2: 2026/07/26 09:27:43 probing bootloader on "/dev/vda"
◲ 172.20.0.2: 2026/07/26 09:27:43 probing bootloader on "/dev/vda"
◱ 172.20.0.2: 2026/07/26 09:27:43 probing bootloader on "/dev/vda"
◰ 172.20.0.2: 2026/07/26 09:27:43 probing bootloader on "/dev/vda"
◳ 172.20.0.2: 2026/07/26 09:27:43 GRUB: BOOT partition not found, skipping probing
◲ 172.20.0.2: 2026/07/26 09:27:43 sd-boot: found UKI files: [Talos-v1.13.0.efi Talos-v1.14.0-alpha.1.efi]
◱ 172.20.0.2: 2026/07/26 09:27:43 sd-boot: LoaderEntryDefault: Talos-v1.14.0-alpha.1.efi
◰ 172.20.0.2: 2026/07/26 09:27:43 found sd-boot bootloader on "/dev/vda"
◳ 172.20.0.2: 2026/07/26 09:27:43 found sd-boot bootloader on "/dev/vda"
◲ 172.20.0.2: 2026/07/26 09:27:43 sd-boot: found existing UKIs during upgrade: [Talos-v1.13.0.efi Talos-v1.14.0-alpha.1.efi]
◱ 172.20.0.2: 2026/07/26 09:27:43 sd-boot: found existing UKIs during upgrade: [Talos-v1.13.0.efi Talos-v1.14.0-alpha.1.efi]
◰ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◳ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◲ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◱ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◰ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◳ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◲ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◱ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◰ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◳ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◲ 172.20.0.2: 2026/07/26 09:27:43 copying /usr/install/amd64/vmlinuz.efi to /boot/EFI/EFI/Linux/Talos-v1.14.0-alpha.2.efi
◱ 172.20.0.2: 2026/07/26 09:27:47 copying /usr/install/amd64/systemd-boot.efi to /boot/EFI/EFI/boot/BOOTX64.efi
◰ 172.20.0.2: 2026/07/26 09:27:47 updating EFI variables
◳ 172.20.0.2: 2026/07/26 09:27:47 using disk gpt with partition 1 and UUID a373dfa3-687f-4ced-9244-58a03b394ca0
◲ 172.20.0.2: 2026/07/26 09:27:47 Existing boot entries: [0 1]
◱ 172.20.0.2: 2026/07/26 09:27:47 Found existing Talos Linux UKI boot entries: [1]
◰ 172.20.0.2: 2026/07/26 09:27:47 created Talos Linux UKI boot entry at index 1
◳ 172.20.0.2: 2026/07/26 09:27:47 META: loading from /dev/vda2
◲ 172.20.0.2: 2026/07/26 09:27:47 META: loaded 1 keys
◱ 172.20.0.2: 2026/07/26 09:27:47 META: saved 2 keys
◰ 172.20.0.2: 2026/07/26 09:27:47 installation of v1.14.0-alpha.2 complete
172.20.0.3: upgrade completed
172.20.0.2: upgrade completed
talos-default-controlplane-1: node drained
talos-default-worker-1: node drained
WARNING: 172.20.0.2: server version 1.14.0-alpha.1 is older than client version 1.14.0-alpha.2-110-gded09cf2a-dirty, 172.20.0.3: server version 1.14.0-alpha.1 is older than client version 1.14.0-alpha.2-110-gded09cf2a-dirty
◰ watching nodes: [172.20.0.2 172.20.0.3]
◳ watching nodes: [172.20.0.2 172.20.0.3]
watching nodes: [172.20.0.2 172.20.0.3]
    * 172.20.0.2: post check passed
    * 172.20.0.3: post check passed
talos-default-controlplane-1: node uncordoned
talos-default-worker-1: node uncordoned


jinx@jinx:~/siderolabs/talos$ $TALOSCTL get imagefactoryschematic -c talos-default -n 172.20.0.3
WARNING: 172.20.0.3: server version 1.14.0-alpha.2 is older than client version 1.14.0-alpha.2-110-gded09cf2a-dirty
NODE         NAMESPACE   TYPE                    ID                        VERSION   SCHEMATIC ID                                                       FLAVOR          API URL
172.20.0.3   runtime     ImageFactorySchematic   image-factory-schematic   1         376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba   Image Factory   https://factory.talos.dev/

jinx@jinx:~/siderolabs/talos$ $TALOSCTL -c talos-default -n 172.20.0.3 version
Client:
	Tag:         v1.14.0-alpha.2-110-gded09cf2a-dirty
	SHA:         ded09cf2-dirty
	Built:       
	Go version:  go1.26.5
	OS/Arch:     linux/amd64
Server:
	NODE:        172.20.0.3
	Tag:         v1.14.0-alpha.2
	SHA:         cd8b0fe3
	Built:       
	Go version:  go1.26.4
	OS/Arch:     linux/amd64
	Enabled:     RBAC

I wanted to test out if I do a upgrade to certain version and schematic and on next say just version upgrade it should pick up the new changed schematic rather than the one during the startup, I was not able to try this out because image factory schematics is available on 1.14.0 alpha and if I build image using alpha and image factory it would certainly give an 500 error as factory supports 1.13.7 for now. Any ideas to test this out?


// If every derived component is set explicitly, no per-node state is needed: the image is uniform.
if upgradeCmdFlags.schematic != "" && upgradeCmdFlags.platform != "" &&
upgradeCmdFlags.secureBootChanged && upgradeCmdFlags.factoryChanged && upgradeCmdFlags.talosVersion != ""{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can maybe remove this talosversion check as well to get a quick image url ref, as version will remain same for all nodes from tag AFAIK

@pranav767
pranav767 force-pushed the feat/improve-talos-upgrade-command branch from ded09cf to d9593ec Compare July 26, 2026 10:05
// machine was installed from an Image Factory image, so its absence is not an error.
schematic, err := safe.StateGetByID[*runtimeres.ImageFactorySchematic](ctx, c.COSI, runtimeres.ImageFactorySchematicID)
if err != nil {
if state.IsNotFoundError(err) || status.Code(err) == codes.PermissionDenied {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On older Talos versions (< 1.14) this resource type doesn't exist at all, so the API returns PermissionDenied rather than NotFound.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: On Hold

Development

Successfully merging this pull request may close these issues.

Improve talos upgrade command

3 participants