Class: Yast::AutoinstPartPlanClass

Inherits:
Module
  • Object
show all
Defined in:
../../src/modules/AutoinstPartPlan.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) addDrive(drive)

Add a new drive to the plan.

Parameters:

  • drive (Hash{String => Object})

    The new drive to add.



916
917
918
919
920
921
# File '../../src/modules/AutoinstPartPlan.rb', line 916

def addDrive(drive)
  drive = deep_copy(drive)
  @AutoPartPlan = internalAddDrive(@AutoPartPlan, drive)
  updateTree
  deep_copy(drive)
end

- (Object) checkSanity

Triggers a sanity check over the current state of the plan.

Returns:

  • true if plan is sane, false otherwise.



844
845
846
# File '../../src/modules/AutoinstPartPlan.rb', line 844

def checkSanity
  internalCheckSanity(@AutoPartPlan)
end

- (Object) deletePartition(driveId, partitionIdx)

Delete a partition on a drive.

to be deleted.

Parameters:

  • driveId (Fixnum)

    Drive containing the partition to be deleted.

  • partitionIdx (Fixnum)

    The partition index identifying the parition

Returns:

  • true if removal was successfull, false otherwise.



1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
# File '../../src/modules/AutoinstPartPlan.rb', line 1044

def deletePartition(driveId, partitionIdx)
  drive = getDrive(driveId)
  if AutoinstDrive.isDrive(drive)
    oldPartitionCount = AutoinstDrive.getPartitionCount(drive)
    drive = AutoinstDrive.removePartition(drive, partitionIdx)
    updateDrive(drive)
    if AutoinstDrive.getPartitionCount(drive) == 0
      # if no partitions are left select parent drive
      selectTreeItem(AutoinstDrive.getNodeReference(drive))
    elsif partitionIdx == Ops.subtract(oldPartitionCount, 1)
      # the removed partition was the last one
      selectTreeItem(
        Ops.add(
          Ops.add(Ops.add("part_", Builtins.tostring(driveId)), "_"),
          Builtins.tostring(Ops.subtract(partitionIdx, 1))
        )
      )
    end
    return true
  else
    Builtins.y2error(
      "Cannot delete partition on invalid drive with index '%1'.",
      driveId
    )
    return false
  end
end

- (Array) Export

Dump the settings to a map, for autoinstallation use.

Returns:

  • (Array)


770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
# File '../../src/modules/AutoinstPartPlan.rb', line 770

def Export
  Builtins.y2milestone("entering Export")
  drives = Builtins.maplist(@AutoPartPlan) do |drive|
    AutoinstDrive.Export(drive)
  end

  clean_drives = Builtins.maplist(drives) do |d|
    p = Builtins.maplist(Ops.get_list(d, "partitions", [])) do |part|
      part = Builtins.remove(part, "fsid") if Builtins.haskey(part, "fsid")
      if Builtins.haskey(part, "used_fs")
        part = Builtins.remove(part, "used_fs")
      end
      deep_copy(part)
    end
    Ops.set(d, "partitions", p)
    # this is to delete the dummy "auto" filled in by UI
    if Builtins.haskey(d, "device") &&
        Ops.get_string(d, "device", "") == "auto"
      d = Builtins.remove(d, "device")
      Builtins.y2milestone("device 'auto' dropped")
    end
    deep_copy(d)
  end

  deep_copy(clean_drives)
end

- (Object) getAvailableMountPoints

Get a list of mount point strings that are currently not in use

Returns:

  • List of currently unused mount points



811
812
813
814
815
816
817
818
819
# File '../../src/modules/AutoinstPartPlan.rb', line 811

def getAvailableMountPoints
  usedMountPoints = internalGetUsedMountPoints(@AutoPartPlan)
  availableMountPoints = []
  availableMountPoints = Builtins.filter(
    AutoinstPartition.getDefaultMountPoints
  ) { |mp| !Builtins.contains(usedMountPoints, mp) }
  Builtins.y2milestone("Available mount points: '%1'", availableMountPoints)
  deep_copy(availableMountPoints)
end

- (Object) getAvailableVolgroups

Get list of (device) names of volume groups present in the plan.

Returns:

  • List of currently present volume group device names.



834
835
836
837
838
# File '../../src/modules/AutoinstPartPlan.rb', line 834

def getAvailableVolgroups
  Builtins.maplist(internalGetAvailableVolgroups(@AutoPartPlan)) do |vg|
    Ops.get_string(vg, "device", "not-set")
  end
end

- (Object) getDrive(which)

Get drive identified by id (as in the tree node strings [“device_1”]). Caution: this is not the same as the index (see getDriveByListIndex()), as the id never changes, independent of the position of this drive in the list.

exists; and empty list otherwise.

Parameters:

  • which (Fixnum)

    ID of drive to acquire.

Returns:

  • The drive identified by ID if a drive with that ID



