github.com/chipaca/snappy@v0.0.0-20210104084008-1f06296fe8ad/gadget/install/partition_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019-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 install_test 21 22 import ( 23 "bytes" 24 "fmt" 25 "io/ioutil" 26 "path/filepath" 27 "testing" 28 "time" 29 30 . "gopkg.in/check.v1" 31 32 "github.com/snapcore/snapd/asserts" 33 "github.com/snapcore/snapd/gadget" 34 "github.com/snapcore/snapd/gadget/install" 35 "github.com/snapcore/snapd/gadget/quantity" 36 "github.com/snapcore/snapd/testutil" 37 ) 38 39 func TestInstall(t *testing.T) { TestingT(t) } 40 41 type partitionTestSuite struct { 42 testutil.BaseTest 43 44 dir string 45 gadgetRoot string 46 cmdPartx *testutil.MockCmd 47 } 48 49 var _ = Suite(&partitionTestSuite{}) 50 51 func (s *partitionTestSuite) SetUpTest(c *C) { 52 s.BaseTest.SetUpTest(c) 53 54 s.dir = c.MkDir() 55 s.gadgetRoot = filepath.Join(c.MkDir(), "gadget") 56 57 s.cmdPartx = testutil.MockCommand(c, "partx", "") 58 s.AddCleanup(s.cmdPartx.Restore) 59 60 cmdSfdisk := testutil.MockCommand(c, "sfdisk", `echo "sfdisk was not mocked"; exit 1`) 61 s.AddCleanup(cmdSfdisk.Restore) 62 cmdLsblk := testutil.MockCommand(c, "lsblk", `echo "lsblk was not mocked"; exit 1`) 63 s.AddCleanup(cmdLsblk.Restore) 64 } 65 66 const ( 67 scriptPartitionsBios = iota 68 scriptPartitionsBiosSeed 69 scriptPartitionsBiosSeedData 70 ) 71 72 func makeSfdiskScript(num int) string { 73 var b bytes.Buffer 74 75 b.WriteString(` 76 >&2 echo "Some warning from sfdisk" 77 echo '{ 78 "partitiontable": { 79 "label": "gpt", 80 "id": "9151F25B-CDF0-48F1-9EDE-68CBD616E2CA", 81 "device": "/dev/node", 82 "unit": "sectors", 83 "firstlba": 34, 84 "lastlba": 8388574, 85 "partitions": [`) 86 87 // BIOS boot partition 88 if num >= scriptPartitionsBios { 89 b.WriteString(` 90 { 91 "node": "/dev/node1", 92 "start": 2048, 93 "size": 2048, 94 "type": "21686148-6449-6E6F-744E-656564454649", 95 "uuid": "2E59D969-52AB-430B-88AC-F83873519F6F", 96 "name": "BIOS Boot" 97 }`) 98 } 99 100 // Seed partition 101 if num >= scriptPartitionsBiosSeed { 102 b.WriteString(`, 103 { 104 "node": "/dev/node2", 105 "start": 4096, 106 "size": 2457600, 107 "type": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", 108 "uuid": "44C3D5C3-CAE1-4306-83E8-DF437ACDB32F", 109 "name": "Recovery" 110 }`) 111 } 112 113 // Data partition 114 if num >= scriptPartitionsBiosSeedData { 115 b.WriteString(`, 116 { 117 "node": "/dev/node3", 118 "start": 2461696, 119 "size": 2457600, 120 "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4", 121 "uuid": "f940029d-bfbb-4887-9d44-321e85c63866", 122 "name": "Writable" 123 }`) 124 } 125 126 b.WriteString(` 127 ] 128 } 129 }'`) 130 return b.String() 131 } 132 133 func makeLsblkScript(num int) string { 134 var b bytes.Buffer 135 136 // BIOS boot partition 137 if num >= scriptPartitionsBios { 138 b.WriteString(` 139 [ "$3" == "/dev/node1" ] && echo '{ 140 "blockdevices": [ {"name": "node1", "fstype": null, "label": null, "uuid": null, "mountpoint": null} ] 141 }'`) 142 } 143 144 // Seed partition 145 if num >= scriptPartitionsBiosSeed { 146 b.WriteString(` 147 [ "$3" == "/dev/node2" ] && echo '{ 148 "blockdevices": [ {"name": "node2", "fstype": "vfat", "label": "ubuntu-seed", "uuid": "A644-B807", "mountpoint": null} ] 149 }'`) 150 } 151 152 // Data partition 153 if num >= scriptPartitionsBiosSeedData { 154 b.WriteString(` 155 [ "$3" == "/dev/node3" ] && echo '{ 156 "blockdevices": [ {"name": "node3", "fstype": "ext4", "label": "ubuntu-data", "uuid": "8781-433a", "mountpoint": null} ] 157 }'`) 158 } 159 160 b.WriteString(` 161 exit 0`) 162 163 return b.String() 164 } 165 166 var mockOnDiskStructureWritable = gadget.OnDiskStructure{ 167 Node: "/dev/node3", 168 LaidOutStructure: gadget.LaidOutStructure{ 169 VolumeStructure: &gadget.VolumeStructure{ 170 Name: "Writable", 171 Size: 1258291200, 172 Type: "83,0FC63DAF-8483-4772-8E79-3D69D8477DE4", 173 Role: "system-data", 174 Label: "ubuntu-data", 175 Filesystem: "ext4", 176 }, 177 StartOffset: 1260388352, 178 Index: 3, 179 }, 180 // expanded to fill the disk 181 Size: 2*quantity.SizeGiB + 845*quantity.SizeMiB + 1031680, 182 } 183 184 var mockOnDiskStructureSave = gadget.OnDiskStructure{ 185 Node: "/dev/node3", 186 LaidOutStructure: gadget.LaidOutStructure{ 187 VolumeStructure: &gadget.VolumeStructure{ 188 Name: "Save", 189 Size: 128 * quantity.SizeMiB, 190 Type: "83,0FC63DAF-8483-4772-8E79-3D69D8477DE4", 191 Role: "system-save", 192 Label: "ubuntu-save", 193 Filesystem: "ext4", 194 }, 195 StartOffset: 1260388352, 196 Index: 3, 197 }, 198 Size: 128 * quantity.SizeMiB, 199 } 200 201 var mockOnDiskStructureWritableAfterSave = gadget.OnDiskStructure{ 202 Node: "/dev/node4", 203 LaidOutStructure: gadget.LaidOutStructure{ 204 VolumeStructure: &gadget.VolumeStructure{ 205 Name: "Writable", 206 Size: 1200 * quantity.SizeMiB, 207 Type: "83,0FC63DAF-8483-4772-8E79-3D69D8477DE4", 208 Role: "system-data", 209 Label: "ubuntu-data", 210 Filesystem: "ext4", 211 }, 212 StartOffset: 1394606080, 213 Index: 4, 214 }, 215 // expanded to fill the disk 216 Size: 2*quantity.SizeGiB + 717*quantity.SizeMiB + 1031680, 217 } 218 219 func (s *partitionTestSuite) TestBuildPartitionList(c *C) { 220 cmdSfdisk := testutil.MockCommand(c, "sfdisk", makeSfdiskScript(scriptPartitionsBiosSeed)) 221 defer cmdSfdisk.Restore() 222 223 cmdLsblk := testutil.MockCommand(c, "lsblk", makeLsblkScript(scriptPartitionsBiosSeed)) 224 defer cmdLsblk.Restore() 225 226 err := makeMockGadget(s.gadgetRoot, gptGadgetContentWithSave) 227 c.Assert(err, IsNil) 228 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 229 c.Assert(err, IsNil) 230 231 dl, err := gadget.OnDiskVolumeFromDevice("/dev/node") 232 c.Assert(err, IsNil) 233 234 // the expected expanded writable partition size is: 235 // start offset = (2M + 1200M), expanded size in sectors = (8388575*512 - start offset)/512 236 sfdiskInput, create := install.BuildPartitionList(dl, pv) 237 c.Assert(sfdiskInput.String(), Equals, 238 `/dev/node3 : start= 2461696, size= 262144, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="Save" 239 /dev/node4 : start= 2723840, size= 5664735, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="Writable" 240 `) 241 c.Check(create, NotNil) 242 c.Assert(create, DeepEquals, []gadget.OnDiskStructure{mockOnDiskStructureSave, mockOnDiskStructureWritableAfterSave}) 243 } 244 245 type uc20Constraints struct{} 246 247 func (c uc20Constraints) Classic() bool { return false } 248 func (c uc20Constraints) Grade() asserts.ModelGrade { return asserts.ModelSigned } 249 250 var uc20mod = uc20Constraints{} 251 252 func (s *partitionTestSuite) TestCreatePartitions(c *C) { 253 cmdSfdisk := testutil.MockCommand(c, "sfdisk", makeSfdiskScript(scriptPartitionsBiosSeed)) 254 defer cmdSfdisk.Restore() 255 256 cmdLsblk := testutil.MockCommand(c, "lsblk", makeLsblkScript(scriptPartitionsBiosSeed)) 257 defer cmdLsblk.Restore() 258 259 calls := 0 260 restore := install.MockEnsureNodesExist(func(ds []gadget.OnDiskStructure, timeout time.Duration) error { 261 calls++ 262 c.Assert(ds, HasLen, 1) 263 c.Assert(ds[0].Node, Equals, "/dev/node3") 264 return nil 265 }) 266 defer restore() 267 268 err := makeMockGadget(s.gadgetRoot, gadgetContent) 269 c.Assert(err, IsNil) 270 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 271 c.Assert(err, IsNil) 272 273 dl, err := gadget.OnDiskVolumeFromDevice("/dev/node") 274 c.Assert(err, IsNil) 275 created, err := install.CreateMissingPartitions(dl, pv) 276 c.Assert(err, IsNil) 277 c.Assert(created, DeepEquals, []gadget.OnDiskStructure{mockOnDiskStructureWritable}) 278 c.Assert(calls, Equals, 1) 279 280 // Check partition table read and write 281 c.Assert(cmdSfdisk.Calls(), DeepEquals, [][]string{ 282 {"sfdisk", "--json", "/dev/node"}, 283 {"sfdisk", "--append", "--no-reread", "/dev/node"}, 284 }) 285 286 // Check partition table update 287 c.Assert(s.cmdPartx.Calls(), DeepEquals, [][]string{ 288 {"partx", "-u", "/dev/node"}, 289 }) 290 } 291 292 func (s *partitionTestSuite) TestRemovePartitionsTrivial(c *C) { 293 // no locally created partitions 294 cmdSfdisk := testutil.MockCommand(c, "sfdisk", makeSfdiskScript(scriptPartitionsBios)) 295 defer cmdSfdisk.Restore() 296 297 cmdLsblk := testutil.MockCommand(c, "lsblk", makeLsblkScript(scriptPartitionsBios)) 298 defer cmdLsblk.Restore() 299 300 err := makeMockGadget(s.gadgetRoot, gadgetContent) 301 c.Assert(err, IsNil) 302 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 303 c.Assert(err, IsNil) 304 305 dl, err := gadget.OnDiskVolumeFromDevice("/dev/node") 306 c.Assert(err, IsNil) 307 308 err = install.RemoveCreatedPartitions(pv, dl) 309 c.Assert(err, IsNil) 310 311 c.Assert(cmdSfdisk.Calls(), DeepEquals, [][]string{ 312 {"sfdisk", "--json", "/dev/node"}, 313 }) 314 315 c.Assert(cmdLsblk.Calls(), DeepEquals, [][]string{ 316 {"lsblk", "--fs", "--json", "/dev/node1"}, 317 }) 318 } 319 320 func (s *partitionTestSuite) TestRemovePartitions(c *C) { 321 const mockSfdiskScriptRemovablePartition = ` 322 if [ -f %[1]s/2 ]; then 323 rm %[1]s/[0-9] 324 elif [ -f %[1]s/1 ]; then 325 touch %[1]s/2 326 exit 0 327 else 328 PART=', 329 {"node": "/dev/node2", "start": 4096, "size": 2457600, "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4", "uuid": "44C3D5C3-CAE1-4306-83E8-DF437ACDB32F", "name": "Recovery"}, 330 {"node": "/dev/node3", "start": 2461696, "size": 2457600, "type": "0FC63DAF-8483-4772-8E79-3D69D8477DE4", "uuid": "44C3D5C3-CAE1-4306-83E8-DF437ACDB32F", "name": "Recovery"} 331 ' 332 touch %[1]s/1 333 fi 334 echo '{ 335 "partitiontable": { 336 "label": "gpt", 337 "id": "9151F25B-CDF0-48F1-9EDE-68CBD616E2CA", 338 "device": "/dev/node", 339 "unit": "sectors", 340 "firstlba": 34, 341 "lastlba": 8388574, 342 "partitions": [ 343 {"node": "/dev/node1", "start": 2048, "size": 2048, "type": "21686148-6449-6E6F-744E-656564454649", "uuid": "2E59D969-52AB-430B-88AC-F83873519F6F", "name": "BIOS Boot"} 344 '"$PART 345 ] 346 } 347 }"` 348 349 cmdSfdisk := testutil.MockCommand(c, "sfdisk", fmt.Sprintf(mockSfdiskScriptRemovablePartition, s.dir)) 350 defer cmdSfdisk.Restore() 351 352 cmdLsblk := testutil.MockCommand(c, "lsblk", makeLsblkScript(scriptPartitionsBiosSeedData)) 353 defer cmdLsblk.Restore() 354 355 dl, err := gadget.OnDiskVolumeFromDevice("/dev/node") 356 c.Assert(err, IsNil) 357 358 c.Assert(cmdLsblk.Calls(), DeepEquals, [][]string{ 359 {"lsblk", "--fs", "--json", "/dev/node1"}, 360 {"lsblk", "--fs", "--json", "/dev/node2"}, 361 {"lsblk", "--fs", "--json", "/dev/node3"}, 362 }) 363 364 err = makeMockGadget(s.gadgetRoot, gadgetContent) 365 c.Assert(err, IsNil) 366 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 367 c.Assert(err, IsNil) 368 369 err = install.RemoveCreatedPartitions(pv, dl) 370 c.Assert(err, IsNil) 371 372 c.Assert(cmdSfdisk.Calls(), DeepEquals, [][]string{ 373 {"sfdisk", "--json", "/dev/node"}, 374 {"sfdisk", "--no-reread", "--delete", "/dev/node", "3"}, 375 {"sfdisk", "--json", "/dev/node"}, 376 }) 377 } 378 379 func (s *partitionTestSuite) TestRemovePartitionsError(c *C) { 380 cmdSfdisk := testutil.MockCommand(c, "sfdisk", makeSfdiskScript(scriptPartitionsBiosSeedData)) 381 defer cmdSfdisk.Restore() 382 383 cmdLsblk := testutil.MockCommand(c, "lsblk", makeLsblkScript(scriptPartitionsBiosSeedData)) 384 defer cmdLsblk.Restore() 385 386 dl, err := gadget.OnDiskVolumeFromDevice("node") 387 c.Assert(err, IsNil) 388 389 err = makeMockGadget(s.gadgetRoot, gadgetContent) 390 c.Assert(err, IsNil) 391 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 392 c.Assert(err, IsNil) 393 394 err = install.RemoveCreatedPartitions(pv, dl) 395 c.Assert(err, ErrorMatches, "cannot remove partitions: /dev/node3") 396 } 397 398 func (s *partitionTestSuite) TestEnsureNodesExist(c *C) { 399 const mockUdevadmScript = `err=%q; echo "$err"; [ -n "$err" ] && exit 1 || exit 0` 400 for _, tc := range []struct { 401 utErr string 402 err string 403 }{ 404 {utErr: "", err: ""}, 405 {utErr: "some error", err: "some error"}, 406 } { 407 c.Logf("utErr:%q err:%q", tc.utErr, tc.err) 408 409 node := filepath.Join(c.MkDir(), "node") 410 err := ioutil.WriteFile(node, nil, 0644) 411 c.Assert(err, IsNil) 412 413 cmdUdevadm := testutil.MockCommand(c, "udevadm", fmt.Sprintf(mockUdevadmScript, tc.utErr)) 414 defer cmdUdevadm.Restore() 415 416 ds := []gadget.OnDiskStructure{{Node: node}} 417 err = install.EnsureNodesExist(ds, 10*time.Millisecond) 418 if tc.err == "" { 419 c.Assert(err, IsNil) 420 } else { 421 c.Assert(err, ErrorMatches, tc.err) 422 } 423 424 c.Assert(cmdUdevadm.Calls(), DeepEquals, [][]string{ 425 {"udevadm", "trigger", "--settle", node}, 426 }) 427 } 428 } 429 430 func (s *partitionTestSuite) TestEnsureNodesExistTimeout(c *C) { 431 cmdUdevadm := testutil.MockCommand(c, "udevadm", "") 432 defer cmdUdevadm.Restore() 433 434 node := filepath.Join(c.MkDir(), "node") 435 ds := []gadget.OnDiskStructure{{Node: node}} 436 t := time.Now() 437 timeout := 1 * time.Second 438 err := install.EnsureNodesExist(ds, timeout) 439 c.Assert(err, ErrorMatches, fmt.Sprintf("device %s not available", node)) 440 c.Assert(time.Since(t) >= timeout, Equals, true) 441 c.Assert(cmdUdevadm.Calls(), HasLen, 0) 442 } 443 444 const gptGadgetContentWithSave = `volumes: 445 pc: 446 bootloader: grub 447 structure: 448 - name: mbr 449 type: mbr 450 size: 440 451 content: 452 - image: pc-boot.img 453 - name: BIOS Boot 454 type: DA,21686148-6449-6E6F-744E-656564454649 455 size: 1M 456 offset: 1M 457 offset-write: mbr+92 458 content: 459 - image: pc-core.img 460 - name: Recovery 461 role: system-seed 462 filesystem: vfat 463 # UEFI will boot the ESP partition by default first 464 type: EF,C12A7328-F81F-11D2-BA4B-00A0C93EC93B 465 size: 1200M 466 content: 467 - source: grubx64.efi 468 target: EFI/boot/grubx64.efi 469 - name: Save 470 role: system-save 471 filesystem: ext4 472 type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4 473 size: 128M 474 - name: Writable 475 role: system-data 476 filesystem: ext4 477 type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4 478 size: 1200M 479 ` 480 481 func (s *partitionTestSuite) TestCreatedDuringInstallGPT(c *C) { 482 cmdLsblk := testutil.MockCommand(c, "lsblk", ` 483 case $3 in 484 /dev/node1) 485 echo '{ "blockdevices": [ {"fstype":"ext4", "label":null} ] }' 486 ;; 487 /dev/node2) 488 echo '{ "blockdevices": [ {"fstype":"ext4", "label":"ubuntu-seed"} ] }' 489 ;; 490 /dev/node3) 491 echo '{ "blockdevices": [ {"fstype":"ext4", "label":"ubuntu-save"} ] }' 492 ;; 493 /dev/node4) 494 echo '{ "blockdevices": [ {"fstype":"ext4", "label":"ubuntu-data"} ] }' 495 ;; 496 *) 497 echo "unexpected args: $*" 498 exit 1 499 ;; 500 esac 501 `) 502 defer cmdLsblk.Restore() 503 cmdSfdisk := testutil.MockCommand(c, "sfdisk", ` 504 echo '{ 505 "partitiontable": { 506 "label": "gpt", 507 "id": "9151F25B-CDF0-48F1-9EDE-68CBD616E2CA", 508 "device": "/dev/node", 509 "unit": "sectors", 510 "firstlba": 34, 511 "lastlba": 8388574, 512 "partitions": [ 513 { 514 "node": "/dev/node1", 515 "start": 2048, 516 "size": 2048, 517 "type": "21686148-6449-6E6F-744E-656564454649", 518 "uuid": "30a26851-4b08-4b8d-8aea-f686e723ed8c", 519 "name": "BIOS boot partition" 520 }, 521 { 522 "node": "/dev/node2", 523 "start": 4096, 524 "size": 2457600, 525 "type": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", 526 "uuid": "7ea3a75a-3f6d-4647-8134-89ae61fe88d5", 527 "name": "Linux filesystem" 528 }, 529 { 530 "node": "/dev/node3", 531 "start": 2461696, 532 "size": 262144, 533 "type": "0fc63daf-8483-4772-8e79-3d69d8477de4", 534 "uuid": "641764aa-a680-4d36-a7ad-f7bd01fd8d12", 535 "name": "Linux filesystem" 536 }, 537 { 538 "node": "/dev/node4", 539 "start": 2723840, 540 "size": 2457600, 541 "type": "0fc63daf-8483-4772-8e79-3d69d8477de4", 542 "uuid": "8ab3e8fd-d53d-4d72-9c5e-56146915fd07", 543 "name": "Another Linux filesystem" 544 } 545 ] 546 } 547 }' 548 `) 549 defer cmdSfdisk.Restore() 550 551 err := makeMockGadget(s.gadgetRoot, gptGadgetContentWithSave) 552 c.Assert(err, IsNil) 553 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 554 c.Assert(err, IsNil) 555 556 dl, err := gadget.OnDiskVolumeFromDevice("node") 557 c.Assert(err, IsNil) 558 559 list := install.CreatedDuringInstall(pv, dl) 560 // only save and writable should show up 561 c.Check(list, DeepEquals, []string{"/dev/node3", "/dev/node4"}) 562 } 563 564 // this is an mbr gadget like the pi, but doesn't have the amd64 mbr structure 565 // so it's probably not representative, but still useful for unit tests here 566 const mbrGadgetContentWithSave = `volumes: 567 pc: 568 schema: mbr 569 bootloader: grub 570 structure: 571 - name: Recovery 572 role: system-seed 573 filesystem: vfat 574 type: EF,C12A7328-F81F-11D2-BA4B-00A0C93EC93B 575 offset: 2M 576 size: 1200M 577 content: 578 - source: grubx64.efi 579 target: EFI/boot/grubx64.efi 580 - name: Boot 581 role: system-boot 582 filesystem: ext4 583 type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4 584 size: 1200M 585 - name: Save 586 role: system-save 587 filesystem: ext4 588 type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4 589 size: 128M 590 - name: Writable 591 role: system-data 592 filesystem: ext4 593 type: 83,0FC63DAF-8483-4772-8E79-3D69D8477DE4 594 size: 1200M 595 ` 596 597 func (s *partitionTestSuite) TestCreatedDuringInstallMBR(c *C) { 598 cmdLsblk := testutil.MockCommand(c, "lsblk", ` 599 what= 600 shift 2 601 case "$1" in 602 /dev/node1) 603 what='{"name": "node1", "fstype":"ext4", "label":"ubuntu-seed"}' 604 ;; 605 /dev/node2) 606 what='{"name": "node2", "fstype":"vfat", "label":"ubuntu-boot"}' 607 ;; 608 /dev/node3) 609 what='{"name": "node3", "fstype":"ext4", "label":"ubuntu-save"}' 610 ;; 611 /dev/node4) 612 what='{"name": "node4", "fstype":"ext4", "label":"ubuntu-data"}' 613 ;; 614 *) 615 echo "unexpected call" 616 exit 1 617 esac 618 619 cat <<EOF 620 { 621 "blockdevices": [ 622 $what 623 ] 624 } 625 EOF`) 626 defer cmdLsblk.Restore() 627 cmdSfdisk := testutil.MockCommand(c, "sfdisk", ` 628 echo '{ 629 "partitiontable": { 630 "label": "dos", 631 "id": "9151F25B-CDF0-48F1-9EDE-68CBD616E2CA", 632 "device": "/dev/node", 633 "unit": "sectors", 634 "firstlba": 0, 635 "lastlba": 8388574, 636 "partitions": [ 637 { 638 "node": "/dev/node1", 639 "start": 0, 640 "size": 2460672, 641 "type": "0a" 642 }, 643 { 644 "node": "/dev/node2", 645 "start": 2461696, 646 "size": 2460672, 647 "type": "b" 648 }, 649 { 650 "node": "/dev/node3", 651 "start": 4919296, 652 "size": 262144, 653 "type": "c" 654 }, 655 { 656 "node": "/dev/node4", 657 "start": 5181440, 658 "size": 2460672, 659 "type": "0d" 660 } 661 ] 662 } 663 }' 664 `) 665 defer cmdSfdisk.Restore() 666 cmdBlockdev := testutil.MockCommand(c, "blockdev", `echo '1234567'`) 667 defer cmdBlockdev.Restore() 668 669 dl, err := gadget.OnDiskVolumeFromDevice("node") 670 c.Assert(err, IsNil) 671 672 err = makeMockGadget(s.gadgetRoot, mbrGadgetContentWithSave) 673 c.Assert(err, IsNil) 674 pv, err := gadget.LaidOutVolumeFromGadget(s.gadgetRoot, uc20mod) 675 c.Assert(err, IsNil) 676 677 list := install.CreatedDuringInstall(pv, dl) 678 c.Assert(list, DeepEquals, []string{"/dev/node2", "/dev/node3", "/dev/node4"}) 679 }