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



129
130
131
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 129

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
# 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
    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 if options[:capture] == :interactive
  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



117
118
119
# File 'lib/nexussw/lxd/transport/mixins/rest.rb', line 117

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

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



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

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



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

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