diff --git a/src/cli/oneimage b/src/cli/oneimage index ea5b07b94f..3822d5222a 100755 --- a/src/cli/oneimage +++ b/src/cli/oneimage @@ -176,6 +176,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + download_desc = <<-EOT.unindent + Downloads an image to a file + EOT + + command :download, download_desc, :imageid, :path do + helper.perform_action(args[0],options,"downloaded") do |image| + image.download(args[1], helper.client) + end + end + delete_desc = <<-EOT.unindent Deletes the given Image EOT diff --git a/src/cli/onemarketapp b/src/cli/onemarketapp index d803e3417e..4451e3b07c 100755 --- a/src/cli/onemarketapp +++ b/src/cli/onemarketapp @@ -19,9 +19,11 @@ ONE_LOCATION=ENV["ONE_LOCATION"] if !ONE_LOCATION - RUBY_LIB_LOCATION="/usr/lib/one/ruby" + RUBY_LIB_LOCATION = "/usr/lib/one/ruby" + VAR_LOCATION = "/var/lib/one" else - RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" + RUBY_LIB_LOCATION = ONE_LOCATION + "/lib/ruby" + VAR_LOCATION = ONE_LOCATION + "/var" end $: << RUBY_LIB_LOCATION @@ -125,6 +127,16 @@ CommandParser::CmdParser.new(ARGV) do end end + download_desc = <<-EOT.unindent + Downloads a MarketApp to a file + EOT + + command :download, download_desc, :appid, :path do + helper.perform_action(args[0],options,"downloaded") do |app| + app.download(args[1], helper.client) + end + end + delete_desc = <<-EOT.unindent Deletes the given marketplace app EOT diff --git a/src/oca/ruby/opennebula/image.rb b/src/oca/ruby/opennebula/image.rb index 6c7cf5fa44..275bb43e82 100644 --- a/src/oca/ruby/opennebula/image.rb +++ b/src/oca/ruby/opennebula/image.rb @@ -252,6 +252,57 @@ module OpenNebula def snapshot_flatten(snap_id) return call(IMAGE_METHODS[:snapshotflatten], @pe_id, snap_id) end + + ####################################################################### + # OCA specific methods + ####################################################################### + + # Invokes 'download.sh' to copy the image to the specified path + # It calls the /export action and downloader.sh + # + # @param path The destination of the downloader.sh action + # @param client The request client + # + # @return [nil, OpenNebula::Error] nil in case of success or Error + def download(path, client) + rc = info + return rc if OpenNebula.is_error?(rc) + + ds_id = self['DATASTORE_ID'] + ds = Datastore.new(Datastore.build_xml(ds_id), client) + + rc = ds.info + return rc if OpenNebula.is_error?(rc) + + drv_message = "" << + "#{to_xml}#{ds.to_xml}" << + "" + + drv_message_64 = Base64::strict_encode64(drv_message) + + export = "#{VAR_LOCATION}/remotes/datastore/#{ds['DS_MAD']}/export" + + export_stdout = `#{export} #{drv_message_64} #{id}` + doc = REXML::Document.new(export_stdout).root + + import_source = doc.elements['IMPORT_SOURCE'].text rescue nil + + if import_source.nil? || import_source.empty? + return OpenNebula::Error.new("Cannot find image source.") + end + + download_cmd = "#{VAR_LOCATION}/remotes/datastore/downloader.sh " << + "#{import_source} #{path}" + + system(download_cmd) + + if (status = $?.exitstatus) != 0 + error_msg = "Error executing '#{download_cmd}'. " << + "Exit status: #{status}" + return OpenNebula::Error.new(error_msg) + end + end + ####################################################################### # Helpers to get Image information ####################################################################### diff --git a/src/oca/ruby/opennebula/marketplaceapp.rb b/src/oca/ruby/opennebula/marketplaceapp.rb index 99689d3043..332cb3e5dc 100644 --- a/src/oca/ruby/opennebula/marketplaceapp.rb +++ b/src/oca/ruby/opennebula/marketplaceapp.rb @@ -216,6 +216,45 @@ module OpenNebula end end + # Invokes 'download.sh' to download the app to the specified path + # + # @param path The destination of the downloader.sh action + # @param client The request client + # + # @return [nil, OpenNebula::Error] nil in case of success or Error + def download(path, client) + rc = info + return rc if OpenNebula.is_error?(rc) + + market_id = self['MARKETPLACE_ID'] + market = MarketPlace.new(MarketPlace.build_xml(market_id), client) + + rc = market.info + return rc if OpenNebula.is_error?(rc) + + # This 'drv_message' is missing some elements, compared to the one + # sent by the core. However, 'downloader.sh' only requires the + # MarketPlace information. + drv_message = "" << + "#{market.to_xml}" << + "" + + drv_message_64 = Base64::strict_encode64(drv_message) + + ENV['DRV_ACTION'] = drv_message_64 + + download_cmd = "#{VAR_LOCATION}/remotes/datastore/downloader.sh " << + "#{self['SOURCE']} #{path}" + + system(download_cmd) + + if (status = $?.exitstatus) != 0 + error_msg = "Error executing '#{download_cmd}'. " << + "Exit status: #{status}" + return OpenNebula::Error.new(error_msg) + end + end + # Enables this app def enable return call(MARKETPLACEAPP_METHODS[:enable], @pe_id, true)