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,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Services
|
|
5
|
+
# Sends a Wake-on-LAN packet to a cluster node.
|
|
6
|
+
#
|
|
7
|
+
# Verifies the node exists in the cluster, calls the WoL API endpoint,
|
|
8
|
+
# and wraps the outcome in a NodeOperationResult. The Proxmox API
|
|
9
|
+
# returns the MAC address used for the magic packet on success, which
|
|
10
|
+
# is surfaced in the result message for confirmation.
|
|
11
|
+
#
|
|
12
|
+
# @example Basic usage
|
|
13
|
+
# service = Wakeonlan.new(node_repository: repo)
|
|
14
|
+
# result = service.execute(node_name: "pve3")
|
|
15
|
+
# result.successful? #=> true
|
|
16
|
+
# result.message #=> "Wake-on-LAN packet sent (MAC: AA:BB:CC:DD:EE:FF)"
|
|
17
|
+
#
|
|
18
|
+
# @see Pvectl::Repositories::Node#wakeonlan API call
|
|
19
|
+
# @see Pvectl::Models::NodeOperationResult Returned result wrapper
|
|
20
|
+
#
|
|
21
|
+
class Wakeonlan
|
|
22
|
+
# Creates a new service.
|
|
23
|
+
#
|
|
24
|
+
# @param node_repository [Repositories::Node] Node repository (DI)
|
|
25
|
+
def initialize(node_repository:)
|
|
26
|
+
@node_repository = node_repository
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Sends the WoL packet to a node.
|
|
30
|
+
#
|
|
31
|
+
# @param node_name [String] target node name
|
|
32
|
+
# @return [Models::NodeOperationResult] outcome (success/failure)
|
|
33
|
+
def execute(node_name:)
|
|
34
|
+
node = @node_repository.get(node_name)
|
|
35
|
+
return not_found_result(node_name) unless node
|
|
36
|
+
|
|
37
|
+
mac = @node_repository.wakeonlan(node_name)
|
|
38
|
+
build_result(node, success: true, message: success_message(mac))
|
|
39
|
+
rescue StandardError => e
|
|
40
|
+
build_result(node || Models::Node.new(name: node_name), success: false, error: e.message)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Builds a NodeOperationResult.
|
|
46
|
+
#
|
|
47
|
+
# @param node [Models::Node] target node
|
|
48
|
+
# @param attrs [Hash] additional attributes (:success, :error, :message)
|
|
49
|
+
# @return [Models::NodeOperationResult]
|
|
50
|
+
def build_result(node, **attrs)
|
|
51
|
+
Models::NodeOperationResult.new(
|
|
52
|
+
operation: :wakeonlan,
|
|
53
|
+
node_model: node,
|
|
54
|
+
resource: { node_name: node.name },
|
|
55
|
+
**attrs
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Builds a not-found error result.
|
|
60
|
+
#
|
|
61
|
+
# @param node_name [String]
|
|
62
|
+
# @return [Models::NodeOperationResult]
|
|
63
|
+
def not_found_result(node_name)
|
|
64
|
+
node = Models::Node.new(name: node_name)
|
|
65
|
+
build_result(node, success: false, error: "Node #{node_name} not found")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Formats the success message including the MAC address when returned.
|
|
69
|
+
#
|
|
70
|
+
# @param mac [String, nil]
|
|
71
|
+
# @return [String]
|
|
72
|
+
def success_message(mac)
|
|
73
|
+
return "Wake-on-LAN packet sent" if mac.nil? || mac.to_s.empty?
|
|
74
|
+
|
|
75
|
+
"Wake-on-LAN packet sent (MAC: #{mac})"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Utils
|
|
5
|
+
# Utility for resolving VMID to VM/container type and node.
|
|
6
|
+
#
|
|
7
|
+
# ResourceResolver auto-detects whether a given VMID belongs to a
|
|
8
|
+
# QEMU virtual machine or LXC container and retrieves its node location.
|
|
9
|
+
# Results are cached for efficiency when resolving multiple VMIDs.
|
|
10
|
+
#
|
|
11
|
+
# @example Resolving a single VMID
|
|
12
|
+
# resolver = ResourceResolver.new(connection)
|
|
13
|
+
# info = resolver.resolve(100)
|
|
14
|
+
# puts "VM #{info[:vmid]} is a #{info[:type]} on #{info[:node]}"
|
|
15
|
+
#
|
|
16
|
+
# @example Resolving multiple VMIDs
|
|
17
|
+
# resolver = ResourceResolver.new(connection)
|
|
18
|
+
# infos = resolver.resolve_multiple([100, 101, 102])
|
|
19
|
+
# infos.each { |i| puts "#{i[:vmid]}: #{i[:type]}" }
|
|
20
|
+
#
|
|
21
|
+
class ResourceResolver
|
|
22
|
+
# Creates a new ResourceResolver.
|
|
23
|
+
#
|
|
24
|
+
# @param connection [Connection] Proxmox API connection
|
|
25
|
+
def initialize(connection)
|
|
26
|
+
@connection = connection
|
|
27
|
+
@cache = nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Resolves a VMID to its resource information.
|
|
31
|
+
#
|
|
32
|
+
# @param vmid [Integer, String] VM or container identifier
|
|
33
|
+
# @return [Hash, nil] hash with :vmid, :node, :type (:qemu or :lxc), :name
|
|
34
|
+
# or nil if not found
|
|
35
|
+
def resolve(vmid)
|
|
36
|
+
vmid = vmid.to_i
|
|
37
|
+
load_resources
|
|
38
|
+
@cache[vmid]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Resolves multiple VMIDs to their resource information.
|
|
42
|
+
#
|
|
43
|
+
# @param vmids [Array<Integer, String>] array of VM/container identifiers
|
|
44
|
+
# @return [Array<Hash>] array of resolved resources (unknown VMIDs are skipped)
|
|
45
|
+
def resolve_multiple(vmids)
|
|
46
|
+
load_resources
|
|
47
|
+
vmids.map { |id| @cache[id.to_i] }.compact
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns all resources in the cluster.
|
|
51
|
+
#
|
|
52
|
+
# @return [Array<Hash>] array of all VM/container resources
|
|
53
|
+
def resolve_all
|
|
54
|
+
load_resources
|
|
55
|
+
@cache.values
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# Loads and caches cluster resources.
|
|
61
|
+
#
|
|
62
|
+
# @return [void]
|
|
63
|
+
def load_resources
|
|
64
|
+
return if @cache
|
|
65
|
+
|
|
66
|
+
response = @connection.client["cluster/resources"].get(type: "vm")
|
|
67
|
+
@cache = {}
|
|
68
|
+
|
|
69
|
+
response.each do |r|
|
|
70
|
+
@cache[r[:vmid]] = {
|
|
71
|
+
vmid: r[:vmid],
|
|
72
|
+
node: r[:node],
|
|
73
|
+
type: r[:type] == "lxc" ? :lxc : :qemu,
|
|
74
|
+
name: r[:name]
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
# Current version of the pvectl gem.
|
|
5
|
+
#
|
|
6
|
+
# Versioning follows Semantic Versioning (https://semver.org/):
|
|
7
|
+
# - MAJOR: breaking changes
|
|
8
|
+
# - MINOR: new features, backwards compatible
|
|
9
|
+
# - PATCH: bug fixes, backwards compatible
|
|
10
|
+
#
|
|
11
|
+
# @return [String] version number in MAJOR.MINOR.PATCH format
|
|
12
|
+
VERSION = "0.2.0"
|
|
13
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Wizards
|
|
5
|
+
# Interactive wizard for creating an LXC container step by step.
|
|
6
|
+
#
|
|
7
|
+
# Uses TTY::Prompt (when available) or a fallback prompt to guide the user
|
|
8
|
+
# through container configuration. Returns a normalized params hash compatible
|
|
9
|
+
# with Services::CreateContainer, or nil if the user cancels.
|
|
10
|
+
#
|
|
11
|
+
# @example Running the wizard
|
|
12
|
+
# wizard = CreateContainer.new(options, global_options)
|
|
13
|
+
# params = wizard.run
|
|
14
|
+
# #=> { hostname: "web-ct", node: "pve1", ... } or nil
|
|
15
|
+
#
|
|
16
|
+
class CreateContainer
|
|
17
|
+
# Creates a new CreateContainer wizard.
|
|
18
|
+
#
|
|
19
|
+
# @param options [Hash] command options (may contain pre-filled values)
|
|
20
|
+
# @param global_options [Hash] global CLI options
|
|
21
|
+
# @param prompt [Object] prompt instance (injectable for testing)
|
|
22
|
+
def initialize(options, global_options, prompt: nil)
|
|
23
|
+
@options = options
|
|
24
|
+
@global_options = global_options
|
|
25
|
+
@prompt = prompt || create_default_prompt
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Runs the wizard and returns params or nil if cancelled.
|
|
29
|
+
#
|
|
30
|
+
# @return [Hash, nil] creation params or nil if user cancels
|
|
31
|
+
def run
|
|
32
|
+
collect_params
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Creates a default prompt, preferring TTY::Prompt with SimplePrompt fallback.
|
|
38
|
+
#
|
|
39
|
+
# @return [Object] prompt object
|
|
40
|
+
def create_default_prompt
|
|
41
|
+
require "tty-prompt"
|
|
42
|
+
TTY::Prompt.new
|
|
43
|
+
rescue LoadError
|
|
44
|
+
Config::SimplePrompt.new
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Collects all parameters interactively.
|
|
48
|
+
#
|
|
49
|
+
# @return [Hash] collected parameters
|
|
50
|
+
def collect_params
|
|
51
|
+
params = {}
|
|
52
|
+
params[:hostname] = @prompt.ask("Container hostname:", required: true)
|
|
53
|
+
params[:ostemplate] = @prompt.ask("OS template path:", required: true)
|
|
54
|
+
params[:node] = @prompt.ask("Node:", default: @options[:node])
|
|
55
|
+
params[:cores] = @prompt.ask("CPU cores:", default: 1, convert: :int)
|
|
56
|
+
params[:memory] = @prompt.ask("Memory (MB):", default: 512, convert: :int)
|
|
57
|
+
params[:swap] = @prompt.ask("Swap (MB):", default: 512, convert: :int)
|
|
58
|
+
params[:rootfs] = collect_rootfs
|
|
59
|
+
params[:mountpoints] = collect_mountpoints
|
|
60
|
+
params[:nets] = collect_nets
|
|
61
|
+
params[:privileged] = true unless @prompt.yes?("Unprivileged container?", default: true)
|
|
62
|
+
params[:start] = true if @prompt.yes?("Start container after creation?")
|
|
63
|
+
params.compact
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Collects root filesystem configuration.
|
|
67
|
+
#
|
|
68
|
+
# @return [Hash] parsed rootfs config
|
|
69
|
+
def collect_rootfs
|
|
70
|
+
input = @prompt.ask("Root FS (storage=X,size=Y):", required: true)
|
|
71
|
+
Parsers::LxcMountConfig.parse(input)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Collects mountpoint configurations interactively.
|
|
75
|
+
#
|
|
76
|
+
# @return [Array<Hash>, nil] mountpoint configs or nil if none added
|
|
77
|
+
def collect_mountpoints
|
|
78
|
+
mps = []
|
|
79
|
+
loop do
|
|
80
|
+
input = @prompt.ask("Mountpoint (mp=/path,storage=X,size=Y) or empty to skip:")
|
|
81
|
+
break if input.nil? || input.empty?
|
|
82
|
+
|
|
83
|
+
mps << Parsers::LxcMountConfig.parse(input)
|
|
84
|
+
break unless @prompt.yes?("Add another mountpoint?")
|
|
85
|
+
end
|
|
86
|
+
mps.empty? ? nil : mps
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Collects network configurations interactively.
|
|
90
|
+
#
|
|
91
|
+
# @return [Array<Hash>, nil] net configs or nil if none added
|
|
92
|
+
def collect_nets
|
|
93
|
+
nets = []
|
|
94
|
+
loop do
|
|
95
|
+
input = @prompt.ask("Network config (bridge=X[,ip=Y]) or empty to skip:")
|
|
96
|
+
break if input.nil? || input.empty?
|
|
97
|
+
|
|
98
|
+
nets << Parsers::LxcNetConfig.parse(input)
|
|
99
|
+
break unless @prompt.yes?("Add another network?")
|
|
100
|
+
end
|
|
101
|
+
nets.empty? ? nil : nets
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Wizards
|
|
5
|
+
# Interactive wizard for creating a VM step by step.
|
|
6
|
+
#
|
|
7
|
+
# Uses TTY::Prompt (when available) or a fallback prompt to guide the user
|
|
8
|
+
# through VM configuration. Returns a normalized params hash compatible
|
|
9
|
+
# with Services::CreateVm, or nil if the user cancels.
|
|
10
|
+
#
|
|
11
|
+
# @example Running the wizard
|
|
12
|
+
# wizard = CreateVm.new(options, global_options)
|
|
13
|
+
# params = wizard.run
|
|
14
|
+
# #=> { name: "web", node: "pve1", cores: 4, ... } or nil
|
|
15
|
+
#
|
|
16
|
+
class CreateVm
|
|
17
|
+
OS_TYPES = %w[l26 l24 win11 win10 win2k22 win2k19 win2k16 win8 win7 other].freeze
|
|
18
|
+
|
|
19
|
+
# Creates a new CreateVm wizard.
|
|
20
|
+
#
|
|
21
|
+
# @param options [Hash] command options (may contain pre-filled values)
|
|
22
|
+
# @param global_options [Hash] global CLI options
|
|
23
|
+
# @param prompt [Object] prompt instance (injectable for testing)
|
|
24
|
+
def initialize(options, global_options, prompt: nil)
|
|
25
|
+
@options = options
|
|
26
|
+
@global_options = global_options
|
|
27
|
+
@prompt = prompt || create_default_prompt
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Runs the wizard and returns params or nil if cancelled.
|
|
31
|
+
#
|
|
32
|
+
# @return [Hash, nil] creation params or nil if user cancels
|
|
33
|
+
def run
|
|
34
|
+
collect_params
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# Creates a default prompt, preferring TTY::Prompt with SimplePrompt fallback.
|
|
40
|
+
#
|
|
41
|
+
# @return [Object] prompt object
|
|
42
|
+
def create_default_prompt
|
|
43
|
+
require "tty-prompt"
|
|
44
|
+
TTY::Prompt.new
|
|
45
|
+
rescue LoadError
|
|
46
|
+
Config::SimplePrompt.new
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Collects all parameters interactively.
|
|
50
|
+
#
|
|
51
|
+
# @return [Hash] collected parameters
|
|
52
|
+
def collect_params
|
|
53
|
+
params = {}
|
|
54
|
+
params[:name] = @prompt.ask("VM name:", required: true)
|
|
55
|
+
params[:node] = @prompt.ask("Node:", default: @options[:node])
|
|
56
|
+
params[:cores] = @prompt.ask("CPU cores:", default: 1, convert: :int)
|
|
57
|
+
params[:sockets] = @prompt.ask("CPU sockets:", default: 1, convert: :int)
|
|
58
|
+
params[:memory] = @prompt.ask("Memory (MB):", default: 2048, convert: :int)
|
|
59
|
+
params[:disks] = collect_disks
|
|
60
|
+
params[:nets] = collect_nets
|
|
61
|
+
params[:ostype] = @prompt.select("OS type:", OS_TYPES)
|
|
62
|
+
params[:agent] = true if @prompt.yes?("Enable QEMU guest agent?")
|
|
63
|
+
params[:start] = true if @prompt.yes?("Start VM after creation?")
|
|
64
|
+
params.compact
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Collects disk configurations interactively.
|
|
68
|
+
#
|
|
69
|
+
# @return [Array<Hash>, nil] disk configs or nil if none added
|
|
70
|
+
def collect_disks
|
|
71
|
+
disks = []
|
|
72
|
+
loop do
|
|
73
|
+
input = @prompt.ask("Disk config (storage=X,size=Y) or empty to skip:")
|
|
74
|
+
break if input.nil? || input.empty?
|
|
75
|
+
|
|
76
|
+
disks << Parsers::DiskConfig.parse(input)
|
|
77
|
+
break unless @prompt.yes?("Add another disk?")
|
|
78
|
+
end
|
|
79
|
+
disks.empty? ? nil : disks
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Collects network configurations interactively.
|
|
83
|
+
#
|
|
84
|
+
# @return [Array<Hash>, nil] net configs or nil if none added
|
|
85
|
+
def collect_nets
|
|
86
|
+
nets = []
|
|
87
|
+
loop do
|
|
88
|
+
input = @prompt.ask("Network config (bridge=X) or empty to skip:")
|
|
89
|
+
break if input.nil? || input.empty?
|
|
90
|
+
|
|
91
|
+
nets << Parsers::NetConfig.parse(input)
|
|
92
|
+
break unless @prompt.yes?("Add another network?")
|
|
93
|
+
end
|
|
94
|
+
nets.empty? ? nil : nets
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|