862
863
864
# File '../../src/modules/AutoinstPartPlan.rb', line 862

def getDrive(which)
  internalGetDrive(@AutoPartPlan, which)
end

- (Object) getDriveByListIndex(index)

Get drive identified by its position in the partition plan.

otherwise.

Parameters:

  • index (Fixnum)

    The list index identifying the drive.

Returns:

  • The drive identifyied by index, the empty list



873
874
875
# File '../../src/modules/AutoinstPartPlan.rb', line 873

def getDriveByListIndex(index)
  internalGetDriveByListIndex(@AutoPartPlan, index)
end

- (Object) getDriveCount

Returns the number of drives present in plan.

Returns:

  • Number of drives present in plan.



881
882
883
# File '../../src/modules/AutoinstPartPlan.rb', line 881

def getDriveCount
  Builtins.size(@AutoPartPlan)
end

- (Boolean) GetModified

Functions which returns if the settings were modified

Returns:

  • (Boolean)

    settings were modified



63
64
65
# File '../../src/modules/AutoinstPartPlan.rb', line 63

def GetModified
  @modified
end

- (Object) getNextAvailableMountPoint

Get the next free/unused mount point string.

Returns:

  • Next free mount point string.



825
826
827
828
# File '../../src/modules/AutoinstPartPlan.rb', line 825

def getNextAvailableMountPoint
  availableMountPoints = getAvailableMountPoints
  Ops.get(availableMountPoints, 0, "")
end

- (Object) getPartition(driveId, partitionIdx)

Get partition identified by partitionIdx on drive with specified id.

Note: Partition index refers to the position of the partition in the list on the drive and thus is subject to invalidation on any modifications of that list.

partition. an empty map otherwise.

Parameters:

  • driveId (Fixnum)

    The integer id of the drive containing the

  • partitionIdx (Fixnum)

    Index of partition to get.

Returns:

  • The partition if driveId and partitionIdx were valid,



955
956
957
958
959
# File '../../src/modules/AutoinstPartPlan.rb', line 955

def getPartition(driveId, partitionIdx)
  currentDrive = getDrive(driveId)
  Builtins.y2milestone("Loaded drive '%1'", currentDrive)
  AutoinstDrive.getPartition(currentDrive, partitionIdx)
end

- (Boolean) Import(settings)

Get all the configuration from a map. When called by inst_auto<module name> (preparing autoinstallation data) the list may be empty.

Parameters:

  • settings (Array<Hash>)

    a list […]

Returns:

  • (Boolean)

    success



718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
# File '../../src/modules/AutoinstPartPlan.rb', line 718

def Import(settings)
  settings = deep_copy(settings)
  Builtins.y2milestone("entering Import with %1", settings)

  # Filter out all tmpfs that have not been defined by the user.
  # User created entries are defined in the fstab only.
  tmpfs_devices = settings.select { |device| device["type"] == :CT_TMPFS }
  tmpfs_devices.each do |device|
    if device["partitions"]
      device["partitions"].delete_if { |partition| partition["ignore_fstab"] }
    end
  end

  # It makes no sense to have tmpfs dummy containers which have no partitions.
  # E.g. the partitions have been filtered because they have not been defined
  # by the user.
  # (bnc#887318)
  settings.delete_if { |device|
    device["type"] == :CT_TMPFS && (!device["partitions"] || device["partitions"].empty? )
  }

  @AutoPartPlan = []
  _IgnoreTypes = [:CT_BTRFS]
  Builtins.foreach(settings) do |drive|
    if !Builtins.contains(
        _IgnoreTypes,
        Ops.get_symbol(drive, "type", :CT_DISK)
      )
      newDrive = AutoinstDrive.parseDrive(drive)
      if AutoinstDrive.isDrive(newDrive)
        @AutoPartPlan = internalAddDrive(@AutoPartPlan, newDrive)
      else
        Builtins.y2error("Couldn't construct DriveT from '%1'", drive)
      end
    else
      Builtins.y2milestone(
        "Ignoring Container type '%1'",
        Ops.get_symbol(drive, "type", :CT_DISK)
      )
    end
  end
  true
end

- (Object) internalAddDrive(plan, drive)

Add a drive to the partition plan.

Parameters:

  • plan (Array<Hash{String => Object>})

    Partition plan.

  • drive (Hash{String => Object})

    The drive to be added

Returns:

  • The partition plan containing the new drive.



136
137
138
139
140
141
142
143
144
145
146
147
# File '../../src/modules/AutoinstPartPlan.rb', line 136

def internalAddDrive(plan, drive)
  plan = deep_copy(plan)
  drive = deep_copy(drive)
  if AutoinstDrive.isDrive(drive)
    # TODO: implement insertion constraints
    return Builtins.add(plan, drive)
  else
    Builtins.y2error("No valid drive '%1'.", drive)
  end

  nil
end

- (Object) internalCheckSanity(plan)

Check the sanity of the partition plan.

