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,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Shared functionality for resource edit commands.
|
|
6
|
+
#
|
|
7
|
+
# Template method pattern: provides common edit workflow
|
|
8
|
+
# (config loading, editor session, diff display, dry-run)
|
|
9
|
+
# while specialization classes define resource-specific hooks.
|
|
10
|
+
#
|
|
11
|
+
# @abstract Include this module and implement template methods.
|
|
12
|
+
#
|
|
13
|
+
# @example Specialization
|
|
14
|
+
# class EditVm
|
|
15
|
+
# include EditResourceCommand
|
|
16
|
+
# private
|
|
17
|
+
# def resource_label = "VM"
|
|
18
|
+
# def resource_id_label = "VMID"
|
|
19
|
+
# # ...
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
module EditResourceCommand
|
|
23
|
+
# Class methods added when the module is included.
|
|
24
|
+
module ClassMethods
|
|
25
|
+
# Executes the edit command.
|
|
26
|
+
#
|
|
27
|
+
# @param args [Array<String>] command arguments
|
|
28
|
+
# @param options [Hash] command options
|
|
29
|
+
# @param global_options [Hash] global CLI options
|
|
30
|
+
# @return [Integer] exit code
|
|
31
|
+
def execute(args, options, global_options)
|
|
32
|
+
new(args, options, global_options).execute
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Hook called when module is included.
|
|
37
|
+
#
|
|
38
|
+
# @param base [Class] the class including this module
|
|
39
|
+
def self.included(base)
|
|
40
|
+
base.extend(ClassMethods)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Initializes an edit command.
|
|
44
|
+
#
|
|
45
|
+
# @param args [Array<String>] command arguments
|
|
46
|
+
# @param options [Hash] command options
|
|
47
|
+
# @param global_options [Hash] global CLI options
|
|
48
|
+
def initialize(args, options, global_options)
|
|
49
|
+
@args = args
|
|
50
|
+
@options = options
|
|
51
|
+
@global_options = global_options
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Executes the edit command.
|
|
55
|
+
#
|
|
56
|
+
# Loads configuration, builds the edit service, and runs it.
|
|
57
|
+
# Handles cancelled edits, successful updates with diff display,
|
|
58
|
+
# dry-run mode, and errors.
|
|
59
|
+
#
|
|
60
|
+
# @return [Integer] exit code
|
|
61
|
+
def execute
|
|
62
|
+
resource_id = @args.first
|
|
63
|
+
return usage_error("#{resource_id_label} is required") unless resource_id
|
|
64
|
+
|
|
65
|
+
load_config
|
|
66
|
+
connection = Pvectl::Connection.new(@config)
|
|
67
|
+
service = build_edit_service(connection)
|
|
68
|
+
result = service.execute(**execute_params(resource_id))
|
|
69
|
+
|
|
70
|
+
if result.nil?
|
|
71
|
+
$stdout.puts "Edit cancelled, no changes made."
|
|
72
|
+
return ExitCodes::SUCCESS
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if result.successful?
|
|
76
|
+
display_diff(result)
|
|
77
|
+
if @options[:"dry-run"]
|
|
78
|
+
$stdout.puts "(dry-run mode — no changes applied)"
|
|
79
|
+
else
|
|
80
|
+
$stdout.puts "#{resource_label} #{resource_id} updated successfully."
|
|
81
|
+
end
|
|
82
|
+
ExitCodes::SUCCESS
|
|
83
|
+
else
|
|
84
|
+
$stderr.puts "Error: #{result.error}"
|
|
85
|
+
ExitCodes::GENERAL_ERROR
|
|
86
|
+
end
|
|
87
|
+
rescue Pvectl::Config::ConfigNotFoundError,
|
|
88
|
+
Pvectl::Config::InvalidConfigError,
|
|
89
|
+
Pvectl::Config::ContextNotFoundError,
|
|
90
|
+
Pvectl::Config::ClusterNotFoundError,
|
|
91
|
+
Pvectl::Config::UserNotFoundError
|
|
92
|
+
raise
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
$stderr.puts "Error: #{e.message}"
|
|
95
|
+
ExitCodes::GENERAL_ERROR
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
# @return [String] human label for resource ("VM" or "container")
|
|
101
|
+
def resource_label
|
|
102
|
+
raise NotImplementedError, "#{self.class} must implement #resource_label"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @return [String] human label for resource ID ("VMID" or "CTID")
|
|
106
|
+
def resource_id_label
|
|
107
|
+
raise NotImplementedError, "#{self.class} must implement #resource_id_label"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Builds execution parameters from resource ID.
|
|
111
|
+
#
|
|
112
|
+
# @param resource_id [String] resource identifier (converted by specializations)
|
|
113
|
+
# @return [Hash] parameters for the edit service (e.g. { vmid: 100 })
|
|
114
|
+
def execute_params(resource_id)
|
|
115
|
+
raise NotImplementedError, "#{self.class} must implement #execute_params"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Builds the edit service for the given connection.
|
|
119
|
+
#
|
|
120
|
+
# @param connection [Connection] API connection
|
|
121
|
+
# @return [Object] edit service instance
|
|
122
|
+
def build_edit_service(connection)
|
|
123
|
+
raise NotImplementedError, "#{self.class} must implement #build_edit_service"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Displays a formatted diff from the operation result.
|
|
127
|
+
#
|
|
128
|
+
# @param result [Models::OperationResult] operation result with diff in resource
|
|
129
|
+
# @return [void]
|
|
130
|
+
def display_diff(result)
|
|
131
|
+
diff = result.resource&.dig(:diff)
|
|
132
|
+
return unless diff
|
|
133
|
+
return if diff[:changed].empty? && diff[:added].empty? && diff[:removed].empty?
|
|
134
|
+
|
|
135
|
+
$stdout.puts "\nChanges:"
|
|
136
|
+
$stdout.puts Pvectl::ConfigSerializer.format_diff(diff)
|
|
137
|
+
$stdout.puts ""
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Loads configuration from file or environment.
|
|
141
|
+
#
|
|
142
|
+
# @return [void]
|
|
143
|
+
def load_config
|
|
144
|
+
service = Pvectl::Config::Service.new
|
|
145
|
+
service.load(config: @global_options[:config])
|
|
146
|
+
@config = service.current_config
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Builds service options from command options.
|
|
150
|
+
#
|
|
151
|
+
# @return [Hash] service options
|
|
152
|
+
def service_options
|
|
153
|
+
opts = {}
|
|
154
|
+
opts[:dry_run] = true if @options[:"dry-run"]
|
|
155
|
+
opts
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Builds an editor session from the --editor option.
|
|
159
|
+
#
|
|
160
|
+
# @return [EditorSession, nil] editor session or nil if no --editor flag
|
|
161
|
+
def build_editor_session
|
|
162
|
+
editor_cmd = @options[:editor]
|
|
163
|
+
return nil unless editor_cmd
|
|
164
|
+
|
|
165
|
+
Pvectl::EditorSession.new(
|
|
166
|
+
editor: ->(path) { system(editor_cmd, path) }
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Outputs usage error and returns exit code.
|
|
171
|
+
#
|
|
172
|
+
# @param message [String] error message
|
|
173
|
+
# @return [Integer] exit code
|
|
174
|
+
def usage_error(message)
|
|
175
|
+
$stderr.puts "Error: #{message}"
|
|
176
|
+
ExitCodes::USAGE_ERROR
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl edit vm` command.
|
|
6
|
+
#
|
|
7
|
+
# Includes EditResourceCommand for shared workflow and overrides
|
|
8
|
+
# template methods with VM-specific behavior.
|
|
9
|
+
#
|
|
10
|
+
# @example Basic usage
|
|
11
|
+
# pvectl edit vm 100
|
|
12
|
+
#
|
|
13
|
+
# @example With custom editor
|
|
14
|
+
# pvectl edit vm 100 --editor nano
|
|
15
|
+
#
|
|
16
|
+
# @example Dry-run mode
|
|
17
|
+
# pvectl edit vm 100 --dry-run
|
|
18
|
+
#
|
|
19
|
+
class EditVm
|
|
20
|
+
include EditResourceCommand
|
|
21
|
+
|
|
22
|
+
# Registers the edit command with the CLI.
|
|
23
|
+
#
|
|
24
|
+
# @param cli [GLI::App] the CLI application object
|
|
25
|
+
# @return [void]
|
|
26
|
+
def self.register(cli)
|
|
27
|
+
cli.desc "Edit a resource configuration"
|
|
28
|
+
cli.long_desc <<~HELP
|
|
29
|
+
Open a VM, container, node, or volume configuration in your text
|
|
30
|
+
editor. The configuration is presented as YAML for easy editing.
|
|
31
|
+
Changes are applied via the Proxmox API when you save and close
|
|
32
|
+
the editor.
|
|
33
|
+
|
|
34
|
+
EXAMPLES
|
|
35
|
+
Edit a VM configuration:
|
|
36
|
+
$ pvectl edit vm 100
|
|
37
|
+
|
|
38
|
+
Edit a container with a specific editor:
|
|
39
|
+
$ pvectl edit container 200 --editor nano
|
|
40
|
+
|
|
41
|
+
Edit a node configuration:
|
|
42
|
+
$ pvectl edit node pve1
|
|
43
|
+
|
|
44
|
+
Edit node DNS resolver settings:
|
|
45
|
+
$ pvectl edit dns pve1
|
|
46
|
+
|
|
47
|
+
Edit volume properties:
|
|
48
|
+
$ pvectl edit volume vm 100 scsi0
|
|
49
|
+
|
|
50
|
+
Edit /etc/hosts on a node:
|
|
51
|
+
$ pvectl edit hosts pve1
|
|
52
|
+
|
|
53
|
+
Preview changes without applying:
|
|
54
|
+
$ pvectl edit vm 100 --dry-run
|
|
55
|
+
|
|
56
|
+
NOTES
|
|
57
|
+
Uses $EDITOR environment variable by default, falling back to vi.
|
|
58
|
+
Override with --editor flag.
|
|
59
|
+
|
|
60
|
+
In --dry-run mode, shows the diff between current and edited
|
|
61
|
+
configuration without applying changes to Proxmox.
|
|
62
|
+
|
|
63
|
+
Supported resource types: vm, container (ct), node, volume, dns, hosts.
|
|
64
|
+
|
|
65
|
+
For DNS, the node identifier is given as a positional argument
|
|
66
|
+
(pvectl edit dns NODE). DNS settings include search domain and
|
|
67
|
+
up to three nameservers (dns1, dns2, dns3).
|
|
68
|
+
|
|
69
|
+
For volumes, syntax is: pvectl edit volume <vm|container> <id> <disk>
|
|
70
|
+
|
|
71
|
+
For hosts, the node identifier is given as a positional argument
|
|
72
|
+
(pvectl edit hosts NODE). The /etc/hosts file is edited as raw
|
|
73
|
+
text — Proxmox requires the pvelocalhost entry to remain present
|
|
74
|
+
and will reject updates removing it.
|
|
75
|
+
|
|
76
|
+
Not all configuration keys can be changed while a VM is running.
|
|
77
|
+
Proxmox will reject invalid changes with an error message.
|
|
78
|
+
|
|
79
|
+
SEE ALSO
|
|
80
|
+
pvectl help describe View current configuration (read-only)
|
|
81
|
+
pvectl help create Create a new resource
|
|
82
|
+
pvectl help set Set individual resource properties
|
|
83
|
+
HELP
|
|
84
|
+
cli.arg_name "RESOURCE_TYPE RESOURCE_ID"
|
|
85
|
+
cli.command :edit do |c|
|
|
86
|
+
c.desc "Override editor command (default: $EDITOR or vi)"
|
|
87
|
+
c.flag [:editor], arg_name: "CMD"
|
|
88
|
+
|
|
89
|
+
c.desc "Show diff without applying changes"
|
|
90
|
+
c.switch [:"dry-run"], negatable: false
|
|
91
|
+
|
|
92
|
+
c.action do |global_options, options, args|
|
|
93
|
+
resource_type = args.shift
|
|
94
|
+
resource_ids = args
|
|
95
|
+
|
|
96
|
+
exit_code = case resource_type
|
|
97
|
+
when "vm"
|
|
98
|
+
Commands::EditVm.execute(resource_ids, options, global_options)
|
|
99
|
+
when "container", "ct"
|
|
100
|
+
Commands::EditContainer.execute(resource_ids, options, global_options)
|
|
101
|
+
when "node"
|
|
102
|
+
Commands::EditNode.execute(resource_ids, options, global_options)
|
|
103
|
+
when "volume"
|
|
104
|
+
Commands::EditVolume.execute(resource_ids, options, global_options)
|
|
105
|
+
when "dns"
|
|
106
|
+
Commands::EditDns.execute(resource_ids, options, global_options)
|
|
107
|
+
when "hosts"
|
|
108
|
+
Commands::EditHosts.execute(resource_ids, options, global_options)
|
|
109
|
+
else
|
|
110
|
+
$stderr.puts "Error: Unknown resource type: #{resource_type}"
|
|
111
|
+
$stderr.puts "Valid types: vm, container, node, volume, dns, hosts"
|
|
112
|
+
ExitCodes::USAGE_ERROR
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
exit exit_code if exit_code != 0
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
# @return [String] human label for VM resources
|
|
123
|
+
def resource_label
|
|
124
|
+
"VM"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @return [String] human label for VM IDs
|
|
128
|
+
def resource_id_label
|
|
129
|
+
"VMID"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Builds execution parameters from a VM ID.
|
|
133
|
+
#
|
|
134
|
+
# @param resource_id [String] VMID (converted to Integer)
|
|
135
|
+
# @return [Hash] parameters for the edit service
|
|
136
|
+
def execute_params(resource_id)
|
|
137
|
+
{ vmid: resource_id.to_i }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Builds the VM edit service.
|
|
141
|
+
#
|
|
142
|
+
# @param connection [Connection] API connection
|
|
143
|
+
# @return [Services::EditVm] VM edit service
|
|
144
|
+
def build_edit_service(connection)
|
|
145
|
+
vm_repo = Pvectl::Repositories::Vm.new(connection)
|
|
146
|
+
Pvectl::Services::EditVm.new(
|
|
147
|
+
vm_repository: vm_repo,
|
|
148
|
+
editor_session: build_editor_session,
|
|
149
|
+
options: service_options
|
|
150
|
+
)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
# Handler for the `pvectl edit volume` command.
|
|
6
|
+
#
|
|
7
|
+
# Does NOT use EditResourceCommand template — has custom flow due to
|
|
8
|
+
# different argument structure (resource_type + id + disk).
|
|
9
|
+
#
|
|
10
|
+
# @example Edit volume properties
|
|
11
|
+
# pvectl edit volume vm 100 scsi0
|
|
12
|
+
#
|
|
13
|
+
# @example With custom editor
|
|
14
|
+
# pvectl edit volume vm 100 scsi0 --editor nano
|
|
15
|
+
#
|
|
16
|
+
# @example Dry-run mode
|
|
17
|
+
# pvectl edit volume vm 100 scsi0 --dry-run
|
|
18
|
+
#
|
|
19
|
+
class EditVolume
|
|
20
|
+
# Class methods for command execution.
|
|
21
|
+
module ClassMethods
|
|
22
|
+
# Executes the edit volume command.
|
|
23
|
+
#
|
|
24
|
+
# @param args [Array<String>] command arguments
|
|
25
|
+
# @param options [Hash] command options
|
|
26
|
+
# @param global_options [Hash] global CLI options
|
|
27
|
+
# @return [Integer] exit code
|
|
28
|
+
def execute(args, options, global_options)
|
|
29
|
+
new(args, options, global_options).execute
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
extend ClassMethods
|
|
34
|
+
|
|
35
|
+
# @param args [Array<String>] command arguments
|
|
36
|
+
# @param options [Hash] command options
|
|
37
|
+
# @param global_options [Hash] global CLI options
|
|
38
|
+
def initialize(args, options, global_options)
|
|
39
|
+
@args = args
|
|
40
|
+
@options = options
|
|
41
|
+
@global_options = global_options
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Executes the edit volume command.
|
|
45
|
+
#
|
|
46
|
+
# @return [Integer] exit code
|
|
47
|
+
def execute
|
|
48
|
+
resource_type = @args[0]
|
|
49
|
+
resource_id = @args[1]
|
|
50
|
+
disk = @args[2]
|
|
51
|
+
|
|
52
|
+
return usage_error("Resource type required (vm, container)") unless resource_type
|
|
53
|
+
return usage_error("Resource ID is required") unless resource_id
|
|
54
|
+
return usage_error("Volume name is required (e.g., scsi0, rootfs)") unless disk
|
|
55
|
+
|
|
56
|
+
load_config
|
|
57
|
+
connection = Pvectl::Connection.new(@config)
|
|
58
|
+
|
|
59
|
+
node = resolve_node(resource_id.to_i, connection, resource_type)
|
|
60
|
+
return ExitCodes::NOT_FOUND unless node
|
|
61
|
+
|
|
62
|
+
repo = build_repository(connection, resource_type)
|
|
63
|
+
service = Pvectl::Services::EditVolume.new(
|
|
64
|
+
repository: repo,
|
|
65
|
+
resource_type: resource_type_symbol(resource_type),
|
|
66
|
+
editor_session: build_editor_session,
|
|
67
|
+
options: service_options
|
|
68
|
+
)
|
|
69
|
+
result = service.execute(id: resource_id.to_i, disk: disk, node: node)
|
|
70
|
+
|
|
71
|
+
if result.nil?
|
|
72
|
+
$stdout.puts "Edit cancelled, no changes made."
|
|
73
|
+
return ExitCodes::SUCCESS
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if result.successful?
|
|
77
|
+
if @options[:"dry-run"]
|
|
78
|
+
$stdout.puts "(dry-run mode — no changes applied)"
|
|
79
|
+
else
|
|
80
|
+
$stdout.puts "Volume #{disk} on #{resource_type} #{resource_id} updated successfully."
|
|
81
|
+
end
|
|
82
|
+
ExitCodes::SUCCESS
|
|
83
|
+
else
|
|
84
|
+
$stderr.puts "Error: #{result.error}"
|
|
85
|
+
ExitCodes::GENERAL_ERROR
|
|
86
|
+
end
|
|
87
|
+
rescue Pvectl::Config::ConfigNotFoundError,
|
|
88
|
+
Pvectl::Config::InvalidConfigError,
|
|
89
|
+
Pvectl::Config::ContextNotFoundError,
|
|
90
|
+
Pvectl::Config::ClusterNotFoundError,
|
|
91
|
+
Pvectl::Config::UserNotFoundError
|
|
92
|
+
raise
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
$stderr.puts "Error: #{e.message}"
|
|
95
|
+
ExitCodes::GENERAL_ERROR
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
# Resolves node for a resource.
|
|
101
|
+
#
|
|
102
|
+
# @param resource_id [Integer] resource ID
|
|
103
|
+
# @param connection [Connection] API connection
|
|
104
|
+
# @param resource_type [String] resource type
|
|
105
|
+
# @return [String, nil] node name or nil
|
|
106
|
+
def resolve_node(resource_id, connection, resource_type)
|
|
107
|
+
return @options[:node] if @options[:node]
|
|
108
|
+
|
|
109
|
+
resolver = Pvectl::Utils::ResourceResolver.new(connection)
|
|
110
|
+
resolved = resolver.resolve(resource_id)
|
|
111
|
+
|
|
112
|
+
unless resolved
|
|
113
|
+
label = resource_type == "vm" ? "VM" : "container"
|
|
114
|
+
$stderr.puts "Error: #{label} #{resource_id} not found"
|
|
115
|
+
return nil
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
resolved[:node]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Builds repository for resource type.
|
|
122
|
+
#
|
|
123
|
+
# @param connection [Connection] API connection
|
|
124
|
+
# @param resource_type [String] resource type
|
|
125
|
+
# @return [Repositories::Vm, Repositories::Container] repository
|
|
126
|
+
def build_repository(connection, resource_type)
|
|
127
|
+
case resource_type
|
|
128
|
+
when "vm"
|
|
129
|
+
Pvectl::Repositories::Vm.new(connection)
|
|
130
|
+
when "container", "ct"
|
|
131
|
+
Pvectl::Repositories::Container.new(connection)
|
|
132
|
+
else
|
|
133
|
+
raise ArgumentError, "Unknown resource type: #{resource_type}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Converts string resource type to symbol.
|
|
138
|
+
#
|
|
139
|
+
# @param resource_type [String] resource type
|
|
140
|
+
# @return [Symbol] :vm or :container
|
|
141
|
+
def resource_type_symbol(resource_type)
|
|
142
|
+
case resource_type
|
|
143
|
+
when "vm" then :vm
|
|
144
|
+
when "container", "ct" then :container
|
|
145
|
+
else :vm
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Builds an editor session from the --editor option.
|
|
150
|
+
#
|
|
151
|
+
# @return [EditorSession, nil] editor session or nil
|
|
152
|
+
def build_editor_session
|
|
153
|
+
editor_cmd = @options[:editor]
|
|
154
|
+
return nil unless editor_cmd
|
|
155
|
+
|
|
156
|
+
Pvectl::EditorSession.new(
|
|
157
|
+
editor: ->(path) { system(editor_cmd, path) }
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Builds service options from command options.
|
|
162
|
+
#
|
|
163
|
+
# @return [Hash] service options
|
|
164
|
+
def service_options
|
|
165
|
+
opts = {}
|
|
166
|
+
opts[:dry_run] = true if @options[:"dry-run"]
|
|
167
|
+
opts
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Loads configuration.
|
|
171
|
+
#
|
|
172
|
+
# @return [void]
|
|
173
|
+
def load_config
|
|
174
|
+
service = Pvectl::Config::Service.new
|
|
175
|
+
service.load(config: @global_options[:config])
|
|
176
|
+
@config = service.current_config
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Outputs usage error.
|
|
180
|
+
#
|
|
181
|
+
# @param message [String] error message
|
|
182
|
+
# @return [Integer] exit code
|
|
183
|
+
def usage_error(message)
|
|
184
|
+
$stderr.puts "Error: #{message}"
|
|
185
|
+
ExitCodes::USAGE_ERROR
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|