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,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for APT packages (pending updates and installed versions).
|
|
6
|
+
#
|
|
7
|
+
# Standard columns highlight the upgrade path; wide columns add metadata
|
|
8
|
+
# useful when triaging updates.
|
|
9
|
+
#
|
|
10
|
+
# @example Using with formatter
|
|
11
|
+
# presenter = AptPackage.new
|
|
12
|
+
# formatter = Formatters::Table.new
|
|
13
|
+
# output = formatter.format(packages, presenter)
|
|
14
|
+
#
|
|
15
|
+
# @see Pvectl::Models::AptPackage AptPackage model
|
|
16
|
+
#
|
|
17
|
+
class AptPackage < Base
|
|
18
|
+
# Returns column headers for standard table output.
|
|
19
|
+
#
|
|
20
|
+
# @return [Array<String>] column headers
|
|
21
|
+
def columns
|
|
22
|
+
%w[NODE PACKAGE CURRENT AVAILABLE ORIGIN]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns additional column headers for wide output.
|
|
26
|
+
#
|
|
27
|
+
# @return [Array<String>] extra column headers
|
|
28
|
+
def extra_columns
|
|
29
|
+
%w[ARCH SECTION PRIORITY DESCRIPTION]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Converts AptPackage model to table row values.
|
|
33
|
+
#
|
|
34
|
+
# @param model [Models::AptPackage] package model
|
|
35
|
+
# @param context [Hash] optional context
|
|
36
|
+
# @return [Array<String>] row values matching columns order
|
|
37
|
+
def to_row(model, **_context)
|
|
38
|
+
[
|
|
39
|
+
model.node || "-",
|
|
40
|
+
model.package || "-",
|
|
41
|
+
model.old_version || "-",
|
|
42
|
+
model.version || "-",
|
|
43
|
+
model.origin || "-"
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns additional values for wide output.
|
|
48
|
+
#
|
|
49
|
+
# @param model [Models::AptPackage] package model
|
|
50
|
+
# @param context [Hash] optional context
|
|
51
|
+
# @return [Array<String>] extra values matching extra_columns order
|
|
52
|
+
def extra_values(model, **_context)
|
|
53
|
+
[
|
|
54
|
+
model.arch || "-",
|
|
55
|
+
model.section || "-",
|
|
56
|
+
model.priority || "-",
|
|
57
|
+
truncate(model.description, 60)
|
|
58
|
+
]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Converts AptPackage model to hash for JSON/YAML output.
|
|
62
|
+
#
|
|
63
|
+
# @param model [Models::AptPackage] package model
|
|
64
|
+
# @return [Hash] hash representation with string keys
|
|
65
|
+
def to_hash(model)
|
|
66
|
+
{
|
|
67
|
+
"node" => model.node,
|
|
68
|
+
"package" => model.package,
|
|
69
|
+
"title" => model.title,
|
|
70
|
+
"current_version" => model.old_version,
|
|
71
|
+
"available_version" => model.version,
|
|
72
|
+
"origin" => model.origin,
|
|
73
|
+
"arch" => model.arch,
|
|
74
|
+
"section" => model.section,
|
|
75
|
+
"priority" => model.priority,
|
|
76
|
+
"description" => model.description,
|
|
77
|
+
"notify_status" => model.notify_status,
|
|
78
|
+
"current_state" => model.current_state,
|
|
79
|
+
"manager_version" => model.manager_version,
|
|
80
|
+
"running_kernel" => model.running_kernel
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Truncates text to fit in a column.
|
|
87
|
+
#
|
|
88
|
+
# @param text [String, nil] text to truncate
|
|
89
|
+
# @param length [Integer] maximum length
|
|
90
|
+
# @return [String] truncated text or "-"
|
|
91
|
+
def truncate(text, length)
|
|
92
|
+
return "-" if text.nil? || text.empty?
|
|
93
|
+
return text if text.length <= length
|
|
94
|
+
|
|
95
|
+
"#{text[0, length - 1]}…"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for Backup models.
|
|
6
|
+
#
|
|
7
|
+
# Formats backups for table, wide, JSON, and YAML output.
|
|
8
|
+
# Standard columns: VMID, TYPE, CREATED, SIZE, STORAGE, PROTECTED
|
|
9
|
+
# Wide columns add: FORMAT, NOTES, VOLID
|
|
10
|
+
#
|
|
11
|
+
# @example Using with formatter
|
|
12
|
+
# presenter = Backup.new
|
|
13
|
+
# formatter = Formatters::Table.new
|
|
14
|
+
# output = formatter.format(backups, presenter)
|
|
15
|
+
#
|
|
16
|
+
# @see Pvectl::Models::Backup Backup model
|
|
17
|
+
# @see Pvectl::Formatters::Table Table formatter
|
|
18
|
+
#
|
|
19
|
+
class Backup < Base
|
|
20
|
+
# Returns column headers for standard table output.
|
|
21
|
+
#
|
|
22
|
+
# @return [Array<String>] column headers
|
|
23
|
+
def columns
|
|
24
|
+
%w[VMID TYPE CREATED SIZE STORAGE PROTECTED]
|
|
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[FORMAT NOTES VOLID]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Converts Backup model to table row values.
|
|
35
|
+
#
|
|
36
|
+
# @param model [Models::Backup] Backup model
|
|
37
|
+
# @param context [Hash] optional context
|
|
38
|
+
# @return [Array] row values matching columns order
|
|
39
|
+
def to_row(model, **_context)
|
|
40
|
+
[
|
|
41
|
+
model.vmid,
|
|
42
|
+
format_type(model.resource_type),
|
|
43
|
+
format_time(model.created_at),
|
|
44
|
+
model.human_size,
|
|
45
|
+
model.storage,
|
|
46
|
+
format_protected(model.protected?)
|
|
47
|
+
]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns additional values for wide output.
|
|
51
|
+
#
|
|
52
|
+
# @param model [Models::Backup] Backup model
|
|
53
|
+
# @param context [Hash] optional context
|
|
54
|
+
# @return [Array] extra values matching extra_columns order
|
|
55
|
+
def extra_values(model, **_context)
|
|
56
|
+
[
|
|
57
|
+
model.format,
|
|
58
|
+
truncate(model.notes, 30),
|
|
59
|
+
model.volid
|
|
60
|
+
]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Converts Backup model to hash for JSON/YAML output.
|
|
64
|
+
#
|
|
65
|
+
# @param model [Models::Backup] Backup model
|
|
66
|
+
# @return [Hash] hash representation with string keys
|
|
67
|
+
def to_hash(model)
|
|
68
|
+
{
|
|
69
|
+
"vmid" => model.vmid,
|
|
70
|
+
"type" => format_type(model.resource_type),
|
|
71
|
+
"volid" => model.volid,
|
|
72
|
+
"storage" => model.storage,
|
|
73
|
+
"node" => model.node,
|
|
74
|
+
"size" => model.size,
|
|
75
|
+
"size_human" => model.human_size,
|
|
76
|
+
"created_at" => model.created_at&.iso8601,
|
|
77
|
+
"format" => model.format,
|
|
78
|
+
"notes" => model.notes,
|
|
79
|
+
"protected" => model.protected?
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
# Formats resource type for display.
|
|
86
|
+
#
|
|
87
|
+
# @param resource_type [Symbol, nil] :qemu or :lxc
|
|
88
|
+
# @return [String] formatted type
|
|
89
|
+
def format_type(resource_type)
|
|
90
|
+
case resource_type
|
|
91
|
+
when :qemu then "qemu"
|
|
92
|
+
when :lxc then "lxc"
|
|
93
|
+
else "-"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Formats time for display.
|
|
98
|
+
#
|
|
99
|
+
# @param time [Time, nil] time to format
|
|
100
|
+
# @return [String] formatted time or "-" if nil
|
|
101
|
+
def format_time(time)
|
|
102
|
+
return "-" if time.nil?
|
|
103
|
+
|
|
104
|
+
time.strftime("%Y-%m-%d %H:%M:%S")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Formats protected status for display.
|
|
108
|
+
#
|
|
109
|
+
# @param protected [Boolean] protection status
|
|
110
|
+
# @return [String] "yes" or "no"
|
|
111
|
+
def format_protected(protected_status)
|
|
112
|
+
protected_status ? "yes" : "no"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Truncates text to specified length.
|
|
116
|
+
#
|
|
117
|
+
# @param text [String, nil] text to truncate
|
|
118
|
+
# @param max_length [Integer] maximum length
|
|
119
|
+
# @return [String, nil] truncated text or nil
|
|
120
|
+
def truncate(text, max_length)
|
|
121
|
+
return nil if text.nil?
|
|
122
|
+
return text if text.length <= max_length
|
|
123
|
+
|
|
124
|
+
"#{text[0, max_length - 3]}..."
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Abstract base class for resource presenters.
|
|
6
|
+
#
|
|
7
|
+
# Presenters define how models are displayed in different formats.
|
|
8
|
+
# Each resource type (VM, Container, Node, etc.) has its own presenter.
|
|
9
|
+
#
|
|
10
|
+
# @abstract Subclass and implement {#columns}, {#to_row}, and {#to_hash}.
|
|
11
|
+
#
|
|
12
|
+
# @example Implementing a resource presenter
|
|
13
|
+
# class VmPresenter < Base
|
|
14
|
+
# def columns
|
|
15
|
+
# ["NAME", "STATUS", "NODE"]
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# def extra_columns
|
|
19
|
+
# ["MEMORY", "CPU"]
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# def to_row(model, **context)
|
|
23
|
+
# [model.name, model.status, model.node]
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# def extra_values(model, **context)
|
|
27
|
+
# [model.memory, model.cpu]
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# def to_hash(model)
|
|
31
|
+
# { "name" => model.name, "status" => model.status, "node" => model.node }
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# @see Pvectl::Formatters::OutputHelper for using presenters with formatters
|
|
36
|
+
#
|
|
37
|
+
class Base
|
|
38
|
+
# Returns column headers for table format.
|
|
39
|
+
#
|
|
40
|
+
# @return [Array<String>] column names (uppercase, e.g., ["NAME", "STATUS"])
|
|
41
|
+
# @raise [NotImplementedError] if not implemented by subclass
|
|
42
|
+
def columns
|
|
43
|
+
raise NotImplementedError, "#{self.class}#columns must be implemented"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns extended column headers for wide format.
|
|
47
|
+
# By default, appends extra_columns to columns.
|
|
48
|
+
#
|
|
49
|
+
# @return [Array<String>] column names (normal + extra)
|
|
50
|
+
def wide_columns
|
|
51
|
+
columns + extra_columns
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns additional columns for wide format.
|
|
55
|
+
# Override in subclass to add extra columns.
|
|
56
|
+
#
|
|
57
|
+
# @return [Array<String>] extra column names (empty by default)
|
|
58
|
+
def extra_columns
|
|
59
|
+
[]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Converts model to table row values.
|
|
63
|
+
#
|
|
64
|
+
# @param model [Object] domain model object
|
|
65
|
+
# @param context [Hash] optional context (e.g., current_context: "prod")
|
|
66
|
+
# @return [Array<String, nil>] row values matching columns order
|
|
67
|
+
# @raise [NotImplementedError] if not implemented by subclass
|
|
68
|
+
def to_row(model, **context)
|
|
69
|
+
raise NotImplementedError, "#{self.class}#to_row must be implemented"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Converts model to wide table row values.
|
|
73
|
+
# By default, appends extra_values to to_row.
|
|
74
|
+
#
|
|
75
|
+
# @param model [Object] domain model object
|
|
76
|
+
# @param context [Hash] optional context
|
|
77
|
+
# @return [Array<String, nil>] row values (normal + extra)
|
|
78
|
+
def to_wide_row(model, **context)
|
|
79
|
+
to_row(model, **context) + extra_values(model, **context)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Returns additional values for wide format.
|
|
83
|
+
# Override in subclass to add extra values.
|
|
84
|
+
#
|
|
85
|
+
# @param model [Object] domain model object
|
|
86
|
+
# @param context [Hash] optional context
|
|
87
|
+
# @return [Array<String, nil>] extra values (empty by default)
|
|
88
|
+
def extra_values(model, **context)
|
|
89
|
+
[]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Converts model to hash for JSON/YAML format.
|
|
93
|
+
#
|
|
94
|
+
# @param model [Object] domain model object
|
|
95
|
+
# @return [Hash] hash representation with string keys
|
|
96
|
+
# @raise [NotImplementedError] if not implemented by subclass
|
|
97
|
+
def to_hash(model)
|
|
98
|
+
raise NotImplementedError, "#{self.class}#to_hash must be implemented"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Converts model to description format (kubectl-style vertical layout).
|
|
102
|
+
# By default, delegates to to_hash. Override for custom describe output.
|
|
103
|
+
#
|
|
104
|
+
# @param model [Object] domain model object
|
|
105
|
+
# @return [Hash] hash representation (keys become labels)
|
|
106
|
+
def to_description(model)
|
|
107
|
+
to_hash(model)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Returns uptime in human-readable format.
|
|
111
|
+
# Delegates to resource.uptime. Override in subclasses with custom logic.
|
|
112
|
+
#
|
|
113
|
+
# @return [String] formatted uptime (e.g., "15d 3h") or "-"
|
|
114
|
+
def uptime_human
|
|
115
|
+
uptime = resource.uptime
|
|
116
|
+
return "-" if uptime.nil? || uptime.zero?
|
|
117
|
+
|
|
118
|
+
days = uptime / 86_400
|
|
119
|
+
hours = (uptime % 86_400) / 3600
|
|
120
|
+
minutes = (uptime % 3600) / 60
|
|
121
|
+
|
|
122
|
+
if days.positive?
|
|
123
|
+
"#{days}d #{hours}h"
|
|
124
|
+
elsif hours.positive?
|
|
125
|
+
"#{hours}h #{minutes}m"
|
|
126
|
+
else
|
|
127
|
+
"#{minutes}m"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Returns tags as array.
|
|
132
|
+
#
|
|
133
|
+
# @return [Array<String>] array of tags, or empty array if no tags
|
|
134
|
+
def tags_array
|
|
135
|
+
tags = resource.tags
|
|
136
|
+
return [] if tags.nil? || tags.empty?
|
|
137
|
+
|
|
138
|
+
tags.split(";").map(&:strip)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Returns tags as comma-separated string.
|
|
142
|
+
#
|
|
143
|
+
# @return [String] formatted tags (e.g., "prod, web") or "-" if no tags
|
|
144
|
+
def tags_display
|
|
145
|
+
arr = tags_array
|
|
146
|
+
arr.empty? ? "-" : arr.join(", ")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Returns template display string.
|
|
150
|
+
#
|
|
151
|
+
# @return [String] "yes" if template, "-" otherwise
|
|
152
|
+
def template_display
|
|
153
|
+
resource.template? ? "yes" : "-"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
private
|
|
157
|
+
|
|
158
|
+
# Returns the current resource model.
|
|
159
|
+
# Must be implemented by subclasses.
|
|
160
|
+
#
|
|
161
|
+
# @return [Object] current model
|
|
162
|
+
# @raise [NotImplementedError] if not implemented
|
|
163
|
+
def resource
|
|
164
|
+
raise NotImplementedError, "#{self.class}#resource must be implemented"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Formats task history for describe output.
|
|
168
|
+
#
|
|
169
|
+
# @param tasks [Array<Models::TaskEntry>, nil] recent tasks
|
|
170
|
+
# @return [Array<Hash>, String] table data or "No task history"
|
|
171
|
+
def format_task_history(tasks)
|
|
172
|
+
return "No task history" if tasks.nil? || tasks.empty?
|
|
173
|
+
|
|
174
|
+
tasks.map do |task|
|
|
175
|
+
start = task.starttime ? Time.at(task.starttime).strftime("%Y-%m-%d %H:%M:%S") : "-"
|
|
176
|
+
dur = task.duration ? "#{task.duration}s" : "-"
|
|
177
|
+
{
|
|
178
|
+
"TYPE" => task.type || "-",
|
|
179
|
+
"STATUS" => task.exitstatus || task.status || "-",
|
|
180
|
+
"DATE" => start,
|
|
181
|
+
"DURATION" => dur,
|
|
182
|
+
"USER" => task.user || "-"
|
|
183
|
+
}
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Formats Firewall section from dedicated API data.
|
|
188
|
+
#
|
|
189
|
+
# Shows firewall options, rules, aliases, and IP sets
|
|
190
|
+
# from the /firewall/ API endpoints. Shared by VM and CT presenters.
|
|
191
|
+
#
|
|
192
|
+
# @param firewall_data [Hash, nil] firewall data with :options, :rules, :aliases, :ipset
|
|
193
|
+
# @return [Hash, String] firewall info or "-" if no data
|
|
194
|
+
def format_firewall(firewall_data)
|
|
195
|
+
return "-" if firewall_data.nil? || firewall_data.empty?
|
|
196
|
+
|
|
197
|
+
options = firewall_data[:options]
|
|
198
|
+
options = {} unless options.is_a?(Hash)
|
|
199
|
+
aliases = firewall_data[:aliases]
|
|
200
|
+
aliases = [] unless aliases.is_a?(Array)
|
|
201
|
+
ipset = firewall_data[:ipset]
|
|
202
|
+
ipset = [] unless ipset.is_a?(Array)
|
|
203
|
+
|
|
204
|
+
result = {
|
|
205
|
+
"Enable" => options[:enable] == 1 ? "Yes" : "No",
|
|
206
|
+
"Input Policy" => (options[:policy_in] || "DROP").to_s,
|
|
207
|
+
"Output Policy" => (options[:policy_out] || "ACCEPT").to_s
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
# Optional options
|
|
211
|
+
result["DHCP"] = options[:dhcp] == 1 ? "Yes" : "No" if options.key?(:dhcp)
|
|
212
|
+
result["MAC Filter"] = options[:macfilter] == 1 ? "Yes" : "No" if options.key?(:macfilter)
|
|
213
|
+
result["IP Filter"] = options[:ipfilter] == 1 ? "Yes" : "No" if options.key?(:ipfilter)
|
|
214
|
+
result["NDP"] = options[:ndp] == 1 ? "Yes" : "No" if options.key?(:ndp)
|
|
215
|
+
result["Router Advertisement"] = options[:radv] == 1 ? "Yes" : "No" if options.key?(:radv)
|
|
216
|
+
result["Log Level In"] = options[:log_level_in].to_s if options[:log_level_in] && options[:log_level_in] != "nolog"
|
|
217
|
+
result["Log Level Out"] = options[:log_level_out].to_s if options[:log_level_out] && options[:log_level_out] != "nolog"
|
|
218
|
+
|
|
219
|
+
# Aliases table
|
|
220
|
+
if aliases.any?
|
|
221
|
+
result["Aliases"] = aliases.map do |a|
|
|
222
|
+
{ "NAME" => a[:name] || "-", "CIDR" => a[:cidr] || "-", "COMMENT" => a[:comment] || "-" }
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# IP Sets table
|
|
227
|
+
if ipset.any?
|
|
228
|
+
result["IP Sets"] = ipset.map do |s|
|
|
229
|
+
{ "NAME" => s[:name] || "-", "COMMENT" => s[:comment] || "-" }
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
result
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Formats Firewall Rules section as a standalone table.
|
|
237
|
+
#
|
|
238
|
+
# Renders firewall rules with the columns: ENABLED, TYPE, ACTION,
|
|
239
|
+
# PROTO, SOURCE, DEST, COMMENT. Used as a top-level describe section
|
|
240
|
+
# for VMs and containers. Empty or missing rules render as "-".
|
|
241
|
+
#
|
|
242
|
+
# @param firewall_data [Hash, nil] firewall data with :rules key
|
|
243
|
+
# @return [Array<Hash>, String] rules table or "-" when empty
|
|
244
|
+
def format_firewall_rules(firewall_data)
|
|
245
|
+
return "-" if firewall_data.nil? || firewall_data.empty?
|
|
246
|
+
|
|
247
|
+
rules = firewall_data[:rules]
|
|
248
|
+
rules = [] unless rules.is_a?(Array)
|
|
249
|
+
return "-" if rules.empty?
|
|
250
|
+
|
|
251
|
+
rules.sort_by { |r| r[:pos].to_i }.map do |rule|
|
|
252
|
+
{
|
|
253
|
+
"ENABLED" => rule[:enable] == 1 ? "yes" : "no",
|
|
254
|
+
"TYPE" => rule[:type]&.to_s&.upcase || "-",
|
|
255
|
+
"ACTION" => rule[:action] || "-",
|
|
256
|
+
"PROTO" => rule[:proto] || "-",
|
|
257
|
+
"SOURCE" => (rule[:source].nil? || rule[:source].to_s.empty?) ? "-" : rule[:source],
|
|
258
|
+
"DEST" => (rule[:dest].nil? || rule[:dest].to_s.empty?) ? "-" : rule[:dest],
|
|
259
|
+
"COMMENT" => (rule[:comment].nil? || rule[:comment].to_s.empty?) ? "-" : rule[:comment]
|
|
260
|
+
}
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# Formats bytes to human readable string.
|
|
265
|
+
#
|
|
266
|
+
# @param bytes [Integer, nil] bytes
|
|
267
|
+
# @return [String] formatted size
|
|
268
|
+
def format_bytes(bytes)
|
|
269
|
+
return "-" if bytes.nil? || bytes.zero?
|
|
270
|
+
|
|
271
|
+
if bytes >= 1024 * 1024 * 1024
|
|
272
|
+
"#{(bytes.to_f / 1024 / 1024 / 1024).round(1)} GiB"
|
|
273
|
+
elsif bytes >= 1024 * 1024
|
|
274
|
+
"#{(bytes.to_f / 1024 / 1024).round(1)} MiB"
|
|
275
|
+
elsif bytes >= 1024
|
|
276
|
+
"#{(bytes.to_f / 1024).round(1)} KiB"
|
|
277
|
+
else
|
|
278
|
+
"#{bytes} B"
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
# Presenter for node capabilities (QEMU CPU models, machine types).
|
|
6
|
+
#
|
|
7
|
+
# Each Capability becomes one row regardless of kind. The DETAILS
|
|
8
|
+
# column adapts to the kind: CPU rows show vendor (and the "custom"
|
|
9
|
+
# marker when applicable), machine rows show the underlying machine
|
|
10
|
+
# family (q35/i440fx).
|
|
11
|
+
#
|
|
12
|
+
# @example Using with formatter
|
|
13
|
+
# presenter = Capability.new
|
|
14
|
+
# formatter = Formatters::Table.new
|
|
15
|
+
# output = formatter.format(capabilities, presenter)
|
|
16
|
+
#
|
|
17
|
+
# @see Pvectl::Models::Capability
|
|
18
|
+
#
|
|
19
|
+
class Capability < Base
|
|
20
|
+
# Returns column headers for table output.
|
|
21
|
+
#
|
|
22
|
+
# @return [Array<String>] column headers
|
|
23
|
+
def columns
|
|
24
|
+
["NODE", "KIND", "NAME", "DETAILS"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Returns extra columns for wide output (machine version, custom flag).
|
|
28
|
+
#
|
|
29
|
+
# @return [Array<String>] extra columns
|
|
30
|
+
def extra_columns
|
|
31
|
+
["VERSION"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Converts capability to a row.
|
|
35
|
+
#
|
|
36
|
+
# @param model [Models::Capability]
|
|
37
|
+
# @param _context [Hash] unused
|
|
38
|
+
# @return [Array<String>]
|
|
39
|
+
def to_row(model, **_context)
|
|
40
|
+
[
|
|
41
|
+
model.node_name || "-",
|
|
42
|
+
model.kind.to_s,
|
|
43
|
+
model.name || "-",
|
|
44
|
+
details(model)
|
|
45
|
+
]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns extra values for wide output.
|
|
49
|
+
#
|
|
50
|
+
# @param model [Models::Capability]
|
|
51
|
+
# @param _context [Hash] unused
|
|
52
|
+
# @return [Array<String>]
|
|
53
|
+
def extra_values(model, **_context)
|
|
54
|
+
[model.version || "-"]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Converts capability to a hash for JSON/YAML output.
|
|
58
|
+
#
|
|
59
|
+
# Only the fields relevant to the kind are included; unset fields
|
|
60
|
+
# are omitted to keep the output compact and readable.
|
|
61
|
+
#
|
|
62
|
+
# @param model [Models::Capability]
|
|
63
|
+
# @return [Hash{String => Object}]
|
|
64
|
+
def to_hash(model)
|
|
65
|
+
base = {
|
|
66
|
+
"node" => model.node_name,
|
|
67
|
+
"kind" => model.kind&.to_s,
|
|
68
|
+
"name" => model.name
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
case model.kind
|
|
72
|
+
when :cpu
|
|
73
|
+
base["vendor"] = model.vendor if model.vendor
|
|
74
|
+
base["custom"] = model.custom
|
|
75
|
+
when :machine
|
|
76
|
+
base["machine_type"] = model.machine_type if model.machine_type
|
|
77
|
+
base["version"] = model.version if model.version
|
|
78
|
+
base["changes"] = model.changes if model.changes
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
base
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Returns the DETAILS column string.
|
|
87
|
+
#
|
|
88
|
+
# @param model [Models::Capability]
|
|
89
|
+
# @return [String]
|
|
90
|
+
def details(model)
|
|
91
|
+
case model.kind
|
|
92
|
+
when :cpu
|
|
93
|
+
parts = [model.vendor].compact
|
|
94
|
+
parts << "custom" if model.custom
|
|
95
|
+
parts.empty? ? "-" : parts.join(" ")
|
|
96
|
+
when :machine
|
|
97
|
+
model.machine_type || "-"
|
|
98
|
+
else
|
|
99
|
+
"-"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Presenters
|
|
5
|
+
module Config
|
|
6
|
+
# Presenter for formatting context list output.
|
|
7
|
+
#
|
|
8
|
+
# Context presenter provides column definitions and row formatting
|
|
9
|
+
# for displaying contexts in table, wide table, JSON, and YAML formats.
|
|
10
|
+
# Inherits from Base to support unified output formatting.
|
|
11
|
+
#
|
|
12
|
+
# @example Using with OutputHelper
|
|
13
|
+
# presenter = Context.new
|
|
14
|
+
# OutputHelper.print(
|
|
15
|
+
# data: contexts,
|
|
16
|
+
# presenter: presenter,
|
|
17
|
+
# format: "table",
|
|
18
|
+
# current_context: "production"
|
|
19
|
+
# )
|
|
20
|
+
#
|
|
21
|
+
# @example Wide format includes DEFAULT-NODE column
|
|
22
|
+
# pvectl config get-contexts -o wide
|
|
23
|
+
# # CURRENT NAME CLUSTER USER DEFAULT-NODE
|
|
24
|
+
# # * production prod admin@pam pve1
|
|
25
|
+
#
|
|
26
|
+
class Context < Pvectl::Presenters::Base
|
|
27
|
+
# Returns the column headers for table output.
|
|
28
|
+
#
|
|
29
|
+
# @return [Array<String>] column names
|
|
30
|
+
def columns
|
|
31
|
+
["CURRENT", "NAME", "CLUSTER", "USER"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns additional columns for wide format.
|
|
35
|
+
#
|
|
36
|
+
# @return [Array<String>] extra column names
|
|
37
|
+
def extra_columns
|
|
38
|
+
["DEFAULT-NODE"]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Converts a context to a table row.
|
|
42
|
+
#
|
|
43
|
+
# @param context [Config::Models::Context] context to format
|
|
44
|
+
# @param current_context [String, nil] name of the current context
|
|
45
|
+
# @param context_kwargs [Hash] additional context (ignored)
|
|
46
|
+
# @return [Array<String>] row values
|
|
47
|
+
def to_row(context, current_context: nil, **context_kwargs)
|
|
48
|
+
[
|
|
49
|
+
context.name == current_context ? "*" : "",
|
|
50
|
+
context.name,
|
|
51
|
+
context.cluster_ref,
|
|
52
|
+
context.user_ref
|
|
53
|
+
]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns additional values for wide format.
|
|
57
|
+
#
|
|
58
|
+
# @param context [Config::Models::Context] context to format
|
|
59
|
+
# @param context_kwargs [Hash] additional context (ignored)
|
|
60
|
+
# @return [Array<String, nil>] extra values
|
|
61
|
+
def extra_values(context, **context_kwargs)
|
|
62
|
+
[context.default_node]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Converts a context to a hash for JSON/YAML output.
|
|
66
|
+
#
|
|
67
|
+
# @param context [Config::Models::Context] context to format
|
|
68
|
+
# @return [Hash] hash representation
|
|
69
|
+
def to_hash(context)
|
|
70
|
+
{
|
|
71
|
+
"name" => context.name,
|
|
72
|
+
"cluster" => context.cluster_ref,
|
|
73
|
+
"user" => context.user_ref,
|
|
74
|
+
"default_node" => context.default_node
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|