X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/4cf4e2cdd773448ce62d2ba5f0e6ca9b1446cba4..ccd618998410873f09444c1fb121e3f9decddc8a:/sdk/cli/bin/arv diff --git a/sdk/cli/bin/arv b/sdk/cli/bin/arv index 947d58e9ac..4db95c846f 100755 --- a/sdk/cli/bin/arv +++ b/sdk/cli/bin/arv @@ -10,6 +10,26 @@ if RUBY_VERSION < '1.9.3' then EOS end +# read authentication data from ~/.arvados if present +lineno = 0 +config_file = File.expand_path('~/.arvados') +if File.exist? config_file then + File.open(config_file, 'r').each do |line| + lineno = lineno + 1 + # skip comments + if line.match('^\s*#') then + next + end + var, val = line.chomp.split('=', 2) + # allow environment settings to override config files. + if var and val + ENV[var] ||= val + else + warn "#{config_file}: #{lineno}: could not parse `#{line}'" + end + end +end + case ARGV[0] when 'keep' ARGV.shift @@ -40,6 +60,9 @@ when 'pipeline' "(see arv-run-pipeline-instance --help for details)\n" end abort +when 'tag' + ARGV.shift + exec `which arv-tag`.strip, *ARGV end ENV['ARVADOS_API_VERSION'] ||= 'v1' @@ -51,6 +74,7 @@ ARVADOS_API_HOST and ARVADOS_API_TOKEN need to be defined as environment variabl end begin + require 'curb' require 'rubygems' require 'google/api_client' require 'json' @@ -59,12 +83,13 @@ begin require 'andand' require 'oj' require 'active_support/inflector' + require 'yaml' rescue LoadError abort <<-EOS Please install all required gems: - gem install google-api-client json trollop andand oj activesupport + gem install activesupport andand curb google-api-client json oj trollop EOS end @@ -176,6 +201,7 @@ def parse_arguments(discovery_document) opt :json, "Return the entire response received from the API server, as a JSON object", :short => "-j" opt :human, "Return the response received from the API server, as a JSON object with whitespace added for human consumption", :short => "-h" opt :pretty, "Synonym of --human", :short => nil + opt :yaml, "Return the response received from the API server, in YAML format", :short => "-y" stop_on resource_types end @@ -214,12 +240,20 @@ def parse_arguments(discovery_document) if body_object["required"] == false is_required = false end - opt resource.to_sym, "#{resource} (request body)", required: is_required, type: :string + opt resource.to_sym, "#{resource} (request body)", { + required: is_required, + type: :string + } + discovered_params[resource.to_sym] = body_object end end + discovered_params.each do |k,v| + k = k.to_sym if ['object', 'array'].index(v["type"]) and method_opts.has_key? k - method_opts[k] = JSON.parse method_opts[k] + if method_opts[k].andand.match /^\// + method_opts[k] = File.open method_opts[k], 'rb' do |f| f.read end + end end end return resource, method, method_opts, global_opts, ARGV @@ -241,16 +275,44 @@ request_parameters = {}.merge(method_opts) resource_body = request_parameters.delete(resource_schema.to_sym) if resource_body request_body = { - resource_schema => JSON.parse(resource_body) + resource_schema => resource_body } else request_body = {} end -request_body[:api_token] = ENV['ARVADOS_API_TOKEN'] -result = client.execute(:api_method => eval(api_method), - :parameters => request_parameters, - :body => request_body, - :authenticated => false) + +case api_method +when + 'arvados.users.event_stream', + 'arvados.jobs.log_stream', + 'arvados.jobs.log_tail_follow' + + # Special case for methods that respond with data streams rather + # than JSON (TODO: use the discovery document instead of a static + # list of methods) + uri_s = eval(api_method).generate_uri(request_parameters) + Curl::Easy.perform(uri_s) do |curl| + curl.headers['Accept'] = 'text/plain' + curl.headers['Authorization'] = "OAuth2 #{ENV['ARVADOS_API_TOKEN']}" + if ENV['ARVADOS_API_HOST_INSECURE'] + curl.ssl_verify_peer = false + curl.ssl_verify_host = false + end + if global_opts[:verbose] + curl.on_header { |data| $stderr.write data } + end + curl.on_body { |data| $stdout.write data } + end + exit 0 +else + request_body[:api_token] = ENV['ARVADOS_API_TOKEN'] + request_body[:_profile] = true + result = client.execute(:api_method => eval(api_method), + :parameters => request_parameters, + :body => request_body, + :authenticated => false) +end + begin results = JSON.parse result.body rescue JSON::ParserError => e @@ -263,6 +325,8 @@ end if global_opts[:human] or global_opts[:pretty] then puts Oj.dump(results, :indent => 1) +elsif global_opts[:yaml] then + puts results.to_yaml elsif global_opts[:json] then puts Oj.dump(results) elsif results["items"] and results["kind"].match /list$/i