Class: Pvectl::Commands::RollbackSnapshot

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/commands/rollback_snapshot.rb,
sig/pvectl/commands/rollback_snapshot.rbs

Overview

Handler for the pvectl rollback snapshot command.

Rolls back a VM/container to a snapshot. Requires --yes flag for confirmation. Only supports single VMID.

Examples:

Rollback to snapshot

pvectl rollback snapshot 100 before-upgrade --yes

Start after rollback (LXC only)

pvectl rollback snapshot 100 before-upgrade --yes --start

Constant Summary collapse

SUPPORTED_RESOURCES =

Returns:

  • (Array[String])
%w[snapshot].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource_type, args, options, global_options) ⇒ RollbackSnapshot

Initializes a rollback snapshot command.

Parameters:

  • resource_type (String, nil)

    resource type (snapshot)

  • args (Array<String>, String, nil)

    VMID and snapshot name

  • options (Hash)

    command options

  • global_options (Hash)

    global CLI options



98
99
100
101
102
103
104
105
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 98

def initialize(resource_type, args, options, global_options)
  @resource_type = resource_type
  @args = Array(args).compact
  @options = options
  @global_options = global_options
  @too_many_args = false
  parse_args!
end

Class Method Details

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

Executes the rollback snapshot command.

Parameters:

  • resource_type (String, nil)

    resource type (snapshot)

  • args (Array<String>, String, nil)

    VMID and snapshot name

  • options (Hash)

    command options

  • global_options (Hash)

    global CLI options

Returns:

  • (Integer)

    exit code



88
89
90
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 88

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

.register(cli) ⇒ void

This method returns an undefined value.

Registers the rollback command with the CLI.

Parameters:

  • cli (GLI::App)

    the CLI application object



21
22
23
24
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
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 21

def self.register(cli)
  cli.desc "Rollback to a snapshot"
  cli.long_desc "    Rollback a virtual machine or container to a previous snapshot,\n    restoring its disk (and optionally RAM) state to the snapshot point.\n\n    WARNING: All changes made after the snapshot will be lost.\n\n    EXAMPLES\n      Rollback a VM to a snapshot:\n        $ pvectl rollback snapshot 100 before-upgrade --yes\n\n      Rollback and start the VM after:\n        $ pvectl rollback snapshot 100 before-upgrade --yes --start\n\n      Async rollback:\n        $ pvectl rollback snapshot 100 before-upgrade --yes --async\n\n    NOTES\n      Rollback always operates on a single VM/container (not batch).\n\n      The VM/container will be stopped during rollback if running.\n\n      --yes is required \u2014 rollback is a destructive operation that\n      discards all changes since the snapshot.\n\n    SEE ALSO\n      pvectl help create snapshot Create a snapshot before changes\n      pvectl help get snapshots   List available snapshots\n      pvectl help describe snapshot  View snapshot details\n  HELP\n  cli.arg_name \"RESOURCE_TYPE ID SNAPSHOT_NAME\"\n  cli.command :rollback do |c|\n    c.desc \"Skip confirmation prompt (REQUIRED for destructive operations)\"\n    c.switch [:yes, :y], negatable: false\n\n    c.desc \"Start VM/container after rollback (LXC only)\"\n    c.switch [:start], negatable: false\n\n    c.desc \"Timeout in seconds for sync operations\"\n    c.flag [:timeout], type: Integer, arg_name: \"SECONDS\"\n\n    c.desc \"Force async mode (return task ID immediately)\"\n    c.switch [:async], negatable: false\n\n    c.action do |global_options, options, args|\n      resource_type = args.shift\n      exit_code = Commands::RollbackSnapshot.execute(\n        resource_type,\n        args,\n        options,\n        global_options\n      )\n      exit exit_code if exit_code != 0\n    end\n  end\nend\n"

Instance Method Details

#determine_exit_code(results) ⇒ Integer

Determines exit code based on results.

Parameters:

Returns:

  • (Integer)

    exit code