Parameters:

  • plan (Array<Hash{String => Object>})

    The partition plan

Returns:

  • true if plan is sane, false otherwise.



300
301
302
303
304
305
306
# File '../../src/modules/AutoinstPartPlan.rb', line 300

def internalCheckSanity(plan)
  plan = deep_copy(plan)
  sane = true
  sane = internalCheckVolgroups(plan)
  # ...
  sane
end

- (Object) internalCheckVolgroups(plan)

Volume group checks: - check that each VG has at least one PV - <others to be implemented>

volume.

Parameters:

  • plan (Array<Hash{String => Object>})

    The partition plan

Returns:

  • true if each volume group has a supplying physical



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File '../../src/modules/AutoinstPartPlan.rb', line 251

def internalCheckVolgroups(plan)
  plan = deep_copy(plan)
  sane = true
  # Check that each volume group has at least
  # one physical volume
  volGroups = internalGetAvailableVolgroups(plan)
  physDrives = internalGetAvailablePhysicalDrives(plan)
  Builtins.foreach(volGroups) do |volGroup|
    # check all physical drives for physical volumes
    # "feeding" current volume group
    found = false
    volGroupName = removePrefix(
      Ops.get_string(volGroup, "device", "xyz"),
      "/dev/"
    )
    Builtins.foreach(physDrives) do |physDrive|
      Builtins.foreach(Ops.get_list(physDrive, "partitions", [])) do |part|
        if volGroupName == Ops.get_string(part, "lvm_group", "zxy")
          found = true
          Builtins.y2milestone(
            "Found 'feeding' partition for volume group '%1'",
            volGroupName
          )
        end
      end
    end
    # if no feeder (PV) was found for current volume group
    # the next instructions taints result
    if !found
      Popup.Error(
        Builtins.sformat(
          _(
            "Volume group '%1' must have at least one physical volume. Provide one."
          ),
          volGroupName
        )
      )
    end
    sane = found
  end
  sane
end

- (Object) internalGetAvailablePhysicalDrives(plan)

Get a list of all physical (not volgroup) drives.

Parameters:

  • plan (Array<Hash{String => Object>})

    The partition plan.

Returns:

  • Partition plan containing only physical drives.



214
215
216
217
218
219
220
221
# File '../../src/modules/AutoinstPartPlan.rb', line 214

def internalGetAvailablePhysicalDrives(plan)
  plan = deep_copy(plan)
  result = []
  result = Builtins.filter(@AutoPartPlan) do |curDrive|
    Ops.get_symbol(curDrive, "type", :CT_LVM) == :CT_DISK
  end
  deep_copy(result)
end

- (Object) internalGetAvailableVolgroups(plan)

Get a list of all drives, that are of a volgroup type.

Parameters:

  • plan (Array<Hash{String => Object>})

    The partition plan.

Returns:

  • Partition plan containing only volgroups.



199
200
201
202
203
204
205
206
# File '../../src/modules/AutoinstPartPlan.rb', line 199

def internalGetAvailableVolgroups(plan)
  plan = deep_copy(plan)
  result = []
  result = Builtins.filter(@AutoPartPlan) do |curDrive|
    Ops.get_symbol(curDrive, "type", :CT_DISK) != :CT_DISK
  end
  deep_copy(result)
end

- (Object) internalGetDrive(plan, which)

Select a drive by its ID, as in the tree item strings (e.g. “drive_1” -> ID = 1).

no drive with that id exists.

Parameters:

  • plan (Array<Hash{String => Object>})

    The partition plan

  • which (Fixnum)

    ID of the drive to return

Returns:

  • The drive with the specified id, or the an empty map if



76
77
78
79
80
81
82
83
84
85
86
# File '../../src/modules/AutoinstPartPlan.rb', line 76

def internalGetDrive(plan, which)
  plan = deep_copy(plan)
  result = {}
  Builtins.foreach(plan) do |currentDrive|
    if which == Ops.get_integer(currentDrive, "_id", -1)
      result = deep_copy(currentDrive)
      raise Break
    end
  end
  deep_copy(result)
end

- (Object) internalGetDriveByListIndex(plan, index)

Select a drive by its position in the drive list (a.k.a partition plan).

valid.

Parameters:

  • plan (Array<Hash{String => Object>})

    Partition plan.

  • index (Fixnum)

    Index of drive in the list

Returns:

  • The spcified drive, or an empty map if the index wasn't



97
98
99
100
# File '../../src/modules/AutoinstPartPlan.rb', line 97

def internalGetDriveByListIndex(plan, index)
  plan = deep_copy(plan)
  Ops.get(plan, index, {})
end

- (Object) internalGetListIndex(plan, which)

Get a list index for a drive id.

Parameters:

  • plan (Array<Hash{String => Object>})

    Partition plan.

  • which (Fixnum)

    the drive id.

