Skip to content

Commit

Permalink
refactor: update go-blockdevice and restructure disk interaction code
Browse files Browse the repository at this point in the history
This refactoring is required to simplify the work to be done to support
disk encryption.

Tried to minimize amount of queries done by `blockdevice` `probe`
methods.
Instead, where we have `runtime.Runtime` we get all required blockdevices
there from blockdevice cache stored in `State().Machine().Disk()`.
This opens a way to store encryption settings in the `Partition`
objects.

Signed-off-by: Artem Chernyshev <artem.0xD2@gmail.com>
  • Loading branch information
Unix4ever committed Jan 28, 2021
1 parent 0aaf8fa commit a83af03
Show file tree
Hide file tree
Showing 21 changed files with 244 additions and 148 deletions.
42 changes: 23 additions & 19 deletions cmd/installer/pkg/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"log"
"path/filepath"

"github.com/talos-systems/go-blockdevice/blockdevice/probe"
"github.com/talos-systems/go-blockdevice/blockdevice"
"github.com/talos-systems/go-procfs/procfs"
"golang.org/x/sys/unix"

Expand Down Expand Up @@ -113,38 +113,42 @@ func NewInstaller(cmdline *procfs.Cmdline, seq runtime.Sequence, opts *Options)
func (i *Installer) probeBootPartition() error {
// there's no reason to discover boot partition if the disk is about to be wiped
if !i.options.Zero {
if dev, err := probe.DevForFileSystemLabel(i.options.Disk, constants.BootPartitionLabel); err != nil {
dev, err := blockdevice.Open(i.options.Disk)
if err != nil {
i.bootPartitionFound = false
} else {
//nolint: errcheck
defer dev.Close()

return err
}

defer dev.Close() // nolint:errcheck

if part, err := dev.GetPartition(constants.BootPartitionLabel); err != nil {
i.bootPartitionFound = false
} else {
i.bootPartitionFound = true

// mount the boot partition temporarily to find the bootloader labels
mountpoints := mount.NewMountPoints()

mountpoint := mount.NewMountPoint(dev.Path, constants.BootMountPoint, dev.SuperBlock.Type(), unix.MS_NOATIME|unix.MS_RDONLY, "")
partPath, err := part.Path()
if err != nil {
return err
}

fsType, err := part.Filesystem()
if err != nil {
return err
}

mountpoint := mount.NewMountPoint(partPath, constants.BootMountPoint, fsType, unix.MS_NOATIME|unix.MS_RDONLY, "")
mountpoints.Set(constants.BootPartitionLabel, mountpoint)

if err := mount.Mount(mountpoints); err != nil {
log.Printf("warning: failed to mount boot partition %q: %s", dev.Path, err)
log.Printf("warning: failed to mount boot partition %q: %s", partPath, err)
} else {
defer mount.Unmount(mountpoints) //nolint: errcheck
}
}

// try legacy boot partition
//
// TODO: remove this in Talos 0.8 (only required for upgrading from 0.6)
if !i.bootPartitionFound {
if dev, err := probe.DevForFileSystemLabel(i.options.Disk, constants.LegacyBootPartitionLabel); err == nil {
//nolint: errcheck
defer dev.Close()

i.bootPartitionFound = true
}
}
}

var err error
Expand Down
21 changes: 16 additions & 5 deletions cmd/installer/pkg/install/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
"errors"
"fmt"

"github.com/talos-systems/go-blockdevice/blockdevice/probe"
"github.com/talos-systems/go-blockdevice/blockdevice"
"github.com/talos-systems/go-blockdevice/blockdevice/filesystem"

"github.com/talos-systems/talos/pkg/machinery/constants"
)
Expand Down Expand Up @@ -50,9 +51,9 @@ func VerifyBootPartition(opts *Options) (err error) {
// VerifyDiskAvailability verifies that no filesystems currently exist with
// the labels used by the OS.
func VerifyDiskAvailability(devpath, label string) (err error) {
var dev *probe.ProbedBlockDevice
var dev *blockdevice.BlockDevice

if dev, err = probe.DevForFileSystemLabel(devpath, label); err != nil {
if dev, err = blockdevice.Open(devpath); err != nil {
// We return here because we only care if we can discover the
// device successfully and confirm that the disk is not in use.
// TODO(andrewrynhard): We should return a custom error type here
Expand All @@ -63,8 +64,18 @@ func VerifyDiskAvailability(devpath, label string) (err error) {
// nolint: errcheck
defer dev.Close()

if dev.SuperBlock != nil {
return fmt.Errorf("target install device %s is not empty, found existing %s file system", label, dev.SuperBlock.Type())
part, err := dev.GetPartition(label)
if err != nil {
return err
}

fsType, err := part.Filesystem()
if err != nil {
return err
}

if fsType != filesystem.Unknown {
return fmt.Errorf("target install device %s is not empty, found existing %s file system", label, fsType)
}

return nil
Expand Down
39 changes: 17 additions & 22 deletions cmd/talosctl/cmd/mgmt/cluster/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,13 @@ func create(ctx context.Context) (err error) {
var cfg config.Provider

nodeReq := provision.NodeRequest{
Name: fmt.Sprintf("%s-master-%d", clusterName, i+1),
Type: machine.TypeControlPlane,
IP: ips[i],
Memory: memory,
NanoCPUs: nanoCPUs,
Disks: disks,
Name: fmt.Sprintf("%s-master-%d", clusterName, i+1),
Type: machine.TypeControlPlane,
IP: ips[i],
Memory: memory,
NanoCPUs: nanoCPUs,
Disks: disks,
SkipInjectingConfig: skipInjectingConfig,
}

if i == 0 {
Expand All @@ -349,21 +350,14 @@ func create(ctx context.Context) (err error) {
}
}

if !skipInjectingConfig {
nodeReq.Config = cfg
}

nodeReq.Config = cfg
request.Nodes = append(request.Nodes, nodeReq)
}

for i := 1; i <= workers; i++ {
name := fmt.Sprintf("%s-worker-%d", clusterName, i)

var cfg config.Provider

if !skipInjectingConfig {
cfg = configBundle.Join()
}
cfg := configBundle.Join()

ip := ips[masters+i-1]

Expand All @@ -376,13 +370,14 @@ func create(ctx context.Context) (err error) {

request.Nodes = append(request.Nodes,
provision.NodeRequest{
Name: name,
Type: machine.TypeJoin,
IP: ip,
Memory: memory,
NanoCPUs: nanoCPUs,
Disks: disks,
Config: cfg,
Name: name,
Type: machine.TypeJoin,
IP: ip,
Memory: memory,
NanoCPUs: nanoCPUs,
Disks: disks,
Config: cfg,
SkipInjectingConfig: skipInjectingConfig,
})
}

Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ require (
github.com/stretchr/testify v1.7.0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
github.com/talos-systems/crypto v0.2.1-0.20210125160556-cf75519cab82
github.com/talos-systems/go-blockdevice v0.1.1-0.20201218174450-f2728a581972
github.com/talos-systems/go-blockdevice v0.1.1-0.20210126125338-5a1c7f768e01
github.com/talos-systems/go-loadbalancer v0.1.0
github.com/talos-systems/go-procfs v0.0.0-20210108152626-8cbc42d3dc24
github.com/talos-systems/go-retry v0.2.0
Expand All @@ -89,7 +89,6 @@ require (
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/freddierice/go-losetup.v1 v1.0.0-20170407175016-fc9adea44124
gopkg.in/fsnotify.v1 v1.4.7
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
Expand Down
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -860,13 +860,14 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/talos-systems/crypto v0.2.1-0.20210125160556-cf75519cab82 h1:5TsM3o/yJJF6kakHyPee88D0yWNNDNKZJ2NCX9MFsKk=
github.com/talos-systems/crypto v0.2.1-0.20210125160556-cf75519cab82/go.mod h1:OXCK52Q0dzm88YRG4VdTBdidkPUtqrCxCyW7bUs4DAw=
github.com/talos-systems/go-blockdevice v0.1.1-0.20201218174450-f2728a581972 h1:/yEPl6h6+pK9XIfQEiZ989GDuw6dCUBeinzUcCu6dyY=
github.com/talos-systems/go-blockdevice v0.1.1-0.20201218174450-f2728a581972/go.mod h1:efEE9wjtgxiovqsZAV39xlOd/AOI/0sLuZqb5jEgeqo=
github.com/talos-systems/go-blockdevice v0.1.1-0.20210126125338-5a1c7f768e01 h1:Efm20xEYOuiSh0Mct8kBudZoS88z5I+fegt5M6Xwqn4=
github.com/talos-systems/go-blockdevice v0.1.1-0.20210126125338-5a1c7f768e01/go.mod h1:DGbop5CJa0PYdhQK9cNVF61pPJNedas1m7Gi/qAnrsM=
github.com/talos-systems/go-loadbalancer v0.1.0 h1:MQFONvSjoleU8RrKq1O1Z8CyTCJGd4SLqdAHDlR6o9s=
github.com/talos-systems/go-loadbalancer v0.1.0/go.mod h1:D5Qjfz+29WVjONWECZvOkmaLsBb3f5YeWME0u/5HmIc=
github.com/talos-systems/go-procfs v0.0.0-20210108152626-8cbc42d3dc24 h1:fN8vYvlB9XBQ5aImb1vLgR0ZaDwvfZfBMptqkpi3aEg=
github.com/talos-systems/go-procfs v0.0.0-20210108152626-8cbc42d3dc24/go.mod h1:ATyUGFQIW8OnbnmvqefZWVPgL9g+CAmXHfkgny21xX8=
github.com/talos-systems/go-retry v0.1.0/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM=
github.com/talos-systems/go-retry v0.1.1-0.20201113203059-8c63d290a688/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM=
github.com/talos-systems/go-retry v0.2.0 h1:YpQHmtTZ2k0i/bBYRIasdVmF0XaiISVJUOrmZ6FzgLU=
github.com/talos-systems/go-retry v0.2.0/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM=
github.com/talos-systems/go-smbios v0.0.0-20200807005123-80196199691e h1:uCp8BfH4Ky2R1XkOKA5pSZpeMMyt0AbH29PIrkoBlaM=
Expand Down Expand Up @@ -1123,9 +1124,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,12 @@ func (s *Server) Rollback(ctx context.Context, in *machine.RollbackRequest) (*ma
}

if err := func() error {
if err := mount.SystemPartitionMount(constants.BootPartitionLabel); err != nil {
if err := mount.SystemPartitionMount(s.Controller.Runtime(), constants.BootPartitionLabel); err != nil {
return fmt.Errorf("error mounting boot partition: %w", err)
}

defer func() {
if err := mount.SystemPartitionUnmount(constants.BootPartitionLabel); err != nil {
if err := mount.SystemPartitionUnmount(s.Controller.Runtime(), constants.BootPartitionLabel); err != nil {
log.Printf("failed unmounting boot partition: %s", err)
}
}()
Expand Down
6 changes: 6 additions & 0 deletions internal/app/machined/pkg/runtime/disk/disk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// 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 disk contains abstract utility function to filter disks in MachineState.Disk call.
package disk
20 changes: 20 additions & 0 deletions internal/app/machined/pkg/runtime/disk/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 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 disk

// Option defines a function that can alter MachineState.Disk() method output.
type Option func(options *Options)

// Options contains disk selection options.
type Options struct {
Label string
}

// WithPartitionLabel select a disk which has the partition labeled.
func WithPartitionLabel(label string) Option {
return func(opts *Options) {
opts.Label = label
}
}
3 changes: 2 additions & 1 deletion internal/app/machined/pkg/runtime/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/talos-systems/os-runtime/pkg/state"
"github.com/talos-systems/os-runtime/pkg/state/registry"

"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/disk"
"github.com/talos-systems/talos/pkg/machinery/config"
)

Expand All @@ -28,7 +29,7 @@ type Machine interface {

// MachineState defines the machined state.
type MachineState interface {
Disk() *probe.ProbedBlockDevice
Disk(options ...disk.Option) *probe.ProbedBlockDevice
Close() error
Installed() bool
IsInstallStaged() bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import (
"strings"
"text/template"

"github.com/talos-systems/go-blockdevice/blockdevice/probe"
"github.com/talos-systems/go-blockdevice/blockdevice/util"
"github.com/talos-systems/go-blockdevice/blockdevice"

"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/machinery/constants"
Expand Down Expand Up @@ -118,22 +117,23 @@ func (g *Grub) Install(fallback string, config interface{}, sequence runtime.Seq
return err
}

dev, err := probe.DevForFileSystemLabel(g.BootDisk, constants.BootPartitionLabel)
dev, err := blockdevice.Open(g.BootDisk)
if err != nil {
return fmt.Errorf("failed to probe boot partition: %w", err)
return err
}

// nolint: errcheck
defer dev.Close()

blk, err := util.DevnameFromPartname(dev.Path)
// verify that BootDisk has boot partition
_, err = dev.GetPartition(constants.BootPartitionLabel)
if err != nil {
return err
}

loopDevice := strings.HasPrefix(blk, "loop")
blk := dev.Device().Name()

blk = fmt.Sprintf("/dev/%s", blk)
loopDevice := strings.HasPrefix(blk, "/dev/loop")

// default: run for GRUB default platform
platforms := []string{""}
Expand Down
14 changes: 12 additions & 2 deletions internal/app/machined/pkg/runtime/v1alpha1/bootloader/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,23 @@ type Meta struct {

// NewMeta initializes and returns a `Meta`.
func NewMeta() (meta *Meta, err error) {
var f *os.File
var (
f *os.File
dev *probe.ProbedBlockDevice
)

f, err = probe.GetPartitionWithName(constants.MetaPartitionLabel)
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/url"
"path/filepath"

"github.com/talos-systems/go-blockdevice/blockdevice/filesystem"
"github.com/talos-systems/go-blockdevice/blockdevice/probe"
"github.com/talos-systems/go-procfs/procfs"
"github.com/talos-systems/go-smbios/smbios"
Expand Down Expand Up @@ -113,7 +114,16 @@ func readConfigFromISO() (b []byte, err error) {
// nolint: errcheck
defer dev.Close()

if err = unix.Mount(dev.Path, mnt, dev.SuperBlock.Type(), unix.MS_RDONLY, ""); err != nil {
sb, err := filesystem.Probe(dev.Device().Name())
if err != nil {
return nil, err
}

if sb == nil {
return nil, fmt.Errorf("failed to get filesystem type")
}

if err = unix.Mount(dev.Device().Name(), mnt, sb.Type(), unix.MS_RDONLY, ""); err != nil {
return nil, fmt.Errorf("failed to mount iso: %w", err)
}

Expand Down

0 comments on commit a83af03

Please sign in to comment.