Module: ForemanFogProxmox::ProxmoxVolumes

Includes:
ProxmoxVmHelper
Included in:
Proxmox, ProxmoxVmCommands
Defined in:
app/models/foreman_fog_proxmox/proxmox_volumes.rb

Instance Method Summary collapse

Methods included from ProxmoxVmHelper

#parse_typed_vm, #vm_collection

Methods included from ProxmoxVmOsTemplateHelper

#ostemplate_keys, #parse_container_ostemplate, #parse_ostemplate, #parse_ostemplate_without_keys

Methods included from ProxmoxVmConfigHelper

#args_a, #config_a, #config_general_or_ostemplate_key?, #config_options, #config_typed_keys, #general_a, #object_to_config_hash, #parse_typed_cpu, #parse_typed_memory, #parsed_typed_config

Methods included from ProxmoxVmVolumesHelper

#add_disk_options, #add_typed_volume, #parse_hard_disk_volume, #parse_typed_volume, #parse_typed_volumes, #parsed_typed_volumes, #remove_volume_keys, #volume_type?

Methods included from ProxmoxVmCloudinitHelper

#parse_server_cloudinit

Methods included from ProxmoxVmCdromHelper

#parse_server_cdrom

Methods included from ProxmoxVmInterfacesHelper

#add_or_delete_typed_interface, #compute_dhcps, #interface_common_typed_keys, #interface_compute_attributes_typed_keys, #parse_typed_interfaces, #parsed_typed_interfaces

Instance Method Details

#add_volume(vm, id, volume_attributes) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 132

def add_volume(vm, id, volume_attributes)
  disk_attributes = { id: id }
  if volume_type?(volume_attributes, 'hard_disk')
    options = volume_options(vm, id, volume_attributes)
    disk_attributes[:storage] = volume_attributes['storage']
    disk_attributes[:size] = volume_attributes['size']
  elsif volume_type?(volume_attributes, 'cdrom')
    disk_attributes[:volid] = volume_attributes[:iso]
  elsif volume_type?(volume_attributes, 'cloud_init')
    disk_attributes[:storage] = volume_attributes['storage']
    disk_attributes[:volid] = "#{volume_attributes['storage']}:cloudinit"
  end
  logger.info("vm #{vm.identity} add volume #{id}")
  logger.debug("add_volume(#{vm.identity}) disk_attributes=#{disk_attributes}")
  vm.attach(disk_attributes, options)
end

#delete_volume(vm, id, volume_attributes) ⇒ Object



27
28
29
30
31
32
33
34
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 27

def delete_volume(vm, id, volume_attributes)
  logger.info("vm #{vm.identity} delete volume #{id}")
  vm.detach(id)
  return unless volume_type?(volume_attributes, 'hard_disk')

  device = Fog::Proxmox::DiskHelper.extract_device(id)
  vm.detach('unused' + device.to_s)
end

#extend_volume(vm, id, diff_size) ⇒ Object



61
62
63
64
65
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 61

def extend_volume(vm, id, diff_size)
  extension = "+#{diff_size}G"
  logger.info("vm #{vm.identity} extend volume #{id} to #{extension}")
  vm.extend(id, extension)
end

#extract_id(vm, volume_attributes) ⇒ Object



121
122
123
124
125
126
127
128
129
130
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 121

def extract_id(vm, volume_attributes)
  id = ''
  if volume_exists?(vm, volume_attributes)
    id = volume_attributes['id']
  else
    device = vm.container? ? 'mp' : volume_attributes['controller']
    id = volume_type?(volume_attributes, 'cdrom') ? 'ide2' : device + volume_attributes['device']
  end
  id
end

#move_volume(id, vm, new_storage) ⇒ Object



67
68
69
70
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 67

def move_volume(id, vm, new_storage)
  logger.info("vm #{vm.identity} move volume #{id} into #{new_storage}")
  vm.move(id, new_storage)
end

#save_volume(vm, volume_attributes) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 149

def save_volume(vm, volume_attributes)
  logger.debug("save_volume(#{vm.identity}) volume_attributes=#{volume_attributes}")
  id = extract_id(vm, volume_attributes)
  if volume_exists?(vm, volume_attributes)
    if volume_to_delete?(volume_attributes)
      delete_volume(vm, id, volume_attributes)
    else
      disk = vm.config.disks.get(id)
      update_volume(vm, disk, volume_attributes) if update_volume_required?(disk.attributes, volume_attributes)
    end
  else
    add_volume(vm, id, volume_attributes)
  end
