pvectl 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.claude/rules/branch-before-changes.md +52 -0
- data/.claude/rules/documentation-updates.md +104 -0
- data/.claude/rules/git-workflow.md +84 -0
- data/.claude/rules/proxmox-api-docs.md +58 -0
- data/.claude/rules/rbs-signatures.md +80 -0
- data/.claude/rules/refactoring-as-design-option.md +35 -0
- data/.claude/scheduled_tasks.lock +1 -0
- data/.claude/settings.json +51 -0
- data/.mcp.json +8 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +138 -0
- data/CLAUDE.md +211 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +143 -0
- data/Rakefile +8 -0
- data/docs/proxmox-api-update.sh +96 -0
- data/exe/pvectl +5 -0
- data/lib/pvectl/argv_preprocessor.rb +334 -0
- data/lib/pvectl/cli.rb +102 -0
- data/lib/pvectl/commands/apt.rb +389 -0
- data/lib/pvectl/commands/clone_container.rb +230 -0
- data/lib/pvectl/commands/clone_vm.rb +331 -0
- data/lib/pvectl/commands/cloudinit/command.rb +122 -0
- data/lib/pvectl/commands/cloudinit/dump.rb +94 -0
- data/lib/pvectl/commands/cloudinit/pending.rb +137 -0
- data/lib/pvectl/commands/cloudinit/regenerate.rb +79 -0
- data/lib/pvectl/commands/config/command.rb +65 -0
- data/lib/pvectl/commands/config/get_contexts.rb +68 -0
- data/lib/pvectl/commands/config/set_cluster.rb +103 -0
- data/lib/pvectl/commands/config/set_context.rb +136 -0
- data/lib/pvectl/commands/config/set_credentials.rb +181 -0
- data/lib/pvectl/commands/config/use_context.rb +69 -0
- data/lib/pvectl/commands/config/view.rb +67 -0
- data/lib/pvectl/commands/console.rb +93 -0
- data/lib/pvectl/commands/console_ct.rb +187 -0
- data/lib/pvectl/commands/console_vm.rb +187 -0
- data/lib/pvectl/commands/container_lifecycle_command.rb +77 -0
- data/lib/pvectl/commands/create_backup.rb +173 -0
- data/lib/pvectl/commands/create_container.rb +141 -0
- data/lib/pvectl/commands/create_resource_command.rb +244 -0
- data/lib/pvectl/commands/create_snapshot.rb +242 -0
- data/lib/pvectl/commands/create_vm.rb +267 -0
- data/lib/pvectl/commands/delete_backup.rb +139 -0
- data/lib/pvectl/commands/delete_command.rb +119 -0
- data/lib/pvectl/commands/delete_container.rb +30 -0
- data/lib/pvectl/commands/delete_snapshot.rb +248 -0
- data/lib/pvectl/commands/delete_vm.rb +127 -0
- data/lib/pvectl/commands/describe/command.rb +251 -0
- data/lib/pvectl/commands/edit_container.rb +56 -0
- data/lib/pvectl/commands/edit_dns.rb +149 -0
- data/lib/pvectl/commands/edit_hosts.rb +135 -0
- data/lib/pvectl/commands/edit_node.rb +54 -0
- data/lib/pvectl/commands/edit_resource_command.rb +180 -0
- data/lib/pvectl/commands/edit_vm.rb +154 -0
- data/lib/pvectl/commands/edit_volume.rb +189 -0
- data/lib/pvectl/commands/feature_command.rb +230 -0
- data/lib/pvectl/commands/feature_container.rb +21 -0
- data/lib/pvectl/commands/feature_vm.rb +94 -0
- data/lib/pvectl/commands/get/command.rb +360 -0
- data/lib/pvectl/commands/get/handlers/backups.rb +76 -0
- data/lib/pvectl/commands/get/handlers/capabilities.rb +107 -0
- data/lib/pvectl/commands/get/handlers/containers.rb +148 -0
- data/lib/pvectl/commands/get/handlers/disks.rb +107 -0
- data/lib/pvectl/commands/get/handlers/dns.rb +94 -0
- data/lib/pvectl/commands/get/handlers/hosts.rb +94 -0
- data/lib/pvectl/commands/get/handlers/nodes.rb +162 -0
- data/lib/pvectl/commands/get/handlers/services.rb +81 -0
- data/lib/pvectl/commands/get/handlers/snapshots.rb +97 -0
- data/lib/pvectl/commands/get/handlers/storage.rb +118 -0
- data/lib/pvectl/commands/get/handlers/subscription.rb +69 -0
- data/lib/pvectl/commands/get/handlers/tasks.rb +89 -0
- data/lib/pvectl/commands/get/handlers/templates.rb +175 -0
- data/lib/pvectl/commands/get/handlers/time.rb +118 -0
- data/lib/pvectl/commands/get/handlers/vms.rb +145 -0
- data/lib/pvectl/commands/get/handlers/volume.rb +134 -0
- data/lib/pvectl/commands/get/resource_handler.rb +63 -0
- data/lib/pvectl/commands/get/resource_registry.rb +18 -0
- data/lib/pvectl/commands/get/watch_loop.rb +129 -0
- data/lib/pvectl/commands/irreversible_command.rb +265 -0
- data/lib/pvectl/commands/logs/command.rb +275 -0
- data/lib/pvectl/commands/logs/handlers/journal.rb +46 -0
- data/lib/pvectl/commands/logs/handlers/syslog.rb +53 -0
- data/lib/pvectl/commands/logs/handlers/task_detail.rb +52 -0
- data/lib/pvectl/commands/logs/handlers/task_logs.rb +115 -0
- data/lib/pvectl/commands/logs/resource_handler.rb +46 -0
- data/lib/pvectl/commands/logs/resource_registry.rb +22 -0
- data/lib/pvectl/commands/migrate_command.rb +282 -0
- data/lib/pvectl/commands/migrate_container.rb +23 -0
- data/lib/pvectl/commands/migrate_vm.rb +122 -0
- data/lib/pvectl/commands/move_disk_command.rb +239 -0
- data/lib/pvectl/commands/move_disk_container.rb +21 -0
- data/lib/pvectl/commands/move_disk_vm.rb +127 -0
- data/lib/pvectl/commands/ping.rb +249 -0
- data/lib/pvectl/commands/pull.rb +342 -0
- data/lib/pvectl/commands/push.rb +352 -0
- data/lib/pvectl/commands/reset.rb +64 -0
- data/lib/pvectl/commands/resource_lifecycle_command.rb +277 -0
- data/lib/pvectl/commands/resource_registry.rb +73 -0
- data/lib/pvectl/commands/restart.rb +70 -0
- data/lib/pvectl/commands/restart_container.rb +18 -0
- data/lib/pvectl/commands/restore_backup.rb +236 -0
- data/lib/pvectl/commands/resume.rb +57 -0
- data/lib/pvectl/commands/rollback_snapshot.rb +228 -0
- data/lib/pvectl/commands/sendkey_vm.rb +205 -0
- data/lib/pvectl/commands/service.rb +293 -0
- data/lib/pvectl/commands/set_container.rb +50 -0
- data/lib/pvectl/commands/set_node.rb +52 -0
- data/lib/pvectl/commands/set_resource_command.rb +185 -0
- data/lib/pvectl/commands/set_vm.rb +136 -0
- data/lib/pvectl/commands/set_volume.rb +212 -0
- data/lib/pvectl/commands/shared_config_parsers.rb +126 -0
- data/lib/pvectl/commands/shared_flags.rb +155 -0
- data/lib/pvectl/commands/shutdown.rb +73 -0
- data/lib/pvectl/commands/shutdown_container.rb +18 -0
- data/lib/pvectl/commands/start.rb +79 -0
- data/lib/pvectl/commands/start_container.rb +18 -0
- data/lib/pvectl/commands/stop.rb +75 -0
- data/lib/pvectl/commands/stop_container.rb +18 -0
- data/lib/pvectl/commands/suspend.rb +64 -0
- data/lib/pvectl/commands/template_command.rb +205 -0
- data/lib/pvectl/commands/template_container.rb +27 -0
- data/lib/pvectl/commands/template_vm.rb +106 -0
- data/lib/pvectl/commands/top/command.rb +206 -0
- data/lib/pvectl/commands/top/handlers/containers.rb +61 -0
- data/lib/pvectl/commands/top/handlers/nodes.rb +61 -0
- data/lib/pvectl/commands/top/handlers/vms.rb +61 -0
- data/lib/pvectl/commands/top/resource_handler.rb +46 -0
- data/lib/pvectl/commands/top/resource_registry.rb +22 -0
- data/lib/pvectl/commands/unlink_disk_vm.rb +232 -0
- data/lib/pvectl/commands/vm_lifecycle_command.rb +77 -0
- data/lib/pvectl/commands/wakeonlan_node.rb +153 -0
- data/lib/pvectl/config/errors.rb +62 -0
- data/lib/pvectl/config/models/cluster.rb +180 -0
- data/lib/pvectl/config/models/context.rb +100 -0
- data/lib/pvectl/config/models/resolved_config.rb +171 -0
- data/lib/pvectl/config/models/user.rb +133 -0
- data/lib/pvectl/config/provider.rb +297 -0
- data/lib/pvectl/config/service.rb +300 -0
- data/lib/pvectl/config/store.rb +161 -0
- data/lib/pvectl/config/wizard.rb +309 -0
- data/lib/pvectl/config_serializer.rb +1034 -0
- data/lib/pvectl/connection/retry_handler.rb +161 -0
- data/lib/pvectl/connection.rb +157 -0
- data/lib/pvectl/console/terminal_session.rb +449 -0
- data/lib/pvectl/editor_session.rb +157 -0
- data/lib/pvectl/exit_codes.rb +43 -0
- data/lib/pvectl/formatters/base.rb +55 -0
- data/lib/pvectl/formatters/color_support.rb +90 -0
- data/lib/pvectl/formatters/json.rb +45 -0
- data/lib/pvectl/formatters/output_helper.rb +77 -0
- data/lib/pvectl/formatters/registry.rb +72 -0
- data/lib/pvectl/formatters/table.rb +235 -0
- data/lib/pvectl/formatters/wide.rb +93 -0
- data/lib/pvectl/formatters/yaml.rb +49 -0
- data/lib/pvectl/manifest_serializer.rb +142 -0
- data/lib/pvectl/models/apt_package.rb +107 -0
- data/lib/pvectl/models/backup.rb +173 -0
- data/lib/pvectl/models/base.rb +49 -0
- data/lib/pvectl/models/capability.rb +62 -0
- data/lib/pvectl/models/container.rb +205 -0
- data/lib/pvectl/models/container_operation_result.rb +27 -0
- data/lib/pvectl/models/dns_config.rb +54 -0
- data/lib/pvectl/models/hosts_file.rb +47 -0
- data/lib/pvectl/models/journal_entry.rb +16 -0
- data/lib/pvectl/models/network_interface.rb +85 -0
- data/lib/pvectl/models/node.rb +195 -0
- data/lib/pvectl/models/node_operation_result.rb +45 -0
- data/lib/pvectl/models/operation_result.rb +110 -0
- data/lib/pvectl/models/physical_disk.rb +193 -0
- data/lib/pvectl/models/service.rb +80 -0
- data/lib/pvectl/models/snapshot.rb +101 -0
- data/lib/pvectl/models/snapshot_description.rb +39 -0
- data/lib/pvectl/models/storage.rb +180 -0
- data/lib/pvectl/models/subscription.rb +87 -0
- data/lib/pvectl/models/syslog_entry.rb +17 -0
- data/lib/pvectl/models/task.rb +95 -0
- data/lib/pvectl/models/task_entry.rb +52 -0
- data/lib/pvectl/models/task_log_line.rb +17 -0
- data/lib/pvectl/models/time_config.rb +47 -0
- data/lib/pvectl/models/vm.rb +137 -0
- data/lib/pvectl/models/vm_operation_result.rb +27 -0
- data/lib/pvectl/models/volume.rb +133 -0
- data/lib/pvectl/models/volume_operation_result.rb +26 -0
- data/lib/pvectl/parsers/cloud_init_config.rb +92 -0
- data/lib/pvectl/parsers/disk_config.rb +97 -0
- data/lib/pvectl/parsers/lxc_mount_config.rb +98 -0
- data/lib/pvectl/parsers/lxc_net_config.rb +97 -0
- data/lib/pvectl/parsers/net_config.rb +95 -0
- data/lib/pvectl/parsers/smart_text.rb +42 -0
- data/lib/pvectl/plugin_loader.rb +157 -0
- data/lib/pvectl/presenters/apt_package.rb +99 -0
- data/lib/pvectl/presenters/backup.rb +128 -0
- data/lib/pvectl/presenters/base.rb +283 -0
- data/lib/pvectl/presenters/capability.rb +104 -0
- data/lib/pvectl/presenters/config/context.rb +80 -0
- data/lib/pvectl/presenters/container.rb +574 -0
- data/lib/pvectl/presenters/container_operation_result.rb +109 -0
- data/lib/pvectl/presenters/disk.rb +184 -0
- data/lib/pvectl/presenters/dns_config.rb +68 -0
- data/lib/pvectl/presenters/hosts_file.rb +61 -0
- data/lib/pvectl/presenters/journal_entry.rb +20 -0
- data/lib/pvectl/presenters/node.rb +762 -0
- data/lib/pvectl/presenters/node_operation_result.rb +50 -0
- data/lib/pvectl/presenters/operation_result.rb +61 -0
- data/lib/pvectl/presenters/service.rb +76 -0
- data/lib/pvectl/presenters/snapshot.rb +239 -0
- data/lib/pvectl/presenters/snapshot_operation_result.rb +125 -0
- data/lib/pvectl/presenters/storage.rb +329 -0
- data/lib/pvectl/presenters/subscription.rb +189 -0
- data/lib/pvectl/presenters/syslog_entry.rb +20 -0
- data/lib/pvectl/presenters/task_entry.rb +69 -0
- data/lib/pvectl/presenters/task_log_line.rb +20 -0
- data/lib/pvectl/presenters/template.rb +76 -0
- data/lib/pvectl/presenters/time_config.rb +86 -0
- data/lib/pvectl/presenters/top_container.rb +112 -0
- data/lib/pvectl/presenters/top_node.rb +115 -0
- data/lib/pvectl/presenters/top_presenter.rb +59 -0
- data/lib/pvectl/presenters/top_vm.rb +105 -0
- data/lib/pvectl/presenters/vm.rb +853 -0
- data/lib/pvectl/presenters/vm_operation_result.rb +109 -0
- data/lib/pvectl/presenters/volume.rb +136 -0
- data/lib/pvectl/presenters/volume_operation_result.rb +58 -0
- data/lib/pvectl/repositories/apt.rb +93 -0
- data/lib/pvectl/repositories/backup.rb +186 -0
- data/lib/pvectl/repositories/base.rb +110 -0
- data/lib/pvectl/repositories/capabilities.rb +96 -0
- data/lib/pvectl/repositories/container.rb +503 -0
- data/lib/pvectl/repositories/disk.rb +87 -0
- data/lib/pvectl/repositories/dns.rb +54 -0
- data/lib/pvectl/repositories/hosts.rb +63 -0
- data/lib/pvectl/repositories/journal.rb +23 -0
- data/lib/pvectl/repositories/node.rb +537 -0
- data/lib/pvectl/repositories/service.rb +139 -0
- data/lib/pvectl/repositories/snapshot.rb +133 -0
- data/lib/pvectl/repositories/storage.rb +302 -0
- data/lib/pvectl/repositories/subscription.rb +77 -0
- data/lib/pvectl/repositories/syslog.rb +25 -0
- data/lib/pvectl/repositories/task.rb +82 -0
- data/lib/pvectl/repositories/task_list.rb +30 -0
- data/lib/pvectl/repositories/task_log.rb +31 -0
- data/lib/pvectl/repositories/time_config.rb +53 -0
- data/lib/pvectl/repositories/vm.rb +616 -0
- data/lib/pvectl/repositories/volume.rb +306 -0
- data/lib/pvectl/selectors/base.rb +201 -0
- data/lib/pvectl/selectors/container.rb +116 -0
- data/lib/pvectl/selectors/disk.rb +59 -0
- data/lib/pvectl/selectors/vm.rb +116 -0
- data/lib/pvectl/selectors/volume.rb +59 -0
- data/lib/pvectl/services/backup.rb +209 -0
- data/lib/pvectl/services/clone_container.rb +260 -0
- data/lib/pvectl/services/clone_vm.rb +265 -0
- data/lib/pvectl/services/cloudinit.rb +96 -0
- data/lib/pvectl/services/console.rb +152 -0
- data/lib/pvectl/services/container_lifecycle.rb +124 -0
- data/lib/pvectl/services/create_container.rb +179 -0
- data/lib/pvectl/services/create_vm.rb +191 -0
- data/lib/pvectl/services/edit_container.rb +125 -0
- data/lib/pvectl/services/edit_dns.rb +159 -0
- data/lib/pvectl/services/edit_hosts.rb +78 -0
- data/lib/pvectl/services/edit_node.rb +147 -0
- data/lib/pvectl/services/edit_vm.rb +125 -0
- data/lib/pvectl/services/edit_volume.rb +224 -0
- data/lib/pvectl/services/get/resource_service.rb +98 -0
- data/lib/pvectl/services/move_disk.rb +132 -0
- data/lib/pvectl/services/pull_config.rb +94 -0
- data/lib/pvectl/services/push_config.rb +524 -0
- data/lib/pvectl/services/resize_volume.rb +253 -0
- data/lib/pvectl/services/resource_delete.rb +169 -0
- data/lib/pvectl/services/resource_migration.rb +170 -0
- data/lib/pvectl/services/sendkey.rb +108 -0
- data/lib/pvectl/services/service_lifecycle.rb +89 -0
- data/lib/pvectl/services/set_container.rb +128 -0
- data/lib/pvectl/services/set_node.rb +236 -0
- data/lib/pvectl/services/set_vm.rb +128 -0
- data/lib/pvectl/services/set_volume.rb +126 -0
- data/lib/pvectl/services/snapshot.rb +261 -0
- data/lib/pvectl/services/task_listing.rb +75 -0
- data/lib/pvectl/services/unlink_disk.rb +86 -0
- data/lib/pvectl/services/vm_lifecycle.rb +124 -0
- data/lib/pvectl/services/wakeonlan.rb +79 -0
- data/lib/pvectl/utils/resource_resolver.rb +80 -0
- data/lib/pvectl/version.rb +13 -0
- data/lib/pvectl/wizards/create_container.rb +105 -0
- data/lib/pvectl/wizards/create_vm.rb +98 -0
- data/lib/pvectl.rb +439 -0
- data/sig/external/gli.rbs +16 -0
- data/sig/external/proxmox_api.rbs +10 -0
- data/sig/pvectl/argv_preprocessor.rbs +53 -0
- data/sig/pvectl/cli.rbs +26 -0
- data/sig/pvectl/commands/apt.rbs +47 -0
- data/sig/pvectl/commands/clone_container.rbs +31 -0
- data/sig/pvectl/commands/clone_vm.rbs +33 -0
- data/sig/pvectl/commands/cloudinit/command.rbs +13 -0
- data/sig/pvectl/commands/cloudinit/dump.rbs +13 -0
- data/sig/pvectl/commands/cloudinit/pending.rbs +17 -0
- data/sig/pvectl/commands/cloudinit/regenerate.rbs +11 -0
- data/sig/pvectl/commands/config/command.rbs +9 -0
- data/sig/pvectl/commands/config/get_contexts.rbs +11 -0
- data/sig/pvectl/commands/config/set_cluster.rbs +11 -0
- data/sig/pvectl/commands/config/set_context.rbs +15 -0
- data/sig/pvectl/commands/config/set_credentials.rbs +15 -0
- data/sig/pvectl/commands/config/use_context.rbs +11 -0
- data/sig/pvectl/commands/config/view.rbs +11 -0
- data/sig/pvectl/commands/console.rbs +9 -0
- data/sig/pvectl/commands/console_ct.rbs +27 -0
- data/sig/pvectl/commands/console_vm.rbs +27 -0
- data/sig/pvectl/commands/container_lifecycle_command.rbs +25 -0
- data/sig/pvectl/commands/create_backup.rbs +29 -0
- data/sig/pvectl/commands/create_container.rbs +30 -0
- data/sig/pvectl/commands/create_resource_command.rbs +53 -0
- data/sig/pvectl/commands/create_snapshot.rbs +35 -0
- data/sig/pvectl/commands/create_vm.rbs +30 -0
- data/sig/pvectl/commands/delete_backup.rbs +25 -0
- data/sig/pvectl/commands/delete_command.rbs +45 -0
- data/sig/pvectl/commands/delete_container.rbs +11 -0
- data/sig/pvectl/commands/delete_snapshot.rbs +35 -0
- data/sig/pvectl/commands/delete_vm.rbs +13 -0
- data/sig/pvectl/commands/describe/command.rbs +27 -0
- data/sig/pvectl/commands/edit_container.rbs +17 -0
- data/sig/pvectl/commands/edit_dns.rbs +25 -0
- data/sig/pvectl/commands/edit_hosts.rbs +23 -0
- data/sig/pvectl/commands/edit_node.rbs +17 -0
- data/sig/pvectl/commands/edit_resource_command.rbs +35 -0
- data/sig/pvectl/commands/edit_vm.rbs +19 -0
- data/sig/pvectl/commands/edit_volume.rbs +24 -0
- data/sig/pvectl/commands/feature_command.rbs +43 -0
- data/sig/pvectl/commands/feature_container.rbs +10 -0
- data/sig/pvectl/commands/feature_vm.rbs +12 -0
- data/sig/pvectl/commands/get/command.rbs +42 -0
- data/sig/pvectl/commands/get/handlers/backups.rbs +23 -0
- data/sig/pvectl/commands/get/handlers/capabilities.rbs +29 -0
- data/sig/pvectl/commands/get/handlers/containers.rbs +35 -0
- data/sig/pvectl/commands/get/handlers/disks.rbs +27 -0
- data/sig/pvectl/commands/get/handlers/dns.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/hosts.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/nodes.rbs +33 -0
- data/sig/pvectl/commands/get/handlers/services.rbs +23 -0
- data/sig/pvectl/commands/get/handlers/snapshots.rbs +27 -0
- data/sig/pvectl/commands/get/handlers/storage.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/subscription.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/tasks.rbs +28 -0
- data/sig/pvectl/commands/get/handlers/templates.rbs +35 -0
- data/sig/pvectl/commands/get/handlers/time.rbs +29 -0
- data/sig/pvectl/commands/get/handlers/vms.rbs +35 -0
- data/sig/pvectl/commands/get/handlers/volume.rbs +27 -0
- data/sig/pvectl/commands/get/resource_handler.rbs +13 -0
- data/sig/pvectl/commands/get/resource_registry.rbs +8 -0
- data/sig/pvectl/commands/get/watch_loop.rbs +33 -0
- data/sig/pvectl/commands/irreversible_command.rbs +32 -0
- data/sig/pvectl/commands/logs/command.rbs +35 -0
- data/sig/pvectl/commands/logs/handlers/journal.rbs +21 -0
- data/sig/pvectl/commands/logs/handlers/syslog.rbs +21 -0
- data/sig/pvectl/commands/logs/handlers/task_detail.rbs +21 -0
- data/sig/pvectl/commands/logs/handlers/task_logs.rbs +35 -0
- data/sig/pvectl/commands/logs/resource_handler.rbs +11 -0
- data/sig/pvectl/commands/logs/resource_registry.rbs +8 -0
- data/sig/pvectl/commands/migrate_command.rbs +45 -0
- data/sig/pvectl/commands/migrate_container.rbs +11 -0
- data/sig/pvectl/commands/migrate_vm.rbs +13 -0
- data/sig/pvectl/commands/move_disk_command.rbs +43 -0
- data/sig/pvectl/commands/move_disk_container.rbs +11 -0
- data/sig/pvectl/commands/move_disk_vm.rbs +13 -0
- data/sig/pvectl/commands/ping.rbs +39 -0
- data/sig/pvectl/commands/pull.rbs +33 -0
- data/sig/pvectl/commands/push.rbs +32 -0
- data/sig/pvectl/commands/reset.rbs +11 -0
- data/sig/pvectl/commands/resource_lifecycle_command.rbs +55 -0
- data/sig/pvectl/commands/resource_registry.rbs +19 -0
- data/sig/pvectl/commands/restart.rbs +11 -0
- data/sig/pvectl/commands/restart_container.rbs +9 -0
- data/sig/pvectl/commands/restore_backup.rbs +27 -0
- data/sig/pvectl/commands/resume.rbs +11 -0
- data/sig/pvectl/commands/rollback_snapshot.rbs +31 -0
- data/sig/pvectl/commands/sendkey_vm.rbs +25 -0
- data/sig/pvectl/commands/service.rbs +38 -0
- data/sig/pvectl/commands/set_container.rbs +13 -0
- data/sig/pvectl/commands/set_node.rbs +13 -0
- data/sig/pvectl/commands/set_resource_command.rbs +25 -0
- data/sig/pvectl/commands/set_vm.rbs +15 -0
- data/sig/pvectl/commands/set_volume.rbs +24 -0
- data/sig/pvectl/commands/shared_config_parsers.rbs +19 -0
- data/sig/pvectl/commands/shared_flags.rbs +10 -0
- data/sig/pvectl/commands/shutdown.rbs +11 -0
- data/sig/pvectl/commands/shutdown_container.rbs +9 -0
- data/sig/pvectl/commands/start.rbs +11 -0
- data/sig/pvectl/commands/start_container.rbs +9 -0
- data/sig/pvectl/commands/stop.rbs +11 -0
- data/sig/pvectl/commands/stop_container.rbs +9 -0
- data/sig/pvectl/commands/suspend.rbs +11 -0
- data/sig/pvectl/commands/template_command.rbs +21 -0
- data/sig/pvectl/commands/template_container.rbs +10 -0
- data/sig/pvectl/commands/template_vm.rbs +12 -0
- data/sig/pvectl/commands/top/command.rbs +31 -0
- data/sig/pvectl/commands/top/handlers/containers.rbs +21 -0
- data/sig/pvectl/commands/top/handlers/nodes.rbs +21 -0
- data/sig/pvectl/commands/top/handlers/vms.rbs +21 -0
- data/sig/pvectl/commands/top/resource_handler.rbs +11 -0
- data/sig/pvectl/commands/top/resource_registry.rbs +8 -0
- data/sig/pvectl/commands/unlink_disk_vm.rbs +27 -0
- data/sig/pvectl/commands/vm_lifecycle_command.rbs +25 -0
- data/sig/pvectl/commands/wakeonlan_node.rbs +21 -0
- data/sig/pvectl/config/errors.rbs +24 -0
- data/sig/pvectl/config/models/cluster.rbs +39 -0
- data/sig/pvectl/config/models/context.rbs +23 -0
- data/sig/pvectl/config/models/resolved_config.rbs +51 -0
- data/sig/pvectl/config/models/user.rbs +31 -0
- data/sig/pvectl/config/provider.rbs +40 -0
- data/sig/pvectl/config/service.rbs +65 -0
- data/sig/pvectl/config/store.rbs +14 -0
- data/sig/pvectl/config/wizard.rbs +48 -0
- data/sig/pvectl/config_serializer.rbs +121 -0
- data/sig/pvectl/connection/retry_handler.rbs +31 -0
- data/sig/pvectl/connection.rbs +35 -0
- data/sig/pvectl/console/terminal_session.rbs +63 -0
- data/sig/pvectl/editor_session.rbs +33 -0
- data/sig/pvectl/exit_codes.rbs +19 -0
- data/sig/pvectl/formatters/base.rbs +13 -0
- data/sig/pvectl/formatters/color_support.rbs +13 -0
- data/sig/pvectl/formatters/json.rbs +7 -0
- data/sig/pvectl/formatters/output_helper.rbs +9 -0
- data/sig/pvectl/formatters/registry.rbs +13 -0
- data/sig/pvectl/formatters/table.rbs +25 -0
- data/sig/pvectl/formatters/wide.rbs +15 -0
- data/sig/pvectl/formatters/yaml.rbs +7 -0
- data/sig/pvectl/manifest_serializer.rbs +18 -0
- data/sig/pvectl/models/apt_package.rbs +26 -0
- data/sig/pvectl/models/backup.rbs +31 -0
- data/sig/pvectl/models/base.rbs +11 -0
- data/sig/pvectl/models/capability.rbs +16 -0
- data/sig/pvectl/models/container.rbs +44 -0
- data/sig/pvectl/models/container_operation_result.rbs +9 -0
- data/sig/pvectl/models/dns_config.rbs +15 -0
- data/sig/pvectl/models/hosts_file.rbs +13 -0
- data/sig/pvectl/models/journal_entry.rbs +10 -0
- data/sig/pvectl/models/network_interface.rbs +20 -0
- data/sig/pvectl/models/node.rbs +47 -0
- data/sig/pvectl/models/node_operation_result.rbs +12 -0
- data/sig/pvectl/models/operation_result.rbs +21 -0
- data/sig/pvectl/models/physical_disk.rbs +35 -0
- data/sig/pvectl/models/service.rbs +18 -0
- data/sig/pvectl/models/snapshot.rbs +21 -0
- data/sig/pvectl/models/snapshot_description.rbs +18 -0
- data/sig/pvectl/models/storage.rbs +39 -0
- data/sig/pvectl/models/subscription.rbs +24 -0
- data/sig/pvectl/models/syslog_entry.rbs +10 -0
- data/sig/pvectl/models/task.rbs +22 -0
- data/sig/pvectl/models/task_entry.rbs +24 -0
- data/sig/pvectl/models/task_log_line.rbs +10 -0
- data/sig/pvectl/models/time_config.rbs +12 -0
- data/sig/pvectl/models/vm.rbs +32 -0
- data/sig/pvectl/models/vm_operation_result.rbs +9 -0
- data/sig/pvectl/models/volume.rbs +29 -0
- data/sig/pvectl/models/volume_operation_result.rbs +9 -0
- data/sig/pvectl/parsers/cloud_init_config.rbs +15 -0
- data/sig/pvectl/parsers/disk_config.rbs +19 -0
- data/sig/pvectl/parsers/lxc_mount_config.rbs +19 -0
- data/sig/pvectl/parsers/lxc_net_config.rbs +19 -0
- data/sig/pvectl/parsers/net_config.rbs +19 -0
- data/sig/pvectl/parsers/smart_text.rbs +7 -0
- data/sig/pvectl/plugin_loader.rbs +25 -0
- data/sig/pvectl/presenters/apt_package.rbs +19 -0
- data/sig/pvectl/presenters/backup.rbs +25 -0
- data/sig/pvectl/presenters/base.rbs +41 -0
- data/sig/pvectl/presenters/capability.rbs +19 -0
- data/sig/pvectl/presenters/config/context.rbs +17 -0
- data/sig/pvectl/presenters/container.rbs +78 -0
- data/sig/pvectl/presenters/container_operation_result.rbs +19 -0
- data/sig/pvectl/presenters/disk.rbs +31 -0
- data/sig/pvectl/presenters/dns_config.rbs +13 -0
- data/sig/pvectl/presenters/hosts_file.rbs +13 -0
- data/sig/pvectl/presenters/journal_entry.rbs +11 -0
- data/sig/pvectl/presenters/node.rbs +118 -0
- data/sig/pvectl/presenters/node_operation_result.rbs +11 -0
- data/sig/pvectl/presenters/operation_result.rbs +17 -0
- data/sig/pvectl/presenters/service.rbs +15 -0
- data/sig/pvectl/presenters/snapshot.rbs +35 -0
- data/sig/pvectl/presenters/snapshot_operation_result.rbs +27 -0
- data/sig/pvectl/presenters/storage.rbs +59 -0
- data/sig/pvectl/presenters/subscription.rbs +36 -0
- data/sig/pvectl/presenters/syslog_entry.rbs +11 -0
- data/sig/pvectl/presenters/task_entry.rbs +21 -0
- data/sig/pvectl/presenters/task_log_line.rbs +11 -0
- data/sig/pvectl/presenters/template.rbs +15 -0
- data/sig/pvectl/presenters/time_config.rbs +19 -0
- data/sig/pvectl/presenters/top_container.rbs +17 -0
- data/sig/pvectl/presenters/top_node.rbs +17 -0
- data/sig/pvectl/presenters/top_presenter.rbs +13 -0
- data/sig/pvectl/presenters/top_vm.rbs +17 -0
- data/sig/pvectl/presenters/vm.rbs +91 -0
- data/sig/pvectl/presenters/vm_operation_result.rbs +19 -0
- data/sig/pvectl/presenters/volume.rbs +23 -0
- data/sig/pvectl/presenters/volume_operation_result.rbs +11 -0
- data/sig/pvectl/repositories/apt.rbs +17 -0
- data/sig/pvectl/repositories/backup.rbs +27 -0
- data/sig/pvectl/repositories/base.rbs +23 -0
- data/sig/pvectl/repositories/capabilities.rbs +20 -0
- data/sig/pvectl/repositories/container.rbs +63 -0
- data/sig/pvectl/repositories/disk.rbs +17 -0
- data/sig/pvectl/repositories/dns.rbs +13 -0
- data/sig/pvectl/repositories/hosts.rbs +13 -0
- data/sig/pvectl/repositories/journal.rbs +7 -0
- data/sig/pvectl/repositories/node.rbs +68 -0
- data/sig/pvectl/repositories/service.rbs +27 -0
- data/sig/pvectl/repositories/snapshot.rbs +19 -0
- data/sig/pvectl/repositories/storage.rbs +37 -0
- data/sig/pvectl/repositories/subscription.rbs +17 -0
- data/sig/pvectl/repositories/syslog.rbs +7 -0
- data/sig/pvectl/repositories/task.rbs +19 -0
- data/sig/pvectl/repositories/task_list.rbs +7 -0
- data/sig/pvectl/repositories/task_log.rbs +11 -0
- data/sig/pvectl/repositories/time_config.rbs +13 -0
- data/sig/pvectl/repositories/vm.rbs +85 -0
- data/sig/pvectl/repositories/volume.rbs +43 -0
- data/sig/pvectl/selectors/base.rbs +37 -0
- data/sig/pvectl/selectors/container.rbs +19 -0
- data/sig/pvectl/selectors/disk.rbs +13 -0
- data/sig/pvectl/selectors/vm.rbs +19 -0
- data/sig/pvectl/selectors/volume.rbs +13 -0
- data/sig/pvectl/services/backup.rbs +27 -0
- data/sig/pvectl/services/clone_container.rbs +35 -0
- data/sig/pvectl/services/clone_vm.rbs +35 -0
- data/sig/pvectl/services/cloudinit.rbs +19 -0
- data/sig/pvectl/services/console.rbs +23 -0
- data/sig/pvectl/services/container_lifecycle.rbs +26 -0
- data/sig/pvectl/services/create_container.rbs +64 -0
- data/sig/pvectl/services/create_vm.rbs +72 -0
- data/sig/pvectl/services/edit_container.rbs +17 -0
- data/sig/pvectl/services/edit_dns.rbs +23 -0
- data/sig/pvectl/services/edit_hosts.rbs +13 -0
- data/sig/pvectl/services/edit_node.rbs +21 -0
- data/sig/pvectl/services/edit_vm.rbs +17 -0
- data/sig/pvectl/services/edit_volume.rbs +18 -0
- data/sig/pvectl/services/get/resource_service.rbs +23 -0
- data/sig/pvectl/services/move_disk.rbs +21 -0
- data/sig/pvectl/services/pull_config.rbs +18 -0
- data/sig/pvectl/services/push_config.rbs +37 -0
- data/sig/pvectl/services/resize_volume.rbs +47 -0
- data/sig/pvectl/services/resource_delete.rbs +27 -0
- data/sig/pvectl/services/resource_migration.rbs +29 -0
- data/sig/pvectl/services/sendkey.rbs +19 -0
- data/sig/pvectl/services/service_lifecycle.rbs +17 -0
- data/sig/pvectl/services/set_container.rbs +14 -0
- data/sig/pvectl/services/set_node.rbs +23 -0
- data/sig/pvectl/services/set_vm.rbs +14 -0
- data/sig/pvectl/services/set_volume.rbs +12 -0
- data/sig/pvectl/services/snapshot.rbs +35 -0
- data/sig/pvectl/services/task_listing.rbs +13 -0
- data/sig/pvectl/services/unlink_disk.rbs +17 -0
- data/sig/pvectl/services/vm_lifecycle.rbs +26 -0
- data/sig/pvectl/services/wakeonlan.rbs +17 -0
- data/sig/pvectl/utils/resource_resolver.rbs +17 -0
- data/sig/pvectl/wizards/create_container.rbs +21 -0
- data/sig/pvectl/wizards/create_vm.rbs +21 -0
- data/sig/pvectl.rbs +9 -0
- metadata +675 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Abstract base class for command resource registries.
|
|
6
|
+
#
|
|
7
|
+
# Provides handler registration and lookup. Each subclass maintains
|
|
8
|
+
# its own isolated set of handlers via +self.inherited+ callback.
|
|
9
|
+
#
|
|
10
|
+
# @abstract Subclass for each command namespace (Get, Top, Logs).
|
|
11
|
+
#
|
|
12
|
+
# @example Creating a command-specific registry
|
|
13
|
+
# module Pvectl::Commands::Logs
|
|
14
|
+
# class ResourceRegistry < Pvectl::Commands::ResourceRegistry; end
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
class ResourceRegistry
|
|
18
|
+
@handlers = {}
|
|
19
|
+
|
|
20
|
+
def self.inherited(subclass)
|
|
21
|
+
super
|
|
22
|
+
subclass.instance_variable_set(:@handlers, {})
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
# Registers a handler class for a resource type.
|
|
27
|
+
#
|
|
28
|
+
# @param resource_type [String, Symbol] primary resource type name
|
|
29
|
+
# @param handler_class [Class] handler class
|
|
30
|
+
# @param aliases [Array<String, Symbol>] alternative names
|
|
31
|
+
# @return [void]
|
|
32
|
+
def register(resource_type, handler_class, aliases: [])
|
|
33
|
+
@handlers[resource_type.to_s] = handler_class
|
|
34
|
+
aliases.each { |a| @handlers[a.to_s] = handler_class }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns a new handler instance for the resource type.
|
|
38
|
+
#
|
|
39
|
+
# @param resource_type [String, Symbol, nil] resource type name
|
|
40
|
+
# @return [Object, nil] handler instance or nil
|
|
41
|
+
def for(resource_type)
|
|
42
|
+
return nil if resource_type.nil?
|
|
43
|
+
|
|
44
|
+
handler_class = @handlers[resource_type.to_s]
|
|
45
|
+
handler_class&.new
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns all registered type names (including aliases).
|
|
49
|
+
#
|
|
50
|
+
# @return [Array<String>] registered type names
|
|
51
|
+
def registered_types
|
|
52
|
+
@handlers.keys
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Checks if a resource type is registered.
|
|
56
|
+
#
|
|
57
|
+
# @param resource_type [String, Symbol] resource type name
|
|
58
|
+
# @return [Boolean]
|
|
59
|
+
def registered?(resource_type)
|
|
60
|
+
@handlers.key?(resource_type.to_s)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Clears all registered handlers.
|
|
64
|
+
#
|
|
65
|
+
# @return [void]
|
|
66
|
+
# @api private
|
|
67
|
+
def reset!
|
|
68
|
+
@handlers = {}
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl restart` command.
|
|
6
|
+
#
|
|
7
|
+
# Restarts one or more virtual machines (reboot).
|
|
8
|
+
#
|
|
9
|
+
# @example Restart a single VM
|
|
10
|
+
# pvectl restart vm 100
|
|
11
|
+
#
|
|
12
|
+
# @example Restart with sync mode
|
|
13
|
+
# pvectl restart vm 100 --wait
|
|
14
|
+
#
|
|
15
|
+
class Restart
|
|
16
|
+
include VmLifecycleCommand
|
|
17
|
+
|
|
18
|
+
# Registers the restart command with the CLI.
|
|
19
|
+
#
|
|
20
|
+
# @param cli [GLI::App] the CLI application object
|
|
21
|
+
# @return [void]
|
|
22
|
+
def self.register(cli)
|
|
23
|
+
cli.desc "Restart virtual machines or containers (reboot)"
|
|
24
|
+
cli.long_desc <<~HELP
|
|
25
|
+
Reboot one or more virtual machines or containers. Sends a reboot
|
|
26
|
+
signal to the guest OS for a clean restart.
|
|
27
|
+
|
|
28
|
+
EXAMPLES
|
|
29
|
+
Reboot a VM:
|
|
30
|
+
$ pvectl restart vm 100
|
|
31
|
+
|
|
32
|
+
Reboot a container:
|
|
33
|
+
$ pvectl restart ct 200
|
|
34
|
+
|
|
35
|
+
Reboot all VMs with a specific tag:
|
|
36
|
+
$ pvectl restart vm --all -l tags=webserver --yes
|
|
37
|
+
|
|
38
|
+
NOTES
|
|
39
|
+
For VMs, this sends an ACPI reboot signal (requires guest agent or
|
|
40
|
+
ACPI support). For containers, uses LXC reboot.
|
|
41
|
+
|
|
42
|
+
For a hard reset (equivalent to pressing the reset button), use
|
|
43
|
+
'pvectl reset' instead (VMs only).
|
|
44
|
+
|
|
45
|
+
SEE ALSO
|
|
46
|
+
pvectl help reset Hard reset (VMs only)
|
|
47
|
+
pvectl help shutdown Graceful shutdown without restart
|
|
48
|
+
HELP
|
|
49
|
+
cli.arg_name "RESOURCE_TYPE [ID...]"
|
|
50
|
+
cli.command :restart do |c|
|
|
51
|
+
SharedFlags.lifecycle(c)
|
|
52
|
+
|
|
53
|
+
c.action do |global_options, options, args|
|
|
54
|
+
resource_type = args.shift
|
|
55
|
+
resource_ids = args
|
|
56
|
+
exit_code = case resource_type
|
|
57
|
+
when "container", "ct"
|
|
58
|
+
RestartContainer.execute(resource_type, resource_ids, options, global_options)
|
|
59
|
+
else
|
|
60
|
+
execute(resource_type, resource_ids, options, global_options)
|
|
61
|
+
end
|
|
62
|
+
exit exit_code if exit_code != 0
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
OPERATION = :restart
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl restart container` command.
|
|
6
|
+
#
|
|
7
|
+
# Restarts one or more LXC containers (reboot).
|
|
8
|
+
#
|
|
9
|
+
# @example Restart a single container
|
|
10
|
+
# pvectl restart container 200
|
|
11
|
+
#
|
|
12
|
+
class RestartContainer
|
|
13
|
+
include ContainerLifecycleCommand
|
|
14
|
+
|
|
15
|
+
OPERATION = :restart
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl restore backup` command.
|
|
6
|
+
#
|
|
7
|
+
# Restores a backup identified by its full volume ID (volid)
|
|
8
|
+
# to a new or existing VM/container.
|
|
9
|
+
# Requires --vmid and --yes flags.
|
|
10
|
+
#
|
|
11
|
+
# @example Restore a backup to new VM
|
|
12
|
+
# pvectl restore backup local:backup/vzdump-qemu-100-xxx.vma.zst --vmid 200 --yes
|
|
13
|
+
#
|
|
14
|
+
# @example Restore with overwrite
|
|
15
|
+
# pvectl restore backup local:backup/vzdump-qemu-100-xxx.vma.zst --vmid 100 --force --yes
|
|
16
|
+
#
|
|
17
|
+
class RestoreBackup
|
|
18
|
+
# Registers the restore command with the CLI.
|
|
19
|
+
#
|
|
20
|
+
# @param cli [GLI::App] the CLI application object
|
|
21
|
+
# @return [void]
|
|
22
|
+
def self.register(cli)
|
|
23
|
+
cli.desc "Restore a resource from backup"
|
|
24
|
+
cli.long_desc <<~HELP
|
|
25
|
+
Restore a virtual machine or container from a backup (vzdump) volume.
|
|
26
|
+
Creates a new or overwrites an existing VM/container with the backup data.
|
|
27
|
+
|
|
28
|
+
EXAMPLES
|
|
29
|
+
Restore to a new VMID:
|
|
30
|
+
$ pvectl restore backup local:backup/vzdump-qemu-100-2026_01_01.vma.zst --vmid 200 --yes
|
|
31
|
+
|
|
32
|
+
Restore to specific storage:
|
|
33
|
+
$ pvectl restore backup local:backup/vzdump-qemu-100-2026_01_01.vma.zst --vmid 200 --storage local-lvm --yes
|
|
34
|
+
|
|
35
|
+
Overwrite existing VM:
|
|
36
|
+
$ pvectl restore backup local:backup/vzdump-qemu-100-2026_01_01.vma.zst --vmid 100 --force --yes
|
|
37
|
+
|
|
38
|
+
Restore and start immediately:
|
|
39
|
+
$ pvectl restore backup local:backup/vzdump-qemu-100-2026_01_01.vma.zst --vmid 200 --start --yes
|
|
40
|
+
|
|
41
|
+
Regenerate unique properties (MAC, UUID):
|
|
42
|
+
$ pvectl restore backup local:backup/vzdump-qemu-100-2026_01_01.vma.zst --vmid 200 --unique --yes
|
|
43
|
+
|
|
44
|
+
NOTES
|
|
45
|
+
--vmid is required to specify the target VM/container ID.
|
|
46
|
+
|
|
47
|
+
--force overwrites an existing VM/container with the same VMID.
|
|
48
|
+
Without it, restore fails if the VMID already exists.
|
|
49
|
+
|
|
50
|
+
--unique regenerates MAC addresses and other unique properties,
|
|
51
|
+
useful when restoring alongside the original VM.
|
|
52
|
+
|
|
53
|
+
Use 'pvectl get backups' to find backup volume IDs.
|
|
54
|
+
|
|
55
|
+
SEE ALSO
|
|
56
|
+
pvectl help create backup Create a new backup
|
|
57
|
+
pvectl help get backups List available backups
|
|
58
|
+
pvectl help delete backup Delete backup volumes
|
|
59
|
+
HELP
|
|
60
|
+
cli.arg_name "RESOURCE_TYPE VOLID"
|
|
61
|
+
cli.command :restore do |c|
|
|
62
|
+
c.desc "Target VMID (required)"
|
|
63
|
+
c.flag [:vmid], arg_name: "VMID", type: Integer
|
|
64
|
+
|
|
65
|
+
c.desc "Target storage"
|
|
66
|
+
c.flag [:storage], arg_name: "STORAGE"
|
|
67
|
+
|
|
68
|
+
c.desc "Overwrite existing VM/container"
|
|
69
|
+
c.switch [:force], negatable: false
|
|
70
|
+
|
|
71
|
+
c.desc "Start after restore"
|
|
72
|
+
c.switch [:start], negatable: false
|
|
73
|
+
|
|
74
|
+
c.desc "Regenerate unique properties (MAC, UUID)"
|
|
75
|
+
c.switch [:unique], negatable: false
|
|
76
|
+
|
|
77
|
+
c.desc "Skip confirmation prompt (REQUIRED)"
|
|
78
|
+
c.switch [:yes, :y], negatable: false
|
|
79
|
+
|
|
80
|
+
c.desc "Timeout in seconds"
|
|
81
|
+
c.flag [:timeout], type: Integer, arg_name: "SECONDS"
|
|
82
|
+
|
|
83
|
+
c.desc "Force async mode"
|
|
84
|
+
c.switch [:async], negatable: false
|
|
85
|
+
|
|
86
|
+
c.action do |global_options, options, args|
|
|
87
|
+
resource_type = args.shift
|
|
88
|
+
volid = args.first
|
|
89
|
+
|
|
90
|
+
exit_code = case resource_type
|
|
91
|
+
when "backup"
|
|
92
|
+
Commands::RestoreBackup.execute(resource_type, volid, options, global_options)
|
|
93
|
+
else
|
|
94
|
+
$stderr.puts "Error: Unknown resource type: #{resource_type}"
|
|
95
|
+
$stderr.puts "Valid types: backup"
|
|
96
|
+
ExitCodes::USAGE_ERROR
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
exit exit_code if exit_code != 0
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Executes the restore backup command.
|
|
105
|
+
#
|
|
106
|
+
# @param resource_type [String, nil] resource type (backup)
|
|
107
|
+
# @param volid [String, nil] backup volume ID
|
|
108
|
+
# @param options [Hash] command options
|
|
109
|
+
# @param global_options [Hash] global CLI options
|
|
110
|
+
# @return [Integer] exit code
|
|
111
|
+
def self.execute(resource_type, volid, options, global_options)
|
|
112
|
+
new(resource_type, volid, options, global_options).execute
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Initializes a restore backup command.
|
|
116
|
+
#
|
|
117
|
+
# @param resource_type [String, nil] resource type (backup)
|
|
118
|
+
# @param volid [String, nil] backup volume ID
|
|
119
|
+
# @param options [Hash] command options
|
|
120
|
+
# @param global_options [Hash] global CLI options
|
|
121
|
+
def initialize(resource_type, volid, options, global_options)
|
|
122
|
+
@resource_type = resource_type
|
|
123
|
+
@volid = volid
|
|
124
|
+
@options = options
|
|
125
|
+
@global_options = global_options
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Executes the restore backup command.
|
|
129
|
+
#
|
|
130
|
+
# @return [Integer] exit code
|
|
131
|
+
def execute
|
|
132
|
+
return usage_error("Resource type required (backup)") unless @resource_type == "backup"
|
|
133
|
+
return usage_error("Backup volid is required") if @volid.nil? || @volid.empty?
|
|
134
|
+
return usage_error("--vmid is required") unless @options[:vmid]
|
|
135
|
+
return usage_error("Confirmation required: use --yes to confirm restore") unless @options[:yes]
|
|
136
|
+
|
|
137
|
+
perform_operation
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
# Performs the backup restore operation.
|
|
143
|
+
#
|
|
144
|
+
# @return [Integer] exit code
|
|
145
|
+
def perform_operation
|
|
146
|
+
load_config
|
|
147
|
+
connection = Pvectl::Connection.new(@config)
|
|
148
|
+
|
|
149
|
+
backup_repo = Pvectl::Repositories::Backup.new(connection)
|
|
150
|
+
resolver = Pvectl::Utils::ResourceResolver.new(connection)
|
|
151
|
+
task_repo = Pvectl::Repositories::Task.new(connection)
|
|
152
|
+
|
|
153
|
+
service = Pvectl::Services::Backup.new(
|
|
154
|
+
backup_repo: backup_repo,
|
|
155
|
+
resource_resolver: resolver,
|
|
156
|
+
task_repo: task_repo,
|
|
157
|
+
options: service_options
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
result = service.restore(
|
|
161
|
+
@volid,
|
|
162
|
+
vmid: @options[:vmid],
|
|
163
|
+
storage: @options[:storage],
|
|
164
|
+
force: @options[:force] || false,
|
|
165
|
+
start: @options[:start] || false,
|
|
166
|
+
unique: @options[:unique] || false
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
output_results([result])
|
|
170
|
+
determine_exit_code([result])
|
|
171
|
+
rescue Pvectl::Config::ConfigNotFoundError,
|
|
172
|
+
Pvectl::Config::InvalidConfigError,
|
|
173
|
+
Pvectl::Config::ContextNotFoundError,
|
|
174
|
+
Pvectl::Config::ClusterNotFoundError,
|
|
175
|
+
Pvectl::Config::UserNotFoundError
|
|
176
|
+
raise
|
|
177
|
+
rescue StandardError => e
|
|
178
|
+
$stderr.puts "Error: #{e.message}"
|
|
179
|
+
ExitCodes::GENERAL_ERROR
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Loads configuration from file or environment.
|
|
183
|
+
#
|
|
184
|
+
# @return [void]
|
|
185
|
+
def load_config
|
|
186
|
+
service = Pvectl::Config::Service.new
|
|
187
|
+
service.load(config: @global_options[:config])
|
|
188
|
+
@config = service.current_config
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Builds service options from command options.
|
|
192
|
+
#
|
|
193
|
+
# @return [Hash] service options
|
|
194
|
+
def service_options
|
|
195
|
+
opts = {}
|
|
196
|
+
opts[:timeout] = @options[:timeout] if @options[:timeout]
|
|
197
|
+
opts[:async] = true if @options[:async]
|
|
198
|
+
opts
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Outputs operation results using the configured formatter.
|
|
202
|
+
#
|
|
203
|
+
# @param results [Array<Models::OperationResult>] operation results
|
|
204
|
+
# @return [void]
|
|
205
|
+
def output_results(results)
|
|
206
|
+
presenter = Pvectl::Presenters::SnapshotOperationResult.new
|
|
207
|
+
format = @global_options[:output] || "table"
|
|
208
|
+
color_flag = @global_options[:color]
|
|
209
|
+
|
|
210
|
+
formatter = Pvectl::Formatters::Registry.for(format)
|
|
211
|
+
output = formatter.format(results, presenter, color: color_flag)
|
|
212
|
+
puts output
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Determines exit code based on results.
|
|
216
|
+
#
|
|
217
|
+
# @param results [Array<Models::OperationResult>] operation results
|
|
218
|
+
# @return [Integer] exit code
|
|
219
|
+
def determine_exit_code(results)
|
|
220
|
+
return ExitCodes::SUCCESS if results.all?(&:successful?)
|
|
221
|
+
return ExitCodes::SUCCESS if results.all?(&:pending?)
|
|
222
|
+
|
|
223
|
+
ExitCodes::GENERAL_ERROR
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Outputs usage error and returns exit code.
|
|
227
|
+
#
|
|
228
|
+
# @param message [String] error message
|
|
229
|
+
# @return [Integer] exit code
|
|
230
|
+
def usage_error(message)
|
|
231
|
+
$stderr.puts "Error: #{message}"
|
|
232
|
+
ExitCodes::USAGE_ERROR
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl resume` command.
|
|
6
|
+
#
|
|
7
|
+
# Resumes one or more suspended virtual machines.
|
|
8
|
+
#
|
|
9
|
+
# @example Resume a single VM
|
|
10
|
+
# pvectl resume vm 100
|
|
11
|
+
#
|
|
12
|
+
# @example Resume with JSON output
|
|
13
|
+
# pvectl resume vm 100 -o json
|
|
14
|
+
#
|
|
15
|
+
class Resume
|
|
16
|
+
include VmLifecycleCommand
|
|
17
|
+
|
|
18
|
+
# Registers the resume command with the CLI.
|
|
19
|
+
#
|
|
20
|
+
# @param cli [GLI::App] the CLI application object
|
|
21
|
+
# @return [void]
|
|
22
|
+
def self.register(cli)
|
|
23
|
+
cli.desc "Resume suspended virtual machines"
|
|
24
|
+
cli.long_desc <<~HELP
|
|
25
|
+
Resume one or more suspended (hibernated) virtual machines. Restores
|
|
26
|
+
the VM's memory state from disk and continues execution.
|
|
27
|
+
|
|
28
|
+
Only available for VMs. Containers do not support resume.
|
|
29
|
+
|
|
30
|
+
EXAMPLES
|
|
31
|
+
Resume a suspended VM:
|
|
32
|
+
$ pvectl resume vm 100
|
|
33
|
+
|
|
34
|
+
Resume all suspended VMs:
|
|
35
|
+
$ pvectl resume vm --all -l status=suspended --yes
|
|
36
|
+
|
|
37
|
+
SEE ALSO
|
|
38
|
+
pvectl help suspend Suspend (hibernate) VMs
|
|
39
|
+
pvectl help start Start a stopped VM (no state restore)
|
|
40
|
+
HELP
|
|
41
|
+
cli.arg_name "RESOURCE_TYPE [ID...]"
|
|
42
|
+
cli.command :resume do |c|
|
|
43
|
+
SharedFlags.lifecycle(c)
|
|
44
|
+
|
|
45
|
+
c.action do |global_options, options, args|
|
|
46
|
+
resource_type = args.shift
|
|
47
|
+
resource_ids = args
|
|
48
|
+
exit_code = execute(resource_type, resource_ids, options, global_options)
|
|
49
|
+
exit exit_code if exit_code != 0
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
OPERATION = :resume
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl rollback snapshot` command.
|
|
6
|
+
#
|
|
7
|
+
# Rolls back a VM/container to a snapshot.
|
|
8
|
+
# Requires --yes flag for confirmation. Only supports single VMID.
|
|
9
|
+
#
|
|
10
|
+
# @example Rollback to snapshot
|
|
11
|
+
# pvectl rollback snapshot 100 before-upgrade --yes
|
|
12
|
+
#
|
|
13
|
+
# @example Start after rollback (LXC only)
|
|
14
|
+
# pvectl rollback snapshot 100 before-upgrade --yes --start
|
|
15
|
+
#
|
|
16
|
+
class RollbackSnapshot
|
|
17
|
+
# Registers the rollback command with the CLI.
|
|
18
|
+
#
|
|
19
|
+
# @param cli [GLI::App] the CLI application object
|
|
20
|
+
# @return [void]
|
|
21
|
+
def self.register(cli)
|
|
22
|
+
cli.desc "Rollback to a snapshot"
|
|
23
|
+
cli.long_desc <<~HELP
|
|
24
|
+
Rollback a virtual machine or container to a previous snapshot,
|
|
25
|
+
restoring its disk (and optionally RAM) state to the snapshot point.
|
|
26
|
+
|
|
27
|
+
WARNING: All changes made after the snapshot will be lost.
|
|
28
|
+
|
|
29
|
+
EXAMPLES
|
|
30
|
+
Rollback a VM to a snapshot:
|
|
31
|
+
$ pvectl rollback snapshot 100 before-upgrade --yes
|
|
32
|
+
|
|
33
|
+
Rollback and start the VM after:
|
|
34
|
+
$ pvectl rollback snapshot 100 before-upgrade --yes --start
|
|
35
|
+
|
|
36
|
+
Async rollback:
|
|
37
|
+
$ pvectl rollback snapshot 100 before-upgrade --yes --async
|
|
38
|
+
|
|
39
|
+
NOTES
|
|
40
|
+
Rollback always operates on a single VM/container (not batch).
|
|
41
|
+
|
|
42
|
+
The VM/container will be stopped during rollback if running.
|
|
43
|
+
|
|
44
|
+
--yes is required — rollback is a destructive operation that
|
|
45
|
+
discards all changes since the snapshot.
|
|
46
|
+
|
|
47
|
+
SEE ALSO
|
|
48
|
+
pvectl help create snapshot Create a snapshot before changes
|
|
49
|
+
pvectl help get snapshots List available snapshots
|
|
50
|
+
pvectl help describe snapshot View snapshot details
|
|
51
|
+
HELP
|
|
52
|
+
cli.arg_name "RESOURCE_TYPE ID SNAPSHOT_NAME"
|
|
53
|
+
cli.command :rollback do |c|
|
|
54
|
+
c.desc "Skip confirmation prompt (REQUIRED for destructive operations)"
|
|
55
|
+
c.switch [:yes, :y], negatable: false
|
|
56
|
+
|
|
57
|
+
c.desc "Start VM/container after rollback (LXC only)"
|
|
58
|
+
c.switch [:start], negatable: false
|
|
59
|
+
|
|
60
|
+
c.desc "Timeout in seconds for sync operations"
|
|
61
|
+
c.flag [:timeout], type: Integer, arg_name: "SECONDS"
|
|
62
|
+
|
|
63
|
+
c.desc "Force async mode (return task ID immediately)"
|
|
64
|
+
c.switch [:async], negatable: false
|
|
65
|
+
|
|
66
|
+
c.action do |global_options, options, args|
|
|
67
|
+
resource_type = args.shift
|
|
68
|
+
exit_code = Commands::RollbackSnapshot.execute(
|
|
69
|
+
resource_type,
|
|
70
|
+
args,
|
|
71
|
+
options,
|
|
72
|
+
global_options
|
|
73
|
+
)
|
|
74
|
+
exit exit_code if exit_code != 0
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
SUPPORTED_RESOURCES = %w[snapshot].freeze
|
|
80
|
+
|
|
81
|
+
# Executes the rollback snapshot command.
|
|
82
|
+
#
|
|
83
|
+
# @param resource_type [String, nil] resource type (snapshot)
|
|
84
|
+
# @param args [Array<String>, String, nil] VMID and snapshot name
|
|
85
|
+
# @param options [Hash] command options
|
|
86
|
+
# @param global_options [Hash] global CLI options
|
|
87
|
+
# @return [Integer] exit code
|
|
88
|
+
def self.execute(resource_type, args, options, global_options)
|
|
89
|
+
new(resource_type, args, options, global_options).execute
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Initializes a rollback snapshot command.
|
|
93
|
+
#
|
|
94
|
+
# @param resource_type [String, nil] resource type (snapshot)
|
|
95
|
+
# @param args [Array<String>, String, nil] VMID and snapshot name
|
|
96
|
+
# @param options [Hash] command options
|
|
97
|
+
# @param global_options [Hash] global CLI options
|
|
98
|
+
def initialize(resource_type, args, options, global_options)
|
|
99
|
+
@resource_type = resource_type
|
|
100
|
+
@args = Array(args).compact
|
|
101
|
+
@options = options
|
|
102
|
+
@global_options = global_options
|
|
103
|
+
@too_many_args = false
|
|
104
|
+
parse_args!
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Executes the rollback snapshot command.
|
|
108
|
+
#
|
|
109
|
+
# @return [Integer] exit code
|
|
110
|
+
def execute
|
|
111
|
+
return usage_error("Resource type required (snapshot)") unless @resource_type
|
|
112
|
+
return usage_error("Unsupported resource: #{@resource_type}") unless SUPPORTED_RESOURCES.include?(@resource_type)
|
|
113
|
+
return usage_error("Rollback supports only single VMID") if @too_many_args
|
|
114
|
+
return usage_error("VMID and snapshot name required") if @vmid.nil? || @snapshot_name.nil?
|
|
115
|
+
return usage_error("Confirmation required: use --yes to confirm rollback") unless @options[:yes]
|
|
116
|
+
|
|
117
|
+
perform_operation
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
# Parses arguments: exactly 2 args - VMID and snapshot name.
|
|
123
|
+
#
|
|
124
|
+
# @return [void]
|
|
125
|
+
def parse_args!
|
|
126
|
+
if @args.size == 2
|
|
127
|
+
@vmid = @args[0].to_i
|
|
128
|
+
@snapshot_name = @args[1]
|
|
129
|
+
elsif @args.size > 2
|
|
130
|
+
# Too many args - rollback only supports single VMID
|
|
131
|
+
@vmid = nil
|
|
132
|
+
@snapshot_name = nil
|
|
133
|
+
@too_many_args = true
|
|
134
|
+
else
|
|
135
|
+
@vmid = nil
|
|
136
|
+
@snapshot_name = nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Performs the snapshot rollback operation.
|
|
141
|
+
#
|
|
142
|
+
# @return [Integer] exit code
|
|
143
|
+
def perform_operation
|
|
144
|
+
load_config
|
|
145
|
+
connection = Pvectl::Connection.new(@config)
|
|
146
|
+
|
|
147
|
+
snapshot_repo = Pvectl::Repositories::Snapshot.new(connection)
|
|
148
|
+
resolver = Pvectl::Utils::ResourceResolver.new(connection)
|
|
149
|
+
task_repo = Pvectl::Repositories::Task.new(connection)
|
|
150
|
+
|
|
151
|
+
service = Pvectl::Services::Snapshot.new(
|
|
152
|
+
snapshot_repo: snapshot_repo,
|
|
153
|
+
resource_resolver: resolver,
|
|
154
|
+
task_repo: task_repo,
|
|
155
|
+
options: service_options
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
result = service.rollback(@vmid, @snapshot_name, start: @options[:start] || false)
|
|
159
|
+
results = [result]
|
|
160
|
+
|
|
161
|
+
output_results(results)
|
|
162
|
+
determine_exit_code(results)
|
|
163
|
+
rescue Pvectl::Config::ConfigNotFoundError,
|
|
164
|
+
Pvectl::Config::InvalidConfigError,
|
|
165
|
+
Pvectl::Config::ContextNotFoundError,
|
|
166
|
+
Pvectl::Config::ClusterNotFoundError,
|
|
167
|
+
Pvectl::Config::UserNotFoundError
|
|
168
|
+
raise
|
|
169
|
+
rescue StandardError => e
|
|
170
|
+
$stderr.puts "Error: #{e.message}"
|
|
171
|
+
ExitCodes::GENERAL_ERROR
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Loads configuration from file or environment.
|
|
175
|
+
#
|
|
176
|
+
# @return [void]
|
|
177
|
+
def load_config
|
|
178
|
+
service = Pvectl::Config::Service.new
|
|
179
|
+
service.load(config: @global_options[:config])
|
|
180
|
+
@config = service.current_config
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Builds service options from command options.
|
|
184
|
+
#
|
|
185
|
+
# @return [Hash] service options
|
|
186
|
+
def service_options
|
|
187
|
+
opts = {}
|
|
188
|
+
opts[:timeout] = @options[:timeout] if @options[:timeout]
|
|
189
|
+
opts[:async] = true if @options[:async]
|
|
190
|
+
opts
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Outputs operation results using the configured formatter.
|
|
194
|
+
#
|
|
195
|
+
# @param results [Array<Models::OperationResult>] operation results
|
|
196
|
+
# @return [void]
|
|
197
|
+
def output_results(results)
|
|
198
|
+
presenter = Pvectl::Presenters::SnapshotOperationResult.new
|
|
199
|
+
format = @global_options[:output] || "table"
|
|
200
|
+
color_flag = @global_options[:color]
|
|
201
|
+
|
|
202
|
+
formatter = Pvectl::Formatters::Registry.for(format)
|
|
203
|
+
output = formatter.format(results, presenter, color: color_flag)
|
|
204
|
+
puts output
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Determines exit code based on results.
|
|
208
|
+
#
|
|
209
|
+
# @param results [Array<Models::OperationResult>] operation results
|
|
210
|
+
# @return [Integer] exit code
|
|
211
|
+
def determine_exit_code(results)
|
|
212
|
+
return ExitCodes::SUCCESS if results.all?(&:successful?)
|
|
213
|
+
return ExitCodes::SUCCESS if results.all?(&:pending?)
|
|
214
|
+
|
|
215
|
+
ExitCodes::GENERAL_ERROR
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Outputs usage error and returns exit code.
|
|
219
|
+
#
|
|
220
|
+
# @param message [String] error message
|
|
221
|
+
# @return [Integer] exit code
|
|
222
|
+
def usage_error(message)
|
|
223
|
+
$stderr.puts "Error: #{message}"
|
|
224
|
+
ExitCodes::USAGE_ERROR
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|