Class: Pvectl::Commands::Apt

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/commands/apt.rb

Overview

Top-level ‘pvectl apt` command for managing APT packages on Proxmox nodes.

Exposes four sub-commands:

  • ‘apt list` list pending package updates

  • ‘apt update` refresh the package index (apt-get update)

  • ‘apt changelog` show changelog for a package

  • ‘apt versions` list installed Proxmox-relevant package versions

Each sub-command requires ‘–node NODE` (falls back to default-node from the active context configuration when not provided).

Examples:

Register with the CLI

Commands::Apt.register(cli)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(operation, args, options, global_options, output: $stdout) ⇒ Apt

Initializes an apt command instance.

Parameters:

  • operation (Symbol)

    operation

  • args (Array<String>)

    positional CLI arguments

  • options (Hash)

    command options

  • global_options (Hash)

    global CLI options

  • output (IO) (defaults to: $stdout)

    IO for output (default: $stdout)



218
219
220
221
222
223
224
# File 'lib/pvectl/commands/apt.rb', line 218

def initialize(operation, args, options, global_options, output: $stdout)
  @operation = operation
  @args = Array(args).compact
  @options = options
  @global_options = global_options
  @output = output
end

Class Method Details

.execute(operation, args, options, global_options) ⇒ Integer

Executes the command.

Parameters:

  • operation (Symbol)

    :list, :update, :changelog, :versions

  • args (Array<String>)

    positional CLI arguments

  • options (Hash)

    command options

  • global_options (Hash)

    global CLI options

Returns:

  • (Integer)

    exit code



207
208
209
# File 'lib/pvectl/commands/apt.rb', line 207

def self.execute(operation, args, options, global_options)
  new(operation, args, options, global_options).execute
end

.register(cli) ⇒ void

This method returns an undefined value.

Registers the apt command and all sub-commands with the CLI.

Parameters:

  • cli (GLI::App)

    the CLI application object



25
26
27
28
29
30
31
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
# File 'lib/pvectl/commands/apt.rb', line 25

def self.register(cli)
  cli.desc "Manage APT packages on Proxmox nodes"
  cli.long_desc <<~HELP
    DESCRIPTION
      Manage APT (Advanced Package Tool) packages on Proxmox VE nodes.
      Wraps the Proxmox /nodes/{node}/apt API to inspect pending updates,
      refresh the package index, read package changelogs, and report
      installed Proxmox-relevant package versions.

    SUB-COMMANDS
      apt list                 List pending package updates
      apt update               Refresh the package index (apt-get update)
      apt changelog PACKAGE    Show changelog for a package
      apt versions             Show installed Proxmox package versions

    EXAMPLES
      List pending updates on a node:
        $ pvectl apt list --node pve1

      Refresh the package index on the default node:
        $ pvectl apt update

      Refresh quietly without sending update notifications:
        $ pvectl apt update --node pve1 --quiet

      Show changelog for a specific package version:
        $ pvectl apt changelog pve-manager --node pve1 --version 8.2.4-1

      Inspect installed Proxmox versions (parity with pveversion -v):
        $ pvectl apt versions --node pve1 -o wide

    NOTES
      --node defaults to the context's default-node when configured.

      Proxmox does NOT expose `apt upgrade` over the API (security
      restriction). To actually install updates you must SSH to the
      node and run apt full-upgrade manually.

      `apt update` is asynchronous; the response includes the Proxmox
      task UPID, inspect with `pvectl get tasks` and
      `pvectl logs task UPID`.

    SEE ALSO
      pvectl help get             List resources (try `get nodes`)
      pvectl help logs            Inspect task output
  HELP

  cli.command :apt do |c|
    # Shared --node flag declared on the parent so every subcommand inherits it.
    c.desc "Node name (defaults to context default-node)"
    c.flag [:node], arg_name: "NODE"

    register_list(c)
    register_update(c)
    register_changelog(c)
    register_versions(c)
  end
end

.register_changelog(parent) ⇒ void

This method returns an undefined value.

