Class: Pvectl::Repositories::Container
- Defined in:
- lib/pvectl/repositories/container.rb
Overview
Repository for LXC containers.
Uses the ‘/cluster/resources` API endpoint to list containers across the cluster. Filters to only include LXC containers (excludes QEMU VMs).
Instance Method Summary collapse
-
#clone(ctid, node, new_ctid, options = {}) ⇒ String
Clones a container to create a new container.
-
#convert_to_template(ctid, node) ⇒ void
Converts a container to a template.
-
#create(node, ctid, params = {}) ⇒ String
Creates a new LXC container on the specified node.
-
#delete(ctid, node, destroy_disks: true, purge: false, force: false) ⇒ String
Deletes a container from the cluster.
-
#describe(ctid) ⇒ Models::Container?
Describes a container with comprehensive details from multiple API endpoints.
-
#feature_available?(ctid, node, feature, snapname: nil) ⇒ Hash
Checks whether a feature (clone, snapshot, copy) is available for a container.
-
#fetch_config(node, ctid) ⇒ Hash
Fetches container configuration.
-
#get(ctid) ⇒ Models::Container?
Gets a single container by CTID.
-
#list(node: nil) ⇒ Array<Models::Container>
Lists all containers in the cluster.
-
#migrate(ctid, node, params = {}) ⇒ String
Migrates a container to another node.
-
#move_volume(ctid, node, volume, target_storage, delete: false, bwlimit: nil) ⇒ String
Moves a container volume to a different storage on the same node.
-
#next_available_ctid ⇒ Integer
Returns the next available CTID from the Proxmox cluster.
-
#resize(ctid, node, disk:, size:) ⇒ nil
Resizes a container disk.
-
#restart(ctid, node) ⇒ String
Restarts a container (reboot).
-
#shutdown(ctid, node) ⇒ String
Shuts down a container gracefully.
-
#start(ctid, node) ⇒ String
Starts a container.
-
#stop(ctid, node) ⇒ String
Stops a container (hard stop).
-
#termproxy(ctid, node) ⇒ Hash
Opens a terminal proxy session for a container.
-
#update(ctid, node, params = {}) ⇒ nil
Updates an existing LXC container configuration.
Methods inherited from Base
Constructor Details
This class inherits a constructor from Pvectl::Repositories::Base
Instance Method Details
#clone(ctid, node, new_ctid, options = {}) ⇒ String
Clones a container to create a new container.
Posts to ‘/nodes/node/lxc/ctid/clone` with the specified parameters. Note: LXC API uses `hostname` parameter (not `name` like QEMU).
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/pvectl/repositories/container.rb', line 131 def clone(ctid, node, new_ctid, = {}) params = { newid: new_ctid } params[:hostname] = [:hostname] if [:hostname] params[:target] = [:target] if [:target] params[:storage] = [:storage] if [:storage] params[:full] = [:full] ? 1 : 0 if .key?(:full) params[:description] = [:description] if [:description] params[:pool] = [:pool] if [:pool] connection.client["nodes/#{node}/lxc/#{ctid}/clone"].post(params) end |
#convert_to_template(ctid, node) ⇒ void
This method returns an undefined value.
Converts a container to a template.
This is an irreversible operation. The container will become read-only and can only be used as a source for cloning.
151 152 153 |
# File 'lib/pvectl/repositories/container.rb', line 151 def convert_to_template(ctid, node) connection.client["nodes/#{node}/lxc/#{ctid}/template"].post({}) end |
#create(node, ctid, params = {}) ⇒ String
Creates a new LXC container on the specified node.
Posts to ‘/nodes/node/lxc` with the container configuration parameters. The ctid is merged into params automatically.
273 274 275 276 |
# File 'lib/pvectl/repositories/container.rb', line 273 def create(node, ctid, params = {}) api_params = params.merge(vmid: ctid) connection.client["nodes/#{node}/lxc"].post(api_params) end |
#delete(ctid, node, destroy_disks: true, purge: false, force: false) ⇒ String
Deletes a container from the cluster.
79 80 81 82 83 84 85 86 |
# File 'lib/pvectl/repositories/container.rb', line 79 def delete(ctid, node, destroy_disks: true, purge: false, force: false) params = {} params["destroy-unreferenced-disks"] = 1 if destroy_disks params[:purge] = 1 if purge params[:force] = 1 if force connection.client["nodes/#{node}/lxc/#{ctid}"].delete(params) end |
#describe(ctid) ⇒ Models::Container?
Describes a container with comprehensive details from multiple API endpoints.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/pvectl/repositories/container.rb', line 54 def describe(ctid) ctid = ctid.to_i basic_data = find_container_basic_data(ctid) return nil if basic_data.nil? node = basic_data[:node] config = fetch_config(node, ctid) status = fetch_status(node, ctid) snapshots = fetch_snapshots(node, ctid) tasks = fetch_tasks(node, ctid) firewall = fetch_firewall(node, ctid) build_describe_model(basic_data, config, status, snapshots, tasks, firewall) end |
#feature_available?(ctid, node, feature, snapname: nil) ⇒ Hash
Checks whether a feature (clone, snapshot, copy) is available for a container.
Calls GET /nodes/{node}/lxc/{vmid}/feature with the feature and optional snapshot name. The Proxmox LXC API returns hasFeature (0/1). Unlike the QEMU variant, the LXC endpoint does not return a nodes array; this method always returns nodes: [] for shape compatibility.
217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/pvectl/repositories/container.rb', line 217 def feature_available?(ctid, node, feature, snapname: nil) params = { feature: feature } params[:snapname] = snapname unless snapname.nil? response = connection.client["nodes/#{node}/lxc/#{ctid}/feature"].get(params: params) data = extract_data(response) { available: data[:hasFeature].to_i == 1, nodes: Array(data[:nodes]) } end |
#fetch_config(node, ctid) ⇒ Hash
Fetches container configuration.
311 312 313 314 315 316 |
# File 'lib/pvectl/repositories/container.rb', line 311 def fetch_config(node, ctid) resp = connection.client["nodes/#{node}/lxc/#{ctid}/config"].get extract_data(resp) rescue StandardError {} end |
#get(ctid) ⇒ Models::Container?
Gets a single container by CTID.
46 47 48 |
# File 'lib/pvectl/repositories/container.rb', line 46 def get(ctid) list.find { |ct| ct.vmid == ctid.to_i } end |
#list(node: nil) ⇒ Array<Models::Container>
Lists all containers in the cluster.
Uses ‘/cluster/resources?type=lxc` endpoint for efficient cluster-wide listing. Filters to only include LXC containers (type == “lxc”).
35 36 37 38 39 40 |
# File 'lib/pvectl/repositories/container.rb', line 35 def list(node: nil) response = connection.client["cluster/resources"].get(params: { type: "vm" }) containers = unwrap(response).select { |r| r[:type] == "lxc" } containers = containers.select { |r| r[:node] == node } if node containers.map { |data| build_model(data) } end |
#migrate(ctid, node, params = {}) ⇒ String
Migrates a container to another node.
162 163 164 165 166 167 168 169 170 171 |
# File 'lib/pvectl/repositories/container.rb', line 162 def migrate(ctid, node, params = {}) unless node.match?(/\A[a-z][a-z0-9-]*\z/) raise ArgumentError, "Invalid node name: #{node}" end unless ctid.is_a?(Integer) && ctid.positive? raise ArgumentError, "Invalid CTID: #{ctid}" end connection.client["nodes/#{node}/lxc/#{ctid}/migrate"].post(params) end |
#move_volume(ctid, node, volume, target_storage, delete: false, bwlimit: nil) ⇒ String
Moves a container volume to a different storage on the same node.
POSTs to /nodes/{node}/lxc/{ctid}/move_volume with the volume identifier and target storage. The operation is asynchronous — the returned UPID can be polled via Repositories::Task to track completion.
193 194 195 196 197 198 199 |
# File 'lib/pvectl/repositories/container.rb', line 193 def move_volume(ctid, node, volume, target_storage, delete: false, bwlimit: nil) params = { volume: volume, storage: target_storage } params[:delete] = 1 if delete params[:bwlimit] = bwlimit if bwlimit connection.client["nodes/#{node}/lxc/#{ctid}/move_volume"].post(params) end |
#next_available_ctid ⇒ Integer
Returns the next available CTID from the Proxmox cluster.
Uses the /cluster/nextid API endpoint which performs server-side allocation. This is more reliable than client-side scanning because it detects stale config files that don’t appear in /cluster/resources.
237 238 239 |
# File 'lib/pvectl/repositories/container.rb', line 237 def next_available_ctid connection.client["cluster/nextid"].get.to_i end |
#resize(ctid, node, disk:, size:) ⇒ nil
Resizes a container disk.
PUTs to /nodes/{node}/lxc/{ctid}/resize with disk identifier and new size. This is a synchronous, irreversible operation —Proxmox does not support shrinking disks.
302 303 304 |
# File 'lib/pvectl/repositories/container.rb', line 302 def resize(ctid, node, disk:, size:) connection.client["nodes/#{node}/lxc/#{ctid}/resize"].put({ disk: disk, size: size }) end |
#restart(ctid, node) ⇒ String
Restarts a container (reboot).
246 247 248 |
# File 'lib/pvectl/repositories/container.rb', line 246 def restart(ctid, node) connection.client["nodes/#{node}/lxc/#{ctid}/status/reboot"].post end |
#shutdown(ctid, node) ⇒ String
Shuts down a container gracefully.
111 112 113 |
# File 'lib/pvectl/repositories/container.rb', line 111 def shutdown(ctid, node) connection.client["nodes/#{node}/lxc/#{ctid}/status/shutdown"].post end |
#start(ctid, node) ⇒ String
Starts a container.
93 94 95 |
# File 'lib/pvectl/repositories/container.rb', line 93 def start(ctid, node) connection.client["nodes/#{node}/lxc/#{ctid}/status/start"].post end |
#stop(ctid, node) ⇒ String
Stops a container (hard stop).
102 103 104 |
# File 'lib/pvectl/repositories/container.rb', line 102 def stop(ctid, node) connection.client["nodes/#{node}/lxc/#{ctid}/status/stop"].post end |
#termproxy(ctid, node) ⇒ Hash
Opens a terminal proxy session for a container.
255 256 257 258 |
# File 'lib/pvectl/repositories/container.rb', line 255 def termproxy(ctid, node) response = connection.client["nodes/#{node}/lxc/#{ctid}/termproxy"].post({}) extract_data(response) end |
#update(ctid, node, params = {}) ⇒ nil
Updates an existing LXC container configuration.
PUTs to /nodes/{node}/lxc/{ctid}/config with configuration parameters. This is a synchronous operation — changes are applied immediately.
287 288 289 |
# File 'lib/pvectl/repositories/container.rb', line 287 def update(ctid, node, params = {}) connection.client["nodes/#{node}/lxc/#{ctid}/config"].put(params) end |