Returns:

  • The list index or -1 if id wasn't found.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File '../../src/modules/AutoinstPartPlan.rb', line 109

def internalGetListIndex(plan, which)
  plan = deep_copy(plan)
  index = 0
  found = false
  Builtins.foreach(plan) do |currentDrive|
    currentID = Ops.get_integer(currentDrive, "_id", -1)
    if which == currentID
      found = true
      raise Break
    end
    index = Ops.add(index, 1)
  end
  return index if found
  -1
end

- (Object) internalGetUsedMountPoints(plan)

Get a list of used mountpoint strings.

Parameters:

  • plan (Array<Hash{String => Object>})

    The partition plan.

Returns:

  • A list of mountpoint strings in use by any partition.



229
230
231
232
233
234
235
236
237
238
239
240
# File '../../src/modules/AutoinstPartPlan.rb', line 229

def internalGetUsedMountPoints(plan)
  plan = deep_copy(plan)
  result = []
  Builtins.foreach(plan) do |drive|
    Builtins.foreach(Ops.get_list(drive, "partitions", [])) do |part|
      mountPoint = Ops.get_string(part, "mount", "")
      result = Builtins.add(result, mountPoint) if "" != mountPoint
    end
  end
  Builtins.y2milestone("Used mount points: '%1'", result)
  deep_copy(result)
end

- (Object) internalRemoveDrive(plan, which)

Remove a drive from the plan.

it was present.

Parameters:

  • plan (Array<Hash{String => Object>})

    Partition plan.

  • which (Fixnum)

    The id of the drive to remove.

Returns:

  • The partition plan lacking the drive that was removed if



157
158
159
160
161
162
163
164
165
166
# File '../../src/modules/AutoinstPartPlan.rb', line 157

def internalRemoveDrive(plan, which)
  plan = deep_copy(plan)
  result = []
  drive = internalGetDrive(plan, which)
  result = Builtins.filter(plan) do |curDrive|
    Ops.get_integer(drive, "_id", 100) !=
      Ops.get_integer(curDrive, "_id", 111)
  end
  deep_copy(result)
end

- (Object) internalUpdateDrive(plan, drive)

Update a drive in the partition plan.

Parameters:

  • plan (Array<Hash{String => Object>})

    Partition plan.

  • drive (Hash{String => Object})

    The drive to be updated.

Returns:

  • Partition plan containing the updated drive.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File '../../src/modules/AutoinstPartPlan.rb', line 175

def internalUpdateDrive(plan, drive)
  plan = deep_copy(plan)
  drive = deep_copy(drive)
  if AutoinstDrive.isDrive(drive)
    plan = Builtins.maplist(@AutoPartPlan) do |curDrive|
      if Ops.get_integer(curDrive, "_id", 100) ==
          Ops.get_integer(drive, "_id", 111)
        next deep_copy(drive)
      else
        next deep_copy(curDrive)
      end
    end
  else
    Builtins.y2error("No valid drive: '%1'", drive)
  end
  deep_copy(plan)
end

- (Object) main



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File '../../src/modules/AutoinstPartPlan.rb', line 13

def main
  Yast.import "UI"
  textdomain "autoinst"

  Yast.include self, "autoinstall/types.rb"
  Yast.include self, "autoinstall/common.rb"
  Yast.include self, "autoinstall/tree.rb"

  Yast.import "AutoinstCommon"
  Yast.import "AutoinstDrive"
  Yast.import "AutoinstPartition"
  Yast.import "Summary"
  Yast.import "Popup"
  Yast.import "Mode"
  Yast.import "StorageDevices"
  Yast.import "Storage"
  Yast.import "Partitions"
  Yast.import "FileSystems"
  Yast.import "Arch"

  # The general idea with this moduls is that it manages a single
  # partition plan (AutoPartPlan) and the user can work on that
  # plan without having to sepcify that variable on each method
  # call.
  # This is on the one hand convenient for the user and on the
  # other hand we have control over the plan.

  # PRIVATE

  # The single plan instance managed by this module.
  #
  # The partition plan is technically a list of DriveT'.
  @AutoPartPlan = []

  # default value of settings modified
  @modified = false
end

- (Object) newPartition(driveId)

Create a new partition on a drive.

The new partition is assinged a default mountpoint and a default parition number, or, in case its parent drive is a LVM, a volume name.

Parameters:

  • driveId (Fixnum)

    The drive to create the new partition on.

Returns:

  • The index of the newly created partition.



1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
# File '../../src/modules/AutoinstPartPlan.rb', line 1000

