Method: OpsWalrus::RemoteImportInvocationContext#_invoke_remote

Defined in:
lib/opswalrus/invocation.rb

#_invoke_remote(*args, **kwargs) ⇒ Object



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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/opswalrus/invocation.rb', line 96

def _invoke_remote(*args, **kwargs)
  # when there are args or kwargs, then the method invocation represents an attempt to run an OpsFile on a remote host,
  # so we want to build up a command and send it to the remote host via HostDSL#run_ops
  @method_chain.unshift(Bundler::BUNDLE_DIR) if @is_invocation_a_call_to_package_in_bundle_dir

  remote_run_command_args = @method_chain.join(" ")

  unless args.empty?
    remote_run_command_args << " "
    remote_run_command_args << args.join(" ")
  end

  # unless kwargs.empty?
  #   remote_run_command_args << " "
  #   remote_run_command_args << kwargs.map do |k, v|
  #     case v
  #     when Array
  #       v.map {|v_element| "#{k}:#{v_element}" }
  #     else
  #       "#{k}:#{v}"
  #     end
  #   end.join(" ")
  # end
  begin
    json = JSON.dump(kwargs) unless kwargs.empty?
    if json
      # write the kwargs to a tempfile
      json_kwargs_tempfile = Tempfile.create('ops_invoke_kwargs')
      json_kwargs_tempfile.write(json)
      json_kwargs_tempfile.close()   # we want to close the file without unlinking so that we can copy it to the remote host before deleting it

      # upload the kwargs file to the remote host
      json_kwargs_tempfile_path = json_kwargs_tempfile.path.to_pathname
      remote_json_kwargs_tempfile_basename = json_kwargs_tempfile_path.basename
      @host_proxy.upload(json_kwargs_tempfile_path, remote_json_kwargs_tempfile_basename)
    end

    # invoke the ops command on the remote host to run the specified ops script on the remote host
    ops_command_options = "--script"
    ops_command_options << " --pass" if @ops_prompt_for_sudo_password
    ops_command_options << " --params #{remote_json_kwargs_tempfile_basename}" if remote_json_kwargs_tempfile_basename

    output, stderr, exit_status = if ops_command_options.empty?
      @host_proxy.run_ops(:run, remote_run_command_args, ops_prompt_for_sudo_password: @ops_prompt_for_sudo_password)
    else
      @host_proxy.run_ops(:run, ops_command_options, remote_run_command_args, ops_prompt_for_sudo_password: @ops_prompt_for_sudo_password)
    end

    App.instance.debug("Remote invocation failed:\n  cmd: ops run #{ops_command_options.to_s} #{remote_run_command_args.to_s}\n  stdout: #{output}\n") unless exit_status == 0

    RemoteInvocation.parse_remote_script_invocation_result(output)
  ensure
    if json_kwargs_tempfile
      json_kwargs_tempfile.close rescue nil
      File.unlink(json_kwargs_tempfile) rescue nil
    end
    # todo: make sure this cleanup is present
    if remote_json_kwargs_tempfile_basename
      # this may fail if the remote host reboots and we try to subsequently connect and delete the file
      @host_proxy.execute(:rm, "-f", remote_json_kwargs_tempfile_basename) rescue nil
    end
  end
end