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,142 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module Pvectl
|
|
6
|
+
# Wraps ConfigSerializer output with a kubectl-like manifest envelope
|
|
7
|
+
# (apiVersion, kind, metadata, spec). Handles bidirectional conversion
|
|
8
|
+
# between YAML manifest files and internal config representations.
|
|
9
|
+
module ManifestSerializer
|
|
10
|
+
API_VERSION = "pvectl/v1"
|
|
11
|
+
|
|
12
|
+
KINDS = {
|
|
13
|
+
vm: "VirtualMachine",
|
|
14
|
+
container: "Container"
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
KINDS_REVERSE = KINDS.invert.transform_keys(&:to_s).freeze
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
# Builds a YAML manifest string from nested config and metadata.
|
|
21
|
+
#
|
|
22
|
+
# @param nested_config [Hash] nested config from ConfigSerializer.to_nested
|
|
23
|
+
# @param type [Symbol] :vm or :container
|
|
24
|
+
# @param metadata [Hash] resource metadata (vmid, name, node, status, tags)
|
|
25
|
+
# @return [String] YAML manifest string
|
|
26
|
+
def to_yaml(nested_config, type:, metadata:)
|
|
27
|
+
manifest = {
|
|
28
|
+
"apiVersion" => API_VERSION,
|
|
29
|
+
"kind" => KINDS.fetch(type),
|
|
30
|
+
"metadata" => build_metadata(metadata),
|
|
31
|
+
"spec" => stringify_keys_deep(nested_config)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
YAML.dump(manifest)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Parses a YAML manifest string into type, metadata, and spec.
|
|
38
|
+
#
|
|
39
|
+
# @param yaml_string [String] YAML manifest
|
|
40
|
+
# @return [Hash] { type: Symbol, metadata: Hash, spec: Hash }
|
|
41
|
+
def from_yaml(yaml_string)
|
|
42
|
+
parsed = YAML.safe_load(yaml_string)
|
|
43
|
+
type = KINDS_REVERSE[parsed["kind"]]
|
|
44
|
+
|
|
45
|
+
{
|
|
46
|
+
type: type,
|
|
47
|
+
metadata: symbolize_metadata(parsed["metadata"] || {}),
|
|
48
|
+
spec: symbolize_keys_deep(parsed["spec"] || {})
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Validates manifest structure (envelope only, not spec content).
|
|
53
|
+
#
|
|
54
|
+
# @param yaml_string [String] YAML manifest
|
|
55
|
+
# @return [Array<String>] error messages (empty if valid)
|
|
56
|
+
def validate(yaml_string)
|
|
57
|
+
errors = []
|
|
58
|
+
|
|
59
|
+
begin
|
|
60
|
+
parsed = YAML.safe_load(yaml_string)
|
|
61
|
+
rescue Psych::SyntaxError => e
|
|
62
|
+
return ["YAML syntax error: #{e.message}"]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
unless parsed.is_a?(Hash)
|
|
66
|
+
return ["Invalid manifest: expected a YAML mapping"]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
unless parsed["apiVersion"]
|
|
70
|
+
errors << "Missing required field 'apiVersion'"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if parsed["apiVersion"] && parsed["apiVersion"] != API_VERSION
|
|
74
|
+
errors << "Unsupported apiVersion '#{parsed["apiVersion"]}'. Expected: #{API_VERSION}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
errors << "Missing required field 'kind'" unless parsed["kind"]
|
|
78
|
+
|
|
79
|
+
if parsed["kind"] && !KINDS_REVERSE.key?(parsed["kind"])
|
|
80
|
+
errors << "Unknown kind '#{parsed["kind"]}'. Valid: #{KINDS.values.join(', ')}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
metadata = parsed["metadata"]
|
|
84
|
+
if metadata.nil? || !metadata.is_a?(Hash)
|
|
85
|
+
errors << "Missing required field 'metadata'"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
errors
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# Builds string-keyed metadata hash from symbol-keyed input.
|
|
94
|
+
#
|
|
95
|
+
# @param metadata [Hash] symbol-keyed metadata
|
|
96
|
+
# @return [Hash] string-keyed metadata for YAML output
|
|
97
|
+
def build_metadata(metadata)
|
|
98
|
+
result = {}
|
|
99
|
+
result["vmid"] = metadata[:vmid] if metadata[:vmid]
|
|
100
|
+
result["name"] = metadata[:name] if metadata[:name]
|
|
101
|
+
result["node"] = metadata[:node] if metadata[:node]
|
|
102
|
+
result["status"] = metadata[:status] if metadata[:status]
|
|
103
|
+
result["tags"] = metadata[:tags] if metadata[:tags]
|
|
104
|
+
result
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Recursively converts symbol keys to string keys.
|
|
108
|
+
#
|
|
109
|
+
# @param hash [Hash] symbol-keyed hash
|
|
110
|
+
# @return [Hash] string-keyed hash
|
|
111
|
+
def stringify_keys_deep(hash)
|
|
112
|
+
hash.transform_keys(&:to_s).transform_values do |v|
|
|
113
|
+
v.is_a?(Hash) ? stringify_keys_deep(v) : v
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Converts string-keyed metadata to symbol-keyed hash.
|
|
118
|
+
#
|
|
119
|
+
# @param hash [Hash] string-keyed metadata from YAML
|
|
120
|
+
# @return [Hash] symbol-keyed metadata
|
|
121
|
+
def symbolize_metadata(hash)
|
|
122
|
+
result = {}
|
|
123
|
+
result[:vmid] = hash["vmid"] if hash["vmid"]
|
|
124
|
+
result[:name] = hash["name"] if hash["name"]
|
|
125
|
+
result[:node] = hash["node"] if hash["node"]
|
|
126
|
+
result[:status] = hash["status"] if hash["status"]
|
|
127
|
+
result[:tags] = hash["tags"] if hash["tags"]
|
|
128
|
+
result
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Recursively converts string keys to symbol keys.
|
|
132
|
+
#
|
|
133
|
+
# @param hash [Hash] string-keyed hash from YAML
|
|
134
|
+
# @return [Hash] symbol-keyed hash
|
|
135
|
+
def symbolize_keys_deep(hash)
|
|
136
|
+
hash.to_h do |k, v|
|
|
137
|
+
[k.to_sym, v.is_a?(Hash) ? symbolize_keys_deep(v) : v]
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents an APT package on a Proxmox node.
|
|
6
|
+
#
|
|
7
|
+
# Single model serves both pending updates (`/apt/update`) and installed
|
|
8
|
+
# package versions (`/apt/versions`). Some attributes only apply to one
|
|
9
|
+
# API: `notify_status` to pending updates, `current_state`,
|
|
10
|
+
# `manager_version`, `running_kernel` to versions.
|
|
11
|
+
#
|
|
12
|
+
# @example Creating a pending update instance
|
|
13
|
+
# pkg = AptPackage.new(
|
|
14
|
+
# Package: "pve-manager",
|
|
15
|
+
# Version: "8.2.4-1",
|
|
16
|
+
# OldVersion: "8.2.3-1",
|
|
17
|
+
# Origin: "Proxmox",
|
|
18
|
+
# node: "pve1"
|
|
19
|
+
# )
|
|
20
|
+
# pkg.package # => "pve-manager"
|
|
21
|
+
# pkg.upgrade? # => true
|
|
22
|
+
#
|
|
23
|
+
# @see Pvectl::Repositories::Apt Repository that creates these instances
|
|
24
|
+
#
|
|
25
|
+
class AptPackage < Base
|
|
26
|
+
# @return [String, nil] package name
|
|
27
|
+
attr_reader :package
|
|
28
|
+
|
|
29
|
+
# @return [String, nil] short package title
|
|
30
|
+
attr_reader :title
|
|
31
|
+
|
|
32
|
+
# @return [String, nil] available / target version
|
|
33
|
+
attr_reader :version
|
|
34
|
+
|
|
35
|
+
# @return [String, nil] currently installed version
|
|
36
|
+
attr_reader :old_version
|
|
37
|
+
|
|
38
|
+
# @return [String, nil] package origin (e.g., "Proxmox", "Debian")
|
|
39
|
+
attr_reader :origin
|
|
40
|
+
|
|
41
|
+
# @return [String, nil] package section
|
|
42
|
+
attr_reader :section
|
|
43
|
+
|
|
44
|
+
# @return [String, nil] package priority
|
|
45
|
+
attr_reader :priority
|
|
46
|
+
|
|
47
|
+
# @return [String, nil] architecture (amd64, arm64, all, ...)
|
|
48
|
+
attr_reader :arch
|
|
49
|
+
|
|
50
|
+
# @return [String, nil] package description
|
|
51
|
+
attr_reader :description
|
|
52
|
+
|
|
53
|
+
# @return [String, nil] notify status (pending updates only)
|
|
54
|
+
attr_reader :notify_status
|
|
55
|
+
|
|
56
|
+
# @return [String, nil] current installed state (versions only)
|
|
57
|
+
attr_reader :current_state
|
|
58
|
+
|
|
59
|
+
# @return [String, nil] pve-manager API server version (versions only)
|
|
60
|
+
attr_reader :manager_version
|
|
61
|
+
|
|
62
|
+
# @return [String, nil] running kernel (proxmox-ve package, versions only)
|
|
63
|
+
attr_reader :running_kernel
|
|
64
|
+
|
|
65
|
+
# @return [String, nil] node name this package belongs to
|
|
66
|
+
attr_reader :node
|
|
67
|
+
|
|
68
|
+
# Creates a new AptPackage instance.
|
|
69
|
+
#
|
|
70
|
+
# Accepts Proxmox API capitalized keys (`Package`, `OldVersion`, ...) as
|
|
71
|
+
# well as snake_case / dasherized variants. Indifferent access on keys.
|
|
72
|
+
#
|
|
73
|
+
# @param attrs [Hash] package attributes from API
|
|
74
|
+
def initialize(attrs = {})
|
|
75
|
+
super
|
|
76
|
+
@package = attributes[:Package] || attributes[:package]
|
|
77
|
+
@title = attributes[:Title] || attributes[:title]
|
|
78
|
+
@version = attributes[:Version] || attributes[:version]
|
|
79
|
+
@old_version = attributes[:OldVersion] || attributes[:old_version] || attributes[:"old-version"]
|
|
80
|
+
@origin = attributes[:Origin] || attributes[:origin]
|
|
81
|
+
@section = attributes[:Section] || attributes[:section]
|
|
82
|
+
@priority = attributes[:Priority] || attributes[:priority]
|
|
83
|
+
@arch = attributes[:Arch] || attributes[:arch]
|
|
84
|
+
@description = attributes[:Description] || attributes[:description]
|
|
85
|
+
@notify_status = attributes[:NotifyStatus] || attributes[:notify_status] || attributes[:"notify-status"]
|
|
86
|
+
@current_state = attributes[:CurrentState] || attributes[:current_state] || attributes[:"current-state"]
|
|
87
|
+
@manager_version = attributes[:ManagerVersion] || attributes[:manager_version] || attributes[:"manager-version"]
|
|
88
|
+
@running_kernel = attributes[:RunningKernel] || attributes[:running_kernel] || attributes[:"running-kernel"]
|
|
89
|
+
@node = attributes[:node]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Returns true if a different version is available.
|
|
93
|
+
#
|
|
94
|
+
# @return [Boolean] true if old_version and version are both set and differ
|
|
95
|
+
def upgrade?
|
|
96
|
+
!old_version.nil? && !version.nil? && old_version != version
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Returns the installed package state, defaults to "Installed" when not provided.
|
|
100
|
+
#
|
|
101
|
+
# @return [String] installed state
|
|
102
|
+
def installed_state
|
|
103
|
+
current_state || "Installed"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a VM/container backup in Proxmox.
|
|
6
|
+
#
|
|
7
|
+
# A backup is a full copy of a VM or container stored on a storage backend.
|
|
8
|
+
# Backups can be created via vzdump and restored to create new VMs/containers.
|
|
9
|
+
#
|
|
10
|
+
# @example Creating a backup model
|
|
11
|
+
# backup = Backup.new(
|
|
12
|
+
# volid: "local:backup/vzdump-qemu-100-2024_01_15-10_30_00.vma.zst",
|
|
13
|
+
# vmid: 100,
|
|
14
|
+
# size: 1610612736,
|
|
15
|
+
# ctime: 1705315800,
|
|
16
|
+
# format: "vma"
|
|
17
|
+
# )
|
|
18
|
+
# backup.human_size # => "1.5 GiB"
|
|
19
|
+
# backup.vm? # => true
|
|
20
|
+
#
|
|
21
|
+
# @see Pvectl::Models::Base Base model class
|
|
22
|
+
#
|
|
23
|
+
class Backup < Base
|
|
24
|
+
# @return [String] full volume identifier (e.g., "local:backup/vzdump-qemu-100-xxx.vma.zst")
|
|
25
|
+
attr_reader :volid
|
|
26
|
+
|
|
27
|
+
# @return [Integer] VM/container ID
|
|
28
|
+
attr_reader :vmid
|
|
29
|
+
|
|
30
|
+
# @return [String, nil] node name where backup is stored
|
|
31
|
+
attr_reader :node
|
|
32
|
+
|
|
33
|
+
# @return [String, nil] storage name (extracted from volid)
|
|
34
|
+
attr_reader :storage
|
|
35
|
+
|
|
36
|
+
# @return [Symbol, nil] resource type (:qemu or :lxc)
|
|
37
|
+
attr_reader :resource_type
|
|
38
|
+
|
|
39
|
+
# @return [String, nil] backup format ("vma", "tar")
|
|
40
|
+
attr_reader :format
|
|
41
|
+
|
|
42
|
+
# @return [Integer, nil] backup size in bytes
|
|
43
|
+
attr_reader :size
|
|
44
|
+
|
|
45
|
+
# @return [Integer, nil] Unix timestamp when backup was created
|
|
46
|
+
attr_reader :ctime
|
|
47
|
+
|
|
48
|
+
# @return [String, nil] optional notes/description
|
|
49
|
+
attr_reader :notes
|
|
50
|
+
|
|
51
|
+
# @return [Boolean] whether backup is protected from deletion
|
|
52
|
+
attr_reader :protected
|
|
53
|
+
|
|
54
|
+
# Creates a new Backup instance.
|
|
55
|
+
#
|
|
56
|
+
# @param attrs [Hash] backup attributes
|
|
57
|
+
# @option attrs [String] :volid volume identifier
|
|
58
|
+
# @option attrs [Integer] :vmid VM/container ID
|
|
59
|
+
# @option attrs [String] :node node name
|
|
60
|
+
# @option attrs [String] :storage storage name (auto-detected from volid if not provided)
|
|
61
|
+
# @option attrs [Symbol] :resource_type :qemu or :lxc (auto-detected from volid if not provided)
|
|
62
|
+
# @option attrs [String] :format backup format
|
|
63
|
+
# @option attrs [Integer] :size size in bytes
|
|
64
|
+
# @option attrs [Integer] :ctime Unix timestamp of creation
|
|
65
|
+
# @option attrs [String] :notes description
|
|
66
|
+
# @option attrs [Boolean] :protected protection status
|
|
67
|
+
def initialize(attrs = {})
|
|
68
|
+
super
|
|
69
|
+
@volid = attributes[:volid]
|
|
70
|
+
@vmid = attributes[:vmid]
|
|
71
|
+
@node = attributes[:node]
|
|
72
|
+
@storage = attributes[:storage] || extract_storage
|
|
73
|
+
@resource_type = attributes[:resource_type] || detect_resource_type
|
|
74
|
+
@format = attributes[:format]
|
|
75
|
+
@size = attributes[:size]
|
|
76
|
+
@ctime = attributes[:ctime]
|
|
77
|
+
@notes = attributes[:notes]
|
|
78
|
+
@protected = attributes[:protected] || false
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Returns the backup creation time as a Time object.
|
|
82
|
+
#
|
|
83
|
+
# @return [Time, nil] creation time or nil if ctime is not set
|
|
84
|
+
def created_at
|
|
85
|
+
return nil if ctime.nil?
|
|
86
|
+
|
|
87
|
+
Time.at(ctime)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Checks if the backup is for a VM (QEMU).
|
|
91
|
+
#
|
|
92
|
+
# @return [Boolean] true if resource_type is :qemu
|
|
93
|
+
def vm?
|
|
94
|
+
resource_type == :qemu
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Checks if the backup is for a container (LXC).
|
|
98
|
+
#
|
|
99
|
+
# @return [Boolean] true if resource_type is :lxc
|
|
100
|
+
def container?
|
|
101
|
+
resource_type == :lxc
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Extracts the filename from the volume identifier.
|
|
105
|
+
#
|
|
106
|
+
# @return [String, nil] filename or nil if volid is not set
|
|
107
|
+
def filename
|
|
108
|
+
return nil if volid.nil?
|
|
109
|
+
|
|
110
|
+
volid.split("/").last
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Returns human-readable size.
|
|
114
|
+
#
|
|
115
|
+
# @return [String, nil] formatted size (e.g., "1.5 GiB") or nil if size is not set
|
|
116
|
+
def human_size
|
|
117
|
+
return nil if size.nil?
|
|
118
|
+
|
|
119
|
+
format_bytes(size)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Checks if the backup is protected from deletion.
|
|
123
|
+
#
|
|
124
|
+
# @return [Boolean] true if protected
|
|
125
|
+
def protected?
|
|
126
|
+
@protected == true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
# Extracts storage name from volid.
|
|
132
|
+
#
|
|
133
|
+
# @return [String, nil] storage name
|
|
134
|
+
def extract_storage
|
|
135
|
+
return nil if volid.nil?
|
|
136
|
+
|
|
137
|
+
volid.split(":").first
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Detects resource type from volid pattern.
|
|
141
|
+
#
|
|
142
|
+
# @return [Symbol, nil] :qemu, :lxc, or nil
|
|
143
|
+
def detect_resource_type
|
|
144
|
+
return nil if volid.nil?
|
|
145
|
+
return :qemu if volid.include?("vzdump-qemu")
|
|
146
|
+
return :lxc if volid.include?("vzdump-lxc")
|
|
147
|
+
|
|
148
|
+
nil
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Formats bytes into human-readable units.
|
|
152
|
+
#
|
|
153
|
+
# @param bytes [Integer] size in bytes
|
|
154
|
+
# @return [String] formatted size
|
|
155
|
+
def format_bytes(bytes)
|
|
156
|
+
units = ["B", "KiB", "MiB", "GiB", "TiB"]
|
|
157
|
+
unit_index = 0
|
|
158
|
+
value = bytes.to_f
|
|
159
|
+
|
|
160
|
+
while value >= 1024 && unit_index < units.size - 1
|
|
161
|
+
value /= 1024
|
|
162
|
+
unit_index += 1
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if unit_index == 0
|
|
166
|
+
"#{value.to_i} #{units[unit_index]}"
|
|
167
|
+
else
|
|
168
|
+
"#{Kernel.format('%.1f', value)} #{units[unit_index]}"
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Abstract base class for domain models.
|
|
6
|
+
#
|
|
7
|
+
# Provides common initialization from hash attributes.
|
|
8
|
+
# All models are immutable - only getters, no setters.
|
|
9
|
+
#
|
|
10
|
+
# Subclasses store domain data and contain domain logic,
|
|
11
|
+
# but do not fetch data themselves (that's the Repository's job).
|
|
12
|
+
#
|
|
13
|
+
# @abstract Subclass and add attr_readers for domain attributes.
|
|
14
|
+
#
|
|
15
|
+
# @example Implementing a model
|
|
16
|
+
# class Vm < Base
|
|
17
|
+
# attr_reader :vmid, :name, :status
|
|
18
|
+
#
|
|
19
|
+
# def initialize(attributes = {})
|
|
20
|
+
# super
|
|
21
|
+
# @vmid = attributes[:vmid]
|
|
22
|
+
# @name = attributes[:name]
|
|
23
|
+
# @status = attributes[:status]
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# def running?
|
|
27
|
+
# status == "running"
|
|
28
|
+
# end
|
|
29
|
+
# end
|
|
30
|
+
#
|
|
31
|
+
# @see Pvectl::Repositories::Base Repository creates model instances
|
|
32
|
+
#
|
|
33
|
+
class Base
|
|
34
|
+
# Creates model from attributes hash.
|
|
35
|
+
#
|
|
36
|
+
# Converts string keys to symbols for consistent access.
|
|
37
|
+
#
|
|
38
|
+
# @param attributes [Hash] attribute key-value pairs
|
|
39
|
+
def initialize(attributes = {})
|
|
40
|
+
@attributes = (attributes || {}).transform_keys(&:to_sym)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
protected
|
|
44
|
+
|
|
45
|
+
# @return [Hash] the raw attributes hash
|
|
46
|
+
attr_reader :attributes
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a single node capability entry — either a supported QEMU
|
|
6
|
+
# CPU model or a supported QEMU machine type.
|
|
7
|
+
#
|
|
8
|
+
# The two kinds share a flat structure with different optional fields
|
|
9
|
+
# populated. A small, kind-aware model keeps the presenter simple while
|
|
10
|
+
# still allowing JSON/YAML output to expose all relevant attributes.
|
|
11
|
+
#
|
|
12
|
+
# @example QEMU CPU capability
|
|
13
|
+
# cap = Capability.new(node_name: "pve1", kind: :cpu, name: "host", vendor: "Intel")
|
|
14
|
+
#
|
|
15
|
+
# @example QEMU machine type capability
|
|
16
|
+
# cap = Capability.new(node_name: "pve1", kind: :machine, name: "pc-q35-8.1", machine_type: "q35", version: "8.1")
|
|
17
|
+
#
|
|
18
|
+
# @see Pvectl::Repositories::Capabilities Repository producing instances
|
|
19
|
+
# @see Pvectl::Presenters::Capability Presenter for display
|
|
20
|
+
#
|
|
21
|
+
class Capability < Base
|
|
22
|
+
# @return [String, nil] node the capability belongs to
|
|
23
|
+
attr_reader :node_name
|
|
24
|
+
|
|
25
|
+
# @return [Symbol] capability kind: :cpu or :machine
|
|
26
|
+
attr_reader :kind
|
|
27
|
+
|
|
28
|
+
# @return [String, nil] identifying name (CPU model or machine id)
|
|
29
|
+
attr_reader :name
|
|
30
|
+
|
|
31
|
+
# @return [String, nil] CPU vendor (only for :cpu kind)
|
|
32
|
+
attr_reader :vendor
|
|
33
|
+
|
|
34
|
+
# @return [Boolean] true when this is a custom CPU model (only :cpu)
|
|
35
|
+
attr_reader :custom
|
|
36
|
+
|
|
37
|
+
# @return [String, nil] machine type — q35 or i440fx (only :machine)
|
|
38
|
+
attr_reader :machine_type
|
|
39
|
+
|
|
40
|
+
# @return [String, nil] machine version (only :machine)
|
|
41
|
+
attr_reader :version
|
|
42
|
+
|
|
43
|
+
# @return [String, nil] notable changes for the version (only :machine)
|
|
44
|
+
attr_reader :changes
|
|
45
|
+
|
|
46
|
+
# Creates a new Capability.
|
|
47
|
+
#
|
|
48
|
+
# @param attributes [Hash] attribute hash
|
|
49
|
+
def initialize(attributes = {})
|
|
50
|
+
super
|
|
51
|
+
@node_name = @attributes[:node_name]
|
|
52
|
+
@kind = @attributes[:kind]
|
|
53
|
+
@name = @attributes[:name]
|
|
54
|
+
@vendor = @attributes[:vendor]
|
|
55
|
+
@custom = @attributes[:custom] || false
|
|
56
|
+
@machine_type = @attributes[:machine_type]
|
|
57
|
+
@version = @attributes[:version]
|
|
58
|
+
@changes = @attributes[:changes]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|