def newPartition(driveId)
  newPartitionIndex = -1
  parentDrive = getDrive(driveId)
  if AutoinstDrive.isDrive(parentDrive)
    mountPoint = getNextAvailableMountPoint
    newPartitionNumber = AutoinstDrive.getNextAvailablePartitionNumber(
      parentDrive
    )
    newPart = AutoinstPartition.new(mountPoint)
    newPart = AutoinstPartition.set(
      newPart,
      "partition_nr",
      newPartitionNumber
    )
    if :CT_DISK != Ops.get_symbol(parentDrive, "type", :Empty)
      newPart = AutoinstPartition.set(
        newPart,
        "lv_name",
        AutoinstPartition.getLVNameFor(mountPoint)
      )
    end
    parentDrive = AutoinstDrive.addPartition(parentDrive, newPart)
    newPartitionIndex = Ops.subtract(
      AutoinstDrive.getPartitionCount(parentDrive),
      1
    )
    updateDrive(parentDrive)
  else
    Builtins.y2error(
      "Cannot create new partition on invalid drive with id '%1'.",
      driveId
    )
  end
  newPartitionIndex
end

- (Object) Read



762
763
764
765
766
# File '../../src/modules/AutoinstPartPlan.rb', line 762

def Read
  Import(
    Convert.convert(ReadHelper(), :from => "list", :to => "list <map>")
  )
end

- (Array) ReadHelper

Create a partition plan for the calling client

Returns:

  • (Array)

    partition plan



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
# File '../../src/modules/AutoinstPartPlan.rb', line 337

