Module: ProxmoxVmCloudinitHelper

Included in:
ProxmoxVmVolumesHelper
Defined in:
app/helpers/proxmox_vm_cloudinit_helper.rb

Overview

Convert a foreman form server hash into a fog-proxmox server attributes hash

Instance Method Summary collapse

Instance Method Details

#attach_cloudinit_iso(node, iso) ⇒ Object



113
114
115
116
117
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 113

def attach_cloudinit_iso(node, iso)
  storage = storages(node, 'iso')[0]
  volume = storage.volumes.detect { |v| v.volid.include? File.basename(iso) }
  { ide2: "#{volume.volid},media=cdrom" }
end

#check_template_format(user_data) ⇒ Object



138
139
140
141
142
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 138

def check_template_format(user_data)
  YAML.safe_load(user_data)
rescue StandardError => e
  raise ::Foreman::Exception, "'User data kind' template provided could not be loaded, please check the format: #{e}"
end

#create_cloudinit_iso(vm_name, configs, ssh) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 45

def create_cloudinit_iso(vm_name, configs, ssh)
  iso = File.join(default_iso_path, "#{vm_name.tr('.', '_')}_cloudinit.iso")
  files = []
  wd = create_temp_directory(ssh)

  configs.each do |config|
    config_file = ssh.run(%(echo "#{config[1]}" >> "#{wd}/#{config[0]}"))
    unless config_file.first.status.zero?
      delete_temp_dir(ssh, wd)
      raise ::Foreman::Exception, "Failed to create file #{config[0]}: #{config_file.first.stdout}"
    end
    files.append(File.join(wd, config[0]))
  end
  generated_iso = ssh.run(generate_iso_command(iso, files))
  unless generated_iso.first.status.zero?
    delete_temp_dir(ssh, wd)
    raise Foreman::Exception, N_("ISO build failed: #{generated_iso.first.stdout}")
  end
  delete_temp_dir(ssh, wd)
  iso
end

#create_temp_directory(ssh) ⇒ Object

Raises:

  • (::Foreman::Exception)


74
75
76
77
78
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 74

def create_temp_directory(ssh)
  res = ssh.run("mktemp -d")
  raise ::Foreman::Exception, "Could not create working directory to store cloudinit config data: #{res.first.stdout}." unless res.first.status.zero?
  res.first.stdout.chomp
end

#default_iso_pathObject



119
120
121
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 119

def default_iso_path
  "/var/lib/vz/template/iso"
end

#delete_temp_dir(ssh, working_dir) ⇒ Object



80
81
82
83
84
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 80

def delete_temp_dir(ssh, working_dir)
  ssh.run("rm -rf #{working_dir}")
rescue Foreman::Exception => e
  logger.warn("Could not delete directory for config files: #{e}. Please delete it manually at #{working_dir}")
end

#generate_iso_command(iso_file, config_files) ⇒ Object



67
68
69
70
71
72
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 67

def generate_iso_command(iso_file, config_files)
  arguments = ["genisoimage", "-output #{iso_file}", '-volid', 'cidata', '-joliet', '-rock']
  iso_command = arguments.concat(config_files).join(' ')
  logger.debug("iso image generation args: #{iso_command}")
  iso_command
end

#parse_cloudinit_config(args) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 86

def parse_cloudinit_config(args)
  filenames = ["meta-data"]
  config_data = ["instance-id: #{args[:name]}"]
  user_data = args.delete(:user_data)
  return args if user_data == ''
  check_template_format(user_data)
  ssh = vm_ssh

  if user_data.include?('#network-config') && user_data.include?('#cloud-config')
    config_data.concat(user_data.split('#network-config'))
    filenames.concat(['user-data', 'network-config'])
  elsif user_data.include?('#network-config') && !user_data.include?('#cloud-config')
    config_data.append(user_data.split('#network-config')[1])
    filenames.append("network-config")
  elsif !user_data.include?('#network-config') && user_data.include?('#cloud-config')
    config_data.append(user_data)
    filenames.append("user-data")
  end

  return args if config_data.length == 1
  configs = filenames.zip(config_data).to_h

  iso = create_cloudinit_iso(args[:name], configs, ssh)
  args[:config_attributes]&.merge!(update_boot_order(args[:image_id]))
  args.merge!(attach_cloudinit_iso(args[:node_id], iso))
end

#parse_server_cloudinit(args) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 27

def parse_server_cloudinit(args)
  cloudinit_h = {}
  cloudinit = args['cloudinit']
  unless ['none'].include? cloudinit
    volid = args['volid']
    storage = args['storage']
    cloudinit_volid = volid if volid
    cloudinit_volid ||= "#{storage}:cloudinit" if storage
    controller = args['controller']
    device = args['device']
    id = "#{controller}#{device}" if controller && device
    cloudinit_h.store(:id, id.to_sym) if id
    cloudinit_h.store(:volid, cloudinit_volid) if cloudinit_volid
    cloudinit_h.store(:media, 'cdrom')
  end
  cloudinit_h
end

#update_boot_order(image_id) ⇒ Object



123
124
125
126
127
128
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 123

def update_boot_order(image_id)
  vm = find_vm_by_uuid(image_id)
  return if vm.disks.nil?
  disks = vm.disks.map { |disk| disk.split(":")[0] }.join(";")
  { boot: "order=" + disks }
end

#vm_sshObject



130
131
132
133
134
135
136
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 130

def vm_ssh
  ssh = Fog::SSH.new(URI.parse(fog_credentials[:proxmox_url]).host, fog_credentials[:proxmox_username].split('@')[0], { password: fog_credentials[:proxmox_password] })
  ssh.run('ls') # test if ssh is successful
  ssh
rescue StandardError => e
  raise ::Foreman::Exception, "Unable to ssh into proxmox server: #{e}"
end