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,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
module Get
|
|
6
|
+
module Handlers
|
|
7
|
+
# Handler for listing backups.
|
|
8
|
+
#
|
|
9
|
+
# Unlike Snapshots handler, Backups allows listing all backups
|
|
10
|
+
# or filtering by optional VMID.
|
|
11
|
+
#
|
|
12
|
+
# @example Usage
|
|
13
|
+
# handler.list(node: nil, name: nil, args: []) # all backups
|
|
14
|
+
# handler.list(node: nil, name: nil, args: ["100"]) # backups for VM 100
|
|
15
|
+
#
|
|
16
|
+
class Backups
|
|
17
|
+
include ResourceHandler
|
|
18
|
+
|
|
19
|
+
def initialize(service: nil)
|
|
20
|
+
@service = service
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Lists backups with optional VMID filter.
|
|
24
|
+
#
|
|
25
|
+
# @param node [String, nil] ignored (backups can span nodes)
|
|
26
|
+
# @param name [String, nil] ignored
|
|
27
|
+
# @param args [Array<String>] optional VMID filter (first arg only)
|
|
28
|
+
# @param storage [String, nil] filter by storage
|
|
29
|
+
# @return [Array<Models::Backup>] collection of backup models
|
|
30
|
+
def list(node: nil, name: nil, args: [], storage: nil, **_options)
|
|
31
|
+
vmid = args.first&.to_i
|
|
32
|
+
vmid = nil if vmid&.zero?
|
|
33
|
+
|
|
34
|
+
service.list(vmid: vmid, storage: storage)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns presenter for backups.
|
|
38
|
+
#
|
|
39
|
+
# @return [Presenters::Backup] backup presenter instance
|
|
40
|
+
def presenter
|
|
41
|
+
Pvectl::Presenters::Backup.new
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def service
|
|
47
|
+
@service ||= build_service
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def build_service
|
|
51
|
+
config_service = Pvectl::Config::Service.new
|
|
52
|
+
config_service.load
|
|
53
|
+
connection = Pvectl::Connection.new(config_service.current_config)
|
|
54
|
+
|
|
55
|
+
backup_repo = Pvectl::Repositories::Backup.new(connection)
|
|
56
|
+
resolver = Pvectl::Utils::ResourceResolver.new(connection)
|
|
57
|
+
task_repo = Pvectl::Repositories::Task.new(connection)
|
|
58
|
+
|
|
59
|
+
Pvectl::Services::Backup.new(
|
|
60
|
+
backup_repo: backup_repo,
|
|
61
|
+
resource_resolver: resolver,
|
|
62
|
+
task_repo: task_repo
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Register handler with ResourceRegistry
|
|
72
|
+
Pvectl::Commands::Get::ResourceRegistry.register(
|
|
73
|
+
"backups",
|
|
74
|
+
Pvectl::Commands::Get::Handlers::Backups,
|
|
75
|
+
aliases: ["backup"]
|
|
76
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
module Get
|
|
6
|
+
module Handlers
|
|
7
|
+
# Handler for `pvectl get node-capabilities`.
|
|
8
|
+
#
|
|
9
|
+
# Surfaces what features a node supports — primarily the available
|
|
10
|
+
# QEMU CPU models and machine types. When `--node` is provided the
|
|
11
|
+
# query is scoped to that node; otherwise the handler iterates all
|
|
12
|
+
# online nodes and aggregates the results, silently skipping
|
|
13
|
+
# unreachable nodes (matches the pattern used by the time handler).
|
|
14
|
+
#
|
|
15
|
+
# @see Pvectl::Repositories::Capabilities
|
|
16
|
+
# @see Pvectl::Presenters::Capability
|
|
17
|
+
#
|
|
18
|
+
class Capabilities
|
|
19
|
+
include ResourceHandler
|
|
20
|
+
|
|
21
|
+
# @param repository [Repositories::Capabilities, nil] capability repo (DI)
|
|
22
|
+
# @param node_repository [Repositories::Node, nil] node repo (DI)
|
|
23
|
+
def initialize(repository: nil, node_repository: nil)
|
|
24
|
+
@repository = repository
|
|
25
|
+
@node_repository = node_repository
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Lists capabilities, optionally scoped to a node.
|
|
29
|
+
#
|
|
30
|
+
# @param node [String, nil] when provided, only that node is queried
|
|
31
|
+
# @param name [String, nil] unused, interface compatibility
|
|
32
|
+
# @param args [Array<String>] unused, interface compatibility
|
|
33
|
+
# @param storage [String, nil] unused, interface compatibility
|
|
34
|
+
# @return [Array<Models::Capability>]
|
|
35
|
+
# @raise [Pvectl::ResourceNotFoundError] if a specific node is requested but missing
|
|
36
|
+
def list(node: nil, name: nil, args: [], storage: nil, **_options)
|
|
37
|
+
return fetch_for(node) if node
|
|
38
|
+
|
|
39
|
+
online_node_names.flat_map do |node_name|
|
|
40
|
+
repository.list(node: node_name)
|
|
41
|
+
rescue StandardError
|
|
42
|
+
[]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns the capability presenter.
|
|
47
|
+
#
|
|
48
|
+
# @return [Presenters::Capability]
|
|
49
|
+
def presenter
|
|
50
|
+
Pvectl::Presenters::Capability.new
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# Fetches capabilities for a specific node, raising when the node
|
|
56
|
+
# itself does not exist in the cluster.
|
|
57
|
+
#
|
|
58
|
+
# @param node_name [String]
|
|
59
|
+
# @return [Array<Models::Capability>]
|
|
60
|
+
# @raise [Pvectl::ResourceNotFoundError]
|
|
61
|
+
def fetch_for(node_name)
|
|
62
|
+
unless node_repository.get(node_name)
|
|
63
|
+
raise Pvectl::ResourceNotFoundError, "Node not found: #{node_name}"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
repository.list(node: node_name)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Names of online nodes.
|
|
70
|
+
#
|
|
71
|
+
# @return [Array<String>]
|
|
72
|
+
def online_node_names
|
|
73
|
+
node_repository.list.select { |n| n.status == "online" }.map(&:name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @return [Repositories::Capabilities]
|
|
77
|
+
def repository
|
|
78
|
+
@repository ||= Pvectl::Repositories::Capabilities.new(connection)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @return [Repositories::Node]
|
|
82
|
+
def node_repository
|
|
83
|
+
@node_repository ||= Pvectl::Repositories::Node.new(connection)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Builds API connection from the current config.
|
|
87
|
+
#
|
|
88
|
+
# @return [Pvectl::Connection]
|
|
89
|
+
def connection
|
|
90
|
+
@connection ||= begin
|
|
91
|
+
config_service = Pvectl::Config::Service.new
|
|
92
|
+
config_service.load
|
|
93
|
+
Pvectl::Connection.new(config_service.current_config)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Register handler with ResourceRegistry under the spec name plus aliases.
|
|
103
|
+
Pvectl::Commands::Get::ResourceRegistry.register(
|
|
104
|
+
"node-capabilities",
|
|
105
|
+
Pvectl::Commands::Get::Handlers::Capabilities,
|
|
106
|
+
aliases: ["capabilities", "caps", "node-capability"]
|
|
107
|
+
)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
module Get
|
|
6
|
+
module Handlers
|
|
7
|
+
# Handler for listing LXC containers.
|
|
8
|
+
#
|
|
9
|
+
# Implements ResourceHandler interface for the "containers" resource type.
|
|
10
|
+
# Uses Repositories::Container for data access and Presenters::Container for formatting.
|
|
11
|
+
#
|
|
12
|
+
# Registered with ResourceRegistry on file load for "containers", "container", "ct", and "cts".
|
|
13
|
+
#
|
|
14
|
+
# @example Using via ResourceRegistry
|
|
15
|
+
# handler = ResourceRegistry.for("containers")
|
|
16
|
+
# containers = handler.list(node: "pve1")
|
|
17
|
+
# presenter = handler.presenter
|
|
18
|
+
#
|
|
19
|
+
# @see Pvectl::Commands::Get::ResourceHandler Handler interface
|
|
20
|
+
# @see Pvectl::Repositories::Container Container repository
|
|
21
|
+
# @see Pvectl::Presenters::Container Container presenter
|
|
22
|
+
#
|
|
23
|
+
class Containers
|
|
24
|
+
include ResourceHandler
|
|
25
|
+
|
|
26
|
+
# CTID validation pattern (100-999999999)
|
|
27
|
+
CTID_PATTERN = /\A[1-9]\d{2,8}\z/
|
|
28
|
+
|
|
29
|
+
# Sort field mappings.
|
|
30
|
+
# Negative values for descending sort (higher values first).
|
|
31
|
+
SORT_FIELDS = {
|
|
32
|
+
"name" => ->(c) { c.name || "" },
|
|
33
|
+
"node" => ->(c) { c.node || "" },
|
|
34
|
+
"cpu" => ->(c) { -(c.cpu || 0) },
|
|
35
|
+
"memory" => ->(c) { -(c.mem || 0) },
|
|
36
|
+
"disk" => ->(c) { -(c.disk || 0) },
|
|
37
|
+
"netin" => ->(c) { -(c.netin || 0) },
|
|
38
|
+
"netout" => ->(c) { -(c.netout || 0) }
|
|
39
|
+
}.freeze
|
|
40
|
+
|
|
41
|
+
# Creates handler with optional repository for dependency injection.
|
|
42
|
+
#
|
|
43
|
+
# @param repository [Repositories::Container, nil] repository (default: create new)
|
|
44
|
+
def initialize(repository: nil)
|
|
45
|
+
@repository = repository
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns selector class for container filtering.
|
|
49
|
+
#
|
|
50
|
+
# @return [Class] Selectors::Container
|
|
51
|
+
def selector_class
|
|
52
|
+
Pvectl::Selectors::Container
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Lists containers with optional filtering and sorting.
|
|
56
|
+
#
|
|
57
|
+
# @param node [String, nil] filter by node name
|
|
58
|
+
# @param name [String, nil] filter by container name
|
|
59
|
+
# @param args [Array<String>] unused, for interface compatibility
|
|
60
|
+
# @param storage [String, nil] unused, for interface compatibility
|
|
61
|
+
# @param sort [String, nil] sort field (name, node, cpu, memory, disk, netin, netout)
|
|
62
|
+
# @return [Array<Models::Container>] collection of Container models
|
|
63
|
+
def list(node: nil, name: nil, args: [], storage: nil, sort: nil, **_options)
|
|
64
|
+
containers = repository.list(node: node)
|
|
65
|
+
containers = containers.select { |c| c.name == name } if name
|
|
66
|
+
containers = apply_sort(containers, sort) if sort
|
|
67
|
+
containers
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Returns presenter for containers.
|
|
71
|
+
#
|
|
72
|
+
# @return [Presenters::Container] Container presenter instance
|
|
73
|
+
def presenter
|
|
74
|
+
Pvectl::Presenters::Container.new
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Describes a single container with comprehensive details.
|
|
78
|
+
#
|
|
79
|
+
# @param name [String] CTID as string (consistent with handler interface)
|
|
80
|
+
# @param node [String, nil] unused, for API consistency
|
|
81
|
+
# @return [Models::Container] Container model with full details
|
|
82
|
+
# @raise [ArgumentError] if CTID format is invalid
|
|
83
|
+
# @raise [Pvectl::ResourceNotFoundError] if container not found
|
|
84
|
+
def describe(name:, node: nil, args: [], vmid: nil)
|
|
85
|
+
raise ArgumentError, "Invalid CTID: must be positive integer (100-999999999)" unless valid_ctid?(name)
|
|
86
|
+
|
|
87
|
+
ctid = name.to_i
|
|
88
|
+
container = repository.describe(ctid)
|
|
89
|
+
raise Pvectl::ResourceNotFoundError, "Container not found: #{ctid}" if container.nil?
|
|
90
|
+
|
|
91
|
+
container
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
# Returns repository, creating it if necessary.
|
|
97
|
+
#
|
|
98
|
+
# @return [Repositories::Container] Container repository
|
|
99
|
+
def repository
|
|
100
|
+
@repository ||= build_repository
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Builds repository with connection from config.
|
|
104
|
+
#
|
|
105
|
+
# @return [Repositories::Container] configured Container repository
|
|
106
|
+
def build_repository
|
|
107
|
+
config_service = Pvectl::Config::Service.new
|
|
108
|
+
config_service.load
|
|
109
|
+
connection = Pvectl::Connection.new(config_service.current_config)
|
|
110
|
+
Pvectl::Repositories::Container.new(connection)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Applies sorting to containers collection.
|
|
114
|
+
#
|
|
115
|
+
# @param containers [Array<Models::Container>] containers to sort
|
|
116
|
+
# @param sort_field [String] field to sort by
|
|
117
|
+
# @return [Array<Models::Container>] sorted containers
|
|
118
|
+
def apply_sort(containers, sort_field)
|
|
119
|
+
sort_proc = SORT_FIELDS[sort_field.to_s]
|
|
120
|
+
return containers unless sort_proc
|
|
121
|
+
|
|
122
|
+
containers.sort_by(&sort_proc)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Validates CTID format.
|
|
126
|
+
#
|
|
127
|
+
# CTID must be a positive integer between 100 and 999999999.
|
|
128
|
+
# The minimum CTID in Proxmox is 100 (unlike VMID which can be 1).
|
|
129
|
+
#
|
|
130
|
+
# @param ctid [String, nil] CTID to validate
|
|
131
|
+
# @return [Boolean] true if valid
|
|
132
|
+
def valid_ctid?(ctid)
|
|
133
|
+
return false if ctid.nil? || ctid.to_s.empty?
|
|
134
|
+
|
|
135
|
+
ctid.to_s.match?(CTID_PATTERN)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Register handler with ResourceRegistry
|
|
144
|
+
Pvectl::Commands::Get::ResourceRegistry.register(
|
|
145
|
+
"containers",
|
|
146
|
+
Pvectl::Commands::Get::Handlers::Containers,
|
|
147
|
+
aliases: ["container", "ct", "cts"]
|
|
148
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
module Get
|
|
6
|
+
module Handlers
|
|
7
|
+
# Handler for listing physical disks on Proxmox nodes.
|
|
8
|
+
#
|
|
9
|
+
# Implements ResourceHandler interface for the "disks" resource type.
|
|
10
|
+
# Uses Repositories::Disk for data access and Presenters::Disk for formatting.
|
|
11
|
+
#
|
|
12
|
+
# @example Using via ResourceRegistry
|
|
13
|
+
# handler = ResourceRegistry.for("disks")
|
|
14
|
+
# disks = handler.list(node: "pve1")
|
|
15
|
+
#
|
|
16
|
+
# @see Pvectl::Commands::Get::ResourceHandler Handler interface
|
|
17
|
+
# @see Pvectl::Repositories::Disk Disk repository
|
|
18
|
+
# @see Pvectl::Presenters::Disk Disk presenter
|
|
19
|
+
#
|
|
20
|
+
class Disks
|
|
21
|
+
include ResourceHandler
|
|
22
|
+
|
|
23
|
+
# Creates handler with optional repository for dependency injection.
|
|
24
|
+
#
|
|
25
|
+
# @param repository [Repositories::Disk, nil] repository (default: create new)
|
|
26
|
+
def initialize(repository: nil)
|
|
27
|
+
@repository = repository
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Lists physical disks with optional filtering.
|
|
31
|
+
#
|
|
32
|
+
# @param node [String, nil] filter by node name
|
|
33
|
+
# @param name [String, nil] filter by device path (e.g., "/dev/sda")
|
|
34
|
+
# @param args [Array<String>] unused, for interface compatibility
|
|
35
|
+
# @param storage [String, nil] unused, for interface compatibility
|
|
36
|
+
# @return [Array<Models::PhysicalDisk>] collection of PhysicalDisk models
|
|
37
|
+
def list(node: nil, name: nil, args: [], storage: nil, **_options)
|
|
38
|
+
disks = repository.list(node: node)
|
|
39
|
+
disks = disks.select { |d| d.devpath == name } if name
|
|
40
|
+
disks
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Describes a single physical disk with SMART data.
|
|
44
|
+
#
|
|
45
|
+
# Locates the disk by devpath across all nodes (or a specific node),
|
|
46
|
+
# then fetches SMART data and merges it into the model.
|
|
47
|
+
#
|
|
48
|
+
# @param name [String] device path (e.g., "/dev/nvme0n1")
|
|
49
|
+
# @param node [String, nil] optional node filter
|
|
50
|
+
# @param args [Array<String>] unused, for interface compatibility
|
|
51
|
+
# @param vmid [String, nil] unused, for interface compatibility
|
|
52
|
+
# @return [Models::PhysicalDisk] enriched disk model
|
|
53
|
+
# @raise [Pvectl::ResourceNotFoundError] when disk not found
|
|
54
|
+
def describe(name:, node: nil, args: [], vmid: nil)
|
|
55
|
+
disks = repository.list(node: node)
|
|
56
|
+
disk = disks.find { |d| d.devpath == name }
|
|
57
|
+
raise Pvectl::ResourceNotFoundError, "Disk not found: #{name}" unless disk
|
|
58
|
+
|
|
59
|
+
smart_data = repository.smart(disk.node, name)
|
|
60
|
+
disk.merge_smart(smart_data)
|
|
61
|
+
disk
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Returns presenter for physical disks.
|
|
65
|
+
#
|
|
66
|
+
# @return [Presenters::Disk] Disk presenter instance
|
|
67
|
+
def presenter
|
|
68
|
+
Pvectl::Presenters::Disk.new
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns selector class for client-side filtering.
|
|
72
|
+
#
|
|
73
|
+
# @return [Class] Selectors::Disk class
|
|
74
|
+
def selector_class
|
|
75
|
+
Pvectl::Selectors::Disk
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
# Returns repository, creating it if necessary.
|
|
81
|
+
#
|
|
82
|
+
# @return [Repositories::Disk] Disk repository
|
|
83
|
+
def repository
|
|
84
|
+
@repository ||= build_repository
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Builds repository with connection from config.
|
|
88
|
+
#
|
|
89
|
+
# @return [Repositories::Disk] configured Disk repository
|
|
90
|
+
def build_repository
|
|
91
|
+
config_service = Pvectl::Config::Service.new
|
|
92
|
+
config_service.load
|
|
93
|
+
connection = Pvectl::Connection.new(config_service.current_config)
|
|
94
|
+
Pvectl::Repositories::Disk.new(connection)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Register handler with ResourceRegistry
|
|
103
|
+
Pvectl::Commands::Get::ResourceRegistry.register(
|
|
104
|
+
"disks",
|
|
105
|
+
Pvectl::Commands::Get::Handlers::Disks,
|
|
106
|
+
aliases: ["disk"]
|
|
107
|
+
)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
module Get
|
|
6
|
+
module Handlers
|
|
7
|
+
# Handler for reading per-node DNS resolver settings.
|
|
8
|
+
#
|
|
9
|
+
# Implements ResourceHandler interface for the "dns" resource type.
|
|
10
|
+
# DNS is a singleton resource per node — there is no cluster-wide DNS
|
|
11
|
+
# configuration, so a node name is always required.
|
|
12
|
+
#
|
|
13
|
+
# @example Using via ResourceRegistry
|
|
14
|
+
# handler = ResourceRegistry.for("dns")
|
|
15
|
+
# dns = handler.list(node: "pve1") # => [DnsConfig]
|
|
16
|
+
#
|
|
17
|
+
# @see Pvectl::Repositories::Dns DNS repository
|
|
18
|
+
# @see Pvectl::Presenters::DnsConfig DNS presenter
|
|
19
|
+
#
|
|
20
|
+
class Dns
|
|
21
|
+
include ResourceHandler
|
|
22
|
+
|
|
23
|
+
# Creates handler with optional repository for dependency injection.
|
|
24
|
+
#
|
|
25
|
+
# @param repository [Repositories::Dns, nil] DNS repository
|
|
26
|
+
def initialize(repository: nil)
|
|
27
|
+
@repository = repository
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the DNS configuration for the given node, wrapped in an array.
|
|
31
|
+
#
|
|
32
|
+
# @param node [String, nil] node name (REQUIRED — DNS is per-node)
|
|
33
|
+
# @param _options [Hash] unused, for interface compatibility
|
|
34
|
+
# @return [Array<Models::DnsConfig>] single-element array with the DNS config
|
|
35
|
+
# @raise [ArgumentError] when no node is provided
|
|
36
|
+
def list(node: nil, **_options)
|
|
37
|
+
raise ArgumentError, "DNS requires --node NODE to identify which node's settings to read" if node.nil? || node.to_s.empty?
|
|
38
|
+
|
|
39
|
+
[repository.fetch(node)]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Returns presenter for DNS configuration.
|
|
43
|
+
#
|
|
44
|
+
# @return [Presenters::DnsConfig] DNS presenter instance
|
|
45
|
+
def presenter
|
|
46
|
+
Pvectl::Presenters::DnsConfig.new
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Describes the DNS configuration for a single node.
|
|
50
|
+
#
|
|
51
|
+
# Accepts either `name` (positional argument from describe command)
|
|
52
|
+
# or `node` (--node flag) as the node identifier.
|
|
53
|
+
#
|
|
54
|
+
# @param name [String, nil] node name (positional)
|
|
55
|
+
# @param node [String, nil] node name (--node flag, fallback)
|
|
56
|
+
# @param _opts [Hash] unused, for interface compatibility
|
|
57
|
+
# @return [Models::DnsConfig] DNS configuration model
|
|
58
|
+
# @raise [ArgumentError] when no node identifier given
|
|
59
|
+
def describe(name:, node: nil, **_opts)
|
|
60
|
+
node_name = name || node
|
|
61
|
+
raise ArgumentError, "Node name required: pvectl describe dns NODE or --node NODE" if node_name.nil? || node_name.to_s.empty?
|
|
62
|
+
|
|
63
|
+
repository.fetch(node_name)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
# Returns repository, creating it if necessary.
|
|
69
|
+
#
|
|
70
|
+
# @return [Repositories::Dns] DNS repository
|
|
71
|
+
def repository
|
|
72
|
+
@repository ||= build_repository
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Builds repository with connection from config.
|
|
76
|
+
#
|
|
77
|
+
# @return [Repositories::Dns] configured DNS repository
|
|
78
|
+
def build_repository
|
|
79
|
+
config_service = Pvectl::Config::Service.new
|
|
80
|
+
config_service.load
|
|
81
|
+
connection = Pvectl::Connection.new(config_service.current_config)
|
|
82
|
+
Pvectl::Repositories::Dns.new(connection)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Register handler with ResourceRegistry
|
|
91
|
+
Pvectl::Commands::Get::ResourceRegistry.register(
|
|
92
|
+
"dns",
|
|
93
|
+
Pvectl::Commands::Get::Handlers::Dns
|
|
94
|
+
)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Commands
|
|
5
|
+
module Get
|
|
6
|
+
module Handlers
|
|
7
|
+
# Handler for reading per-node /etc/hosts contents.
|
|
8
|
+
#
|
|
9
|
+
# Implements ResourceHandler interface for the "hosts" resource type.
|
|
10
|
+
# /etc/hosts is a singleton resource per node — there is no cluster-wide
|
|
11
|
+
# hosts file, so a node name is always required.
|
|
12
|
+
#
|
|
13
|
+
# @example Using via ResourceRegistry
|
|
14
|
+
# handler = ResourceRegistry.for("hosts")
|
|
15
|
+
# hosts = handler.list(node: "pve1") # => [HostsFile]
|
|
16
|
+
#
|
|
17
|
+
# @see Pvectl::Repositories::Hosts Hosts repository
|
|
18
|
+
# @see Pvectl::Presenters::HostsFile HostsFile presenter
|
|
19
|
+
#
|
|
20
|
+
class Hosts
|
|
21
|
+
include ResourceHandler
|
|
22
|
+
|
|
23
|
+
# Creates handler with optional repository for dependency injection.
|
|
24
|
+
#
|
|
25
|
+
# @param repository [Repositories::Hosts, nil] Hosts repository
|
|
26
|
+
def initialize(repository: nil)
|
|
27
|
+
@repository = repository
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the /etc/hosts contents for the given node, wrapped in an array.
|
|
31
|
+
#
|
|
32
|
+
# @param node [String, nil] node name (REQUIRED — hosts is per-node)
|
|
33
|
+
# @param _options [Hash] unused, for interface compatibility
|
|
34
|
+
# @return [Array<Models::HostsFile>] single-element array with the hosts file
|
|
35
|
+
# @raise [ArgumentError] when no node is provided
|
|
36
|
+
def list(node: nil, **_options)
|
|
37
|
+
raise ArgumentError, "hosts requires --node NODE to identify which node's /etc/hosts to read" if node.nil? || node.to_s.empty?
|
|
38
|
+
|
|
39
|
+
[repository.fetch(node)]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Returns presenter for /etc/hosts.
|
|
43
|
+
#
|
|
44
|
+
# @return [Presenters::HostsFile] HostsFile presenter instance
|
|
45
|
+
def presenter
|
|
46
|
+
Pvectl::Presenters::HostsFile.new
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Describes the /etc/hosts contents for a single node.
|
|
50
|
+
#
|
|
51
|
+
# Accepts either `name` (positional argument from describe command)
|
|
52
|
+
# or `node` (--node flag) as the node identifier.
|
|
53
|
+
#
|
|
54
|
+
# @param name [String, nil] node name (positional)
|
|
55
|
+
# @param node [String, nil] node name (--node flag, fallback)
|
|
56
|
+
# @param _opts [Hash] unused, for interface compatibility
|
|
57
|
+
# @return [Models::HostsFile] hosts file model
|
|
58
|
+
# @raise [ArgumentError] when no node identifier given
|
|
59
|
+
def describe(name:, node: nil, **_opts)
|
|
60
|
+
node_name = name || node
|
|
61
|
+
raise ArgumentError, "Node name required: pvectl describe hosts NODE or --node NODE" if node_name.nil? || node_name.to_s.empty?
|
|
62
|
+
|
|
63
|
+
repository.fetch(node_name)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
# Returns repository, creating it if necessary.
|
|
69
|
+
#
|
|
70
|
+
# @return [Repositories::Hosts] hosts repository
|
|
71
|
+
def repository
|
|
72
|
+
@repository ||= build_repository
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Builds repository with connection from config.
|
|
76
|
+
#
|
|
77
|
+
# @return [Repositories::Hosts] configured hosts repository
|
|
78
|
+
def build_repository
|
|
79
|
+
config_service = Pvectl::Config::Service.new
|
|
80
|
+
config_service.load
|
|
81
|
+
connection = Pvectl::Connection.new(config_service.current_config)
|
|
82
|
+
Pvectl::Repositories::Hosts.new(connection)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Register handler with ResourceRegistry
|
|
91
|
+
Pvectl::Commands::Get::ResourceRegistry.register(
|
|
92
|
+
"hosts",
|
|
93
|
+
Pvectl::Commands::Get::Handlers::Hosts
|
|
94
|
+
)
|