Module: NexusSW::LXD::Transport::Mixins::Rest

Includes:
Helpers::ExecuteMixin, Helpers::FolderTxfr, Helpers::UsersMixin
Included in:
Rest
Defined in:
lib/nexussw/lxd/transport/mixins/rest.rb

Defined Under Namespace

Classes: StdinStub, WSController

Instance Attribute Summary collapse

Attributes included from Helpers::UsersMixin

#file_mode, #gid, #uid, #username

Instance Method Summary collapse

Methods included from Helpers::UsersMixin

#reset_user, #user

Methods included from Helpers::FolderTxfr

#download_files_individually, #download_folder, #download_using_tarball, #upload_files_individually, #upload_folder, #upload_using_tarball

Methods included from Helpers::ExecuteMixin

#execute

Instance Attribute Details

#apiObject (readonly)

Returns the value of attribute api.



23
24
25
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 23

def api
  @api
end

#configObject (readonly)

Returns the value of attribute config.



23
24
25
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 23

def config
  @config
end

#container_nameObject (readonly)

Returns the value of attribute container_name.



23
24
25
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 23

def container_name
  @container_name
end

#rest_endpointObject (readonly)

Returns the value of attribute rest_endpoint.



23
24
25
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 23

def rest_endpoint
  @rest_endpoint
end

Instance Method Details

#download_file(path, local_path) ⇒ Object



131
132
133
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 131

def download_file(path, local_path)
  api.pull_file container_name, path, local_path
end

#execute_chunked(command, options = {}, &block) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 64

def execute_chunked(command, options = {}, &block)
  opid = nil
  backchannel = nil
  getlogs = false
  command = runas_command(command, options)
  if block_given? && (options[:capture] || !config[:info][:api_extensions].include?("container_exec_recording"))
    apiopts = { 'wait-for-websocket': true, interactive: false, sync: false }
    apiopts[:interactive] = true if options[:capture] == :interactive
    retval = api.execute_command(container_name, command, apiopts)[:metadata]
    opid = retval[:id]
    backchannel = options[:capture] == :interactive ? ws_connect(opid, retval[:metadata][:fds]) : ws_connect(opid, retval[:metadata][:fds], &block)

    # patch for interactive session
    if options[:capture] == :interactive
      return Helpers::ExecuteMixin::InteractiveResult.new(command, options, StdinStub.pipe(backchannel.waitlist[:'0']), backchannel).tap do |active|
        backchannel.callback = proc do |stdout|
          active.send_output stdout
        end
        yield active
        backchannel.exit if backchannel.respond_to? :exit
        retval = api.wait_for_operation opid
        active.exitstatus = retval[:metadata][:return].to_i
      end
    end
  elsif block_given? && config[:info][:api_extensions].include?("container_exec_recording")
    getlogs = true
    retval = api.execute_command(container_name, command, 'record-output': true, interactive: false, sync: false)
    opid = retval[:metadata][:id]
  else
    opid = api.execute_command(container_name, command, sync: false)[:metadata][:id]
  end
  LXD.with_timeout_and_retries({ timeout: 0 }.merge(options)) do
    begin
      retval = api.wait_for_operation(opid)[:metadata]
      backchannel.join if backchannel.respond_to? :join
      if getlogs
        begin
          stdout_log = retval[:metadata][:output][:'1'].split("/").last
          stderr_log = retval[:metadata][:output][:'2'].split("/").last
          stdout = api.log container_name, stdout_log
          stderr = api.log container_name, stderr_log
          yield stdout, stderr

          api.delete_log container_name, stdout_log
          api.delete_log container_name, stderr_log
        end
      end
      return Helpers::ExecuteMixin::ExecuteResult.new command, options, retval[:metadata][:return].to_i
    rescue Faraday::TimeoutError => e
      raise Timeout::Retry.new e # rubocop:disable Style/RaiseArgs
    end
  end
end

#initialize(container_name, config = {}) ⇒ Object



14
15
16
17
18
19
20
21
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 14

def initialize(container_name, config = {})
  @container_name = container_name
  @config = config
  @rest_endpoint = config[:rest_endpoint]
  @driver_options = config[:driver_options]
  @api = config[:connection]
  raise "The rest transport requires the following keys: { :connection, :driver_options, :rest_endpoint }" unless @rest_endpoint && @api && @driver_options
end

#read_file(path) ⇒ Object

empty ” instead of an exception is a chef-provisioning expectation - at this level we’ll let the exception propagate



119
120
121
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 119

def read_file(path)
  api.read_file container_name, path
end

#upload_file(local_path, path, options = {}) ⇒ Object



135
136
137
138
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 135

def upload_file(local_path, path, options = {})
  # return api.push_file(local_path, container_name, path)
  write_file(path, IO.binread(local_path), options)
end

#write_file(path, content, options = {}) ⇒ Object



123
124
125
126
127
128
129
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 123

def write_file(path, content, options = {})
  options = options.merge content: content
  options[:uid] ||= uid if uid
  options[:gid] ||= gid if gid
  options[:file_mode] ||= file_mode if file_mode
  api.write_file container_name, path, options
end