Class: Pvectl::Services::CreateContainer

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

Overview

Orchestrates LXC container creation operations.

Handles auto-CTID allocation, parameter building (mapping rootfs/mountpoints/net configs to Proxmox API format), sync/async modes, and optional auto-start.

Examples:

Basic container creation

service = CreateContainer.new(container_repository: ct_repo, task_repository: task_repo)
result = service.execute(hostname: "web-ct", node: "pve1",
                         ostemplate: "local:vztmpl/debian-12.tar.zst",
                         cores: 2, memory: 2048)

Async creation with auto-start

service = CreateContainer.new(container_repository: ct_repo, task_repository: task_repo,
                              options: { async: true, start: true })
result = service.execute(ctid: 200, hostname: "db-ct", node: "pve1",
                         ostemplate: "local:vztmpl/debian-12.tar.zst")

Constant Summary collapse

DEFAULT_TIMEOUT =

Returns Default timeout for create operations (seconds).

Returns:

  • (Integer)

    Default timeout for create operations (seconds)

300
START_TIMEOUT =

Returns Default timeout for start operations (seconds).

Returns:

  • (Integer)

    Default timeout for start operations (seconds)

60

Instance Method Summary collapse

Constructor Details

#initialize(container_repository:, task_repository:, options: {}) ⇒ CreateContainer

Creates a new CreateContainer service.

Parameters:

  • container_repository (Repositories::Container)

    Container repository

  • task_repository (Repositories::Task)

    Task repository

  • options (Hash) (defaults to: {})

    Options (timeout, async, start)

  • container_repository: (Object)
  • task_repository: (Object)
  • options: (Hash[Symbol, untyped]) (defaults to: {})


34
35
36
37
38
# File 'lib/pvectl/services/create_container.rb', line 34

def initialize(container_repository:, task_repository:, options: {})
  @container_repository = container_repository
  @task_repository = task_repository
  @options = options
end

Instance Method Details

#add_mountpoint_params(params, mountpoints) ⇒ void

This method returns an undefined value.

Adds mountpoint parameters mapped to mp0, mp1, etc.

Parameters:

  • params (Hash)

    Parameters hash to modify

  • mountpoints (Array<Hash>)

    Mountpoint configurations



126
127
128
129
130
# File 'lib/pvectl/services/create_container.rb', line 126

def add_mountpoint_params(params, mountpoints)
  mountpoints.each_with_index do |mp, index|
    params[:"mp#{index}"] = Parsers::LxcMountConfig.to_proxmox(mp)
  end
end

#add_net_params(params, nets) ⇒ void

This method returns an undefined value.

Adds network parameters mapped to net0, net1, etc.

Parameters:

  • params (Hash)

    Parameters hash to modify

  • nets (Array<Hash>)

    Network configurations



137
138
139
140
141
# File 'lib/pvectl/services/create_container.rb', line 137

def add_net_params(params, nets)
  nets.each_with_index do |net, index|
    params[:"net#{index}"] = Parsers::LxcNetConfig.to_proxmox(net)
  end
end

#build_params(hostname:, ostemplate:, cores:, memory:, swap:, rootfs:, mountpoints:, nets:, privileged:, features:, password:, ssh_public_keys:, onboot:, startup:, description:, tags:, pool:) ⇒ Hash

Builds Proxmox API parameters from user-friendly options.

Maps rootfs/mountpoint configs through Parsers::LxcMountConfig.to_proxmox and network configs through Parsers::LxcNetConfig.to_proxmox.

Returns:

  • (Hash)

    Proxmox API parameters



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/pvectl/services/create_container.rb', line 99

def build_params(hostname:, ostemplate:, cores:, memory:, swap:, rootfs:,
                 mountpoints:, nets:, privileged:, features:, password:,
                 ssh_public_keys:, onboot:, startup:, description:, tags:, pool:)
  params = { hostname: hostname, ostemplate: ostemplate }
  params[:cores] = cores if cores
  params[:memory] = memory if memory
  params[:swap] = swap if swap
  params[:unprivileged] = privileged ? 0 : 1 unless privileged.nil?
  params[:rootfs] = Parsers::LxcMountConfig.to_proxmox(rootfs) if rootfs
  add_mountpoint_params(params, mountpoints) if mountpoints
  add_net_params(params, nets) if nets
  params[:features] = features if features
  params[:password] = password if password
  params[:"ssh-public-keys"] = ssh_public_keys if ssh_public_keys
  params[:onboot] = onboot ? 1 : 0 unless onboot.nil?
  params[:startup] = startup if startup
  params[:description] = description if description
  params[:tags] = tags if tags
  params[:pool] = pool if pool
  params
