Andrey Smirnov 807a9950ac
fix: use custom Talos/kernel version when generating UKI
See https://github.com/siderolabs/image-factory/issues/44

Instead of using constants, use proper Talos version and kernel version
discovered from the image.

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
2023-11-03 11:14:02 +04:00

70 lines
1.5 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package uki
import (
"bytes"
"encoding/binary"
"fmt"
"os"
"strings"
)
// DiscoverKernelVersion reads kernel version from the kernel image.
//
// This only works for x86 kernel images.
//
// Based on https://www.kernel.org/doc/html/v5.6/x86/boot.html.
func DiscoverKernelVersion(kernelPath string) (string, error) {
f, err := os.Open(kernelPath)
if err != nil {
return "", err
}
defer f.Close() //nolint:errcheck
header := make([]byte, 1024)
_, err = f.Read(header)
if err != nil {
return "", err
}
// check header magic
if string(header[0x202:0x206]) != "HdrS" {
return "", fmt.Errorf("invalid kernel image")
}
setupSects := header[0x1f1]
versionOffset := binary.LittleEndian.Uint16(header[0x20e:0x210])
if versionOffset == 0 {
return "", fmt.Errorf("no kernel version")
}
if versionOffset > uint16(setupSects)*0x200 {
return "", fmt.Errorf("invalid kernel version offset")
}
versionOffset += 0x200
version := make([]byte, 256)
_, err = f.ReadAt(version, int64(versionOffset))
if err != nil {
return "", err
}
idx := bytes.IndexByte(version, 0)
if idx == -1 {
return "", fmt.Errorf("invalid kernel version")
}
versionString := string(version[:idx])
versionString, _, _ = strings.Cut(versionString, " ")
return versionString, nil
}