Class: Pvectl::Commands::Service
- Inherits:
-
Object
- Object
- Pvectl::Commands::Service
- Defined in:
- lib/pvectl/commands/service.rb
Overview
Top-level ‘pvectl service` command for managing systemd services on Proxmox nodes.
Exposes four lifecycle sub-commands:
-
‘service start <name>` start a service
-
‘service stop <name>` stop a service (irreversible — requires –yes or prompt)
-
‘service restart <name>` hard restart a service (irreversible — requires –yes or prompt)
-
‘service reload <name>` reload (graceful where supported)
Each sub-command requires ‘–node NODE` (falls back to default-node from the active context configuration when not provided).
Constant Summary collapse
- CONFIRMABLE_OPERATIONS =
All confirmable operations (stop and restart can disrupt running workloads).
%i[stop restart].freeze
- OPERATIONS =
All supported operations.
%i[start stop restart reload].freeze
Class Method Summary collapse
-
.execute(operation, args, options, global_options) ⇒ Integer
Executes the command.
-
.register(cli) ⇒ void
Registers the service command and all sub-commands with the CLI.
-
.register_subcommand(parent, operation) ⇒ void
Registers a single lifecycle sub-command.
-
.subcommand_long_desc(operation) ⇒ String
Builds the man-page-style long_desc for a sub-command.
Instance Method Summary collapse
-
#execute ⇒ Integer
Executes the command.
-
#initialize(operation, args, options, global_options, prompt: $stdin, output: $stdout) ⇒ Service
constructor
Initializes a service lifecycle command.
Constructor Details
#initialize(operation, args, options, global_options, prompt: $stdin, output: $stdout) ⇒ Service
Initializes a service lifecycle command.
163 164 165 166 167 168 169 170 |
# File 'lib/pvectl/commands/service.rb', line 163 def initialize(operation, args, , , prompt: $stdin, output: $stdout) @operation = operation @args = Array(args).compact @options = @global_options = @prompt = prompt @output = output end |
Class Method Details
.execute(operation, args, options, global_options) ⇒ Integer
Executes the command.
151 152 153 |
# File 'lib/pvectl/commands/service.rb', line 151 def self.execute(operation, args, , ) new(operation, args, , ).execute end |
.register(cli) ⇒ void
This method returns an undefined value.
Registers the service command and all sub-commands with the CLI.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/pvectl/commands/service.rb', line 32 def self.register(cli) cli.desc "Manage systemd services on Proxmox nodes" cli.long_desc <<~HELP Manage systemd services running on Proxmox VE nodes. Wraps the Proxmox /nodes/{node}/services API to start, stop, restart, or reload daemons such as pveproxy, pvedaemon, corosync, and others. SUB-COMMANDS service start NAME Start a stopped service service stop NAME Stop a running service (irreversible) service restart NAME Hard restart a service (irreversible) service reload NAME Reload a service (graceful where supported) EXAMPLES Restart the API proxy on a single node (with confirmation skipped): $ pvectl service restart pveproxy --node pve1 --yes Start a stopped service on the default node: $ pvectl service start cron Stop a service after interactive confirmation: $ pvectl service stop pve-firewall --node pve1 Reload the syslog daemon (no interruption to running workloads): $ pvectl service reload syslog --node pve1 NOTES --node defaults to the context's default-node if configured. stop and restart are irreversible and require either an interactive "yes" confirmation or the --yes flag to skip the prompt. Restarting pveproxy or corosync can momentarily disconnect the current API session and break cluster membership respectively. Use --yes only when you understand the impact. Operations are asynchronous — the result includes the Proxmox task UPID which can be inspected with `pvectl get tasks` and `pvectl logs task UPID`. SEE ALSO pvectl help get List resources (try `get services`) pvectl help logs Inspect task output HELP cli.command :service do |c| # Shared flags declared on the parent so all subcommands inherit them. # Avoids GLI flag-redefinition errors when the same flag is needed by # multiple sibling subcommands (e.g. start/stop/restart/reload all # need --node and --yes). c.desc "Node name (defaults to context default-node)" c.flag [:node], arg_name: "NODE" c.desc "Skip interactive confirmation prompt" c.switch [:yes, :y], negatable: false OPERATIONS.each do |op| register_subcommand(c, op) end end end |
.register_subcommand(parent, operation) ⇒ void
This method returns an undefined value.
Registers a single lifecycle sub-command.
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/pvectl/commands/service.rb', line 98 def self.register_subcommand(parent, operation) parent.desc "#{operation.capitalize} a systemd service on a Proxmox node" parent.long_desc subcommand_long_desc(operation) parent.arg_name "SERVICE_NAME" parent.command operation do |sub| sub.action do |, , args| exit_code = execute(operation, args, , ) exit exit_code if exit_code != 0 end end end |
.subcommand_long_desc(operation) ⇒ String
Builds the man-page-style long_desc for a sub-command.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/pvectl/commands/service.rb', line 114 def self.subcommand_long_desc(operation) action = operation.to_s confirm_note = if CONFIRMABLE_OPERATIONS.include?(operation) "This operation is irreversible. Without --yes, pvectl will\n prompt for interactive confirmation before contacting the API." else "No confirmation is required for this operation." end <<~HELP #{action.capitalize} a systemd service on a Proxmox node. EXAMPLES $ pvectl service #{action} pveproxy --node pve1 $ pvectl service #{action} pveproxy --node pve1 --yes NOTES #{confirm_note} Restarting pveproxy or corosync can momentarily disconnect the current API session and break cluster membership respectively. --node defaults to the context's default-node. SEE ALSO pvectl help service Parent command pvectl help get List resources (try `get services`) HELP end |
Instance Method Details
#execute ⇒ Integer
Executes the command.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/pvectl/commands/service.rb', line 175 def execute return usage_error("service name is required") if @args.empty? service_name = @args.first load_config node = resolve_node return config_error("node is required (provide --node or configure default-node)") unless node return ExitCodes::SUCCESS unless confirm!(service_name, node) result = perform(service_name, node) output_result(result) result.failed? ? ExitCodes::GENERAL_ERROR : ExitCodes::SUCCESS rescue Pvectl::Config::ConfigNotFoundError, Pvectl::Config::InvalidConfigError, Pvectl::Config::ContextNotFoundError, Pvectl::Config::ClusterNotFoundError, Pvectl::Config::UserNotFoundError => e $stderr.puts "Error: #{e.}" ExitCodes::CONFIG_ERROR rescue StandardError => e $stderr.puts "Error: #{e.}" ExitCodes::GENERAL_ERROR end |