end

#build_result(resource_info, **attrs) ⇒ Models::ContainerOperationResult

Builds a ContainerOperationResult with the :create operation.

Creates a minimal Container model for presenter compatibility.

Parameters:

  • resource_info (Hash)

    Resource info (ctid, hostname, node)

  • attrs (Hash)

    Additional result attributes

Returns:



167
168
169
170
171
172
173
174
175
176
# File 'lib/pvectl/services/create_container.rb', line 167

def build_result(resource_info, **attrs)
  container = Models::Container.new(
    vmid: resource_info[:ctid],
    name: resource_info[:hostname],
    node: resource_info[:node]
  )
  Models::ContainerOperationResult.new(
    operation: :create, container: container, resource: resource_info, **attrs
  )
end

#execute(ctid: nil, hostname:, node:, ostemplate:, cores: nil, memory: nil, swap: nil, rootfs: nil, mountpoints: nil, nets: nil, privileged: nil, features: nil, password: nil, ssh_public_keys: nil, onboot: nil, startup: nil, description: nil, tags: nil, pool: nil) ⇒ Models::ContainerOperationResult

Executes container creation operation.

Parameters:

  • ctid (Integer, nil) (defaults to: nil)

    Container identifier (auto-allocated if nil)

  • hostname (String)

    Container hostname

  • node (String)

    Target node

  • ostemplate (String)

    OS template path

  • cores (Integer, nil) (defaults to: nil)

    Number of CPU cores

  • memory (Integer, nil) (defaults to: nil)

    Memory in MB

  • swap (Integer, nil) (defaults to: nil)

    Swap in MB

  • rootfs (Hash, nil) (defaults to: nil)

    Root filesystem config

  • mountpoints (Array<Hash>, nil) (defaults to: nil)

    Mountpoint configurations

  • nets (Array<Hash>, nil) (defaults to: nil)

    Network configurations

  • privileged (Boolean, nil) (defaults to: nil)

    Create privileged container

  • features (String, nil) (defaults to: nil)

    LXC features string

  • password (String, nil) (defaults to: nil)

    Root password

  • ssh_public_keys (String, nil) (defaults to: nil)

    SSH public keys

  • onboot (Boolean, nil) (defaults to: nil)

    Start on boot

  • startup (String, nil) (defaults to: nil)

    Startup order spec

  • description (String, nil) (defaults to: nil)

    Container description

  • tags (String, nil) (defaults to: nil)

    Tags (comma-separated)

  • pool (String, nil) (defaults to: nil)

    Resource pool

Returns:



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
# File 'lib/pvectl/services/create_container.rb', line 62

def execute(ctid: nil, hostname:, node:, ostemplate:, cores: nil, memory: nil,
            swap: nil, rootfs: nil, mountpoints: nil, nets: nil, privileged: nil,
            features: nil, password: nil, ssh_public_keys: nil, onboot: nil,
            startup: nil, description: nil, tags: nil, pool: nil)
  ctid ||= @container_repository.next_available_ctid

  params = build_params(
    hostname: hostname, ostemplate: ostemplate, cores: cores, memory: memory,
    swap: swap, rootfs: rootfs, mountpoints: mountpoints, nets: nets,
    privileged: privileged, features: features, password: password,
    ssh_public_keys: ssh_public_keys, onboot: onboot, startup: startup,
    description: description, tags: tags, pool: pool
  )

  upid = @container_repository.create(node, ctid, params)
  resource_info = { ctid: ctid, hostname: hostname, node: node }

  if @options[:async]
    build_result(resource_info, task_upid: upid, success: :pending)
  else
    task = @task_repository.wait(upid, timeout: timeout)
    start_container(ctid, node) if task.successful? && @options[:start]
    build_result(resource_info, task: task, success: task.successful?)
  end
rescue StandardError => e
  build_result({ ctid: ctid, hostname: hostname, node: node },
               success: false, error: e.message)
end

#start_container(ctid, node) ⇒ void

This method returns an undefined value.

Starts a container after successful creation.

Parameters:

  • ctid (Integer)

    Container identifier

  • node (String)

    Node name



148
149
150
151
# File 'lib/pvectl/services/create_container.rb', line 148

def start_container(ctid, node)
  upid = @container_repository.start(ctid, node)
  @task_repository.wait(upid, timeout: START_TIMEOUT)
end

#timeoutInteger

Returns configured timeout.

Returns:

  • (Integer)

    Timeout in seconds



156
157
158
# File 'lib/pvectl/services/create_container.rb', line 156

def timeout
  @options[:timeout] || DEFAULT_TIMEOUT
end