Registers the ‘apt changelog` subcommand.

Parameters:

  • parent (GLI::Command)

    parent apt command



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/pvectl/commands/apt.rb', line 148

def self.register_changelog(parent)
  parent.desc "Show the changelog for an APT package on a node"
  parent.long_desc <<~HELP
    Show the upstream changelog for a package on the target node. When
    --version is omitted the latest available version's changelog is
    returned.

    EXAMPLES
      $ pvectl apt changelog pve-manager --node pve1
      $ pvectl apt changelog pve-manager --node pve1 --version 8.2.4-1

    SEE ALSO
      pvectl help apt          Parent command
  HELP
  parent.arg_name "PACKAGE"
  parent.command :changelog do |sub|
    sub.desc "Package version (optional, defaults to latest)"
    sub.flag [:version], arg_name: "VERSION"

    sub.action do |global_options, options, args|
      exit_code = execute(:changelog, args, options, global_options)
      exit exit_code if exit_code != 0
    end
  end
end

.register_list(parent) ⇒ void

This method returns an undefined value.

Registers the ‘apt list` subcommand.

Parameters:

  • parent (GLI::Command)

    parent apt command



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/pvectl/commands/apt.rb', line 88

def self.register_list(parent)
  parent.desc "List pending APT updates on a node"
  parent.long_desc <<~HELP
    List packages that have an available APT update on the target node.

    EXAMPLES
      $ pvectl apt list --node pve1
      $ pvectl apt list --node pve1 -o wide
      $ pvectl apt list --node pve1 -o json

    SEE ALSO
      pvectl help apt          Parent command
  HELP
  parent.command :list do |sub|
    sub.action do |global_options, options, args|
      exit_code = execute(:list, args, options, global_options)
      exit exit_code if exit_code != 0
    end
  end
end

.register_update(parent) ⇒ void

This method returns an undefined value.

Registers the ‘apt update` subcommand.

Parameters:

  • parent (GLI::Command)

    parent apt command



113
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/apt.rb', line 113

def self.register_update(parent)
  parent.desc "Refresh the APT package index on a node (apt-get update)"
  parent.long_desc <<~HELP
    Refresh the APT package index on the target node. Equivalent to
    running `apt-get update` directly on the node.

    This does NOT install updates — Proxmox does not expose apt upgrade
    over the API for security reasons.

    EXAMPLES
      $ pvectl apt update --node pve1
      $ pvectl apt update --node pve1 --quiet
      $ pvectl apt update --node pve1 --notify

    SEE ALSO
      pvectl help apt          Parent command
  HELP
  parent.command :update do |sub|
    sub.desc "Send a notification about new packages"
    sub.switch [:notify], negatable: false

    sub.desc "Suppress progress output"
    sub.switch [:quiet], negatable: false

    sub.action do |global_options, options, args|
      exit_code = execute(:update, args, options, global_options)
      exit exit_code if exit_code != 0
    end
  end
end

.register_versions(parent) ⇒ void

This method returns an undefined value.

Registers the ‘apt versions` subcommand.

Parameters:

  • parent (GLI::Command)

    parent apt command



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/apt.rb', line 178

def self.register_versions(parent)
  parent.desc "Show installed Proxmox package versions on a node"
  parent.long_desc <<~HELP
    Show installed versions of important Proxmox VE packages on the
    target node — parity with `pveversion -v` on the node itself.

    EXAMPLES
      $ pvectl apt versions --node pve1
      $ pvectl apt versions --node pve1 -o wide
      $ pvectl apt versions --node pve1 -o yaml

    SEE ALSO
      pvectl help apt          Parent command
  HELP
  parent.command :versions do |sub|
    sub.action do |global_options, options, args|
      exit_code = execute(:versions, args, options, global_options)
      exit exit_code if exit_code != 0
    end
  end
end

Instance Method Details

#executeInteger

Executes the command.

Returns:

  • (Integer)

    exit code



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/pvectl/commands/apt.rb', line 229

def execute
  load_config
  node = resolve_node
  return config_error("node is required (provide --node or configure default-node)") unless node

  case @operation
  when :list      then run_list(node)
  when :update    then run_update(node)
  when :changelog then run_changelog(node)
  when :versions  then run_versions(node)
  else
    usage_error("Unknown apt operation: #{@operation}")
  end
rescue Pvectl::Config::ConfigNotFoundError,
       Pvectl::Config::InvalidConfigError,
       Pvectl::Config::ContextNotFoundError,
       Pvectl::Config::ClusterNotFoundError,
       Pvectl::Config::UserNotFoundError => e
  $stderr.puts "Error: #{e.message}"
  ExitCodes::CONFIG_ERROR
rescue StandardError => e
  $stderr.puts "Error: #{e.message}"
  ExitCodes::GENERAL_ERROR
end