| require "#{__dir__}/response/success.rb" |
| require "#{__dir__}/response/error.rb" |
| require "#{__dir__}/filepath.rb" |
| |
| class RunApp |
| include Filepath |
| |
| def call(env) |
| if !File.exist? ENTRYPOINT then |
| return ErrorResponse.new 'Invalid Action: no action file found', 500 |
| end |
| |
| # Set environment variables |
| body = Rack::Request.new(env).body.read |
| data = JSON.parse(body) || {} |
| env = {'BUNDLE_GEMFILE' => PROGRAM_DIR + 'Gemfile'} |
| ['api_key', 'namespace', 'action_name', 'activation_id', 'deadline'].each{|e| |
| env["__OW_#{e.upcase}"] = data[e] if data[e] && data[e].is_a?(String) |
| } |
| |
| # Save parameter values to file in order to let runner.rb read this later |
| File.write PARAM, data['value'].to_json |
| |
| # Execute the action with given parameters |
| if system(env, "bundle exec ruby -r #{ENTRYPOINT} #{RACKAPP_DIR}runner.rb | tee #{OUT}") then |
| if File.exist? RESULT then |
| result = File.read(RESULT) |
| if valid_json?(result) then |
| SuccessResponse.new(JSON.parse(result)) |
| else |
| warn "Result must be an array but has type '#{result.class.to_s}': #{result}" |
| ErrorResponse.new 'The action did not return a dictionary.', 502 |
| end |
| else |
| ErrorResponse.new 'Invalid Action: An error occurred running the action', 502 |
| end |
| else |
| ErrorResponse.new "Invalid Action: the execution was not successful. / #{File.read(OUT)}}", 502 |
| end |
| end |
| |
| private |
| def valid_json?(json) |
| JSON.parse(json).class == Hash |
| rescue |
| false |
| end |
| end |