211
212
213
214
215
216
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 211

def determine_exit_code(results)
  return ExitCodes::SUCCESS if results.all?(&:successful?)
  return ExitCodes::SUCCESS if results.all?(&:pending?)

  ExitCodes::GENERAL_ERROR
end

#executeInteger

Executes the rollback snapshot command.

Returns:

  • (Integer)

    exit code



110
111
112
113
114
115
116
117
118
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 110

def execute
  return usage_error("Resource type required (snapshot)") unless @resource_type
  return usage_error("Unsupported resource: #{@resource_type}") unless SUPPORTED_RESOURCES.include?(@resource_type)
  return usage_error("Rollback supports only single VMID") if @too_many_args
  return usage_error("VMID and snapshot name required") if @vmid.nil? || @snapshot_name.nil?
  return usage_error("Confirmation required: use --yes to confirm rollback") unless @options[:yes]

  perform_operation
end

#load_configvoid

This method returns an undefined value.

Loads configuration from file or environment.



177
178
179
180
181
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 177

def load_config
  service = Pvectl::Config::Service.new
  service.load(config: @global_options[:config])
  @config = service.current_config
end

#output_results(results) ⇒ void

This method returns an undefined value.

Outputs operation results using the configured formatter.

Parameters:



197
198
199
200
201
202
203
204
205
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 197

def output_results(results)
  presenter = Pvectl::Presenters::SnapshotOperationResult.new
  format = @global_options[:output] || "table"
  color_flag = @global_options[:color]

  formatter = Pvectl::Formatters::Registry.for(format)
  output = formatter.format(results, presenter, color: color_flag)
  puts output
end

#parse_args!void

This method returns an undefined value.

Parses arguments: exactly 2 args - VMID and snapshot name.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 125

def parse_args!
  if @args.size == 2
    @vmid = @args[0].to_i
    @snapshot_name = @args[1]
  elsif @args.size > 2
    # Too many args - rollback only supports single VMID
    @vmid = nil
    @snapshot_name = nil
    @too_many_args = true
  else
    @vmid = nil
    @snapshot_name = nil
  end
end

#perform_operationInteger

Performs the snapshot rollback operation.

Returns:

  • (Integer)

    exit code



143
144
145
146
147
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/rollback_snapshot.rb', line 143

def perform_operation
  load_config
  connection = Pvectl::Connection.new(@config)

  snapshot_repo = Pvectl::Repositories::Snapshot.new(connection)
  resolver = Pvectl::Utils::ResourceResolver.new(connection)
  task_repo = Pvectl::Repositories::Task.new(connection)

  service = Pvectl::Services::Snapshot.new(
    snapshot_repo: snapshot_repo,
    resource_resolver: resolver,
    task_repo: task_repo,
    options: service_options
  )

  result = service.rollback(@vmid, @snapshot_name, start: @options[:start] || false)
  results = [result]

  output_results(results)
  determine_exit_code(results)
rescue Pvectl::Config::ConfigNotFoundError,
       Pvectl::Config::InvalidConfigError,
       Pvectl::Config::ContextNotFoundError,
       Pvectl::Config::ClusterNotFoundError,
       Pvectl::Config::UserNotFoundError
  raise
rescue StandardError => e
  $stderr.puts "Error: #{e.message}"
  ExitCodes::GENERAL_ERROR
end

#service_optionsHash

Builds service options from command options.

Returns:

  • (Hash)

    service options



186
187
188
189
190
191
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 186

def service_options
  opts = {}
  opts[:timeout] = @options[:timeout] if @options[:timeout]
  opts[:async] = true if @options[:async]
  opts
end

#usage_error(message) ⇒ Integer

Outputs usage error and returns exit code.

Parameters:

  • message (String)

    error message

Returns:

  • (Integer)

    exit code



222
223
224
225
# File 'lib/pvectl/commands/rollback_snapshot.rb', line 222

def usage_error(message)
  $stderr.puts "Error: #{message}"
  ExitCodes::USAGE_ERROR
end