mirror of
https://github.com/siderolabs/talos.git
synced 2025-09-17 03:41:11 +02:00
Fix all discovered issues. Detected couple bugs, fixed them as well. Signed-off-by: Artem Chernyshev <artem.0xD2@gmail.com>
125 lines
2.6 KiB
Go
125 lines
2.6 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 bootloader
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/talos-systems/go-blockdevice/blockdevice/probe"
|
|
|
|
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/adv"
|
|
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/adv/syslinux"
|
|
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/adv/talos"
|
|
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub"
|
|
"github.com/talos-systems/talos/pkg/machinery/constants"
|
|
)
|
|
|
|
// Meta represents the meta reader.
|
|
type Meta struct {
|
|
*os.File
|
|
LegacyADV adv.ADV
|
|
ADV adv.ADV
|
|
}
|
|
|
|
// NewMeta initializes and returns a `Meta`.
|
|
func NewMeta() (meta *Meta, err error) {
|
|
var (
|
|
f *os.File
|
|
dev *probe.ProbedBlockDevice
|
|
)
|
|
|
|
dev, err = probe.GetDevWithPartitionName(constants.MetaPartitionLabel)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
part, err := dev.OpenPartition(constants.MetaPartitionLabel)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
f = part.Device()
|
|
|
|
adv, err := talos.NewADV(f)
|
|
if adv == nil && err != nil {
|
|
// if adv is not nil, but err is nil, it might be missing ADV, ignore it
|
|
return nil, err
|
|
}
|
|
|
|
legacyAdv, err := syslinux.NewADV(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Meta{
|
|
File: f,
|
|
LegacyADV: legacyAdv,
|
|
ADV: adv,
|
|
}, nil
|
|
}
|
|
|
|
func (m *Meta) Write() error {
|
|
serialized, err := m.ADV.Bytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := m.File.WriteAt(serialized, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if n != len(serialized) {
|
|
return fmt.Errorf("expected to write %d bytes, wrote %d", len(serialized), n)
|
|
}
|
|
|
|
serialized, err = m.LegacyADV.Bytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
offset, err := m.File.Seek(-int64(len(serialized)), io.SeekEnd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err = m.File.WriteAt(serialized, offset)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if n != len(serialized) {
|
|
return fmt.Errorf("expected to write %d bytes, wrote %d", len(serialized), n)
|
|
}
|
|
|
|
return m.File.Sync()
|
|
}
|
|
|
|
// Revert reverts the default bootloader label to the previous installation.
|
|
func (m *Meta) Revert() (err error) {
|
|
label, ok := m.LegacyADV.ReadTag(adv.Upgrade)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
if label == "" {
|
|
m.LegacyADV.DeleteTag(adv.Upgrade)
|
|
|
|
return m.Write()
|
|
}
|
|
|
|
g := &grub.Grub{}
|
|
|
|
if err = g.Default(label); err != nil {
|
|
return err
|
|
}
|
|
|
|
m.LegacyADV.DeleteTag(adv.Upgrade)
|
|
|
|
return m.Write()
|
|
}
|