Last active
May 21, 2024 08:31
-
-
Save ancorgs/adc5001598005a43ac13969c3ff4de64 to your computer and use it in GitHub Desktop.
Considering Agama storage autoinstallation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Class to calculate a storage proposal for autoinstallation | |
# | |
# @example Creating a proposal from the current AutoYaST profile | |
# partitioning = Yast::Profile.current["partitioning"] | |
# proposal = Y2Storage::AutoinstProposal.new(partitioning: partitioning) | |
# proposal.proposed? # => false | |
# proposal.devices # => nil | |
# proposal.planned_devices # => nil | |
# | |
# proposal.propose # Performs the calculation | |
# | |
# proposal.proposed? # => true | |
# proposal.devices # => Proposed layout | |
# | |
class AutoinstProposal < Proposal::Base | |
# @return [AutoinstProfile::PartitioningSection] Partitioning layout from an AutoYaST profile | |
attr_reader :partitioning | |
# @return [AutoinstIssues::List] List of found AutoYaST issues | |
attr_reader :issues_list | |
# @return [DiskSize] Missing space for the originally planned devices | |
attr_reader :missing_space | |
# Constructor | |
# | |
# @param partitioning [Array<Hash>] Partitioning schema from an AutoYaST profile | |
# @param proposal_settings [Y2Storage::ProposalSettings] Guided proposal settings | |
# @param devicegraph [Devicegraph] starting point. If nil, then probed devicegraph | |
# will be used | |
# @param disk_analyzer [DiskAnalyzer] by default, the method will create a new one | |
# based on the initial devicegraph or will use the one in {StorageManager} if | |
# starting from probed (i.e. 'devicegraph' argument is also missing) | |
# @param issues_list [AutoinstIssues::List] List of AutoYaST issues to register them | |
def initialize(partitioning: [], proposal_settings: nil, devicegraph: nil, disk_analyzer: nil, | |
issues_list: nil) | |
super(devicegraph: devicegraph, disk_analyzer: disk_analyzer) | |
@issues_list = issues_list || ::Installation::AutoinstIssues::List.new | |
@proposal_settings = proposal_settings | |
@partitioning = AutoinstProfile::PartitioningSection.new_from_hashes(partitioning) | |
end | |
private | |
# Calculates the proposal | |
def calculate_proposal | |
# This is actually the only time "partitioning" is used as input to the algorithm. All the rest | |
# is based on "drives" | |
drives = Proposal::AutoinstDrivesMap.new(initial_devicegraph, partitioning, issues_list) | |
if issues_list.fatal? | |
@devices = nil | |
return @devices | |
end | |
@devices = propose_devicegraph(initial_devicegraph, drives) | |
end | |
# Proposes a devicegraph based on given drives map | |
# | |
# This method falls back to #proposed_guided_devicegraph when the device map | |
# does not contain any partition. | |
def propose_devicegraph(devicegraph, drives) | |
if drives.partitions? | |
@planned_devices = plan_devices(devicegraph, drives) | |
# Rest of the algorithm | |
else | |
log.info "No partitions were specified. Falling back to guided setup planning." | |
propose_guided_devicegraph(devicegraph, drives) | |
end | |
end | |
# Calculates list of planned devices | |
# | |
# If the list does not contain any partition, then it follows the same | |
# approach as the guided proposal | |
# | |
# @param devicegraph [Devicegraph] Starting point | |
# @param drives [Proposal::AutoinstDrivesMap] Devices map from an AutoYaST profile | |
# @return [Planned::DevicesCollection] Devices to add | |
def plan_devices(devicegraph, drives) | |
planner = Proposal::AutoinstDevicesPlanner.new(devicegraph, issues_list) | |
planner.planned_devices(drives) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The 22 kinds of AutoinstIssues | |
# | |
# conflicting_attrs.rb missing_reusable_filesystem.rb no_partitionable.rb | |
# could_not_calculate_boot.rb missing_reuse_info.rb no_proposal.rb | |
# could_not_create_boot.rb missing_root.rb shrinked_planned_devices.rb | |
# exception.rb missing_value.rb surplus_partitions.rb | |
# invalid_encryption.rb multiple_bcache_members.rb thin_pool_not_found.rb | |
# invalid_value.rb no_components.rb unsupported_drive_section.rb | |
# missing_btrfs_quotas.rb no_disk.rb | |
# missing_reusable_device.rb no_disk_space.rb | |
# Base class for autoinstallation problems. | |
# | |
# Installation::AutoinstIssues offers an API to register and report | |
# AutoYaST problems. | |
class Issue | |
# @return [#parent,#section_name] Section where it was detected (see {AutoinstProfile}) | |
attr_reader :section | |
end | |
# Represents an AutoYaST situation where an invalid value was given. | |
# | |
# @example Invalid value 'auto' for attribute :size on /home partition | |
# section = AutoinstProfile::PartitioningSection.new_from_hashes({"size" => "auto"}) | |
# problem = InvalidValue.new(section, :size) | |
# problem.value #=> "auto" | |
# problem.attr #=> :size | |
class InvalidValue | |
# @return [Symbol] Name of the missing attribute | |
attr_reader :attr | |
# @return [Object] New value or :skip to skip the section. | |
attr_reader :new_value | |
end | |
# Conflicting attributes where specified for the given section. | |
# | |
# The conflict is resolved and the 'selected_attr' is honored while the rest | |
# is ignored. | |
class ConflictingAttrs | |
# @return [Symbol] Selected attribute | |
attr_reader :selected_attr | |
# @return [Array<Symbol>] List of ignored attributes | |
attr_reader :ignored_attrs | |
end | |
# Represents a situation where a suitable device to be reused was not found. | |
# | |
# @example | |
# section = AutoinstProfile::PartitionSection.new_from_hashes({}) | |
# problem = MissingReusableDevice.new(section) | |
class MissingReusableDevice; end | |
# It was not possible to find a way to make the system bootable | |
class CouldNotCalculateBoot; end | |
# It was not possible to allocate the extra partitions needed for booting | |
class CouldNotCreateBoot; end | |
# Represents a problem that occurs when an exception is raised. | |
# | |
# This error is used as a fallback for any problem that arises during | |
# proposal which is not handled in an specific way. It includes the | |
# exception which caused the problem to be registered. | |
class Exception | |
attr_reader :error | |
end | |
# Represents a problem with encryption settings | |
# | |
# This issues are considered 'fatal' because they might lead to a situation | |
# where a device is not unencrypted as it was intended. | |
# | |
# @example The encryption method is not available in the running system | |
# hash = { "crypt_method" => :pervasive_luks2 } | |
# section = AutoinstProfile::PartitionSection.new_from_hashes(hash) | |
# issue = InvalidEncryption.new(section, :unavailable) | |
# | |
# @example The encryption method is unknown | |
# hash = { "crypt_method" => :foo } | |
# section = AutoinstProfile::PartitionSection.new_from_hashes(hash) | |
# issue = InvalidEncryption.new(section, :unknown) | |
# | |
# @example The encryption method is not suitable for the device | |
# hash = { "mount" => "/", "crypt_method" => :random_swap } | |
# section = AutoinstProfile::PartitionSection.new_from_hashes(hash) | |
# issue = InvalidEncryption.new(section, :unsuitable) | |
class InvalidEncryption | |
# @return [Symbol] Reason which causes the encryption to be invalid | |
attr_reader :reason | |
end | |
# And much more... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment