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
- #attach_cloudinit_iso(node, storage_id, iso) ⇒ Object
- #check_template_format(user_data) ⇒ Object
- #cloudinit_clone_args(args, vm_instance) ⇒ Object
- #create_cloudinit_iso(vm_name, configs) ⇒ Object
- #create_temp_directory ⇒ Object
- #delete_temp_dir(working_dir) ⇒ Object
- #generate_iso_command(iso_file, config_files) ⇒ Object
- #parse_cloudinit_config(args, vm_node: ) ⇒ Object
- #parse_server_cloudinit(args) ⇒ Object
- #upload_iso(node, storage_id, iso, vm_node: node) ⇒ Object
Instance Method Details
#attach_cloudinit_iso(node, storage_id, iso) ⇒ Object
140 141 142 143 144 145 146 147 148 149 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 140 def attach_cloudinit_iso(node, storage_id, iso) storage = client.nodes.get(node).storages.get(storage_id) volume = storage&.volumes&.all&.detect do |v| File.basename(v.volid) == File.basename(iso) end raise ::Foreman::Exception, "Could not find generated cloud-init ISO #{File.basename(iso)} on storage #{storage_id} for node #{node}" unless volume { ide2: "#{volume.volid},media=cdrom" } end |
#check_template_format(user_data) ⇒ Object
151 152 153 154 155 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 151 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 |
#cloudinit_clone_args(args, vm_instance) ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 86 def cloudinit_clone_args(args, vm_instance) return args unless args[:user_data] actual_node = vm_instance.node_id logger.info("Cloud-init ISO storage will be validated for cloned VM node #{actual_node} instead of selected node #{args[:node_id]}") if args[:node_id] != actual_node parse_cloudinit_config(args, vm_node: actual_node) end |
#create_cloudinit_iso(vm_name, configs) ⇒ Object
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 48 def create_cloudinit_iso(vm_name, configs) wd = create_temp_directory iso = File.join(wd, "#{vm_name.tr('.', '_')}_cloudinit.iso") files = [] configs.each do |config| config_file = File.join(wd, config[0]) File.write(config_file, config[1]) files.append(config_file) end logger.debug("Generating cloud-init ISO at #{iso}") stdout, stderr, status = Open3.capture3(*generate_iso_command(iso, files)) raise Foreman::Exception, N_("ISO build failed: #{stderr.presence || stdout}") unless status.success? yield iso ensure delete_temp_dir(wd) if wd && Dir.exist?(wd) end |
#create_temp_directory ⇒ Object
74 75 76 77 78 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 74 def create_temp_directory Dir.mktmpdir rescue StandardError => e raise ::Foreman::Exception, "Could not create working directory to store cloudinit config data: #{e}." end |
#delete_temp_dir(working_dir) ⇒ Object
80 81 82 83 84 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 80 def delete_temp_dir(working_dir) FileUtils.remove_entry(working_dir) rescue StandardError => 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'] arguments.concat(config_files) logger.debug("iso image generation args: #{arguments.join(' ')}") arguments end |
#parse_cloudinit_config(args, vm_node: ) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 95 def parse_cloudinit_config(args, vm_node: args[:node_id]) 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) 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 create_cloudinit_iso(args[:name], configs) do |iso| storage = upload_iso(args[:node_id], args[:iso_upload_storage], iso, vm_node: vm_node) args.merge!(attach_cloudinit_iso(vm_node, storage, iso)) end end |
#parse_server_cloudinit(args) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 30 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 |
#upload_iso(node, storage_id, iso, vm_node: node) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'app/helpers/proxmox_vm_cloudinit_helper.rb', line 122 def upload_iso(node, storage_id, iso, vm_node: node) raise ::Foreman::Exception, _('ISO upload storage must be selected') if storage_id.blank? iso_storages = storages(node, 'iso') storage = iso_storages.find { |s| s.identity == storage_id } raise ::Foreman::Exception, "Could not find selected ISO upload storage #{storage_id} for node #{node}" unless storage if node != vm_node vm_storage = storages(vm_node, 'iso').find { |s| s.identity == storage_id } raise ::Foreman::Exception, "Selected ISO upload storage #{storage_id} is not accessible from cloned VM node #{vm_node}" unless vm_storage storage = vm_storage end storage.upload_iso(iso) storage.identity end |