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,329 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for Proxmox cluster storage pools.
|
|
6
|
+
#
|
|
7
|
+
# Defines column layout and formatting for table output.
|
|
8
|
+
# Standard columns show essential storage info.
|
|
9
|
+
# Wide columns add content types and shared status.
|
|
10
|
+
#
|
|
11
|
+
# @example Using with formatter
|
|
12
|
+
# presenter = Storage.new
|
|
13
|
+
# formatter = Formatters::Table.new
|
|
14
|
+
# output = formatter.format(storage_pools, presenter)
|
|
15
|
+
#
|
|
16
|
+
# @see Pvectl::Models::Storage Storage model
|
|
17
|
+
# @see Pvectl::Formatters::Table Table formatter
|
|
18
|
+
#
|
|
19
|
+
class Storage < Base
|
|
20
|
+
# Returns column headers for standard table output.
|
|
21
|
+
#
|
|
22
|
+
# @return [Array<String>] column headers
|
|
23
|
+
def columns
|
|
24
|
+
%w[NAME TYPE STATUS USED TOTAL %USED NODE]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Returns additional column headers for wide output.
|
|
28
|
+
#
|
|
29
|
+
# @return [Array<String>] extra column headers
|
|
30
|
+
def extra_columns
|
|
31
|
+
%w[CONTENT SHARED]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Converts Storage model to table row values.
|
|
35
|
+
#
|
|
36
|
+
# @param model [Models::Storage] Storage model
|
|
37
|
+
# @param context [Hash] optional context
|
|
38
|
+
# @return [Array<String>] row values matching columns order
|
|
39
|
+
def to_row(model, **_context)
|
|
40
|
+
@storage = model
|
|
41
|
+
[
|
|
42
|
+
storage.name,
|
|
43
|
+
type_display,
|
|
44
|
+
status_display,
|
|
45
|
+
used_display,
|
|
46
|
+
total_display,
|
|
47
|
+
usage_display,
|
|
48
|
+
node_display
|
|
49
|
+
]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns additional values for wide output.
|
|
53
|
+
#
|
|
54
|
+
# @param model [Models::Storage] Storage model
|
|
55
|
+
# @param context [Hash] optional context
|
|
56
|
+
# @return [Array<String>] extra values matching extra_columns order
|
|
57
|
+
def extra_values(model, **_context)
|
|
58
|
+
@storage = model
|
|
59
|
+
[
|
|
60
|
+
content_display,
|
|
61
|
+
shared_display
|
|
62
|
+
]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Converts Storage model to hash for JSON/YAML output.
|
|
66
|
+
#
|
|
67
|
+
# Returns a structured hash with nested objects for complex data.
|
|
68
|
+
#
|
|
69
|
+
# @param model [Models::Storage] Storage model
|
|
70
|
+
# @return [Hash] hash representation with string keys
|
|
71
|
+
def to_hash(model)
|
|
72
|
+
@storage = model
|
|
73
|
+
{
|
|
74
|
+
"name" => storage.name,
|
|
75
|
+
"type" => storage.plugintype,
|
|
76
|
+
"status" => storage.status,
|
|
77
|
+
"node" => storage.node,
|
|
78
|
+
"shared" => storage.shared?,
|
|
79
|
+
"content" => storage.content,
|
|
80
|
+
"disk" => {
|
|
81
|
+
"used_bytes" => storage.disk,
|
|
82
|
+
"total_bytes" => storage.maxdisk,
|
|
83
|
+
"used_gb" => disk_used_gb,
|
|
84
|
+
"total_gb" => disk_total_gb,
|
|
85
|
+
"usage_percent" => usage_percent
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Converts Storage model to description format for describe command.
|
|
91
|
+
#
|
|
92
|
+
# Returns a structured Hash with sections for kubectl-style vertical output.
|
|
93
|
+
# Nested Hashes create indented subsections.
|
|
94
|
+
# Arrays of Hashes render as inline tables.
|
|
95
|
+
#
|
|
96
|
+
# @param model [Models::Storage] Storage model with describe details
|
|
97
|
+
# @return [Hash] structured hash for describe formatter
|
|
98
|
+
def to_description(model)
|
|
99
|
+
@storage = model
|
|
100
|
+
|
|
101
|
+
{
|
|
102
|
+
"Name" => storage.name,
|
|
103
|
+
"Type" => type_display,
|
|
104
|
+
"Status" => status_display,
|
|
105
|
+
"Shared" => shared_display,
|
|
106
|
+
"Nodes" => nodes_display,
|
|
107
|
+
|
|
108
|
+
"Capacity" => build_capacity_section,
|
|
109
|
+
|
|
110
|
+
"Configuration" => build_configuration_section,
|
|
111
|
+
|
|
112
|
+
"Content Summary" => format_content_summary,
|
|
113
|
+
|
|
114
|
+
"Backup Retention" => format_backup_retention
|
|
115
|
+
}
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# -----------------------------------------------------------------
|
|
119
|
+
# Display Methods (moved from Models::Storage)
|
|
120
|
+
# -----------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
# Returns storage type for display.
|
|
123
|
+
#
|
|
124
|
+
# @return [String] storage plugin type or "-"
|
|
125
|
+
def type_display
|
|
126
|
+
storage.plugintype || "-"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Returns status for display.
|
|
130
|
+
# Maps "available" to "active" for consistency with kubectl style.
|
|
131
|
+
#
|
|
132
|
+
# @return [String] status (active, inactive)
|
|
133
|
+
def status_display
|
|
134
|
+
storage.active? ? "active" : "inactive"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Returns node display.
|
|
138
|
+
# Shows "-" for shared storage (available on multiple nodes).
|
|
139
|
+
#
|
|
140
|
+
# @return [String] node name or "-" for shared storage
|
|
141
|
+
def node_display
|
|
142
|
+
storage.shared? ? "-" : (storage.node || "-")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Returns disk used in GB.
|
|
146
|
+
#
|
|
147
|
+
# @return [Float, nil] disk used in GB, or nil if unavailable
|
|
148
|
+
def disk_used_gb
|
|
149
|
+
return nil if storage.disk.nil?
|
|
150
|
+
|
|
151
|
+
(storage.disk.to_f / 1024 / 1024 / 1024).round(1)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Returns total disk in GB.
|
|
155
|
+
#
|
|
156
|
+
# @return [Float, nil] total disk in GB, or nil if unavailable
|
|
157
|
+
def disk_total_gb
|
|
158
|
+
return nil if storage.maxdisk.nil?
|
|
159
|
+
|
|
160
|
+
(storage.maxdisk.to_f / 1024 / 1024 / 1024).round(1)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Returns storage usage percentage.
|
|
164
|
+
#
|
|
165
|
+
# @return [Integer, nil] usage percentage (0-100), or nil if unavailable
|
|
166
|
+
def usage_percent
|
|
167
|
+
return nil if storage.maxdisk.nil? || storage.maxdisk.zero? || storage.disk.nil?
|
|
168
|
+
|
|
169
|
+
((storage.disk.to_f / storage.maxdisk) * 100).round
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Returns available bytes in GB.
|
|
173
|
+
#
|
|
174
|
+
# @return [Float, nil] available bytes in GB, or nil if unavailable
|
|
175
|
+
def avail_gb
|
|
176
|
+
return nil if storage.avail.nil?
|
|
177
|
+
|
|
178
|
+
(storage.avail.to_f / 1024 / 1024 / 1024).round(1)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Returns available storage formatted with appropriate unit (GB or TB).
|
|
182
|
+
#
|
|
183
|
+
# @return [String] formatted available storage (e.g., "55 GB" or "2.0 TB") or "-"
|
|
184
|
+
def avail_display
|
|
185
|
+
return "-" unless storage.active? && avail_gb
|
|
186
|
+
|
|
187
|
+
format_size(avail_gb)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Returns used storage formatted with appropriate unit (GB or TB).
|
|
191
|
+
#
|
|
192
|
+
# @return [String] formatted used storage (e.g., "45 GB" or "1.2 TB") or "-"
|
|
193
|
+
def used_display
|
|
194
|
+
return "-" unless storage.active? && disk_used_gb
|
|
195
|
+
|
|
196
|
+
format_size(disk_used_gb)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Returns total storage formatted with appropriate unit (GB or TB).
|
|
200
|
+
#
|
|
201
|
+
# @return [String] formatted total storage (e.g., "100 GB" or "2.0 TB") or "-"
|
|
202
|
+
def total_display
|
|
203
|
+
return "-" if disk_total_gb.nil?
|
|
204
|
+
|
|
205
|
+
format_size(disk_total_gb)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Returns usage percentage for display.
|
|
209
|
+
#
|
|
210
|
+
# @return [String] percentage (e.g., "45%") or "-" if unavailable
|
|
211
|
+
def usage_display
|
|
212
|
+
return "-" unless storage.active? && usage_percent
|
|
213
|
+
|
|
214
|
+
"#{usage_percent}%"
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Returns content types for display.
|
|
218
|
+
#
|
|
219
|
+
# @return [String] comma-separated content types or "-"
|
|
220
|
+
def content_display
|
|
221
|
+
storage.content.nil? || storage.content.empty? ? "-" : storage.content
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Returns shared status for display.
|
|
225
|
+
#
|
|
226
|
+
# @return [String] "yes" or "no"
|
|
227
|
+
def shared_display
|
|
228
|
+
storage.shared? ? "yes" : "no"
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
private
|
|
232
|
+
|
|
233
|
+
# @return [Models::Storage] the current storage being presented
|
|
234
|
+
attr_reader :storage
|
|
235
|
+
|
|
236
|
+
# Formats size with appropriate unit (GB or TB).
|
|
237
|
+
#
|
|
238
|
+
# @param gb [Float] size in GB
|
|
239
|
+
# @return [String] formatted size
|
|
240
|
+
def format_size(gb)
|
|
241
|
+
if gb >= 1024
|
|
242
|
+
"#{(gb / 1024).round(1)} TB"
|
|
243
|
+
else
|
|
244
|
+
"#{gb.round(0).to_i} GB"
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# -----------------------------------------------------------------
|
|
249
|
+
# Helper methods for to_description
|
|
250
|
+
# -----------------------------------------------------------------
|
|
251
|
+
|
|
252
|
+
# Returns nodes display for describe output.
|
|
253
|
+
# Shows "all" if nodes_allowed is nil (available on all nodes).
|
|
254
|
+
#
|
|
255
|
+
# @return [String] nodes list or "all"
|
|
256
|
+
def nodes_display
|
|
257
|
+
storage.nodes_allowed.nil? ? "all" : storage.nodes_allowed
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Builds the capacity section for describe output.
|
|
261
|
+
#
|
|
262
|
+
# @return [Hash] capacity metrics
|
|
263
|
+
def build_capacity_section
|
|
264
|
+
{
|
|
265
|
+
"Total" => total_display,
|
|
266
|
+
"Used" => used_display,
|
|
267
|
+
"Available" => avail_display,
|
|
268
|
+
"Usage" => usage_display
|
|
269
|
+
}
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Builds the configuration section for describe output.
|
|
273
|
+
# Includes type-specific configuration fields.
|
|
274
|
+
#
|
|
275
|
+
# @return [Hash, String] configuration fields or "-" if empty
|
|
276
|
+
def build_configuration_section
|
|
277
|
+
config = {}
|
|
278
|
+
config["Path"] = storage.path if storage.path
|
|
279
|
+
config["Server"] = storage.server if storage.server
|
|
280
|
+
config["Export"] = storage.export if storage.export
|
|
281
|
+
config["Volume Group"] = storage.vgname if storage.vgname
|
|
282
|
+
config["Thin Pool"] = storage.thinpool if storage.thinpool
|
|
283
|
+
config["Pool"] = storage.pool if storage.pool
|
|
284
|
+
config["Content Types"] = storage.content if storage.content
|
|
285
|
+
config.empty? ? "-" : config
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Formats content summary from volumes list.
|
|
289
|
+
# Groups volumes by type and calculates counts and sizes.
|
|
290
|
+
#
|
|
291
|
+
# @return [Array<Hash>, String] formatted table data or "-" if no volumes
|
|
292
|
+
def format_content_summary
|
|
293
|
+
return "-" if storage.volumes.nil? || storage.volumes.empty?
|
|
294
|
+
|
|
295
|
+
# Group volumes by content type
|
|
296
|
+
grouped = storage.volumes.group_by { |v| v[:content] || v["content"] }
|
|
297
|
+
|
|
298
|
+
grouped.map do |content_type, volumes|
|
|
299
|
+
total_size = volumes.sum { |v| v[:size] || v["size"] || 0 }
|
|
300
|
+
size_gb = (total_size.to_f / 1024 / 1024 / 1024).round(1)
|
|
301
|
+
{
|
|
302
|
+
"TYPE" => content_type || "-",
|
|
303
|
+
"COUNT" => volumes.size.to_s,
|
|
304
|
+
"SIZE" => format_size(size_gb)
|
|
305
|
+
}
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Formats backup retention policy for describe output.
|
|
310
|
+
#
|
|
311
|
+
# @return [Hash, String] retention settings or "-" if not configured
|
|
312
|
+
def format_backup_retention
|
|
313
|
+
return "-" if storage.prune_backups.nil?
|
|
314
|
+
|
|
315
|
+
retention = {}
|
|
316
|
+
prune = storage.prune_backups
|
|
317
|
+
|
|
318
|
+
# Handle both string and symbol keys
|
|
319
|
+
retention["Keep Last"] = prune[:"keep-last"] || prune["keep-last"] if prune[:"keep-last"] || prune["keep-last"]
|
|
320
|
+
retention["Keep Daily"] = prune[:"keep-daily"] || prune["keep-daily"] if prune[:"keep-daily"] || prune["keep-daily"]
|
|
321
|
+
retention["Keep Weekly"] = prune[:"keep-weekly"] || prune["keep-weekly"] if prune[:"keep-weekly"] || prune["keep-weekly"]
|
|
322
|
+
retention["Keep Monthly"] = prune[:"keep-monthly"] || prune["keep-monthly"] if prune[:"keep-monthly"] || prune["keep-monthly"]
|
|
323
|
+
retention["Keep Yearly"] = prune[:"keep-yearly"] || prune["keep-yearly"] if prune[:"keep-yearly"] || prune["keep-yearly"]
|
|
324
|
+
|
|
325
|
+
retention.empty? ? "-" : retention
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for Proxmox subscription records.
|
|
6
|
+
#
|
|
7
|
+
# Default table view masks the license key to avoid leaking it in shared
|
|
8
|
+
# screenshots; the full key is only shown via `-o wide`, `-o json`, or
|
|
9
|
+
# `-o yaml` so revealing it is an explicit user choice.
|
|
10
|
+
#
|
|
11
|
+
# @see Pvectl::Models::Subscription
|
|
12
|
+
#
|
|
13
|
+
class Subscription < Base
|
|
14
|
+
# @return [Array<String>] standard column headers
|
|
15
|
+
def columns
|
|
16
|
+
%w[NODE LEVEL STATUS NEXTDUEDATE KEY]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [Array<String>] extra column headers for wide output
|
|
20
|
+
def extra_columns
|
|
21
|
+
%w[PRODUCT REGDATE SERVERID]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param model [Models::Subscription]
|
|
25
|
+
# @return [Array<String>]
|
|
26
|
+
def to_row(model, **_context)
|
|
27
|
+
@subscription = model
|
|
28
|
+
[
|
|
29
|
+
node_display,
|
|
30
|
+
level_display,
|
|
31
|
+
status_display,
|
|
32
|
+
nextduedate_display,
|
|
33
|
+
masked_key
|
|
34
|
+
]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @param model [Models::Subscription]
|
|
38
|
+
# @return [Array<String>]
|
|
39
|
+
def extra_values(model, **_context)
|
|
40
|
+
@subscription = model
|
|
41
|
+
[
|
|
42
|
+
product_display,
|
|
43
|
+
regdate_display,
|
|
44
|
+
serverid_display
|
|
45
|
+
]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Wide row exposes the full key (after PRODUCT/REGDATE/SERVERID extras).
|
|
49
|
+
# We replace the masked KEY column with the full one to make `-o wide`
|
|
50
|
+
# useful for copying the license out without re-running with `-o json`.
|
|
51
|
+
#
|
|
52
|
+
# @param model [Models::Subscription]
|
|
53
|
+
# @return [Array<String>]
|
|
54
|
+
def to_wide_row(model, **context)
|
|
55
|
+
row = to_row(model, **context).dup
|
|
56
|
+
row[columns.index("KEY")] = full_key_display
|
|
57
|
+
row + extra_values(model, **context)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Hash representation for JSON/YAML output. Includes the full key —
|
|
61
|
+
# JSON/YAML output is opt-in via `-o`, so the user already asked for
|
|
62
|
+
# the raw data.
|
|
63
|
+
#
|
|
64
|
+
# @param model [Models::Subscription]
|
|
65
|
+
# @return [Hash{String => Object}]
|
|
66
|
+
def to_hash(model)
|
|
67
|
+
@subscription = model
|
|
68
|
+
{
|
|
69
|
+
"node" => subscription.node,
|
|
70
|
+
"status" => subscription.status,
|
|
71
|
+
"level" => subscription.level,
|
|
72
|
+
"product" => subscription.productname,
|
|
73
|
+
"key" => subscription.key,
|
|
74
|
+
"next_due_date" => subscription.nextduedate,
|
|
75
|
+
"registration_date" => subscription.regdate,
|
|
76
|
+
"checktime" => subscription.checktime,
|
|
77
|
+
"server_id" => subscription.serverid,
|
|
78
|
+
"sockets" => subscription.sockets,
|
|
79
|
+
"url" => subscription.url,
|
|
80
|
+
"message" => subscription.message
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Description-style hash for `pvectl describe subscription` future use.
|
|
85
|
+
#
|
|
86
|
+
# @param model [Models::Subscription]
|
|
87
|
+
# @return [Hash{String => Object}]
|
|
88
|
+
def to_description(model)
|
|
89
|
+
@subscription = model
|
|
90
|
+
{
|
|
91
|
+
"Node" => node_display,
|
|
92
|
+
"Status" => status_display,
|
|
93
|
+
"Level" => level_display,
|
|
94
|
+
"Product" => product_display,
|
|
95
|
+
"Key" => masked_key,
|
|
96
|
+
"Next Due Date" => nextduedate_display,
|
|
97
|
+
"Registration Date" => regdate_display,
|
|
98
|
+
"Server ID" => serverid_display,
|
|
99
|
+
"Sockets" => sockets_display,
|
|
100
|
+
"Last Check" => checktime_display,
|
|
101
|
+
"Message" => message_display
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @return [String]
|
|
106
|
+
def node_display
|
|
107
|
+
subscription.node || "-"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# @return [String]
|
|
111
|
+
def status_display
|
|
112
|
+
subscription.status || "-"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @return [String]
|
|
116
|
+
def level_display
|
|
117
|
+
subscription.level || "-"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# @return [String]
|
|
121
|
+
def product_display
|
|
122
|
+
subscription.productname || "-"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# @return [String]
|
|
126
|
+
def regdate_display
|
|
127
|
+
subscription.regdate || "-"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# @return [String]
|
|
131
|
+
def serverid_display
|
|
132
|
+
subscription.serverid || "-"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# @return [String]
|
|
136
|
+
def nextduedate_display
|
|
137
|
+
subscription.nextduedate || "-"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @return [String]
|
|
141
|
+
def sockets_display
|
|
142
|
+
subscription.sockets ? subscription.sockets.to_s : "-"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @return [String]
|
|
146
|
+
def message_display
|
|
147
|
+
subscription.message || "-"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @return [String] formatted timestamp or "-"
|
|
151
|
+
def checktime_display
|
|
152
|
+
return "-" if subscription.checktime.nil? || subscription.checktime.to_i.zero?
|
|
153
|
+
|
|
154
|
+
Time.at(subscription.checktime.to_i).utc.strftime("%Y-%m-%d %H:%M:%S UTC")
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Returns the license key with the middle masked.
|
|
158
|
+
#
|
|
159
|
+
# Proxmox keys look like `pveXp-1234567890` (16 chars). We preserve the
|
|
160
|
+
# 6-char prefix (`pveXp-`) and the last 4 chars, masking the rest.
|
|
161
|
+
# Returns "-" when no key is set (community node).
|
|
162
|
+
#
|
|
163
|
+
# @return [String]
|
|
164
|
+
def masked_key
|
|
165
|
+
key = subscription.key
|
|
166
|
+
return "-" if key.nil? || key.empty?
|
|
167
|
+
|
|
168
|
+
if key.length <= 6
|
|
169
|
+
key
|
|
170
|
+
elsif key.length <= 10
|
|
171
|
+
"#{key[0, 4]}***#{key[-2..]}"
|
|
172
|
+
else
|
|
173
|
+
"#{key[0, 6]}****#{key[-4..]}"
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# @return [String] full key or "-"
|
|
178
|
+
def full_key_display
|
|
179
|
+
key = subscription.key
|
|
180
|
+
key.nil? || key.empty? ? "-" : key
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
private
|
|
184
|
+
|
|
185
|
+
# @return [Models::Subscription]
|
|
186
|
+
attr_reader :subscription
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for syslog entries (pvectl logs node).
|
|
6
|
+
class SyslogEntry < Base
|
|
7
|
+
def columns
|
|
8
|
+
%w[LINE TEXT]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_row(model, **_context)
|
|
12
|
+
[model.n.to_s, model.t || ""]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_hash(model)
|
|
16
|
+
{ "line" => model.n, "text" => model.t }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for task list entries (pvectl logs vm/ct).
|
|
6
|
+
class TaskEntry < Base
|
|
7
|
+
def columns
|
|
8
|
+
%w[STARTTIME TYPE STATUS USER DURATION NODE]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def extra_columns
|
|
12
|
+
%w[UPID ENDTIME ID PID]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_row(model, **_context)
|
|
16
|
+
[
|
|
17
|
+
format_time(model.starttime),
|
|
18
|
+
model.type || "-",
|
|
19
|
+
model.exitstatus || model.status || "-",
|
|
20
|
+
model.user || "-",
|
|
21
|
+
format_duration(model.duration),
|
|
22
|
+
model.node || "-"
|
|
23
|
+
]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def extra_values(model, **_context)
|
|
27
|
+
[
|
|
28
|
+
model.upid || "-",
|
|
29
|
+
format_time(model.endtime),
|
|
30
|
+
model.id || "-",
|
|
31
|
+
model.pid&.to_s || "-"
|
|
32
|
+
]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_hash(model)
|
|
36
|
+
{
|
|
37
|
+
"starttime" => model.starttime,
|
|
38
|
+
"endtime" => model.endtime,
|
|
39
|
+
"type" => model.type,
|
|
40
|
+
"status" => model.status,
|
|
41
|
+
"exitstatus" => model.exitstatus,
|
|
42
|
+
"user" => model.user,
|
|
43
|
+
"duration" => model.duration,
|
|
44
|
+
"node" => model.node,
|
|
45
|
+
"id" => model.id,
|
|
46
|
+
"upid" => model.upid
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def format_time(timestamp)
|
|
53
|
+
return "-" if timestamp.nil?
|
|
54
|
+
Time.at(timestamp).strftime("%Y-%m-%d %H:%M:%S")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def format_duration(seconds)
|
|
58
|
+
return "-" if seconds.nil?
|
|
59
|
+
if seconds < 60
|
|
60
|
+
"#{seconds}s"
|
|
61
|
+
elsif seconds < 3600
|
|
62
|
+
"#{seconds / 60}m#{seconds % 60}s"
|
|
63
|
+
else
|
|
64
|
+
"#{seconds / 3600}h#{(seconds % 3600) / 60}m"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for task log lines (pvectl logs task UPID).
|
|
6
|
+
class TaskLogLine < Base
|
|
7
|
+
def columns
|
|
8
|
+
%w[LINE TEXT]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_row(model, **_context)
|
|
12
|
+
[model.n.to_s, model.t || ""]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_hash(model)
|
|
16
|
+
{ "line" => model.n, "text" => model.t }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for template listing (mixed VM and Container templates).
|
|
6
|
+
#
|
|
7
|
+
# Handles both Models::Vm and Models::Container via duck typing.
|
|
8
|
+
# Both models share: vmid, name, type, node, maxdisk, tags.
|
|
9
|
+
#
|
|
10
|
+
# @example Using with formatter
|
|
11
|
+
# presenter = Template.new
|
|
12
|
+
# formatter = Formatters::Table.new
|
|
13
|
+
# output = formatter.format(templates, presenter)
|
|
14
|
+
#
|
|
15
|
+
# @see Pvectl::Models::Vm VM model
|
|
16
|
+
# @see Pvectl::Models::Container Container model
|
|
17
|
+
#
|
|
18
|
+
class Template < Base
|
|
19
|
+
# Returns column headers for template listing.
|
|
20
|
+
#
|
|
21
|
+
# @return [Array<String>] column names
|
|
22
|
+
def columns
|
|
23
|
+
%w[ID NAME TYPE NODE DISK TAGS]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Converts a template model to table row.
|
|
27
|
+
#
|
|
28
|
+
# @param model [Models::Vm, Models::Container] template model
|
|
29
|
+
# @param context [Hash] unused
|
|
30
|
+
# @return [Array<String>] row values
|
|
31
|
+
def to_row(model, **_context)
|
|
32
|
+
[
|
|
33
|
+
model.vmid.to_s,
|
|
34
|
+
model.name || "-",
|
|
35
|
+
model.type || "-",
|
|
36
|
+
model.node || "-",
|
|
37
|
+
format_disk(model.maxdisk),
|
|
38
|
+
model.tags || "-"
|
|
39
|
+
]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Converts a template model to hash for JSON/YAML.
|
|
43
|
+
#
|
|
44
|
+
# @param model [Models::Vm, Models::Container] template model
|
|
45
|
+
# @return [Hash] hash representation
|
|
46
|
+
def to_hash(model)
|
|
47
|
+
{
|
|
48
|
+
"id" => model.vmid,
|
|
49
|
+
"name" => model.name,
|
|
50
|
+
"type" => model.type,
|
|
51
|
+
"node" => model.node,
|
|
52
|
+
"disk" => model.maxdisk,
|
|
53
|
+
"tags" => model.tags
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# Formats disk size in human-readable format.
|
|
60
|
+
#
|
|
61
|
+
# @param bytes [Integer, nil] disk size in bytes
|
|
62
|
+
# @return [String] formatted size
|
|
63
|
+
def format_disk(bytes)
|
|
64
|
+
return "-" unless bytes && bytes.positive?
|
|
65
|
+
|
|
66
|
+
if bytes >= 1_073_741_824
|
|
67
|
+
"#{(bytes.to_f / 1_073_741_824).round(1)}G"
|
|
68
|
+
elsif bytes >= 1_048_576
|
|
69
|
+
"#{(bytes.to_f / 1_048_576).round(1)}M"
|
|
70
|
+
else
|
|
71
|
+
"#{bytes}B"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|