Class: Pvectl::Services::ResizeVolume
- Inherits:
-
Object
- Object
- Pvectl::Services::ResizeVolume
- Defined in:
- lib/pvectl/services/resize_volume.rb
Overview
Orchestrates volume resize operations for VMs and containers.
Handles size parsing, preflight validation (current size comparison), and execution via the repository interface. Works polymorphically with both VM and Container repositories (they share #fetch_config and #resize).
Two-phase operation:
-
#preflight — validates volume exists, computes new size, checks constraints
-
#perform — executes the actual resize via repository
Defined Under Namespace
Classes: ParsedSize, SizeTooSmallError, VolumeNotFoundError
Constant Summary collapse
- SIZE_PATTERN =
Size regex: optional +, digits with optional decimal, optional T/G/M/K suffix.
/\A(\+)?(\d+(?:\.\d+)?)([TGMK])?\z/i- UNIT_MULTIPLIERS =
Multipliers for converting units to megabytes (MB as base unit).
{ "T" => 1024 * 1024, "G" => 1024, "M" => 1, "K" => 1.0 / 1024 }.freeze
Class Method Summary collapse
-
.parse_size(size_str) ⇒ ParsedSize
Parses a size string into a ParsedSize.
Instance Method Summary collapse
-
#initialize(repository:) ⇒ ResizeVolume
constructor
Creates a new ResizeVolume service.
-
#perform(id, disk, raw_size, node:) ⇒ Models::OperationResult
Executes the disk resize via repository.
-
#preflight(id, disk, parsed_size, node:) ⇒ Hash
Validates the resize operation and returns size information.
Constructor Details
#initialize(repository:) ⇒ ResizeVolume
Creates a new ResizeVolume service.
96 97 98 |
# File 'lib/pvectl/services/resize_volume.rb', line 96 def initialize(repository:) @repository = repository end |
Class Method Details
.parse_size(size_str) ⇒ ParsedSize
Parses a size string into a ParsedSize.
Accepts formats like “10G”, “+10G”, “1.5T”, “512M”, “+100”. Suffix is uppercased. No suffix means raw number.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/pvectl/services/resize_volume.rb', line 72 def self.parse_size(size_str) raise ArgumentError, "Size cannot be empty" if size_str.nil? || size_str.strip.empty? match = SIZE_PATTERN.match(size_str.strip) raise ArgumentError, "Invalid size format: #{size_str}" unless match plus, number, suffix = match.captures suffix = suffix&.upcase raise ArgumentError, "Size must be positive: #{size_str}" if number.to_f <= 0 clean_value = "#{number}#{suffix}" raw_value = "#{plus}#{number}#{suffix}" ParsedSize.new( relative: !plus.nil?, value: clean_value, raw: raw_value ) end |
Instance Method Details
#perform(id, disk, raw_size, node:) ⇒ Models::OperationResult
Executes the disk resize via repository.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/pvectl/services/resize_volume.rb', line 129 def perform(id, disk, raw_size, node:) @repository.resize(id, node, disk: disk, size: raw_size) Models::OperationResult.new( operation: :resize_volume, success: true, resource: { id: id, node: node, disk: disk, size: raw_size } ) rescue StandardError => e Models::OperationResult.new( operation: :resize_volume, success: false, error: e., resource: { id: id, node: node, disk: disk } ) end |
#preflight(id, disk, parsed_size, node:) ⇒ Hash
Validates the resize operation and returns size information.
Checks that the disk exists in the resource config, extracts current size, calculates new size, and validates constraints (absolute must be larger than current).
113 114 115 116 117 118 119 120 |
# File 'lib/pvectl/services/resize_volume.rb', line 113 def preflight(id, disk, parsed_size, node:) config = @repository.fetch_config(node, id) current_size = extract_disk_size(config, disk, id) new_size = calculate_new_size(current_size, parsed_size) validate_new_size!(current_size, new_size, parsed_size) { disk: disk, current_size: current_size, new_size: new_size } end |