def ReadHelper
  Mode.SetMode("normal")
  StorageDevices.InitDone
  _StorageMap = Builtins.eval(Storage.GetTargetMap)

  _StorageMap = _StorageMap.select do |d, p|
    ok = d != "/dev/evms" && d != "/dev/nfs"
	if( ok && p.fetch("partitions", []).size==0 )
	  ok = p.fetch("used_by_type",:UB_NONE)==:UB_LVM
	end
	ok
  end
  Builtins.y2milestone("Storagemap %1", _StorageMap)
  #        list evms_vgs = [];

  drives = Builtins.maplist(_StorageMap) do |k, v|
    partitions = []
    winp = []
    no_format_list = [65, 6, 222]
    no_create_list = [222]
    usepartitions = []
    cyl_size = Ops.get_integer(v, "cyl_size", 0)
    no_create = false
    Builtins.foreach(Ops.get_list(v, "partitions", [])) do |pe|
      next if Ops.get_symbol(pe, "type", :x) == :extended
      new_pe = {}
      Ops.set(new_pe, "create", true)
      new_pe["ignore_fstab"] = pe["ignore_fstab"] if pe.has_key?("ignore_fstab")
      skipwin = false
      if Builtins.haskey(pe, "enc_type")
        Ops.set(
          new_pe,
          "enc_type",
          Ops.get_symbol(pe, "enc_type", :twofish)
        )
        Ops.set(new_pe, "crypt_key", "ENTER KEY HERE")
        Ops.set(new_pe, "loop_fs", true)
        Ops.set(new_pe, "crypt_fs", true)
      end
      if Builtins.haskey(pe, "fsid")
        fsid = Ops.get_integer(pe, "fsid", 131)
        wintypes = Builtins.union(
          Partitions.fsid_wintypes,
          Partitions.fsid_dostypes
        )
        allwin = Builtins.union(wintypes, Partitions.fsid_ntfstypes)
        if Builtins.contains(allwin, fsid) &&
            !Builtins.issubstring(Ops.get_string(pe, "mount", ""), "/boot") &&
              !Ops.get_boolean(pe, "boot", false)
          #                    if (contains(allwin, fsid) && ! issubstring(pe["mount"]:"", "/boot") )
          Builtins.y2debug("Windows partitions found: %1", fsid)
          winp = Builtins.add(winp, Ops.get_integer(pe, "nr", 0))
          skipwin = true
          no_create = true if Ops.greater_than(Builtins.size(partitions), 0)
        end
        if Builtins.contains(allwin, fsid) &&
            Builtins.issubstring(Ops.get_string(pe, "mount", ""), "/boot")
          Ops.set(new_pe, "partition_id", 259)
        else
          Ops.set(new_pe, "partition_id", Ops.get_integer(pe, "fsid", 131))
        end
        if Builtins.contains(no_format_list, Ops.get_integer(pe, "fsid", 0))
          Ops.set(new_pe, "format", false)
        end
        if Builtins.contains(no_create_list, Ops.get_integer(pe, "fsid", 0))
          Ops.set(new_pe, "create", false)
        end
      end
      if Builtins.haskey(pe, "type") &&
          Ops.get_symbol(pe, "type", :x) == :primary
        Ops.set(new_pe, "partition_type", "primary") # can we always copy that element?
      end
      if Builtins.haskey(pe, "region") &&
          Ops.get_boolean(new_pe, "create", true) == true
        # don't clone the exact region.
        # I don't see any benefit in cloning that strict.
        #new_pe["region"] = pe["region"]:[];
        #                    new_pe["size"] = sformat("%1", pe["size_k"]:0*1024);
        if Ops.less_than(
            Ops.subtract(
              Ops.multiply(Ops.get_integer(pe, "size_k", 0), 1024),
              cyl_size
            ),
            cyl_size
          ) # bnc#415005
          Ops.set(new_pe, "size", Builtins.sformat("%1", cyl_size))
        else
          Ops.set(
            new_pe,
            "size",
            Builtins.sformat(
              "%1",
              Ops.subtract(
                Ops.multiply(Ops.get_integer(pe, "size_k", 0), 1024),
                cyl_size
              )
            )
          )
        end # one cylinder buffer for #262535
      end
      if Builtins.haskey(pe, "label")
        Ops.set(new_pe, "label", Ops.get_string(pe, "label", ""))
      end
      if Builtins.haskey(pe, "mountby")
        Ops.set(new_pe, "mountby", Ops.get_symbol(pe, "mountby", :nomb))
      end
      if Builtins.haskey(pe, "fstopt")
        Ops.set(new_pe, "fstopt", Ops.get_string(pe, "fstopt", "defaults"))
      end
      # LVM Group
      if Builtins.haskey(pe, "used_by_type") &&
          Ops.get_symbol(pe, "used_by_type", :nothing) == :UB_LVM
        Ops.set(
          new_pe,
          "lvm_group",
          Builtins.substring(Ops.get_string(pe, "used_by_device", ""), 5)
        )
      end
      # LV
      if Ops.get_symbol(pe, "type", :unknown) == :lvm
        Ops.set(new_pe, "lv_name", Ops.get_string(pe, "name", ""))
        Ops.set(
          new_pe,
          "size",
          Builtins.sformat(
            "%1",
            Ops.multiply(Ops.get_integer(pe, "size_k", 0), 1024)
          )
        )
        if Builtins.haskey(pe, "stripes")
          Ops.set(new_pe, "stripes", Ops.get_integer(pe, "stripes", 0))
          Ops.set(
            new_pe,
            "stripesize",
            Ops.get_integer(pe, "stripesize", 4)
          )
        end
      end
      if Builtins.haskey(pe, "used_by_type") &&
          Ops.get_symbol(pe, "used_by_type", :nothing) == :UB_MD
        Ops.set(
          new_pe,
          "raid_name",
          Ops.get_string(pe, "used_by_device", "")
        )
      end
      # Used Filesystem
      # Raid devices get the filesystem lying on them as
      # detected_fs!
      if Builtins.haskey(pe, "used_fs") &&
          Ops.get_integer(pe, "fsid", 0) != 253
        Ops.set(new_pe, "filesystem", Ops.get_symbol(pe, "used_fs") do
          Partitions.DefaultFs
        end)
        Ops.set(
          new_pe,
          "format",
          Ops.get_boolean(
            new_pe,
            "format",
            Ops.get_boolean(pe, "format", true)
          )
        )
      end
      if Ops.get_boolean(new_pe, "format", false) &&
          !Builtins.isempty(Ops.get_string(pe, "mkfs_options", ""))
        Ops.set(
          new_pe,
          "mkfs_options",
          Ops.get_string(pe, "mkfs_options", "")
        )
      end
      # Subvolumes
      # Save possibly existing subvolumes
      if !Builtins.isempty(Ops.get_list(pe, "subvol", []))
        defsub = ""
        if !Builtins.isempty(FileSystems.default_subvol)
          defsub = Ops.add(FileSystems.default_subvol, "/")
        end
        Ops.set(
          new_pe,
          "subvolumes",
          Builtins.maplist(Ops.get_list(pe, "subvol", [])) do |p|
            if Ops.greater_than(Builtins.size(defsub), 0) &&
                Builtins.substring(
                  Ops.get_string(p, "name", ""),
                  0,
                  Builtins.size(defsub)
                ) == defsub
              next Builtins.substring(
                Ops.get_string(p, "name", ""),
                Builtins.size(defsub)
              )
            else
              next Ops.get_string(p, "name", "")
            end
          end
        )
        Ops.set(
          new_pe,
          "subvolumes",
          Builtins.filter(Ops.get_list(new_pe, "subvolumes", [])) do |s|
            !Builtins.isempty(s)
          end
        )
      end
      # Handle thin stuff
      Ops.set(new_pe, "pool", true) if Ops.get_boolean(pe, "pool", false)
      if !Builtins.isempty(Ops.get_string(pe, "used_pool", ""))
        Ops.set(new_pe, "used_pool", Ops.get_string(pe, "used_pool", ""))
      end
      # if the filesystem is unknown, we have detected_fs and no longer used_fs
      # don't know why yast2-storage is having two keys for that.
      # maybe it would be even okay to look only for "detected_fs" to set format to false
      # bnc#542331 (L3: AutoYaST clone module fails to set format option for non-formatted logical volumes)
      if Ops.get_symbol(pe, "detected_fs", :known) == :unknown
        Ops.set(new_pe, "format", false)
      end
      if Builtins.haskey(pe, "nr") &&
          Ops.get_symbol(pe, "type", :unknown) != :lvm
        if !skipwin
          Builtins.y2debug(
            "Adding partition to be used: %1",
            Ops.get_integer(pe, "nr", 0)
          )
          usepartitions = Builtins.add(
            usepartitions,
            Ops.get_integer(pe, "nr", 0)
          )
        end
        Ops.set(new_pe, "partition_nr", Ops.get_integer(pe, "nr", 0))
      end
      if Ops.get_string(pe, "mount", "") != ""
        Ops.set(new_pe, "mount", Ops.get_string(pe, "mount", ""))
      end
      if k == "/dev/md"
        raid_options = {}
        raid_options["persistent_superblock"] = pe.fetch("persistent_superblock",false)
        raid_options["raid_type"] = pe.fetch("raid_type", "raid0")
        raid_options["device_order"] = pe.fetch("devices",[])
 if pe["device"].start_with?("/dev/md/")
   raid_options["raid_name"] = pe["device"]
 end
        new_pe["raid_options"]=raid_options
      end
      if !skipwin && Ops.get_integer(new_pe, "partition_id", 0) != 15
        partitions = Builtins.add(partitions, new_pe)
      end
    end
    # don't create partitions that are between windows partitions
    # they must exist
    drive = {}
    Ops.set(drive, "type", Ops.get_symbol(v, "type", :CT_DISK))
    Ops.set(drive, "disklabel", Ops.get_string(v, "label", "msdos"))
    if no_create
      partitions = Builtins.maplist(
        Convert.convert(partitions, :from => "list", :to => "list <map>")
      ) do |m|
        Ops.set(m, "create", false)
        deep_copy(m)
      end
    end
	if( v.fetch("used_by_type",:UB_NONE)==:UB_LVM && partitions.empty? )
	  partitions = [{ "partition_nr" => 0, "create" => false,
               "lvm_group" => v.fetch("used_by_device", "")[5..-1],
 "size" => "max" }]
	  Builtins.y2milestone( "lvm full disk v:%1", v )
	  Builtins.y2milestone( "lvm full disk p:%1", partitions )
	end
    Ops.set(drive, "partitions", partitions)
    if Arch.s390 && Ops.get_symbol(v, "type", :CT_DISK) == :CT_DISK
      Ops.set(
        drive,
        "device",
        Ops.add("/dev/disk/by-path/", Ops.get_string(v, "udev_path", k))
      )
      Builtins.y2milestone(
        "s390 found. Setting device to by-path: %1",
        Ops.get_string(drive, "device", "")
      )
    else
      Ops.set(drive, "device", k)
    end
    if Ops.get_symbol(v, "type", :CT_UNKNOWN) == :CT_LVM
      Ops.set(
        drive,
        "pesize",
        Builtins.sformat(
          "%1M",
          Ops.divide(Ops.get_integer(v, "pesize", 1), 1024 * 1024)
        )
      )
      Ops.set(drive, "type", :CT_LVM)
    end
    if Builtins.haskey(v, "lvm2") && Ops.get_boolean(v, "lvm2", false)
      Ops.set(drive, "lvm2", true)
    end
    if Ops.greater_than(Builtins.size(partitions), 0)
      if Builtins.size(winp) == 0
        Ops.set(drive, "use", "all")
      else
        up = []
        Builtins.foreach(usepartitions) do |i|
          up = Builtins.add(up, Builtins.sformat("%1", i))
        end
        Ops.set(drive, "use", Builtins.mergestring(up, ","))
      end
    end
    deep_copy(drive)
  end
  #        drives = filter( map v, (list<map>)drives, ``{
  #            if( ! (contains( evms_vgs, v["device"]:"") && v["type"]:`x == `CT_LVM ) )
  #                return true;
  #            y2milestone("kicking LVM %1 out of the profile because an EVMS with that name exists",v);
  #            return false;
  #        });
  # remove drives with no mountpoint
  drives = Builtins.filter(
    Convert.convert(drives, :from => "list", :to => "list <map>")
  ) do |v|
    keep = false
    Builtins.foreach(Ops.get_list(v, "partitions", [])) do |p|
      if Ops.get_string(p, "mount", "") != "" ||
          Builtins.haskey(p, "lvm_group") ||
          Builtins.haskey(p, "raid_name")
        keep = true
        raise Break
      end
    end
    keep
  end

  Mode.SetMode("autoinst_config")
  deep_copy(drives)