end

#update_cdrom(vm, disk, volume_attributes) ⇒ Object



50
51
52
53
54
55
56
57
58
59
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 50

def update_cdrom(vm, disk, volume_attributes)
  new_disk = { id: disk.id }
  if ['none', 'cdrom'].include?(volume_attributes[:cdrom])
    new_disk[:volid] = volume_attributes[:cdrom]
  else
    new_disk[:storage] = volume_attributes[:storage]
    new_disk[:volid] = volume_attributes[:volid]
  end
  vm.attach(new_disk, {})
end

#update_options(disk, vm, volume_attributes) ⇒ Object



72
73
74
75
76
77
78
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 72

def update_options(disk, vm, volume_attributes)
  options = volume_options(vm, disk.id, volume_attributes) if volume_type?(volume_attributes, 'hard_disk')
  logger.info("vm #{vm.identity} update volume #{disk.id} to #{options}")
  new_disk = { id: disk.id }
  new_disk[:volid] = disk.volid
  vm.attach(new_disk, options)
end

#update_volume(vm, disk, volume_attributes) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 80

def update_volume(vm, disk, volume_attributes)
  id = disk.id
  if volume_type?(volume_attributes, 'cdrom')
    update_cdrom(vm, disk, volume_attributes)
  elsif volume_type?(volume_attributes, 'hard_disk')
    diff_size = volume_attributes['size'].to_i - disk.size.to_i if volume_attributes['size'] && disk.size
    unless diff_size >= 0
      raise ::Foreman::Exception,
        format(_('Unable to shrink %<id>s size. Proxmox allows only increasing size.'), id: id)
    end
    diff_size = volume_attributes['size'].to_i - disk.size.to_i if volume_attributes['size'] && disk.size
    raise ::Foreman::Exception, format(_('Unable to shrink %<id>s size. Proxmox allows only increasing size.'), id: id) unless diff_size >= 0

    new_storage = volume_attributes['storage']

    if diff_size > 0
      extend_volume(vm, id, diff_size)
    elsif disk.storage != new_storage
      move_volume(id, vm, new_storage)
    else
      update_options(disk, vm, volume_attributes)
    end
  end
end

#update_volume_required?(old_volume_attributes, new_volume_attributes) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
48
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 43

def update_volume_required?(old_volume_attributes, new_volume_attributes)
  old_h = ForemanFogProxmox::HashCollection.new_hash_reject_empty_values(old_volume_attributes)
  new_h = ForemanFogProxmox::HashCollection.new_hash_reject_empty_values(new_volume_attributes)
  new_h = ForemanFogProxmox::HashCollection.new_hash_reject_keys(new_h, ['cdrom', 'cloudinit', 'storage_type'])
  !ForemanFogProxmox::HashCollection.equals?(old_h.with_indifferent_access, new_h.with_indifferent_access)
end

#volume_exists?(vm, volume_attributes) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
108
109
110
111
112
113
114
115
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 105

def volume_exists?(vm, volume_attributes)
  disk = vm.config.disks.get(volume_attributes['id'])
  return false unless disk

  # Return boolean if disk of type hard_disk, cloud_init, cdrom or rootfs(LXC container) exists
  if disk.hard_disk? || disk.cloud_init? || disk.rootfs?
    volume_attributes['volid'].present?
  elsif disk.cdrom?
    volume_attributes['cdrom'].present?
  end
end

#volume_options(vm, id, volume_attributes) ⇒ Object



36
37
38
39
40
41
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 36

def volume_options(vm, id, volume_attributes)
  options = {}
  options.store(:mp, volume_attributes['mp']) if vm.container? && id != 'rootfs'
  options.store(:cache, volume_attributes['cache']) unless vm.container? || volume_attributes['cache'].empty?
  options
end

#volume_to_delete?(volume_attributes) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
# File 'app/models/foreman_fog_proxmox/proxmox_volumes.rb', line 117

def volume_to_delete?(volume_attributes)
  volume_attributes['_delete'].blank? ? false : Foreman::Cast.to_bool(volume_attributes['_delete'])
end