Mateusz Urbanek 1b834b7d2a
feat: add SHA-256 and SHA-512 checksum frontend
Add enterprise-only checksum endpoint: appending .sha256 or .sha512
to any /image/ path returns a single-line checksum file instead of
the asset. Algorithm is selected from the suffix; the Checksummer
interface takes the suffix so no circular import is needed.

Wizard UI shows (sha256) and (sha512) links per download button;
non-enterprise builds show a localized (checksums) tooltip.
Integration tests cover both algorithms (GET, HEAD, validate,
reproducibility, error cases).

Signed-off-by: Mateusz Urbanek <mateusz.urbanek@siderolabs.com>
2026-04-17 14:11:55 +02:00

310 lines
15 KiB
HTML

{{ define "wizard-final" }}
{{ template "hidden-inputs" . }}
{{ template "header" (t .Localizer "final.title") }}
<div class="mb-6 text-sm">
{{ t .Localizer "final.image" }}{{ template "copyable-text" .Schematic}}
</div>
<div class="mb-6 text-sm font-mono bg-slate-200 dark:bg-slate-700 p-1 whitespace-pre">{{ .Marshaled }}</div>
<div class="mb-6 prose prose-sm dark:prose-invert max-w-none">
<h2>{{ t .Localizer "final.first_boot" }}</h2>
{{ if eq .Target "metal" }}
<p>{{ t .Localizer "final.first_boot.metal" }}</p>
{{ else if eq .Target "cloud" }}
<p>{{ t .Localizer "final.first_boot.cloud" }} {{ .PlatformMeta.Label }}:</p>
{{ else if eq .Target "sbc" }}
<p>{{ t .Localizer "final.first_boot.sbc" }} {{ .BoardMeta.Label }}:</p>
{{ end }}
<dl>
{{ if or (eq .Target "metal") (eq .Target "cloud") }}
{{ range .PlatformMeta.BootMethods }}
{{ if eq . "disk-image" }}
{{ template "disk-image" $ }}
{{ else if eq . "iso" }}
{{ template "iso" $ }}
{{ else if eq . "pxe" }}
{{ template "pxe-boot" $ }}
{{ end }}
{{ end }}
{{ else if eq .Target "sbc" }}
{{ template "board-image" . }}
{{ end }}
</dl>
{{ if or (eq .Target "metal") (and (eq .Target "cloud") .PlatformMeta.NotOnlyDiskImage) }}
<h2>{{ t .Localizer "final.initial_installation" }}</h2>
<p>
{{ t .Localizer "final.initial_installation.description" }}<br>
{{ template "installer-image" . }}
</p>
{{ end }}
<h2>{{ t .Localizer "final.upgrading" }}</h2>
<p>
{{ t .Localizer "final.upgrading.to" }}<a
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/configure-your-talos-cluster/lifecycle-management/upgrading-talos/"
target="_blank">{{ t
.Localizer "final.upgrading.name" }}</a>{{ t .Localizer "final.upgrading.description" }}<br>
{{ template "installer-image" . }}
</p>
{{ if not (version_less .Version "1.12.0-alpha.2") }}
<h2>{{ t .Localizer "final.local_test_cluster" }}</h2>
<p>
{{ t .Localizer "final.local_test_cluster.prompt" }}<br>
{{ template "talosctl-cluster-create" . }}
</p>
{{ end }}
<h2>{{ t .Localizer "final.booter" }}</h2>
<p>
{{ t .Localizer "final.booter.command_pre" }}<a href="https://github.com/siderolabs/booter"
target="_blank">{{ t
.Localizer "final.booter.name" }}</a>{{ t .Localizer "final.booter.command_post" }}<br>
{{ template "booter-command" . }}
</p>
<h2>{{ t .Localizer "final.documentation" }}</h2>
<ul>
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/getting-started/what's-new-in-talos/">{{
t
.Localizer "final.documentation.new" }}{{ short_version .Version }}</a>
</li>
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/getting-started/support-matrix/">{{
t .Localizer "final.documentation.matrix" }}{{ short_version .Version
}}</a></li>
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/getting-started/getting-started/">{{
t .Localizer
"final.documentation.getting_started" }}</a></li>
{{ if eq .Target "metal" }}
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/network-config/">{{
t .Localizer "final.documentation.metal" }}</a></li>
{{ else if eq .Target "cloud" }}
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}{{ .PlatformMeta.Documentation }}">{{
.PlatformMeta.Label }} {{ t .Localizer "final.documentation.cloud"
}}</a></li>
{{ else if eq .Target "sbc" }}
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}{{ .BoardMeta.Documentation }}">{{
.BoardMeta.Label }} {{ t .Localizer "final.documentation.sbc" }}</a>
</li>
{{ end }}
{{ if eq .SecureBoot "true" }}
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/secureboot/">{{
t .Localizer "final.documentation.secure_boot" }}</a></li>
{{ end }}
{{ if .ProductionGuideAvailable }}
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/getting-started/prodnotes/">{{
t
.Localizer "final.documentation.production" }}</a></li>
{{ end }}
{{ if .TroubleshootingGuideAvailable }}
<li><a target="_blank"
href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/troubleshooting/troubleshooting/">{{
t .Localizer
"final.documentation.troubleshooting" }}</a></li>
{{ end }}
</ul>
{{ if eq .Target "metal" }}
<h2>{{ t .Localizer "final.extra" }}</h2>
<dl>
{{ if eq .SecureBoot "true" }}
{{ template "secureboot-extra-assets" . }}
{{ else }}
{{ template "extra-assets" . }}
{{ end }}
</dl>
{{ end }}
{{ if .SBOMAvailable }}
<h2>{{ t .Localizer "final.extra.spdx" }}</h2>
{{ if .Enterprise }}
<dl>
<dd><a target="_blank" href="{{ .SPDXBaseURL }}">{{ .SPDXBaseURL }}</a></dd>
</dl>
{{ else }}
<dl>
<dd>{{ t .Localizer "final.extra.spdx_enterprise_feature" }}</dd>
</dl>
{{ end }}
{{ end }}
</div>
<div class="flex gap-4">
{{ template "back-button" (dict "Params"
"target,version,platform,board,arch,secureboot,extensions,selected-bootloader,selected-cmdline,selected-overlay-options"
"Localizer" .Localizer) }}
</div>
{{ end }}
{{ define "iso" }}
{{ if eq .SecureBoot "true" }}
<dt>SecureBoot ISO</dt>
<dd><a href="{{ .PlatformMeta.SecureBootISOPath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.SecureBootISOPath
.Arch | $.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.SecureBootISOPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
(<a href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/secureboot/"
target="_blank">{{ t .Localizer "final.disk_image.secure_boot_docs" }}</a>)
</dd>
{{ else}}
<dt>ISO</dt>
<dd><a href="{{ .PlatformMeta.ISOPath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.ISOPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.ISOPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
{{ if eq .Target "metal" }}
(<a href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/iso/"
target="_blank">{{ t .Localizer "final.disk_image.iso_docs" }}</a>)
{{ end }}
</dd>
{{ end }}
{{ end }}
{{ define "disk-image" }}
{{ if eq .SecureBoot "true" }}
<dt>{{ t .Localizer "final.disk_image.secure_boot" }}</dt>
<dd><a href="{{ .PlatformMeta.SecureBootDiskImageDefaultPath .Arch | $.ImageBaseURL.JoinPath }}">{{
.PlatformMeta.SecureBootDiskImageDefaultPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.SecureBootDiskImageDefaultPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
{{ if eq .Target "metal" }}
(<a href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/secureboot/"
target="_blank">{{ t .Localizer "final.disk_image.secure_boot_docs" }}</a>)
{{ end }}
</dd>
{{ else }}
{{ if eq .Target "metal" }}
<dt>{{ t .Localizer "final.disk_image.all" }} (raw)</dt>
<dd><a href="{{ .PlatformMeta.DiskImageDefaultPath .Arch | $.ImageBaseURL.JoinPath }}">{{
.PlatformMeta.DiskImageDefaultPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.DiskImageDefaultPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
<dt>{{ t .Localizer "final.disk_image.all" }} (qcow2)</dt>
<dd><a href="{{ .PlatformMeta.DiskImagePath .Arch "qcow2" | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.DiskImagePath
.Arch "qcow2" |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.DiskImagePath .Arch "qcow2") "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
{{ else }}
<dt>{{ t .Localizer "final.disk_image.all" }}</dt>
<dd><a href="{{ .PlatformMeta.DiskImageDefaultPath .Arch | $.ImageBaseURL.JoinPath }}">{{
.PlatformMeta.DiskImageDefaultPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.DiskImageDefaultPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
{{ end }}
{{ end}}
{{ end }}
{{ define "pxe-boot" }}
{{ if eq .SecureBoot "true" }}
<dt>
{{ t .Localizer "final.pxe.secure_boot" }} (iPXE script)
{{ if eq .Target "metal" }}
(<a href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/pxe/"
target="_blank">{{ t .Localizer "final.pxe.docs" }}</a>)
{{ end }}
</dt>
<dd>{{ .PlatformMeta.SecureBootPXEScriptPath .Arch | $.PXEBaseURL.JoinPath }}</dd>
{{ else }}
<dt>
{{ t .Localizer "final.pxe.boot" }} (iPXE script)
{{ if eq .Target "metal" }}
(<a href="https://docs.siderolabs.com/talos/{{ short_version .Version }}/platform-specific-installations/bare-metal-platforms/pxe/"
target="_blank">{{ t .Localizer "final.pxe.docs" }}</a>)
{{ end }}
</dt>
<dd>
{{ template "copyable-text" (.PlatformMeta.PXEScriptPath .Arch | $.PXEBaseURL.JoinPath) }}
</dd>
{{ end }}
{{ end }}
{{ define "board-image" }}
<dt>{{ t .Localizer "final.board_image" }}</dt>
<dd><a href="{{ .BoardMeta.DiskImagePath .Version | $.ImageBaseURL.JoinPath }}">{{ .BoardMeta.DiskImagePath .Version |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.BoardMeta.DiskImagePath .Version) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
{{ end }}
{{ define "installer-image" }}
{{ if eq .SecureBoot "true"}}
{{ template "copyable-text" .SecureBootInstallerImage }}
{{ else }}
{{ template "copyable-text" .InstallerImage }}
{{ end }}
{{ end }}
{{ define "talosctl-cluster-create" }}
{{ template "copyable-text" (printf "talosctl cluster create qemu --schematic-id=%s --talos-version=v%s" .Schematic .Version) }}
{{ end }}
{{ define "booter-command" }}
{{ template "copyable-text" (printf "docker run --rm --network host ghcr.io/siderolabs/booter:v0.3.0 --talos-version=v%s --schematic-id=%s" .Version .Schematic) }}
{{ end }}
{{ define "extra-assets" }}
<dt>{{ t .Localizer "final.extra.kernel_image" }}</dt>
<dd><a href="{{ .PlatformMeta.KernelPath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.KernelPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.KernelPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
<dt>{{ t .Localizer "final.extra.cmdline" }}</dt>
<dd><a href="{{ .PlatformMeta.CmdlinePath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.CmdlinePath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.CmdlinePath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
<dt>{{ t .Localizer "final.extra.initramfs" }}</dt>
<dd><a href="{{ .PlatformMeta.InitramfsPath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.InitramfsPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.InitramfsPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
<dt>UKI</dt>
<dd><a href="{{ .PlatformMeta.UKIPath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.UKIPath .Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.UKIPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
{{ if .TalosctlAvailable }}
<dt>{{ t .Localizer "final.extra.talosctl" }}</dt>
{{ range $index, $path := .TalosctlMeta.TalosctlPaths .TalosctlTuples }}
<dd><a href="{{ $path | $.TalosctlBaseURL.JoinPath }}">{{ $path |
$.TalosctlBaseURL.JoinPath }}</a>
</dd>
{{ end }}
{{ end }}
{{ end }}
{{ define "secureboot-extra-assets" }}
<dt>SecureBoot UKI</dt>
<dd><a href="{{ .PlatformMeta.SecureBootUKIPath .Arch | $.ImageBaseURL.JoinPath }}">{{ .PlatformMeta.SecureBootUKIPath
.Arch |
$.ImageBaseURL.JoinPath }}</a>
{{ template "checksum-link" (dict "Path" (.PlatformMeta.SecureBootUKIPath .Arch) "ChecksumBaseURL" $.ChecksumBaseURL "Enterprise" $.Enterprise "Localizer" $.Localizer) }}
</dd>
{{ end }}
{{ define "checksum-link" }}{{ if .Enterprise }}<a href="{{ printf "%s.sha256" .Path | .ChecksumBaseURL.JoinPath }}" class="text-xs ml-1">(sha256)</a><a href="{{ printf "%s.sha512" .Path | .ChecksumBaseURL.JoinPath }}" class="text-xs ml-1">(sha512)</a>{{ else }}<span class="text-xs ml-1 text-gray-400 cursor-not-allowed" title="{{ t .Localizer "final.extra.checksum_enterprise_feature" }}">(checksums)</span>{{ end }}{{ end }}
{{ template "wizard-final" . }}