module OpenNebulaHelper
Constants
- APPEND
- AS_GROUP
- AS_USER
- BinarySufix
- CAPACITY_OPTIONS_VM
- CLIENT_OPTIONS
- CLI_ADDONS_LOCATION
- DECRYPT
- DESCRIBE
- DRY
- EDITOR_PATH
- EXTENDED
- FORCE
- FORMAT
- GROUP_OPTIONS
- JSON
- KILOBYTES
- NUMERIC
- ONE_VERSION
- OPTIONS
- TABLE_CONF_PATH
- TEMPLATE_NAME_VM
Command line VM template options
- TEMPLATE_OPTIONS
NOTE: Other options defined using this array, add new options at the end
- TEMPLATE_OPTIONS_VM
- UPDATECONF_OPTIONS_VM
- VAR_LOCATION
- XML
Options
- XSD_PATH
- YAML
Public Class Methods
append_template(id, resource, path=nil, xpath='TEMPLATE')
click to toggle source
# File lib/one_helper.rb, line 1560 def OpenNebulaHelper.append_template(id, resource, path=nil, xpath='TEMPLATE') return update_template_helper(true, id, resource, path, xpath) end
boolean_to_str(str)
click to toggle source
# File lib/one_helper.rb, line 1436 def OpenNebulaHelper.boolean_to_str(str) if str.to_i == 1 "Yes" else "No" end end
bytes_to_unit(value, unit = 'K')
click to toggle source
# File lib/one_helper.rb, line 1523 def OpenNebulaHelper.bytes_to_unit(value, unit = 'K') j = 0 i = BinarySufix.index(unit).to_i while j < i do value /= 1024.0 j += 1 end value end
cluster_str(str)
click to toggle source
If the cluster name is empty, returns a '-' char.
@param str [String || Hash] Cluster name, or empty Hash (when <CLUSTER/>) @return [String] the same Cluster name, or '-' if it is empty
# File lib/one_helper.rb, line 1539 def OpenNebulaHelper.cluster_str(str) if str != nil && !str.empty? str else "-" end end
clusters_str(clusters)
click to toggle source
# File lib/one_helper.rb, line 1547 def OpenNebulaHelper.clusters_str(clusters) if clusters.nil? "-" else [clusters].flatten.join(',') end end
create_ar(options)
click to toggle source
# File lib/one_helper.rb, line 1860 def self.create_ar(options) ar = 'AR = [ ' if options[:ip] if options[:ip6_global] || options[:ip6_ula] ar << 'TYPE="IP4_6"' elsif options[:ip6] ar << 'TYPE="IP4_6_STATIC"' else ar << 'TYPE="IP4"' end elsif options[:ip6] ar << 'TYPE="IP6_STATIC"' elsif options[:ip6_global] || options[:ip6_ula] ar << 'TYPE="IP6"' else ar << 'TYPE="ETHER"' end if options[:size] ar << ', SIZE = ' << options[:size] else unless options[:ip6] STDERR.puts 'Address range needs to specify size (-s size)' exit(-1) end end if options[:ip6] m = %r{([\h:]*)\/(\d.*)$}.match(options[:ip6]) if m.nil? || m[1].nil? STDERR.puts 'Missing or wrong IP6' exit(-1) else begin require 'ipaddr' ip = IPAddr.new(m[1]) if !ip.ipv6? STDERR.puts 'Wrong IP6 format address' exit(-1) end rescue StandardError STDERR.puts 'Wrong IP6 format address' exit(-1) end end if m[2].nil? STDERR.puts 'IP6 address need to set the prefix length' exit(-1) end ar << ", PREFIX_LENGTH=\"#{m[2]}\"" options[:ip6] = m[1] end ar << ', IP = ' << options[:ip] if options[:ip] ar << ', IP6 = ' << options[:ip6] if options[:ip6] ar << ', MAC = ' << options[:mac] if options[:mac] if options[:ip6_global] ar << ', GLOBAL_PREFIX = ' << options[:ip6_global] end if options[:ip6_ula] ar << ', ULA_PREFIX = ' << options[:ip6_ula] end ar << ', GATEWAY = ' << options[:gateway] if options[:gateway] ar << ', MASK = ' << options[:netmask] if options[:netmask] ar << ', VN_MAD = ' << options[:vn_mad] if options[:vn_mad] ar << ', VLAN_ID = ' << options[:vlanid] if options[:vlanid] ar << ']' end
create_context(options)
click to toggle source
# File lib/one_helper.rb, line 1713 def self.create_context(options) context_options = [:ssh, :net_context, :context, :init, :files_ds, :startscript, :report_ready] if !(options.keys & context_options).empty? lines=[] if options[:ssh] if options[:ssh]==true lines<<"SSH_PUBLIC_KEY=\"$USER[SSH_PUBLIC_KEY]\"" else begin key=File.read(options[:ssh]).strip rescue Exception => e STDERR.puts e.message exit(-1) end lines<<"SSH_PUBLIC_KEY=\"#{key}\"" end end if options[:net_context] lines << "NETWORK = \"YES\"" end lines+=options[:context] if options[:context] if options[:files_ds] text='FILES_DS="' text << options[:files_ds].map do |file| %Q<$FILE[IMAGE=\\"#{file}\\"]> end.join(' ') text << '"' lines << text end if options[:init] lines << %Q<INIT_SCRIPTS="#{options[:init].join(' ')}"> end if options[:startscript] script = nil begin script = File.read(options[:startscript]).strip rescue Exception => e STDERR.puts e.message exit(-1) end script = Base64::strict_encode64(script) lines<<"START_SCRIPT_BASE64=\"#{script}\"" end if options[:report_ready] lines << "REPORT_READY = \"YES\"" end if !lines.empty? "CONTEXT=[\n" << lines.map{|l| " " << l }.join(",\n") << "\n]\n" else nil end else nil end end
create_disk_net(objects, section, name)
click to toggle source
# File lib/one_helper.rb, line 1662 def self.create_disk_net(objects, section, name) template='' objects.each do |obj| obj, *extra_attributes = obj.split(":") # When extra attributes do not contain = character include # them in the previous value. Fixes adding MAC addresses. These # contain ":" character also used as extra attributes separator. # # It may be needed to strip the value from start and end quotes # as the value could be written as this: # # --nic 'some_net:mac="00:0A:12:34:56:78"' # attrs = [] extra_attributes.each do |str| if str.include?("=") attrs << str else attrs.last << ":#{str}" end end extra_attributes = attrs res=parse_user_object(obj) return [-1, "#{section.capitalize} \"#{obj}\" malformed"] if !res user, object=*res template<<"#{section.upcase}=[\n" if object.downcase == "auto" template<<" NETWORK_MODE=\"#{object}\"\n" else template<<" #{name.upcase}_UNAME=\"#{user}\",\n" if user extra_attributes.each do |extra_attribute| key, value = extra_attribute.split("=") template<<" #{key.upcase}=\"#{value}\",\n" end if object.match(/^\d+$/) template<<" #{name.upcase}_ID=#{object}\n" else template<<" #{name.upcase}=\"#{object}\"\n" end end template<<"]\n" end if objects [0, template] end
create_template(options, template_obj=nil)
click to toggle source
# File lib/one_helper.rb, line 1778 def self.create_template(options, template_obj=nil) template='' template<<"NAME=\"#{options[:name]}\"\n" if options[:name] if options[:arch] || options[:boot] template<<"OS = [\n" lines=[] lines<<" ARCH = \"#{options[:arch]}\"" if options[:arch] lines<<" BOOT = \"#{options[:boot]}\"" if options[:boot] template<<lines.join(",\n") template << " ]\n" end template<<"CPU=#{options[:cpu]}\n" if options[:cpu] template<<"VCPU=#{options[:vcpu]}\n" if options[:vcpu] template<<"MEMORY=#{options[:memory]}\n" if options[:memory] template<<"#{options[:raw]}\n" if options[:raw] template<<"AS_UID=#{options[:as_uid]}\n" if options[:as_uid] template<<"AS_GID=#{options[:as_gid]}\n" if options[:as_gid] if options[:disk] res=create_disk_net(options[:disk], 'DISK', 'IMAGE') return res if res.first!=0 template<<res.last end if options[:nic] res=create_disk_net(options[:nic], 'NIC', 'NETWORK') return res if res.first!=0 template<<res.last end if options[:vnc] vnc_listen=options[:vnc_listen] || "0.0.0.0" template<<"GRAPHICS=[ TYPE=\"vnc\", LISTEN=\"#{vnc_listen}\"" if options[:vnc_password] template << ", PASSWD=\"#{options[:vnc_password]}\"" end if options[:vnc_keymap] template << ", KEYMAP=\"#{options[:vnc_keymap]}\"" end template<<' ]' << "\n" end if options[:spice] spice_listen=options[:spice_listen] || "0.0.0.0" template<<"GRAPHICS=[ TYPE=\"spice\", LISTEN=\"#{spice_listen}\"" if options[:spice_password] template << ", PASSWD=\"#{options[:spice_password]}\"" end if options[:spice_keymap] template << ", KEYMAP=\"#{options[:spice_keymap]}\"" end template<<' ]' << "\n" end template<<"VCENTER_VM_FOLDER=#{options[:vcenter_vm_folder]}\n" if options[:vcenter_vm_folder] context=create_context(options) template<<context if context if options[:userdata] && !template_obj.nil? if template_obj.has_elements?('TEMPLATE/EC2') template_obj.add_element( 'TEMPLATE/EC2', 'USERDATA' => options[:userdata]) template << template_obj.template_like_str( 'TEMPLATE', false, 'EC2') end end [0, template] end
create_template_options_used?(options)
click to toggle source
# File lib/one_helper.rb, line 1938 def self.create_template_options_used?(options) # Get the template options names as symbols. options hash # uses symbols template_options=OpenNebulaHelper::TEMPLATE_OPTIONS.map do |o| o[:name].to_sym end # Check if one at least one of the template options is # in options hash (template_options-options.keys)!=template_options end
download_resource_sunstone(kind, id, path, force)
click to toggle source
# File lib/one_helper.rb, line 1961 def self.download_resource_sunstone(kind, id, path, force) client = OneHelper.client user, password = client.one_auth.split(":", 2) # Step 1: Build Session to get Cookie uri = URI(File.join(sunstone_url,"login")) req = Net::HTTP::Post.new(uri) req.basic_auth user, password begin res = Net::HTTP.start(uri.hostname, uri.port) do |http| http.request(req) end rescue return OpenNebula::Error.new("Error connecting to '#{uri}'.") end cookie = res.response['set-cookie'].split('; ')[0] if cookie.nil? return OpenNebula::Error.new("Unable to get Cookie. Is OpenNebula running?") end # Step 2: Open '/' to get the csrftoken uri = URI(sunstone_url) req = Net::HTTP::Get.new(uri) req['Cookie'] = cookie begin res = Net::HTTP.start(uri.hostname, uri.port) do |http| http.request(req) end rescue return OpenNebula::Error.new("Error connecting to '#{uri}'.") end m = res.body.match(/var csrftoken = '(.*)';/) csrftoken = m[1] rescue nil if csrftoken.nil? return OpenNebula::Error.new("Unable to get csrftoken.") end # Step 3: Download resource uri = URI(File.join(sunstone_url, kind.to_s, id.to_s, "download?csrftoken=#{csrftoken}")) req = Net::HTTP::Get.new(uri) req['Cookie'] = cookie req['User-Agent'] = "OpenNebula CLI" begin File.open(path, 'wb') do |f| Net::HTTP.start(uri.hostname, uri.port) do |http| http.request(req) do |res| res.read_body do |chunk| f.write(chunk) end end end end rescue Errno::EACCES return OpenNebula::Error.new("Target file not writable.") end error_message = nil File.open(path, 'rb') do |f| begin f.seek(-1024, IO::SEEK_END) rescue Errno::EINVAL end tail = f.read m = tail.match(/@\^_\^@ (.*) @\^_\^@/m) error_message = m[1] if m end if error_message File.unlink(path) return OpenNebula::Error.new("Remote server error: #{error_message}") end end
editor_input(contents=nil)
click to toggle source
# File lib/one_helper.rb, line 1620 def OpenNebulaHelper.editor_input(contents=nil) require 'tempfile' tmp = Tempfile.new("one_cli") if contents tmp << contents tmp.flush end editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH system("#{editor_path} #{tmp.path}") unless $?.exitstatus == 0 puts "Editor not defined" exit -1 end tmp.close str = File.read(tmp.path) return str end
get_plot(x, y, attr, title)
click to toggle source
Returns plot object to print it on the CLI
@param x [Array] Data to x axis (Time axis) @param y [Array] Data to y axis @param attr [String] Parameter to y axis @param title [String] Plot title
@return Gnuplot plot object
# File lib/one_helper.rb, line 2263 def OpenNebulaHelper.get_plot(x, y, attr, title) # Require gnuplot gem only here begin require 'gnuplot' rescue LoadError, Gem::LoadError STDERR.puts( 'Gnuplot gem is not installed, run `gem install gnuplot` '\ 'to install it' ) exit(-1) end # Check if gnuplot is installed on the system unless system('gnuplot --version') STDERR.puts( 'Gnuplot is not installed, install it depending on your distro' ) exit(-1) end Gnuplot.open do |gp| Gnuplot::Plot.new(gp) do |p| p.title title p.xlabel 'Time' p.ylabel attr p.xdata 'time' p.timefmt "'%H:%M'" p.format "x '%H:%M'" p.style 'data lines' p.terminal 'dumb' p.data << Gnuplot::DataSet.new([x, y]) do |ds| ds.with = 'linespoints' ds.linewidth = '3' ds.using = '1:2' ds.notitle end end end end
level_lock_to_str(str)
click to toggle source
# File lib/one_helper.rb, line 2051 def OpenNebulaHelper.level_lock_to_str(str) level = str.to_i if level == 0 "None" elsif level == 1 "Use" elsif level == 2 "Manage" elsif level == 3 "Admin" elsif level == 4 "All" else "-" end end
parse_user_inputs(inputs, keys = [])
click to toggle source
# File lib/one_helper.rb, line 2068 def OpenNebulaHelper.parse_user_inputs(inputs, keys = []) unless inputs.keys == keys puts 'There are some parameters that require user input. ' \ 'Use the string <<EDITOR>> to launch an editor ' \ '(e.g. for multi-line inputs)' end answers = {} inputs.each do |key, val| next if keys.include? key input_cfg = val.split('|', -1) if input_cfg.length < 3 STDERR.puts 'Malformed user input. It should have at least 3 '\ "parts separated by '|':" STDERR.puts " #{key}: #{val}" exit(-1) end mandatory, type, description, params, initial = input_cfg optional = mandatory.strip == 'O' type.strip! description.strip! if input_cfg.length > 3 if input_cfg.length != 5 STDERR.puts 'Malformed user input. It should have 5 parts'\ " separated by '|':" STDERR.puts " #{key}: #{val}" exit(-1) end params.strip! initial.strip! end puts " * (#{key}) #{description}" header = ' ' if !initial.nil? && initial != '' header += "Press enter for default (#{initial}). " end case type when 'text', 'text64' print header answer = STDIN.readline.chop if answer == '<<EDITOR>>' answer = OpenNebulaHelper.editor_input end # use default in case it's empty answer = initial if answer.empty? if type == 'text64' answer = Base64.encode64(answer).strip.delete("\n") end when 'boolean' print header answer = STDIN.readline.chop # use default in case it's empty answer = initial if answer.empty? unless %w[YES NO].include?(answer) STDERR.puts "Invalid boolean '#{answer}'" STDERR.puts 'Boolean has to be YES or NO' exit(-1) end when 'password' print header answer = OpenNebulaHelper::OneHelper.get_password # use default in case it's empty answer = initial if answer.empty? when 'number', 'number-float' if type == 'number' header += 'Integer: ' exp = OneTemplateHelper::INT_EXP else header += 'Float: ' exp = OneTemplateHelper::FLOAT_EXP end begin print header answer = STDIN.readline.chop answer = initial if answer == '' noanswer = ((answer == '') && optional) end while !noanswer && (answer =~ exp) == nil if noanswer next end when 'range', 'range-float' min, max = params.split('..') if min.nil? || max.nil? STDERR.puts 'Malformed user input. '\ "Parameters should be 'min..max':" STDERR.puts " #{key}: #{val}" exit(-1) end if type == 'range' exp = OneTemplateHelper::INT_EXP min = min.to_i max = max.to_i header += "Integer in the range [#{min}..#{max}]: " else exp = OneTemplateHelper::FLOAT_EXP min = min.to_f max = max.to_f header += "Float in the range [#{min}..#{max}]: " end begin print header answer = STDIN.readline.chop answer = initial if answer == '' noanswer = (answer == '') && optional end while !noanswer && ((answer =~ exp) == nil || answer.to_f < min || answer.to_f > max) if noanswer next end when 'list' options = params.split(',') options.each_with_index do |opt, i| puts " #{i} #{opt}" end puts header += 'Please type the selection number: ' begin print header answer = STDIN.readline.chop if answer == '' answer = initial else answer = options[answer.to_i] end noanswer = ((answer == '') && optional) end while !noanswer && !options.include?(answer) if noanswer next end when 'fixed' puts " Fixed value of (#{initial}). Cannot be changed" answer = initial else STDERR.puts 'Wrong type for user input:' STDERR.puts " #{key}: #{val}" exit(-1) end answers[key] = answer end answers end
parse_user_object(user_object)
click to toggle source
# File lib/one_helper.rb, line 1644 def self.parse_user_object(user_object) reg=/^([^\[]+)(?:\[([^\]]+)\])?$/ m=user_object.match(reg) return nil if !m user=nil if m[2] user=m[1] object=m[2] else object=m[1] end [user, object] end
period_to_str(time, print_seconds=true)
click to toggle source
# File lib/one_helper.rb, line 1478 def OpenNebulaHelper.period_to_str(time, print_seconds=true) seconds=time.to_i minutes, seconds=seconds.divmod(60) hours, minutes=minutes.divmod(60) days, hours=hours.divmod(24) if print_seconds "%3dd %02dh%02dm%02ds" % [days, hours, minutes, seconds] else "%3dd %02dh%02dm" % [days, hours, minutes] end end
rname_to_id(name, poolname)
click to toggle source
# File lib/one_helper.rb, line 1378 def OpenNebulaHelper.rname_to_id(name, poolname) return 0, name.to_i if name.match(/^[0123456789]+$/) client=OneHelper.client pool = case poolname when "HOST" then OpenNebula::HostPool.new(client) when "HOOK" then OpenNebula::HookPool.new(client) when "GROUP" then OpenNebula::GroupPool.new(client) when "USER" then OpenNebula::UserPool.new(client) when "DATASTORE" then OpenNebula::DatastorePool.new(client) when "CLUSTER" then OpenNebula::ClusterPool.new(client) when "VNET" then OpenNebula::VirtualNetworkPool.new(client) when "IMAGE" then OpenNebula::ImagePool.new(client) when "VMTEMPLATE" then OpenNebula::TemplatePool.new(client) when "VNTEMPLATES" then OpenNebula::VNTemplatePool.new(client) when "VM" then OpenNebula::VirtualMachinePool.new(client) when "ZONE" then OpenNebula::ZonePool.new(client) when "MARKETPLACE" then OpenNebula::MarketPlacePool.new(client) when "FLOWTEMPLATES" then OpenNebula::ServiceTemplatePool.new(client) end rc = pool.info if OpenNebula.is_error?(rc) return -1, "OpenNebula #{poolname} name not found," << " use the ID instead" end OneHelper.name_to_id(name, pool, poolname) end
rname_to_id_desc(poolname)
click to toggle source
# File lib/one_helper.rb, line 1432 def OpenNebulaHelper.rname_to_id_desc(poolname) "OpenNebula #{poolname} name or id" end
short_period_to_str(time, print_seconds=true)
click to toggle source
# File lib/one_helper.rb, line 1491 def OpenNebulaHelper.short_period_to_str(time, print_seconds=true) seconds=time.to_i minutes, seconds=seconds.divmod(60) hours, minutes=minutes.divmod(60) if print_seconds "%3dh%02dm%02ds" % [hours, minutes, seconds] else "%3dh%02dm" % [hours, minutes] end end
size_in_mb(size)
click to toggle source
# File lib/one_helper.rb, line 1409 def OpenNebulaHelper.size_in_mb(size) m = size.match(/^(\d+(?:\.\d+)?)(t|tb|m|mb|g|gb)?$/i) if !m # return OpenNebula::Error.new('Size value malformed') return -1, 'Size value malformed' else multiplier=case m[2] when /(t|tb)/i 1024*1024 when /(g|gb)/i 1024 else 1 end value=m[1].to_f*multiplier # return value.ceil return 0, value.ceil end end
sunstone_url()
click to toggle source
# File lib/one_helper.rb, line 1950 def self.sunstone_url if (one_sunstone = ENV['ONE_SUNSTONE']) one_sunstone elsif (one_xmlrpc = ENV['ONE_XMLRPC']) uri = URI(one_xmlrpc) "#{uri.scheme}://#{uri.host}:9869" else "http://localhost:9869" end end
time_to_str(time, print_seconds=true, print_hours=true, print_years=false)
click to toggle source
# File lib/one_helper.rb, line 1444 def OpenNebulaHelper.time_to_str(time, print_seconds=true, print_hours=true, print_years=false) value = time.to_i if value==0 value='-' else if print_hours if print_seconds if print_years value=Time.at(value).strftime("%m/%d/%y %H:%M:%S") else value=Time.at(value).strftime("%m/%d %H:%M:%S") end else if print_years value=Time.at(value).strftime("%m/%d/%y %H:%M") else value=Time.at(value).strftime("%m/%d %H:%M") end end else if print_years value=Time.at(value).strftime("%m/%d/%y") else value=Time.at(value).strftime("%m/%d") end end end return value end
unit_to_str(value, options, unit="K")
click to toggle source
# File lib/one_helper.rb, line 1505 def OpenNebulaHelper.unit_to_str(value, options, unit="K") if options[:kilobytes] value else i=BinarySufix.index(unit).to_i while value > 1024 && i < 3 do value /= 1024.0 i+=1 end value = (value * 10).round / 10.0 value = value.to_i if value - value.round == 0 st = value.to_s + BinarySufix[i] end end
update_obj(obj, file, plain = false) { |obj| ... }
click to toggle source
# File lib/one_helper.rb, line 1583 def OpenNebulaHelper.update_obj(obj, file, plain = false) rc = obj.info(true) return rc if OpenNebula.is_error?(rc) if file path = file else tmp = Tempfile.new(obj['ID']) path = tmp.path tmp.write(yield(obj)) if block_given? tmp.flush if ENV['EDITOR'] editor_path = ENV['EDITOR'] else editor_path = EDITOR_PATH end system("#{editor_path} #{path}") unless $CHILD_STATUS.exitstatus.zero? STDERR.puts 'Editor not defined' exit(-1) end tmp.close end if plain obj.update(File.read(path), plain) else obj.update(File.read(path)) end end
update_template(id, resource, path=nil, xpath='TEMPLATE')
click to toggle source
# File lib/one_helper.rb, line 1556 def OpenNebulaHelper.update_template(id, resource, path=nil, xpath='TEMPLATE') return update_template_helper(false, id, resource, path, xpath) end
update_template_helper(append, id, resource, path, xpath, update=true)
click to toggle source
# File lib/one_helper.rb, line 1564 def OpenNebulaHelper.update_template_helper(append, id, resource, path, xpath, update=true) if path return File.read(path) elsif append return editor_input() else if update rc = resource.info if OpenNebula.is_error?(rc) puts rc.message exit -1 end end return editor_input(resource.template_like_str(xpath)) end end