Class: Pvectl::Repositories::Backup

Inherits:
Base
  • Object
show all
Defined in:
lib/pvectl/repositories/backup.rb,
sig/pvectl/repositories/backup.rbs

Overview

Repository for backup operations in Proxmox.

Handles listing, creating, deleting, and restoring backups via the Proxmox API (vzdump).

Examples:

Listing backups

repo = Backup.new(connection)
backups = repo.list(node: "pve1", storage: "local")

Creating a backup

upid = repo.create(100, "pve1", storage: "local", mode: "snapshot")

Restoring a backup

upid = repo.restore("local:backup/vzdump-qemu-100.vma.zst", "pve1", vmid: 200)

See Also:

Instance Attribute Summary

Attributes inherited from Base

#connection

Instance Method Summary collapse

Methods inherited from Base

#build_model, #extract_data, #get, #initialize, #models_from, #unwrap

Constructor Details

This class inherits a constructor from Pvectl::Repositories::Base

Instance Method Details

#build_backup_model(data, node, storage) ⇒ Models::Backup

Builds a Backup model from API response data.



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/pvectl/repositories/backup.rb', line 153

def build_backup_model(data, node, storage)
  Models::Backup.new(
    volid: data[:volid] || data["volid"],
    vmid: data[:vmid] || data["vmid"],
    node: node,
    storage: storage,
    size: data[:size] || data["size"],
    ctime: data[:ctime] || data["ctime"],
    format: data[:format] || data["format"],
    notes: data[:notes] || data["notes"],
    protected: (data[:protected] || data["protected"]) == 1
  )
end

#create(vmid, node, storage:, mode: "snapshot", compress: "zstd", notes: nil, protected: false) ⇒ String

Creates a backup using vzdump.



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/pvectl/repositories/backup.rb', line 59

def create(vmid, node, storage:, mode: "snapshot", compress: "zstd", notes: nil, protected: false)
  params = {
    vmid: vmid,
    storage: storage,
    mode: mode,
    compress: compress
  }
  params[:notes] = notes if notes
  params[:protected] = 1 if protected

  connection.client["nodes/#{node}/vzdump"].post(params)
end

#delete(volid, node) ⇒ String?

Deletes a backup.



77
78
79
80
81
# File 'lib/pvectl/repositories/backup.rb', line 77

def delete(volid, node)
  storage = parse_storage(volid)
  encoded_volid = ERB::Util.url_encode(volid)
  connection.client["nodes/#{node}/storage/#{storage}/content/#{encoded_volid}"].delete
end

#detect_type_from_volid(volid) ⇒ Symbol

Detects resource type from volid pattern.



179
180
181
182
183
# File 'lib/pvectl/repositories/backup.rb', line 179

def detect_type_from_volid(volid)
  return :lxc if volid.include?("vzdump-lxc")

  :qemu
end

#list(vmid: nil, storage: nil, node: nil) ⇒ Array<Models::Backup>

Lists backups from storage.

When node and storage are not specified, discovers all nodes and backup-capable storages automatically.



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/pvectl/repositories/backup.rb', line 35

def list(vmid: nil, storage: nil, node: nil)
  nodes = node ? [node] : list_nodes
  storages_by_node = storage ? Hash[nodes.map { |n| [n, [storage]] }] : nil

  backups = []
  nodes.each do |n|
    backup_storages = storages_by_node ? storages_by_node[n] : list_backup_storages(n)
    backup_storages.each do |s|
      backups.concat(list_from_storage(n, s, vmid: vmid))
    end
  end
  backups
end

#list_backup_storages(node) ⇒ Array<String>

Lists storages that support backup content on a node.



123
124
125
126
127
128
129
# File 'lib/pvectl/repositories/backup.rb', line 123

def list_backup_storages(node)
  response = connection.client["nodes/#{node}/storage"].get
  response.select do |s|
    content = s[:content] || s["content"] || ""
    content.include?("backup")
  end.map { |s| s[:storage] || s["storage"] }
end

#list_from_storage(node, storage, vmid: nil) ⇒ Array<Models::Backup>

Lists backups from a specific storage on a node.



137
138
139
140
141
142
143
144
145
# File 'lib/pvectl/repositories/backup.rb', line 137

def list_from_storage(node, storage, vmid: nil)
  response = connection.client["nodes/#{node}/storage/#{storage}/content"].get(params: { content: "backup" })

  backups = response.map do |data|
    build_backup_model(data, node, storage)
  end

  vmid ? backups.select { |b| b.vmid == vmid } : backups
end

#list_nodesArray<String>

Lists all nodes in the cluster.



114
115
116
117
# File 'lib/pvectl/repositories/backup.rb', line 114

def list_nodes
  response = connection.client["nodes"].get
  response.map { |n| n[:node] || n["node"] }
end

#parse_storage(volid) ⇒ String

Extracts storage name from volid.



171
172
173
# File 'lib/pvectl/repositories/backup.rb', line 171

def parse_storage(volid)
  volid.split(":").first
end

#restore(volid, node, vmid:, storage: nil, force: false, start: false, unique: false) ⇒ String

Restores a backup to a new or existing VM/container.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/pvectl/repositories/backup.rb', line 93

def restore(volid, node, vmid:, storage: nil, force: false, start: false, unique: false)
  resource_type = detect_type_from_volid(volid)
  endpoint = resource_type == :lxc ? "lxc" : "qemu"

  params = {
    archive: volid,
    vmid: vmid
  }
  params[:storage] = storage if storage
  params[:force] = 1 if force
  params[:start] = 1 if start
  params[:unique] = 1 if unique

  connection.client["nodes/#{node}/#{endpoint}"].post(params)
end