mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-11 07:31:18 +02:00
Use a global instance, handle loading/saving META in global context. Deprecate legacy syslinux ADV, provide an easier interface for consumers. Expose META as resources. Fix the bootloader revert process (it was completely broken for quite a while :sad:). This is a first step which mostly does preparation work, real changes will come in the next PRs: * add APIs to write to META * consume META keys for platform network config for `metal` * custom key for URL `${code}` Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
115 lines
2.3 KiB
Go
115 lines
2.3 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 main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/siderolabs/go-blockdevice/blockdevice/probe"
|
|
|
|
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub"
|
|
"github.com/siderolabs/talos/internal/pkg/meta"
|
|
"github.com/siderolabs/talos/internal/pkg/mount"
|
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
|
)
|
|
|
|
func revertBootloader() {
|
|
if err := revertBootloadInternal(); err != nil {
|
|
log.Printf("failed to revert bootloader: %s", err)
|
|
}
|
|
}
|
|
|
|
//nolint:gocyclo
|
|
func revertBootloadInternal() error {
|
|
metaState, err := meta.New(context.Background(), nil)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
// no META, no way to revert
|
|
return nil
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
label, ok := metaState.ReadTag(meta.Upgrade)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
if label == "" {
|
|
if _, err = metaState.DeleteTag(context.Background(), meta.Upgrade); err != nil {
|
|
return err
|
|
}
|
|
|
|
return metaState.Flush()
|
|
}
|
|
|
|
log.Printf("reverting failed upgrade, switching to %q", label)
|
|
|
|
// attempt to mount BOOT partition directly without using other code paths, as they rely on Runtime
|
|
dev, err := probe.GetDevWithPartitionName(constants.BootPartitionLabel)
|
|
if os.IsNotExist(err) {
|
|
// no BOOT partition???
|
|
return nil
|
|
}
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer dev.Close() //nolint:errcheck
|
|
|
|
mp, err := mount.SystemMountPointForLabel(dev.BlockDevice, constants.BootPartitionLabel)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if mp == nil {
|
|
return nil
|
|
}
|
|
|
|
alreadyMounted, err := mp.IsMounted()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !alreadyMounted {
|
|
if err = mp.Mount(); err != nil {
|
|
return err
|
|
}
|
|
|
|
defer mp.Unmount() //nolint:errcheck
|
|
}
|
|
|
|
conf, err := grub.Read(grub.ConfigPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if conf == nil {
|
|
return nil
|
|
}
|
|
|
|
bootEntry, err := grub.ParseBootLabel(label)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if conf.Default != bootEntry {
|
|
conf.Default, conf.Fallback = bootEntry, conf.Default
|
|
if err = conf.Write(grub.ConfigPath); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if _, err = metaState.DeleteTag(context.Background(), meta.Upgrade); err != nil {
|
|
return err
|
|
}
|
|
|
|
return metaState.Flush()
|
|
}
|