Module: Pvectl::Commands::ResourceLifecycleCommand Abstract
- Included in:
- ContainerLifecycleCommand, VmLifecycleCommand
- Defined in:
- lib/pvectl/commands/resource_lifecycle_command.rb,
sig/pvectl/commands/resource_lifecycle_command.rbs
Overview
Include a specialization module (VmLifecycleCommand, ContainerLifecycleCommand) instead of this one directly.
Shared functionality for lifecycle commands across resource types.
Template method pattern: provides common flow (validate, resolve, confirm, execute, output) while specialization modules define resource-specific hooks.
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
-
.included(base) ⇒ void
Hook called when module is included.
Instance Method Summary collapse
-
#apply_selectors(resources) ⇒ Array<Object>
Applies selectors to resource collection.
-
#build_presenter ⇒ Object
Presenter for results.
-
#build_repository(connection) ⇒ Object
Repository for this resource type.
-
#build_selector(strings) ⇒ Object
Selector for filtering.
-
#build_service(repo, task_repo, options) ⇒ Object
Lifecycle service.
-
#confirm_operation(resources) ⇒ Boolean
Confirms multi-resource operation with user.
-
#determine_exit_code(results) ⇒ Integer
Determines exit code based on results.
-
#execute ⇒ Integer
Executes the lifecycle command.
-
#initialize(resource_type, resource_ids, options, global_options) ⇒ ResourceLifecycleCommand
Initializes a lifecycle command.
-
#load_config ⇒ void
Loads configuration from file or environment.
-
#no_resources_found ⇒ Integer
Outputs no resources found error and returns exit code.
-
#operation_name ⇒ Symbol
Returns the operation name for this command.
-
#output_results(results) ⇒ void
Outputs operation results using the configured formatter.
-
#perform_operation ⇒ Integer
Performs the lifecycle operation.
-
#resolve_resources(repo) ⇒ Array<Object>
Resolves resources based on resource_ids, --all flag, or selectors.
-
#resource_id_label ⇒ String
Human label for resource ID ("VMID", "CTID").
-
#resource_label ⇒ String
Human label for resource ("VM", "container").
-
#selector_strings ⇒ Array<String>
Returns selector strings from options.
-
#service_options ⇒ Hash
Builds service options from command options.
-
#supported_resources ⇒ Array<String>
Supported resource type strings.
-
#usage_error(message) ⇒ Integer
Outputs usage error and returns exit code.
Class Method Details
.included(base) ⇒ void
This method returns an undefined value.
Hook called when module is included.
44 45 46 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 44 def self.included(base) base.extend(ClassMethods) end |
Instance Method Details
#apply_selectors(resources) ⇒ Array<Object>
Applies selectors to resource collection.
177 178 179 180 181 182 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 177 def apply_selectors(resources) return resources if selector_strings.empty? selector = build_selector(selector_strings) selector.apply(resources) end |
#build_presenter ⇒ Object
Returns presenter for results.
105 106 107 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 105 def build_presenter raise NotImplementedError, "#{self.class} must implement #build_presenter" end |
#build_repository(connection) ⇒ Object
Returns repository for this resource type.
95 96 97 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 95 def build_repository(connection) raise NotImplementedError, "#{self.class} must implement #build_repository" end |
#build_selector(strings) ⇒ Object
Returns selector for filtering.
110 111 112 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 110 def build_selector(strings) raise NotImplementedError, "#{self.class} must implement #build_selector" end |
#build_service(repo, task_repo, options) ⇒ Object
Returns lifecycle service.
100 101 102 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 100 def build_service(repo, task_repo, ) raise NotImplementedError, "#{self.class} must implement #build_service" end |
#confirm_operation(resources) ⇒ Boolean
Confirms multi-resource operation with user.
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 188 def confirm_operation(resources) return true if resources.size == 1 return true if [:yes] $stdout.puts "You are about to #{operation_name} #{resources.size} #{resource_label}s:" resources.each { |r| $stdout.puts " - #{r.vmid} (#{r.name || 'unnamed'}) on #{r.node}" } $stdout.puts "" $stdout.print "Proceed? [y/N]: " response = $stdin.gets&.strip&.downcase %w[y yes].include?(response) end |
#determine_exit_code(results) ⇒ Integer
Determines exit code based on results.
247 248 249 250 251 252 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 247 def determine_exit_code(results) return Pvectl::ExitCodes::SUCCESS if results.all?(&:successful?) return Pvectl::ExitCodes::SUCCESS if results.all?(&:pending?) Pvectl::ExitCodes::GENERAL_ERROR end |
#execute ⇒ Integer
Executes the lifecycle command.
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 64 def execute return usage_error("Resource type required (#{supported_resources.join(', ')})") unless @resource_type return usage_error("Unsupported resource: #{@resource_type}") unless supported_resources.include?(@resource_type) if @resource_ids.empty? && ![:all] && selector_strings.empty? return usage_error("#{resource_id_label}, --all, or -l selector required") end perform_operation end |
#initialize(resource_type, resource_ids, options, global_options) ⇒ ResourceLifecycleCommand
Initializes a lifecycle command.
54 55 56 57 58 59 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 54 def initialize(resource_type, resource_ids, , ) @resource_type = resource_type @resource_ids = Array(resource_ids).compact = = end |
#load_config ⇒ void
This method returns an undefined value.
Loads configuration from file or environment.
211 212 213 214 215 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 211 def load_config service = Pvectl::Config::Service.new service.load(config: [:config]) @config = service.current_config end |
#no_resources_found ⇒ Integer
Outputs no resources found error and returns exit code.
266 267 268 269 270 271 272 273 274 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 266 def no_resources_found msg = if [:all] || selector_strings.any? [:node] ? "No #{resource_label}s found on node #{@options[:node]}" : "No #{resource_label}s found matching criteria" else "No #{resource_label}s found for given #{resource_id_label}s" end $stderr.puts "Error: #{msg}" Pvectl::ExitCodes::NOT_FOUND end |
#operation_name ⇒ Symbol
Returns the operation name for this command.
204 205 206 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 204 def operation_name self.class::OPERATION end |
#output_results(results) ⇒ void
This method returns an undefined value.
Outputs operation results using the configured formatter.
233 234 235 236 237 238 239 240 241 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 233 def output_results(results) presenter = build_presenter format = [:output] || "table" color_flag = [:color] formatter = Pvectl::Formatters::Registry.for(format) output = formatter.format(results, presenter, color: color_flag) puts output end |
#perform_operation ⇒ Integer
Performs the lifecycle operation.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 119 def perform_operation load_config connection = Pvectl::Connection.new(@config) repo = build_repository(connection) task_repo = Pvectl::Repositories::Task.new(connection) resources = resolve_resources(repo) return no_resources_found if resources.empty? return Pvectl::ExitCodes::SUCCESS unless confirm_operation(resources) service = build_service(repo, task_repo, ) results = service.execute(operation_name, resources) output_results(results) determine_exit_code(results) rescue Pvectl::Config::ConfigNotFoundError, Pvectl::Config::InvalidConfigError, Pvectl::Config::ContextNotFoundError, Pvectl::Config::ClusterNotFoundError, Pvectl::Config::UserNotFoundError raise rescue StandardError => e $stderr.puts "Error: #{e.message}" Pvectl::ExitCodes::GENERAL_ERROR end |
#resolve_resources(repo) ⇒ Array<Object>
Resolves resources based on resource_ids, --all flag, or selectors.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 150 def resolve_resources(repo) resources = if [:all] repo.list(node: [:node]) elsif @resource_ids.any? resolved = @resource_ids.map { |id| repo.get(id.to_i) }.compact resolved = resolved.select { |r| r.node == [:node] } if [:node] resolved else return [] if selector_strings.empty? repo.list(node: [:node]) end apply_selectors(resources) end |
#resource_id_label ⇒ String
Returns human label for resource ID ("VMID", "CTID").
90 91 92 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 90 def resource_id_label raise NotImplementedError, "#{self.class} must implement #resource_id_label" end |
#resource_label ⇒ String
Returns human label for resource ("VM", "container").
85 86 87 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 85 def resource_label raise NotImplementedError, "#{self.class} must implement #resource_label" end |
#selector_strings ⇒ Array<String>
Returns selector strings from options.
169 170 171 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 169 def selector_strings Array([:selector] || [:l]) end |
#service_options ⇒ Hash
Builds service options from command options.
220 221 222 223 224 225 226 227 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 220 def opts = {} opts[:timeout] = [:timeout] if [:timeout] opts[:async] = true if [:async] opts[:wait] = true if [:wait] opts[:fail_fast] = true if [:"fail-fast"] opts end |
#supported_resources ⇒ Array<String>
Returns supported resource type strings.
80 81 82 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 80 def supported_resources raise NotImplementedError, "#{self.class} must implement #supported_resources" end |
#usage_error(message) ⇒ Integer
Outputs usage error and returns exit code.
258 259 260 261 |
# File 'lib/pvectl/commands/resource_lifecycle_command.rb', line 258 def usage_error() $stderr.puts "Error: #{message}" Pvectl::ExitCodes::USAGE_ERROR end |