end

- (Object) removeDrive(which)

Remove drive identified by drive ID from the partition plan. Selects preceeding drive, if deleted drive was last in list. Otherwise the successor is selected.

Parameters:

  • which (Fixnum)

    ID of drive to delete.



891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
# File '../../src/modules/AutoinstPartPlan.rb', line 891

def removeDrive(which)
  # most of the complexity here is due to correct
  # reselection behaviour after a drive has been deleted
  removalDriveIdx = internalGetListIndex(@AutoPartPlan, which)
  oldDriveCount = getDriveCount
  @AutoPartPlan = internalRemoveDrive(@AutoPartPlan, which)
  drive = {}
  if Ops.greater_than(oldDriveCount, 1) &&
      removalDriveIdx == Ops.subtract(oldDriveCount, 1)
    # lowest drive in tree was deleted, select predecessor
    drive = getDriveByListIndex(Ops.subtract(removalDriveIdx, 1))
  else
    # a top or middle one was deleted, select successor
    drive = getDriveByListIndex(removalDriveIdx)
  end
  selectTreeItem(AutoinstDrive.getNodeReference(drive))
  updateTree

  nil
end

- (Object) Reset



797
798
799
800
801
# File '../../src/modules/AutoinstPartPlan.rb', line 797

def Reset
  @AutoPartPlan = []

  nil
