github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/osutil/disks/disks_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package disks_test
    21  
    22  import (
    23  	"fmt"
    24  	"io/ioutil"
    25  	"os"
    26  	"path/filepath"
    27  
    28  	. "gopkg.in/check.v1"
    29  
    30  	"golang.org/x/xerrors"
    31  
    32  	"github.com/snapcore/snapd/dirs"
    33  	"github.com/snapcore/snapd/osutil"
    34  	"github.com/snapcore/snapd/osutil/disks"
    35  	"github.com/snapcore/snapd/testutil"
    36  )
    37  
    38  type diskSuite struct {
    39  	testutil.BaseTest
    40  }
    41  
    42  var _ = Suite(&diskSuite{})
    43  
    44  func (s *diskSuite) SetUpTest(c *C) {
    45  	dirs.SetRootDir(c.MkDir())
    46  }
    47  
    48  func (s *diskSuite) TestDiskFromMountPointUnhappyMissingMountpoint(c *C) {
    49  	// no mount points
    50  	restore := osutil.MockMountInfo(``)
    51  	defer restore()
    52  
    53  	_, err := disks.DiskFromMountPoint("/run/mnt/blah", nil)
    54  	c.Assert(err, ErrorMatches, "cannot find mountpoint \"/run/mnt/blah\"")
    55  }
    56  
    57  func (s *diskSuite) TestDiskFromMountPointUnhappyMissingUdevProps(c *C) {
    58  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/vda4 rw
    59  `)
    60  	defer restore()
    61  
    62  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
    63  		c.Assert(dev, Equals, "/dev/vda4")
    64  		return map[string]string{
    65  			"prop": "hello",
    66  		}, nil
    67  	})
    68  	defer restore()
    69  
    70  	_, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
    71  	c.Assert(err, ErrorMatches, "cannot find disk for partition /dev/vda4, incomplete udev output")
    72  }
    73  
    74  func (s *diskSuite) TestDiskFromMountPointUnhappyBadUdevPropsMountpointPartition(c *C) {
    75  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/vda4 rw
    76  `)
    77  	defer restore()
    78  
    79  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
    80  		c.Assert(dev, Equals, "/dev/vda4")
    81  		return map[string]string{
    82  			"ID_PART_ENTRY_DISK": "not-a-number",
    83  		}, nil
    84  	})
    85  	defer restore()
    86  
    87  	_, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
    88  	c.Assert(err, ErrorMatches, `cannot find disk for partition /dev/vda4, bad udev output: invalid device number format: \(expected <int>:<int>\)`)
    89  }
    90  
    91  func (s *diskSuite) TestDiskFromMountPointUnhappyIsDecryptedDeviceNotDiskDevice(c *C) {
    92  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/vda4 rw
    93  `)
    94  	defer restore()
    95  
    96  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
    97  		switch dev {
    98  		case "/dev/vda4":
    99  			return map[string]string{
   100  				"ID_PART_ENTRY_DISK": "42:0",
   101  				// DEVTYPE == partition is unexpected for this, so this makes
   102  				// DiskFromMountPoint fail, as decrypted devices should not be
   103  				// direct partitions, they should be mapper device volumes/disks
   104  				"DEVTYPE": "partition",
   105  			}, nil
   106  		default:
   107  			c.Logf("unexpected udev device properties requested: %s", dev)
   108  			c.Fail()
   109  			return nil, fmt.Errorf("unexpected udev device")
   110  		}
   111  	})
   112  	defer restore()
   113  
   114  	opts := &disks.Options{IsDecryptedDevice: true}
   115  	_, err := disks.DiskFromMountPoint("/run/mnt/point", opts)
   116  	c.Assert(err, ErrorMatches, `mountpoint source /dev/vda4 is not a decrypted device: devtype is not disk \(is partition\)`)
   117  }
   118  
   119  func (s *diskSuite) TestDiskFromMountPointUnhappyIsDecryptedDeviceNoSysfs(c *C) {
   120  	restore := osutil.MockMountInfo(`130 30 252:0 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/mapper/something rw
   121  `)
   122  	defer restore()
   123  
   124  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
   125  		switch dev {
   126  		case "/dev/mapper/something":
   127  			return map[string]string{
   128  				"DEVTYPE": "disk",
   129  			}, nil
   130  		default:
   131  			c.Logf("unexpected udev device properties requested: %s", dev)
   132  			c.Fail()
   133  			return nil, fmt.Errorf("unexpected udev device")
   134  
   135  		}
   136  	})
   137  	defer restore()
   138  
   139  	// no sysfs files mocking
   140  
   141  	opts := &disks.Options{IsDecryptedDevice: true}
   142  	_, err := disks.DiskFromMountPoint("/run/mnt/point", opts)
   143  	c.Assert(err, ErrorMatches, `mountpoint source /dev/mapper/something is not a decrypted device: could not read device mapper metadata: open /sys/dev/block/252:0/dm/uuid: no such file or directory`)
   144  }
   145  
   146  func (s *diskSuite) TestDiskFromMountPointHappyNoPartitions(c *C) {
   147  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/vda4 rw
   148  `)
   149  	defer restore()
   150  
   151  	// mock just the partition's disk major minor in udev, but no actual
   152  	// partitions
   153  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
   154  		switch dev {
   155  		case "/dev/block/42:1", "/dev/vda4":
   156  			return map[string]string{
   157  				"ID_PART_ENTRY_DISK": "42:0",
   158  			}, nil
   159  		default:
   160  			c.Logf("unexpected udev device properties requested: %s", dev)
   161  			c.Fail()
   162  			return nil, fmt.Errorf("unexpected udev device")
   163  
   164  		}
   165  	})
   166  	defer restore()
   167  
   168  	disk, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
   169  	c.Assert(err, IsNil)
   170  	c.Assert(disk.Dev(), Equals, "42:0")
   171  	c.Assert(disk.HasPartitions(), Equals, true)
   172  	// trying to search for any labels though will fail
   173  	_, err = disk.FindMatchingPartitionUUID("ubuntu-boot")
   174  	c.Assert(err, ErrorMatches, "no partitions found for disk 42:0")
   175  }
   176  
   177  func (s *diskSuite) TestDiskFromMountPointHappyOnePartition(c *C) {
   178  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/vda1 rw
   179  `)
   180  	defer restore()
   181  
   182  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
   183  		switch dev {
   184  		case "/dev/block/42:1", "/dev/vda1":
   185  			return map[string]string{
   186  				"ID_PART_ENTRY_DISK": "42:0",
   187  				"DEVTYPE":            "partition",
   188  				"ID_FS_LABEL_ENC":    "ubuntu-seed",
   189  				"ID_PART_ENTRY_UUID": "ubuntu-seed-partuuid",
   190  			}, nil
   191  		case "/dev/block/42:2":
   192  			return nil, fmt.Errorf("Unknown device 42:2")
   193  		default:
   194  			c.Logf("unexpected udev device properties requested: %s", dev)
   195  			c.Fail()
   196  			return nil, fmt.Errorf("unexpected udev device")
   197  
   198  		}
   199  	})
   200  	defer restore()
   201  
   202  	d, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
   203  	c.Assert(err, IsNil)
   204  	c.Assert(d.Dev(), Equals, "42:0")
   205  	c.Assert(d.HasPartitions(), Equals, true)
   206  
   207  	label, err := d.FindMatchingPartitionUUID("ubuntu-seed")
   208  	c.Assert(err, IsNil)
   209  	c.Assert(label, Equals, "ubuntu-seed-partuuid")
   210  }
   211  
   212  func (s *diskSuite) TestDiskFromMountPointHappy(c *C) {
   213  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/vda1 rw
   214  `)
   215  	defer restore()
   216  
   217  	udevadmCmd := testutil.MockCommand(c, "udevadm", `
   218  if [ "$*" = "info --query property --name /dev/vda1" ]; then
   219  	echo "ID_PART_ENTRY_DISK=42:0"
   220  else
   221  	echo "unexpected arguments"
   222  	exit 1
   223  fi
   224  `)
   225  
   226  	d, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
   227  	c.Assert(err, IsNil)
   228  	c.Assert(d.Dev(), Equals, "42:0")
   229  	c.Assert(d.HasPartitions(), Equals, true)
   230  
   231  	c.Assert(udevadmCmd.Calls(), DeepEquals, [][]string{
   232  		{"udevadm", "info", "--query", "property", "--name", "/dev/vda1"},
   233  	})
   234  }
   235  
   236  func (s *diskSuite) TestDiskFromMountPointVolumeHappy(c *C) {
   237  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/mapper/something rw
   238  `)
   239  	defer restore()
   240  
   241  	udevadmCmd := testutil.MockCommand(c, "udevadm", `
   242  if [ "$*" = "info --query property --name /dev/mapper/something" ]; then
   243  	# not a partition, so no ID_PART_ENTRY_DISK, but we will have DEVTYPE=disk
   244  	echo "DEVTYPE=disk"
   245  else
   246  	echo "unexpected arguments"
   247  	exit 1
   248  fi
   249  `)
   250  
   251  	d, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
   252  	c.Assert(err, IsNil)
   253  	c.Assert(d.Dev(), Equals, "42:1")
   254  	c.Assert(d.HasPartitions(), Equals, false)
   255  
   256  	c.Assert(udevadmCmd.Calls(), DeepEquals, [][]string{
   257  		{"udevadm", "info", "--query", "property", "--name", "/dev/mapper/something"},
   258  	})
   259  }
   260  
   261  func (s *diskSuite) TestDiskFromMountPointIsDecryptedDeviceVolumeHappy(c *C) {
   262  	restore := osutil.MockMountInfo(`130 30 242:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/mapper/something rw
   263  `)
   264  	defer restore()
   265  
   266  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
   267  		switch dev {
   268  		case "/dev/mapper/something":
   269  			return map[string]string{
   270  				"DEVTYPE": "disk",
   271  			}, nil
   272  		case "/dev/disk/by-uuid/5a522809-c87e-4dfa-81a8-8dc5667d1304":
   273  			return map[string]string{
   274  				"DEVTYPE": "disk",
   275  			}, nil
   276  		default:
   277  			c.Logf("unexpected udev device properties requested: %s", dev)
   278  			c.Fail()
   279  			return nil, fmt.Errorf("unexpected udev device")
   280  
   281  		}
   282  	})
   283  	defer restore()
   284  
   285  	// mock the /sys/dev/block dir
   286  	devBlockDir := filepath.Join(dirs.SysfsDir, "dev", "block")
   287  	restore = disks.MockDevBlockDir(devBlockDir)
   288  	defer restore()
   289  
   290  	// mock the sysfs dm uuid and name files
   291  	dmDir := filepath.Join(devBlockDir, "242:1", "dm")
   292  	err := os.MkdirAll(dmDir, 0755)
   293  	c.Assert(err, IsNil)
   294  
   295  	b := []byte("something")
   296  	err = ioutil.WriteFile(filepath.Join(dmDir, "name"), b, 0644)
   297  	c.Assert(err, IsNil)
   298  
   299  	b = []byte("CRYPT-LUKS2-5a522809c87e4dfa81a88dc5667d1304-something")
   300  	err = ioutil.WriteFile(filepath.Join(dmDir, "uuid"), b, 0644)
   301  	c.Assert(err, IsNil)
   302  
   303  	opts := &disks.Options{IsDecryptedDevice: true}
   304  	d, err := disks.DiskFromMountPoint("/run/mnt/point", opts)
   305  	c.Assert(err, IsNil)
   306  	c.Assert(d.Dev(), Equals, "242:1")
   307  	c.Assert(d.HasPartitions(), Equals, false)
   308  }
   309  
   310  func (s *diskSuite) TestDiskFromMountPointNotDiskUnsupported(c *C) {
   311  	restore := osutil.MockMountInfo(`130 30 42:1 / /run/mnt/point rw,relatime shared:54 - ext4 /dev/not-a-disk rw
   312  `)
   313  	defer restore()
   314  
   315  	udevadmCmd := testutil.MockCommand(c, "udevadm", `
   316  if [ "$*" = "info --query property --name /dev/not-a-disk" ]; then
   317  	echo "DEVTYPE=not-a-disk"
   318  else
   319  	echo "unexpected arguments"
   320  	exit 1
   321  fi
   322  `)
   323  
   324  	_, err := disks.DiskFromMountPoint("/run/mnt/point", nil)
   325  	c.Assert(err, ErrorMatches, "unsupported DEVTYPE \"not-a-disk\" for mount point source /dev/not-a-disk")
   326  
   327  	c.Assert(udevadmCmd.Calls(), DeepEquals, [][]string{
   328  		{"udevadm", "info", "--query", "property", "--name", "/dev/not-a-disk"},
   329  	})
   330  }
   331  
   332  func (s *diskSuite) TestDiskFromMountPointPartitionsHappy(c *C) {
   333  	restore := osutil.MockMountInfo(`130 30 42:4 / /run/mnt/data rw,relatime shared:54 - ext4 /dev/vda4 rw
   334   130 30 42:4 / /run/mnt/ubuntu-boot rw,relatime shared:54 - ext4 /dev/vda3 rw
   335  `)
   336  	defer restore()
   337  
   338  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
   339  		switch dev {
   340  		case "/dev/vda4", "/dev/vda3":
   341  			return map[string]string{
   342  				"ID_PART_ENTRY_DISK": "42:0",
   343  			}, nil
   344  		case "/dev/block/42:1":
   345  			return map[string]string{
   346  				// bios-boot does not have a filesystem label, so it shouldn't
   347  				// be found, but this is not fatal
   348  				"DEVTYPE":            "partition",
   349  				"ID_PART_ENTRY_UUID": "bios-boot-partuuid",
   350  			}, nil
   351  		case "/dev/block/42:2":
   352  			return map[string]string{
   353  				"DEVTYPE":            "partition",
   354  				"ID_FS_LABEL_ENC":    "ubuntu-seed",
   355  				"ID_PART_ENTRY_UUID": "ubuntu-seed-partuuid",
   356  			}, nil
   357  		case "/dev/block/42:3":
   358  			return map[string]string{
   359  				"DEVTYPE":            "partition",
   360  				"ID_FS_LABEL_ENC":    "ubuntu-boot",
   361  				"ID_PART_ENTRY_UUID": "ubuntu-boot-partuuid",
   362  			}, nil
   363  		case "/dev/block/42:4":
   364  			return map[string]string{
   365  				"DEVTYPE":            "partition",
   366  				"ID_FS_LABEL_ENC":    "ubuntu-data",
   367  				"ID_PART_ENTRY_UUID": "ubuntu-data-partuuid",
   368  			}, nil
   369  		case "/dev/block/42:5":
   370  			return nil, fmt.Errorf("Unknown device 42:5")
   371  		default:
   372  			c.Logf("unexpected udev device properties requested: %s", dev)
   373  			c.Fail()
   374  			return nil, fmt.Errorf("unexpected udev device")
   375  
   376  		}
   377  	})
   378  	defer restore()
   379  
   380  	ubuntuDataDisk, err := disks.DiskFromMountPoint("/run/mnt/data", nil)
   381  	c.Assert(err, IsNil)
   382  	c.Assert(ubuntuDataDisk, Not(IsNil))
   383  	c.Assert(ubuntuDataDisk.Dev(), Equals, "42:0")
   384  
   385  	// we have the ubuntu-seed, ubuntu-boot, and ubuntu-data partition labels
   386  	for _, label := range []string{"ubuntu-seed", "ubuntu-boot", "ubuntu-data"} {
   387  		id, err := ubuntuDataDisk.FindMatchingPartitionUUID(label)
   388  		c.Assert(err, IsNil)
   389  		c.Assert(id, Equals, label+"-partuuid")
   390  	}
   391  
   392  	// and the mountpoint for ubuntu-boot at /run/mnt/ubuntu-boot matches the
   393  	// same disk
   394  	matches, err := ubuntuDataDisk.MountPointIsFromDisk("/run/mnt/ubuntu-boot", nil)
   395  	c.Assert(err, IsNil)
   396  	c.Assert(matches, Equals, true)
   397  
   398  	// and we can find the partition for ubuntu-boot first and then match
   399  	// that with ubuntu-data too
   400  	ubuntuBootDisk, err := disks.DiskFromMountPoint("/run/mnt/ubuntu-boot", nil)
   401  	c.Assert(err, IsNil)
   402  	c.Assert(ubuntuBootDisk, Not(IsNil))
   403  	c.Assert(ubuntuBootDisk.Dev(), Equals, "42:0")
   404  
   405  	// we have the ubuntu-seed, ubuntu-boot, and ubuntu-data partition labels
   406  	for _, label := range []string{"ubuntu-seed", "ubuntu-boot", "ubuntu-data"} {
   407  		id, err := ubuntuBootDisk.FindMatchingPartitionUUID(label)
   408  		c.Assert(err, IsNil)
   409  		c.Assert(id, Equals, label+"-partuuid")
   410  	}
   411  
   412  	// and the mountpoint for ubuntu-boot at /run/mnt/ubuntu-boot matches the
   413  	// same disk
   414  	matches, err = ubuntuBootDisk.MountPointIsFromDisk("/run/mnt/data", nil)
   415  	c.Assert(err, IsNil)
   416  	c.Assert(matches, Equals, true)
   417  
   418  	// finally we can't find the bios-boot partition because it has no label
   419  	_, err = ubuntuBootDisk.FindMatchingPartitionUUID("bios-boot")
   420  	c.Assert(err, ErrorMatches, "filesystem label \"bios-boot\" not found")
   421  	var notFoundErr disks.FilesystemLabelNotFoundError
   422  	c.Assert(xerrors.As(err, &notFoundErr), Equals, true)
   423  
   424  	_, err = ubuntuDataDisk.FindMatchingPartitionUUID("bios-boot")
   425  	c.Assert(err, ErrorMatches, "filesystem label \"bios-boot\" not found")
   426  	c.Assert(xerrors.As(err, &notFoundErr), Equals, true)
   427  }
   428  
   429  func (s *diskSuite) TestDiskFromMountPointDecryptedDevicePartitionsHappy(c *C) {
   430  	restore := osutil.MockMountInfo(`130 30 252:0 / /run/mnt/data rw,relatime shared:54 - ext4 /dev/mapper/ubuntu-data-3776bab4-8bcc-46b7-9da2-6a84ce7f93b4 rw
   431   130 30 42:4 / /run/mnt/ubuntu-boot rw,relatime shared:54 - ext4 /dev/vda3 rw
   432  `)
   433  	defer restore()
   434  
   435  	restore = disks.MockUdevPropertiesForDevice(func(dev string) (map[string]string, error) {
   436  		switch dev {
   437  		case "/dev/mapper/ubuntu-data-3776bab4-8bcc-46b7-9da2-6a84ce7f93b4":
   438  			return map[string]string{
   439  				// the mapper device is a disk/volume
   440  				"DEVTYPE": "disk",
   441  			}, nil
   442  		case "/dev/vda4",
   443  			"/dev/vda3",
   444  			"/dev/disk/by-uuid/5a522809-c87e-4dfa-81a8-8dc5667d1304":
   445  			return map[string]string{
   446  				"ID_PART_ENTRY_DISK": "42:0",
   447  				"DEVTYPE":            "partition",
   448  			}, nil
   449  		case "/dev/block/42:1":
   450  			return map[string]string{
   451  				// bios-boot does not have a filesystem label, so it shouldn't
   452  				// be found, but this is not fatal
   453  				"DEVTYPE":            "partition",
   454  				"ID_PART_ENTRY_UUID": "bios-boot-partuuid",
   455  			}, nil
   456  		case "/dev/block/42:2":
   457  			return map[string]string{
   458  				"DEVTYPE":            "partition",
   459  				"ID_FS_LABEL_ENC":    "ubuntu-seed",
   460  				"ID_PART_ENTRY_UUID": "ubuntu-seed-partuuid",
   461  			}, nil
   462  		case "/dev/block/42:3":
   463  			return map[string]string{
   464  				"DEVTYPE":            "partition",
   465  				"ID_FS_LABEL_ENC":    "ubuntu-boot",
   466  				"ID_PART_ENTRY_UUID": "ubuntu-boot-partuuid",
   467  			}, nil
   468  		case "/dev/block/42:4":
   469  			return map[string]string{
   470  				"DEVTYPE":            "partition",
   471  				"ID_FS_LABEL_ENC":    "ubuntu-data-enc",
   472  				"ID_PART_ENTRY_UUID": "ubuntu-data-enc-partuuid",
   473  			}, nil
   474  		case "/dev/block/42:5":
   475  			return nil, fmt.Errorf("Unknown device 42:5")
   476  		default:
   477  			c.Logf("unexpected udev device properties requested: %s", dev)
   478  			c.Fail()
   479  			return nil, fmt.Errorf("unexpected udev device")
   480  
   481  		}
   482  	})
   483  	defer restore()
   484  
   485  	// mock the /sys/dev/block dir
   486  	devBlockDir := filepath.Join(dirs.SysfsDir, "dev", "block")
   487  	restore = disks.MockDevBlockDir(devBlockDir)
   488  	defer restore()
   489  
   490  	// mock the sysfs dm uuid and name files
   491  	dmDir := filepath.Join(devBlockDir, "252:0", "dm")
   492  	err := os.MkdirAll(dmDir, 0755)
   493  	c.Assert(err, IsNil)
   494  
   495  	b := []byte("ubuntu-data-3776bab4-8bcc-46b7-9da2-6a84ce7f93b4")
   496  	err = ioutil.WriteFile(filepath.Join(dmDir, "name"), b, 0644)
   497  	c.Assert(err, IsNil)
   498  
   499  	b = []byte("CRYPT-LUKS2-5a522809c87e4dfa81a88dc5667d1304-ubuntu-data-3776bab4-8bcc-46b7-9da2-6a84ce7f93b4")
   500  	err = ioutil.WriteFile(filepath.Join(dmDir, "uuid"), b, 0644)
   501  	c.Assert(err, IsNil)
   502  
   503  	opts := &disks.Options{IsDecryptedDevice: true}
   504  	ubuntuDataDisk, err := disks.DiskFromMountPoint("/run/mnt/data", opts)
   505  	c.Assert(err, IsNil)
   506  	c.Assert(ubuntuDataDisk, Not(IsNil))
   507  	c.Assert(ubuntuDataDisk.Dev(), Equals, "42:0")
   508  
   509  	// we have the ubuntu-seed, ubuntu-boot, and ubuntu-data partition labels
   510  	for _, label := range []string{"ubuntu-seed", "ubuntu-boot", "ubuntu-data-enc"} {
   511  		id, err := ubuntuDataDisk.FindMatchingPartitionUUID(label)
   512  		c.Assert(err, IsNil)
   513  		c.Assert(id, Equals, label+"-partuuid")
   514  	}
   515  
   516  	// and the mountpoint for ubuntu-boot at /run/mnt/ubuntu-boot matches the
   517  	// same disk
   518  	matches, err := ubuntuDataDisk.MountPointIsFromDisk("/run/mnt/ubuntu-boot", nil)
   519  	c.Assert(err, IsNil)
   520  	c.Assert(matches, Equals, true)
   521  
   522  	// and we can find the partition for ubuntu-boot first and then match
   523  	// that with ubuntu-data too
   524  	ubuntuBootDisk, err := disks.DiskFromMountPoint("/run/mnt/ubuntu-boot", nil)
   525  	c.Assert(err, IsNil)
   526  	c.Assert(ubuntuBootDisk, Not(IsNil))
   527  	c.Assert(ubuntuBootDisk.Dev(), Equals, "42:0")
   528  
   529  	// we have the ubuntu-seed, ubuntu-boot, and ubuntu-data partition labels
   530  	for _, label := range []string{"ubuntu-seed", "ubuntu-boot", "ubuntu-data-enc"} {
   531  		id, err := ubuntuBootDisk.FindMatchingPartitionUUID(label)
   532  		c.Assert(err, IsNil)
   533  		c.Assert(id, Equals, label+"-partuuid")
   534  	}
   535  
   536  	// and the mountpoint for ubuntu-boot at /run/mnt/ubuntu-boot matches the
   537  	// same disk
   538  	matches, err = ubuntuBootDisk.MountPointIsFromDisk("/run/mnt/data", opts)
   539  	c.Assert(err, IsNil)
   540  	c.Assert(matches, Equals, true)
   541  }