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,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents the result of a lifecycle operation on a VM.
|
|
6
|
+
#
|
|
7
|
+
# Combines VM, task status, and error information into a single object
|
|
8
|
+
# for consistent presentation of operation results.
|
|
9
|
+
#
|
|
10
|
+
# @example Successful sync operation
|
|
11
|
+
# result = OperationResult.new(vm: vm, task: task, success: task.successful?)
|
|
12
|
+
# result.successful? #=> true
|
|
13
|
+
# result.message #=> "OK"
|
|
14
|
+
#
|
|
15
|
+
# @example Async operation (pending)
|
|
16
|
+
# result = OperationResult.new(vm: vm, task_upid: upid, success: :pending)
|
|
17
|
+
# result.pending? #=> true
|
|
18
|
+
# result.message #=> "Task: UPID:pve1:..."
|
|
19
|
+
#
|
|
20
|
+
# @example Failed operation
|
|
21
|
+
# result = OperationResult.new(vm: vm, success: false, error: "Permission denied")
|
|
22
|
+
# result.failed? #=> true
|
|
23
|
+
# result.message #=> "Permission denied"
|
|
24
|
+
#
|
|
25
|
+
class OperationResult < Base
|
|
26
|
+
# @return [Hash, nil] Generic resource info (for snapshot/backup operations)
|
|
27
|
+
attr_reader :resource
|
|
28
|
+
|
|
29
|
+
# @return [Symbol] The operation performed (:start, :stop, etc.)
|
|
30
|
+
attr_reader :operation
|
|
31
|
+
|
|
32
|
+
# @return [Models::Task, nil] The task (for completed sync operations)
|
|
33
|
+
attr_reader :task
|
|
34
|
+
|
|
35
|
+
# @return [String, nil] The task UPID (for async operations)
|
|
36
|
+
attr_reader :task_upid
|
|
37
|
+
|
|
38
|
+
# @return [Boolean, Symbol] true, false, or :pending
|
|
39
|
+
attr_reader :success
|
|
40
|
+
|
|
41
|
+
# @return [String, nil] Error message if operation failed
|
|
42
|
+
attr_reader :error
|
|
43
|
+
|
|
44
|
+
# Creates a new OperationResult.
|
|
45
|
+
#
|
|
46
|
+
# @param attrs [Hash] Result attributes
|
|
47
|
+
def initialize(attrs = {})
|
|
48
|
+
super(attrs)
|
|
49
|
+
@resource = @attributes[:resource]
|
|
50
|
+
@operation = @attributes[:operation]
|
|
51
|
+
@task = @attributes[:task]
|
|
52
|
+
@task_upid = @attributes[:task_upid]
|
|
53
|
+
@success = @attributes[:success]
|
|
54
|
+
@error = @attributes[:error]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Checks if the operation was successful.
|
|
58
|
+
#
|
|
59
|
+
# @return [Boolean] true if success is true or task succeeded
|
|
60
|
+
def successful?
|
|
61
|
+
success == true || task&.successful?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Checks if the operation failed.
|
|
65
|
+
#
|
|
66
|
+
# @return [Boolean] true if success is false, :partial, or task failed
|
|
67
|
+
def failed?
|
|
68
|
+
success == false || success == :partial || task&.failed?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Checks if the operation is still pending (async).
|
|
72
|
+
#
|
|
73
|
+
# @return [Boolean] true if success is :pending or task is pending
|
|
74
|
+
def pending?
|
|
75
|
+
success == :pending || task&.pending?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Checks if the operation partially succeeded (e.g. clone OK, config update failed).
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean] true if success is :partial
|
|
81
|
+
def partial?
|
|
82
|
+
success == :partial
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Returns human-readable status.
|
|
86
|
+
#
|
|
87
|
+
# @return [String] "Pending", "Success", or "Failed"
|
|
88
|
+
def status_text
|
|
89
|
+
return "Pending" if pending?
|
|
90
|
+
return "Partial" if partial?
|
|
91
|
+
return "Success" if successful?
|
|
92
|
+
|
|
93
|
+
"Failed"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Returns the result message for display.
|
|
97
|
+
#
|
|
98
|
+
# Priority: error > task.exitstatus > task_upid > status_text
|
|
99
|
+
#
|
|
100
|
+
# @return [String] Result message
|
|
101
|
+
def message
|
|
102
|
+
return error if error
|
|
103
|
+
return task.exitstatus if task
|
|
104
|
+
return "Task: #{task_upid}" if task_upid
|
|
105
|
+
|
|
106
|
+
status_text
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a physical disk (block device) on a Proxmox node.
|
|
6
|
+
#
|
|
7
|
+
# PhysicalDisk instances are created from the Proxmox API responses
|
|
8
|
+
# and provide domain methods for disk analysis.
|
|
9
|
+
#
|
|
10
|
+
# @example Creating a disk from API data
|
|
11
|
+
# disk = PhysicalDisk.new(
|
|
12
|
+
# devpath: "/dev/sda",
|
|
13
|
+
# model: "Samsung SSD 970",
|
|
14
|
+
# size: 500_000_000_000,
|
|
15
|
+
# type: "ssd",
|
|
16
|
+
# health: "PASSED",
|
|
17
|
+
# node: "pve1",
|
|
18
|
+
# gpt: 1,
|
|
19
|
+
# mounted: 1,
|
|
20
|
+
# used: "LVM"
|
|
21
|
+
# )
|
|
22
|
+
# disk.ssd? # => true
|
|
23
|
+
# disk.healthy? # => true
|
|
24
|
+
# disk.size_gb # => 465.7
|
|
25
|
+
# disk.gpt? # => true
|
|
26
|
+
# disk.mounted? # => true
|
|
27
|
+
# disk.osd? # => false
|
|
28
|
+
#
|
|
29
|
+
# @see Pvectl::Models::Base Base class for all models
|
|
30
|
+
#
|
|
31
|
+
class PhysicalDisk < Base
|
|
32
|
+
# @return [String, nil] device path (e.g., "/dev/sda")
|
|
33
|
+
attr_reader :devpath
|
|
34
|
+
|
|
35
|
+
# @return [String, nil] disk model name
|
|
36
|
+
attr_reader :model
|
|
37
|
+
|
|
38
|
+
# @return [Integer, nil] disk size in bytes
|
|
39
|
+
attr_reader :size
|
|
40
|
+
|
|
41
|
+
# @return [String, nil] disk type ("ssd", "hdd", etc.)
|
|
42
|
+
attr_reader :type
|
|
43
|
+
|
|
44
|
+
# @return [String, nil] SMART health status (e.g., "PASSED", "FAILED")
|
|
45
|
+
attr_reader :health
|
|
46
|
+
|
|
47
|
+
# @return [String, nil] disk serial number
|
|
48
|
+
attr_reader :serial
|
|
49
|
+
|
|
50
|
+
# @return [String, nil] disk vendor
|
|
51
|
+
attr_reader :vendor
|
|
52
|
+
|
|
53
|
+
# @return [String, nil] Proxmox node name this disk belongs to
|
|
54
|
+
attr_reader :node
|
|
55
|
+
|
|
56
|
+
# @return [Integer, nil] whether disk has a GPT partition table (1 = yes, 0 = no)
|
|
57
|
+
attr_reader :gpt
|
|
58
|
+
|
|
59
|
+
# @return [Integer, nil] whether disk is mounted (1 = yes, 0 = no)
|
|
60
|
+
attr_reader :mounted
|
|
61
|
+
|
|
62
|
+
# @return [String, nil] how the disk is used (e.g., "LVM", "ZFS", "ext4")
|
|
63
|
+
attr_reader :used
|
|
64
|
+
|
|
65
|
+
# @return [String, nil] World Wide Name identifier
|
|
66
|
+
attr_reader :wwn
|
|
67
|
+
|
|
68
|
+
# @return [Integer, nil] Ceph OSD ID (-1 if not an OSD)
|
|
69
|
+
attr_reader :osdid
|
|
70
|
+
|
|
71
|
+
# @return [String, nil] parent device path (e.g., "/dev/sda" for partition "/dev/sda1")
|
|
72
|
+
attr_reader :parent
|
|
73
|
+
|
|
74
|
+
# @return [String, nil] SMART type ("ata" or "text")
|
|
75
|
+
attr_reader :smart_type
|
|
76
|
+
|
|
77
|
+
# @return [Array<Hash>, nil] ATA SMART attributes array
|
|
78
|
+
attr_reader :smart_attributes
|
|
79
|
+
|
|
80
|
+
# @return [String, nil] raw SMART text (NVMe/SAS)
|
|
81
|
+
attr_reader :smart_text
|
|
82
|
+
|
|
83
|
+
# @return [Integer, nil] disk wearout percentage
|
|
84
|
+
attr_reader :wearout
|
|
85
|
+
|
|
86
|
+
# Creates a new PhysicalDisk instance.
|
|
87
|
+
#
|
|
88
|
+
# @param attrs [Hash] disk attributes from API
|
|
89
|
+
# @option attrs [String] :devpath device path
|
|
90
|
+
# @option attrs [String] :model disk model name
|
|
91
|
+
# @option attrs [Integer] :size disk size in bytes
|
|
92
|
+
# @option attrs [String] :type disk type
|
|
93
|
+
# @option attrs [String] :health SMART health status
|
|
94
|
+
# @option attrs [String] :serial serial number
|
|
95
|
+
# @option attrs [String] :vendor vendor name
|
|
96
|
+
# @option attrs [String] :node Proxmox node name
|
|
97
|
+
# @option attrs [Integer] :gpt GPT partition table flag (1/0)
|
|
98
|
+
# @option attrs [Integer] :mounted mounted flag (1/0)
|
|
99
|
+
# @option attrs [String] :used usage type
|
|
100
|
+
# @option attrs [String] :wwn World Wide Name
|
|
101
|
+
# @option attrs [Integer] :osdid Ceph OSD ID
|
|
102
|
+
# @option attrs [String] :parent parent device path
|
|
103
|
+
# @option attrs [String] :smart_type SMART data type ("ata" or "text")
|
|
104
|
+
# @option attrs [Array<Hash>] :smart_attributes ATA SMART attributes
|
|
105
|
+
# @option attrs [String] :smart_text raw SMART text (NVMe/SAS)
|
|
106
|
+
# @option attrs [Integer] :wearout wearout percentage
|
|
107
|
+
def initialize(attrs = {})
|
|
108
|
+
super
|
|
109
|
+
@devpath = attributes[:devpath]
|
|
110
|
+
@model = attributes[:model]
|
|
111
|
+
@size = attributes[:size]
|
|
112
|
+
@type = attributes[:type]
|
|
113
|
+
@health = attributes[:health]
|
|
114
|
+
@serial = attributes[:serial]
|
|
115
|
+
@vendor = attributes[:vendor]
|
|
116
|
+
@node = attributes[:node]
|
|
117
|
+
@gpt = attributes[:gpt]
|
|
118
|
+
@mounted = attributes[:mounted]
|
|
119
|
+
@used = attributes[:used]
|
|
120
|
+
@wwn = attributes[:wwn]
|
|
121
|
+
@osdid = attributes[:osdid]
|
|
122
|
+
@parent = attributes[:parent]
|
|
123
|
+
@smart_type = attributes[:smart_type]
|
|
124
|
+
@smart_attributes = attributes[:smart_attributes]
|
|
125
|
+
@smart_text = attributes[:smart_text]
|
|
126
|
+
@wearout = attributes[:wearout]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Returns disk size in gigabytes.
|
|
130
|
+
#
|
|
131
|
+
# @return [Float, nil] size in GB (binary, 1024-based), or nil if size unknown
|
|
132
|
+
#
|
|
133
|
+
# @example
|
|
134
|
+
# disk = PhysicalDisk.new(size: 500_000_000_000)
|
|
135
|
+
# disk.size_gb # => 465.7
|
|
136
|
+
def size_gb
|
|
137
|
+
return nil if size.nil?
|
|
138
|
+
|
|
139
|
+
(size.to_f / 1024 / 1024 / 1024).round(1)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Checks if disk SMART health status is PASSED.
|
|
143
|
+
#
|
|
144
|
+
# @return [Boolean] true if health is "PASSED"
|
|
145
|
+
def healthy?
|
|
146
|
+
health == "PASSED"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Checks if disk is an SSD.
|
|
150
|
+
#
|
|
151
|
+
# @return [Boolean] true if type is "ssd"
|
|
152
|
+
def ssd?
|
|
153
|
+
type == "ssd"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Checks if disk has a GPT partition table.
|
|
157
|
+
#
|
|
158
|
+
# @return [Boolean] true if gpt is 1
|
|
159
|
+
def gpt?
|
|
160
|
+
gpt == 1
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Checks if disk is currently mounted.
|
|
164
|
+
#
|
|
165
|
+
# @return [Boolean] true if mounted is 1
|
|
166
|
+
def mounted?
|
|
167
|
+
mounted == 1
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Checks if disk is a Ceph OSD.
|
|
171
|
+
#
|
|
172
|
+
# @return [Boolean] true if osdid is non-nil and >= 0
|
|
173
|
+
def osd?
|
|
174
|
+
!osdid.nil? && osdid >= 0
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Merges SMART data into the model.
|
|
178
|
+
#
|
|
179
|
+
# Called after initial construction when SMART data is fetched separately
|
|
180
|
+
# from the disk list endpoint.
|
|
181
|
+
#
|
|
182
|
+
# @param smart_data [Hash{Symbol => untyped}] SMART response data
|
|
183
|
+
# @return [void]
|
|
184
|
+
def merge_smart(smart_data)
|
|
185
|
+
@smart_type = smart_data[:type]
|
|
186
|
+
@smart_attributes = smart_data[:attributes]
|
|
187
|
+
@smart_text = smart_data[:text]
|
|
188
|
+
@wearout = smart_data[:wearout]
|
|
189
|
+
@health = smart_data[:health] if smart_data[:health]
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a Proxmox service running on a node.
|
|
6
|
+
#
|
|
7
|
+
# Services are system daemons that make up the Proxmox VE platform,
|
|
8
|
+
# such as pveproxy, pvedaemon, pve-cluster, etc.
|
|
9
|
+
#
|
|
10
|
+
# @example Creating a service instance
|
|
11
|
+
# service = Service.new(
|
|
12
|
+
# service: "pveproxy",
|
|
13
|
+
# name: "pveproxy",
|
|
14
|
+
# state: "running",
|
|
15
|
+
# desc: "PVE API Proxy Server"
|
|
16
|
+
# )
|
|
17
|
+
# service.running? # => true
|
|
18
|
+
#
|
|
19
|
+
# @see Pvectl::Repositories::Service Repository that creates these instances
|
|
20
|
+
#
|
|
21
|
+
class Service < Base
|
|
22
|
+
# @return [String] the service identifier
|
|
23
|
+
attr_reader :service
|
|
24
|
+
|
|
25
|
+
# @return [String, nil] the display name of the service
|
|
26
|
+
attr_reader :name
|
|
27
|
+
|
|
28
|
+
# @return [String] the current state (running, stopped, etc.)
|
|
29
|
+
attr_reader :state
|
|
30
|
+
|
|
31
|
+
# @return [String, nil] the service description
|
|
32
|
+
attr_reader :desc
|
|
33
|
+
|
|
34
|
+
# @return [String, nil] systemd ActiveState (active, inactive, failed, ...)
|
|
35
|
+
attr_reader :active_state
|
|
36
|
+
|
|
37
|
+
# @return [String, nil] systemd UnitFileState (enabled, disabled, masked, ...)
|
|
38
|
+
attr_reader :unit_state
|
|
39
|
+
|
|
40
|
+
# @return [String, nil] node name this service belongs to
|
|
41
|
+
attr_reader :node
|
|
42
|
+
|
|
43
|
+
# Creates a new Service instance.
|
|
44
|
+
#
|
|
45
|
+
# @param attrs [Hash] service attributes
|
|
46
|
+
# @option attrs [String] :service the service identifier
|
|
47
|
+
# @option attrs [String] :name the display name
|
|
48
|
+
# @option attrs [String] :state the current state
|
|
49
|
+
# @option attrs [String] :desc the description
|
|
50
|
+
# @option attrs [String] :active_state systemd ActiveState
|
|
51
|
+
# @option attrs [String] :unit_state systemd UnitFileState
|
|
52
|
+
# @option attrs [String] :node the node this service runs on
|
|
53
|
+
def initialize(attrs = {})
|
|
54
|
+
super
|
|
55
|
+
@service = attributes[:service]
|
|
56
|
+
@name = attributes[:name]
|
|
57
|
+
@state = attributes[:state]
|
|
58
|
+
@desc = attributes[:desc]
|
|
59
|
+
# Accept both symbol keys (:active_state) and dasherized keys (:"active-state")
|
|
60
|
+
@active_state = attributes[:active_state] || attributes[:"active-state"]
|
|
61
|
+
@unit_state = attributes[:unit_state] || attributes[:"unit-state"]
|
|
62
|
+
@node = attributes[:node]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Checks if the service is currently running.
|
|
66
|
+
#
|
|
67
|
+
# @return [Boolean] true if state is "running"
|
|
68
|
+
def running?
|
|
69
|
+
state == "running"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns the display name, falling back to service identifier.
|
|
73
|
+
#
|
|
74
|
+
# @return [String] the name to display
|
|
75
|
+
def display_name
|
|
76
|
+
name || service
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a VM/container snapshot in Proxmox.
|
|
6
|
+
#
|
|
7
|
+
# A snapshot captures the state of a VM or container at a specific point in time,
|
|
8
|
+
# including optionally the VM memory state (vmstate).
|
|
9
|
+
#
|
|
10
|
+
# @example Creating a snapshot model
|
|
11
|
+
# snapshot = Snapshot.new(
|
|
12
|
+
# name: "before-upgrade",
|
|
13
|
+
# snaptime: 1706800000,
|
|
14
|
+
# description: "Snapshot before upgrade",
|
|
15
|
+
# vmstate: 1
|
|
16
|
+
# )
|
|
17
|
+
# snapshot.has_vmstate? # => true
|
|
18
|
+
# snapshot.created_at # => 2024-02-01 12:26:40 +0000
|
|
19
|
+
#
|
|
20
|
+
# @see Pvectl::Models::Base Base model class
|
|
21
|
+
#
|
|
22
|
+
class Snapshot < Base
|
|
23
|
+
# @return [String] snapshot name/identifier
|
|
24
|
+
attr_reader :name
|
|
25
|
+
|
|
26
|
+
# @return [Integer, nil] Unix timestamp when snapshot was created
|
|
27
|
+
attr_reader :snaptime
|
|
28
|
+
|
|
29
|
+
# @return [String, nil] optional description of the snapshot
|
|
30
|
+
attr_reader :description
|
|
31
|
+
|
|
32
|
+
# @return [Integer, nil] 1 if VM memory state was saved, 0 or nil otherwise
|
|
33
|
+
attr_reader :vmstate
|
|
34
|
+
|
|
35
|
+
# @return [String, nil] parent snapshot name for snapshot trees
|
|
36
|
+
attr_reader :parent
|
|
37
|
+
|
|
38
|
+
# @return [Integer, nil] VM/container ID this snapshot belongs to
|
|
39
|
+
attr_reader :vmid
|
|
40
|
+
|
|
41
|
+
# @return [String, nil] node name where the VM/container resides
|
|
42
|
+
attr_reader :node
|
|
43
|
+
|
|
44
|
+
# @return [Symbol, nil] resource type (:qemu for VM, :lxc for container)
|
|
45
|
+
attr_reader :resource_type
|
|
46
|
+
|
|
47
|
+
# Creates a new Snapshot instance.
|
|
48
|
+
#
|
|
49
|
+
# @param attrs [Hash] snapshot attributes
|
|
50
|
+
# @option attrs [String] :name snapshot name
|
|
51
|
+
# @option attrs [Integer] :snaptime Unix timestamp of creation
|
|
52
|
+
# @option attrs [String] :description snapshot description
|
|
53
|
+
# @option attrs [Integer] :vmstate 1 if VM state saved, 0 otherwise
|
|
54
|
+
# @option attrs [String] :parent parent snapshot name
|
|
55
|
+
# @option attrs [Integer] :vmid VM/container ID
|
|
56
|
+
# @option attrs [String] :node node name
|
|
57
|
+
# @option attrs [Symbol] :resource_type :qemu or :lxc
|
|
58
|
+
def initialize(attrs = {})
|
|
59
|
+
super
|
|
60
|
+
@name = attributes[:name]
|
|
61
|
+
@snaptime = attributes[:snaptime]
|
|
62
|
+
@description = attributes[:description]
|
|
63
|
+
@vmstate = attributes[:vmstate]
|
|
64
|
+
@parent = attributes[:parent]
|
|
65
|
+
@vmid = attributes[:vmid]
|
|
66
|
+
@node = attributes[:node]
|
|
67
|
+
@resource_type = attributes[:resource_type]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Checks if the snapshot includes VM memory state.
|
|
71
|
+
#
|
|
72
|
+
# @return [Boolean] true if vmstate equals 1
|
|
73
|
+
def has_vmstate?
|
|
74
|
+
vmstate == 1
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Returns the snapshot creation time as a Time object.
|
|
78
|
+
#
|
|
79
|
+
# @return [Time, nil] creation time or nil if snaptime is not set
|
|
80
|
+
def created_at
|
|
81
|
+
return nil if snaptime.nil?
|
|
82
|
+
|
|
83
|
+
Time.at(snaptime)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Checks if the snapshot belongs to a VM (QEMU).
|
|
87
|
+
#
|
|
88
|
+
# @return [Boolean] true if resource_type is :qemu
|
|
89
|
+
def vm?
|
|
90
|
+
resource_type == :qemu
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Checks if the snapshot belongs to a container (LXC).
|
|
94
|
+
#
|
|
95
|
+
# @return [Boolean] true if resource_type is :lxc
|
|
96
|
+
def container?
|
|
97
|
+
resource_type == :lxc
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Wraps snapshot describe data: target snapshot + siblings for tree building.
|
|
6
|
+
#
|
|
7
|
+
# Used by the describe command to return rich snapshot data without
|
|
8
|
+
# changing the existing single-model return convention in ResourceService.
|
|
9
|
+
#
|
|
10
|
+
# @example Single VM
|
|
11
|
+
# desc = SnapshotDescription.new(entries: [
|
|
12
|
+
# SnapshotDescription::Entry.new(snapshot: snap, siblings: all_snaps)
|
|
13
|
+
# ])
|
|
14
|
+
#
|
|
15
|
+
# @example Multiple VMs
|
|
16
|
+
# desc = SnapshotDescription.new(entries: [entry1, entry2])
|
|
17
|
+
# desc.single? # => false
|
|
18
|
+
#
|
|
19
|
+
class SnapshotDescription
|
|
20
|
+
# Holds a single snapshot + its siblings for one VM/container.
|
|
21
|
+
Entry = Struct.new(:snapshot, :siblings, keyword_init: true)
|
|
22
|
+
|
|
23
|
+
# @return [Array<Entry>] entries per VM/container
|
|
24
|
+
attr_reader :entries
|
|
25
|
+
|
|
26
|
+
# @param entries [Array<Entry>] snapshot entries
|
|
27
|
+
def initialize(entries:)
|
|
28
|
+
@entries = entries
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns true when describing a snapshot from a single VM.
|
|
32
|
+
#
|
|
33
|
+
# @return [Boolean]
|
|
34
|
+
def single?
|
|
35
|
+
entries.length == 1
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a storage pool in the Proxmox cluster.
|
|
6
|
+
#
|
|
7
|
+
# Immutable domain model containing storage attributes and predicate methods.
|
|
8
|
+
# Created by Repositories::Storage from API data.
|
|
9
|
+
# Display formatting is handled by Presenters::Storage.
|
|
10
|
+
#
|
|
11
|
+
# @example Creating a Storage model
|
|
12
|
+
# storage = Storage.new(name: "local", plugintype: "dir", status: "available")
|
|
13
|
+
# storage.active? #=> true
|
|
14
|
+
# storage.shared? #=> false
|
|
15
|
+
#
|
|
16
|
+
# @example From API response
|
|
17
|
+
# data = { "storage" => "local", "plugintype" => "dir", "status" => "available" }
|
|
18
|
+
# storage = Storage.new(data)
|
|
19
|
+
#
|
|
20
|
+
# @see Pvectl::Repositories::Storage Repository that creates Storage instances
|
|
21
|
+
# @see Pvectl::Presenters::Storage Presenter for formatting Storage data
|
|
22
|
+
#
|
|
23
|
+
class Storage < Base
|
|
24
|
+
# @return [String] storage pool name
|
|
25
|
+
attr_reader :name
|
|
26
|
+
|
|
27
|
+
# @return [String] storage plugin type (dir, lvmthin, rbd, nfs, zfspool, etc.)
|
|
28
|
+
attr_reader :plugintype
|
|
29
|
+
|
|
30
|
+
# @return [String] storage status (available, unavailable)
|
|
31
|
+
attr_reader :status
|
|
32
|
+
|
|
33
|
+
# @return [String, nil] node name (nil for shared storage)
|
|
34
|
+
attr_reader :node
|
|
35
|
+
|
|
36
|
+
# @return [Integer, nil] disk used in bytes
|
|
37
|
+
attr_reader :disk
|
|
38
|
+
|
|
39
|
+
# @return [Integer, nil] total disk in bytes
|
|
40
|
+
attr_reader :maxdisk
|
|
41
|
+
|
|
42
|
+
# @return [String, nil] comma-separated content types (images, iso, vztmpl, backup, rootdir)
|
|
43
|
+
attr_reader :content
|
|
44
|
+
|
|
45
|
+
# @return [Integer] shared flag (1 = shared, 0 = local)
|
|
46
|
+
attr_reader :shared
|
|
47
|
+
|
|
48
|
+
# @return [Integer, nil] available bytes (from /nodes/{node}/storage)
|
|
49
|
+
attr_reader :avail
|
|
50
|
+
|
|
51
|
+
# @return [Integer, nil] enabled flag (0/1) (from /nodes/{node}/storage)
|
|
52
|
+
attr_reader :enabled
|
|
53
|
+
|
|
54
|
+
# @return [Integer, nil] active flag (0/1) (from /nodes/{node}/storage)
|
|
55
|
+
attr_reader :active_flag
|
|
56
|
+
|
|
57
|
+
# Configuration fields (from /storage/{storage} API endpoint)
|
|
58
|
+
# @return [String, nil] path for dir, nfs storage types
|
|
59
|
+
attr_reader :path
|
|
60
|
+
|
|
61
|
+
# @return [String, nil] server for nfs, iscsi, ceph
|
|
62
|
+
attr_reader :server
|
|
63
|
+
|
|
64
|
+
# @return [String, nil] export path (nfs)
|
|
65
|
+
attr_reader :export
|
|
66
|
+
|
|
67
|
+
# @return [String, nil] pool name (zfs, ceph)
|
|
68
|
+
attr_reader :pool
|
|
69
|
+
|
|
70
|
+
# @return [String, nil] volume group (lvm)
|
|
71
|
+
attr_reader :vgname
|
|
72
|
+
|
|
73
|
+
# @return [String, nil] thin pool name (lvmthin)
|
|
74
|
+
attr_reader :thinpool
|
|
75
|
+
|
|
76
|
+
# @return [String, nil] allowed nodes (nil = all)
|
|
77
|
+
attr_reader :nodes_allowed
|
|
78
|
+
|
|
79
|
+
# @return [Hash, nil] retention policy hash
|
|
80
|
+
attr_reader :prune_backups
|
|
81
|
+
|
|
82
|
+
# @return [Integer, nil] max backups (deprecated)
|
|
83
|
+
attr_reader :max_files
|
|
84
|
+
|
|
85
|
+
# Content summary
|
|
86
|
+
# @return [Array<Hash>] volumes from /content endpoint
|
|
87
|
+
attr_reader :volumes
|
|
88
|
+
|
|
89
|
+
# Creates a new Storage model from attributes.
|
|
90
|
+
#
|
|
91
|
+
# Handles field aliasing between different API endpoints:
|
|
92
|
+
# - /cluster/resources uses: disk, maxdisk
|
|
93
|
+
# - /nodes/{node}/storage uses: used, total, avail
|
|
94
|
+
#
|
|
95
|
+
# @param attrs [Hash] Storage attributes from API (string or symbol keys)
|
|
96
|
+
def initialize(attrs = {})
|
|
97
|
+
super(attrs)
|
|
98
|
+
@name = @attributes[:name] || @attributes[:storage]
|
|
99
|
+
@plugintype = @attributes[:plugintype] || @attributes[:type]
|
|
100
|
+
@node = @attributes[:node]
|
|
101
|
+
@content = @attributes[:content]
|
|
102
|
+
@shared = @attributes[:shared] || 0
|
|
103
|
+
|
|
104
|
+
# Handle field aliasing between endpoints
|
|
105
|
+
# /cluster/resources uses: disk, maxdisk
|
|
106
|
+
# /nodes/{node}/storage uses: used, total, avail
|
|
107
|
+
@disk = @attributes[:disk] || @attributes[:used]
|
|
108
|
+
@maxdisk = @attributes[:maxdisk] || @attributes[:total]
|
|
109
|
+
@avail = @attributes[:avail]
|
|
110
|
+
@enabled = @attributes[:enabled]
|
|
111
|
+
@active_flag = @attributes[:active]
|
|
112
|
+
|
|
113
|
+
# Status normalization: /nodes/{node}/storage has no status field
|
|
114
|
+
# Derive from active flag if status not present
|
|
115
|
+
@status = @attributes[:status] || derive_status_from_active
|
|
116
|
+
|
|
117
|
+
# Configuration fields from /storage/{storage} API endpoint
|
|
118
|
+
@path = @attributes[:path]
|
|
119
|
+
@server = @attributes[:server]
|
|
120
|
+
@export = @attributes[:export]
|
|
121
|
+
@pool = @attributes[:pool]
|
|
122
|
+
@vgname = @attributes[:vgname]
|
|
123
|
+
@thinpool = @attributes[:thinpool]
|
|
124
|
+
@nodes_allowed = @attributes[:nodes] # API returns "nodes" not "nodes_allowed"
|
|
125
|
+
@prune_backups = @attributes[:"prune-backups"] # API uses hyphen
|
|
126
|
+
@max_files = @attributes[:maxfiles]
|
|
127
|
+
@volumes = @attributes[:volumes] || []
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Checks if the storage is active/available.
|
|
131
|
+
#
|
|
132
|
+
# @return [Boolean] true if status is "available" or "active"
|
|
133
|
+
def active?
|
|
134
|
+
status == "available" || status == "active"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Returns used bytes (alias for disk).
|
|
138
|
+
# Provides semantic clarity when working with /nodes/{node}/storage API.
|
|
139
|
+
#
|
|
140
|
+
# @return [Integer, nil] bytes used
|
|
141
|
+
def used
|
|
142
|
+
disk
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Returns total bytes (alias for maxdisk).
|
|
146
|
+
# Provides semantic clarity when working with /nodes/{node}/storage API.
|
|
147
|
+
#
|
|
148
|
+
# @return [Integer, nil] total bytes
|
|
149
|
+
def total
|
|
150
|
+
maxdisk
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Checks if the storage is enabled.
|
|
154
|
+
#
|
|
155
|
+
# @return [Boolean] true if enabled flag is 1
|
|
156
|
+
def enabled?
|
|
157
|
+
enabled == 1
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Checks if the storage is shared across nodes.
|
|
161
|
+
#
|
|
162
|
+
# @return [Boolean] true if shared flag is 1
|
|
163
|
+
def shared?
|
|
164
|
+
shared == 1
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
private
|
|
168
|
+
|
|
169
|
+
# Derives status from active flag when status not present.
|
|
170
|
+
# Used for /nodes/{node}/storage API which doesn't return status field.
|
|
171
|
+
#
|
|
172
|
+
# @return [String, nil] derived status or nil if active_flag not set
|
|
173
|
+
def derive_status_from_active
|
|
174
|
+
return nil if @active_flag.nil?
|
|
175
|
+
|
|
176
|
+
@active_flag == 1 ? "available" : "unavailable"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|