end

- (Object) SetModified

Function sets internal variable, which indicates, that any settings were modified, to “true”



53
54
55
56
57
58
# File '../../src/modules/AutoinstPartPlan.rb', line 53

def SetModified
  Builtins.y2milestone("SetModified")
  @modified = true

  nil
end

- (String) Summary

Return summary of configuration

Returns:

  • (String)

    configuration summary dialog



680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
# File '../../src/modules/AutoinstPartPlan.rb', line 680

def Summary
  summary = ""
  summary = Summary.AddHeader(summary, _("Drives"))
  unless @AutoPartPlan.empty?
    # We are counting harddisks only (type CT_DISK)
    num = @AutoPartPlan.count{|drive| drive["type"] == :CT_DISK }
    summary = Summary.AddLine(
      summary,
      (n_("%s drive in total", "%s drives in total", num) % num)
    )
    summary = Summary.OpenList(summary)
    Builtins.foreach(@AutoPartPlan) do |drive|
      driveDesc = AutoinstDrive.getNodeName(drive, true)
      summary = Summary.AddListItem(summary, driveDesc)
      summary = Summary.OpenList(summary)
      Builtins.foreach(Ops.get_list(drive, "partitions", [])) do |part|
        summary = Summary.AddListItem(
          summary,
          AutoinstPartition.getPartitionDescription(part, true)
        )
      end
      summary = Summary.CloseList(summary)
      summary = Summary.AddNewLine(summary)
    end
    summary = Summary.CloseList(summary)
  else
    summary = Summary.AddLine( summary,
      _("Not yet cloned.")
    )
  end
  summary
end

- (Object) updateDrive(drive)

Update a drive in the plan. If the drive didn't exist in the first place nothing happens (use add in that case).

Parameters:

  • The

    drive to update.



928
929
930
931
932
933
934
# File '../../src/modules/AutoinstPartPlan.rb', line 928

def updateDrive(drive)
  drive = deep_copy(drive)
  @AutoPartPlan = internalUpdateDrive(@AutoPartPlan, drive)
  updateTree

  nil
end

- (Object) updatePartition(driveId, partitionIdx, partition)

Update a partition on a drive.

Note: Partition index refers to the position of the partition in the list on the drive and thus is subject to invalidation on any modifications of that list.

partition.

Parameters:

  • driveId (Fixnum)

    The integer id of the drive containing the

  • partitionIdx (Fixnum)

    Index of the partition to update.

  • partition (Hash{String => Object})

    The updated/new partition.

Returns:

  • true if update was successfull, false otherwise.



974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
# File '../../src/modules/AutoinstPartPlan.rb', line 974

def updatePartition(driveId, partitionIdx, partition)
  partition = deep_copy(partition)
  drive = getDrive(driveId)
  if AutoinstDrive.isDrive(drive)
    drive = AutoinstDrive.updatePartition(drive, partitionIdx, partition)
    updateDrive(drive)
    return true
  else
    Builtins.y2milestone(
      "Could not update partition. Invalid driveId: '%1'",
      driveId
    )
    return false
  end
end

- (Object) updateTree

Create tree structure from AutoPartPlan



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File '../../src/modules/AutoinstPartPlan.rb', line 309

def updateTree
  Builtins.y2milestone("entering updateTree")
  # remember selected tree item
  item = currentTreeItem
  tree = []
  # let tree widget reflect AutoPartPlan
  Builtins.foreach(@AutoPartPlan) do |drive|
    tree = Builtins.add(tree, AutoinstDrive.createTree(drive))
  end
  Builtins.y2milestone("Setting tree: '%1'", tree)
  if Ops.greater_than(Builtins.size(@AutoPartPlan), 0)
    setTree(tree)
    # restore former selection
    if nil != item && "" != item
      Builtins.y2milestone("reselecting item '%1' after tree update.", item)
      selectTreeItem(item)
    else
      firstDrive = internalGetDriveByListIndex(@AutoPartPlan, 0)
      selectTreeItem(AutoinstDrive.getNodeReference(firstDrive))
    end
  end

  nil
end