Class: Pvectl::Commands::CloneContainer
- Inherits:
-
Object
- Object
- Pvectl::Commands::CloneContainer
- Includes:
- SharedConfigParsers
- Defined in:
- lib/pvectl/commands/clone_container.rb,
sig/pvectl/commands/clone_container.rbs
Overview
Handler for the pvectl clone container command.
Clones a container by CTID, supporting full and linked clones, custom hostname, target node, storage, pool, and description. No batch operations - clones exactly one container at a time.
Class Method Summary collapse
-
.execute(args, options, global_options) ⇒ Integer
Executes the clone container command.
Instance Method Summary collapse
-
#display_clone_summary(ctid, config_params) ⇒ Symbol?
Displays clone summary with config changes and prompts for confirmation.
-
#display_config_changes(params) ⇒ void
Displays the config changes section of the clone summary.
-
#execute ⇒ Integer
Executes the clone container command.
-
#initialize(args, options, global_options) ⇒ CloneContainer
constructor
Initializes a clone container command.
-
#load_config ⇒ void
Loads configuration from file or environment.
-
#output_result(result) ⇒ void
Outputs operation result using the configured formatter.
-
#perform_clone(ctid, config_params) ⇒ Integer
Performs the clone operation.
-
#print_progress(result) ⇒ void
Prints progress message for sync mode.
-
#service_options ⇒ Hash
Builds service options from command options.
-
#usage_error(message) ⇒ Integer
Outputs usage error and returns exit code.
Methods included from SharedConfigParsers
#build_ct_config_params, #build_vm_config_params, #parse_ct_mountpoints, #parse_ct_nets, #parse_vm_cloud_init, #parse_vm_disks, #parse_vm_nets
Constructor Details
#initialize(args, options, global_options) ⇒ CloneContainer
Initializes a clone container command.
38 39 40 41 42 |
# File 'lib/pvectl/commands/clone_container.rb', line 38 def initialize(args, , ) @args = args = = end |
Class Method Details
.execute(args, options, global_options) ⇒ Integer
Executes the clone container command.
29 30 31 |
# File 'lib/pvectl/commands/clone_container.rb', line 29 def self.execute(args, , ) new(args, , ).execute end |
Instance Method Details
#display_clone_summary(ctid, config_params) ⇒ Symbol?
Displays clone summary with config changes and prompts for confirmation.
Only called when config params are present. Shows source/target info and the config changes that will be applied after cloning.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/pvectl/commands/clone_container.rb', line 172 def display_clone_summary(ctid, config_params) $stdout.puts "" $stdout.puts " Clone Container - Summary" $stdout.puts " #{'─' * 40}" $stdout.puts " Source: #{ctid}" $stdout.puts " New ID: #{@options[:newid] || '(auto)'}" $stdout.puts " Hostname: #{@options[:name] || '(auto)'}" target_display = [:target] ? "→ #{@options[:target]}" : "(same)" $stdout.puts " Node: #{target_display}" $stdout.puts " Storage: #{@options[:storage]}" if [:storage] display_config_changes(config_params) $stdout.puts " #{'─' * 40}" $stdout.puts "" return nil if [:yes] $stdout.print "Clone and configure this container? [y/N] " $stdout.flush answer = $stdin.gets&.strip&.downcase answer == "y" ? nil : :cancelled end |
#display_config_changes(params) ⇒ void
This method returns an undefined value.
Displays the config changes section of the clone summary.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/pvectl/commands/clone_container.rb', line 198 def display_config_changes(params) $stdout.puts " ── Config changes #{'─' * 23}" $stdout.puts " CPU: #{params[:cores]} cores" if params[:cores] $stdout.puts " Memory: #{params[:memory]} MB" if params[:memory] $stdout.puts " Swap: #{params[:swap]} MB" if params[:swap] if params[:rootfs] $stdout.puts " RootFS: #{params[:rootfs][:storage]}, #{params[:rootfs][:size]}" end if params[:mountpoints] params[:mountpoints].each_with_index do |mp, i| $stdout.puts " MP#{i}: #{mp[:mp]}, #{mp[:storage]}" end end if params[:nets] params[:nets].each_with_index do |n, i| $stdout.puts " Net#{i}: #{n[:bridge]}" end end $stdout.puts " Privileged: yes" if params[:privileged] $stdout.puts " Tags: #{params[:tags]}" if params[:tags] end |
#execute ⇒ Integer
Executes the clone container command.
Builds config params from shared flags, validates async+config compatibility, and delegates to the clone operation.
50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/pvectl/commands/clone_container.rb', line 50 def execute ctid = @args.first return usage_error("Source CTID required") unless ctid config_params = build_ct_config_params if [:async] && !config_params.empty? return usage_error("Config flags require sync mode (remove --async)") end perform_clone(ctid.to_i, config_params) end |
#load_config ⇒ void
This method returns an undefined value.
Loads configuration from file or environment.
133 134 135 136 137 |
# File 'lib/pvectl/commands/clone_container.rb', line 133 def load_config service = Pvectl::Config::Service.new service.load(config: [:config]) @config = service.current_config end |
#output_result(result) ⇒ void
This method returns an undefined value.
Outputs operation result using the configured formatter.
154 155 156 157 158 159 160 161 162 |
# File 'lib/pvectl/commands/clone_container.rb', line 154 def output_result(result) presenter = Pvectl::Presenters::ContainerOperationResult.new format = [:output] || "table" color_flag = [:color] formatter = Pvectl::Formatters::Registry.for(format) output = formatter.format([result], presenter, color: color_flag) puts output end |
#perform_clone(ctid, config_params) ⇒ Integer
Performs the clone operation.
When config params are present, displays a summary and prompts for confirmation before proceeding. Passes config_params to the service for the two-step clone+configure flow.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/pvectl/commands/clone_container.rb', line 74 def perform_clone(ctid, config_params) unless config_params.empty? return ExitCodes::SUCCESS if display_clone_summary(ctid, config_params) == :cancelled end load_config connection = Pvectl::Connection.new(@config) ct_repo = Pvectl::Repositories::Container.new(connection) task_repo = Pvectl::Repositories::Task.new(connection) service = Pvectl::Services::CloneContainer.new( container_repository: ct_repo, task_repository: task_repo, options: ) result = service.execute( ctid: ctid, new_ctid: [:newid]&.to_i, hostname: [:name], target_node: [:target], storage: [:storage], linked: [:linked], pool: [:pool], description: [:description], config_params: config_params ) print_progress(result) if ![:async] && result.container output_result(result) result.failed? ? ExitCodes::GENERAL_ERROR : ExitCodes::SUCCESS 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}" ExitCodes::GENERAL_ERROR end |
#print_progress(result) ⇒ void
This method returns an undefined value.
Prints progress message for sync mode.
122 123 124 125 126 127 128 |
# File 'lib/pvectl/commands/clone_container.rb', line 122 def print_progress(result) source = result.container new_hostname = result.resource&.dig(:hostname) || "clone" new_id = result.resource&.dig(:new_ctid) $stderr.puts "Cloning container #{source.vmid} (#{source.name || 'unnamed'}) to #{new_id} (#{new_hostname})..." $stderr.puts "" end |
#service_options ⇒ Hash
Builds service options from command options.
142 143 144 145 146 147 148 |
# File 'lib/pvectl/commands/clone_container.rb', line 142 def opts = {} opts[:timeout] = [:timeout] if [:timeout] opts[:async] = true if [:async] opts[:start] = true if [:start] opts end |
#usage_error(message) ⇒ Integer
Outputs usage error and returns exit code.
224 225 226 227 |
# File 'lib/pvectl/commands/clone_container.rb', line 224 def usage_error() $stderr.puts "Error: #{message}" ExitCodes::USAGE_ERROR end |