module NexusSW::LXD::Driver::Mixins::Rest

Attributes

api[R]
driver_options[R]
rest_endpoint[R]

Public Class Methods

new(rest_endpoint, driver_options = {}, inner_driver = nil) click to toggle source

PARITY note: CLI functions are on an indefinite timeout by default, yet we have a 2 minute socket read timeout Leaving it alone, for now, on calls that are quick in nature Adapting on known long running calls such as create, stop, execute

# File lib/nexussw/lxd/driver/mixins/rest.rb, line 13
def initialize(rest_endpoint, driver_options = {}, inner_driver = nil)
  @rest_endpoint = rest_endpoint
  @driver_options = driver_options
  apioptions = (driver_options || {}).merge(
    api_endpoint: rest_endpoint,
    auto_sync: true
  )
  @api = inner_driver || RestAPI.new(apioptions)
end

Public Instance Methods

container(container_id) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 108
def container(container_id)
  Driver.convert_bools api.container(container_id)[:metadata]
end
container_exists?(container_id) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 112
def container_exists?(container_id)
  api.containers[:metadata].map { |url| url.split("/").last }.include? container_id
end
container_state(container_id) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 103
def container_state(container_id)
  return nil unless container_status(container_id) == "running" # Parity with CLI
  api.container_state(container_id)[:metadata]
end
container_status(container_id) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 99
def container_status(container_id)
  STATUS_CODES[api.container(container_id)[:metadata][:status_code].to_i]
end
create_container(container_name, container_options = {}) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 35
def create_container(container_name, container_options = {})
  autostart = (container_options.delete(:autostart) != false)
  if container_exists?(container_name)
    start_container(container_name) if autostart
    return container_name
  end
  # parity note: CLI will run indefinitely rather than timeout hence the 0 timeout
  retry_forever do
    api.create_container(container_name, container_options.merge(sync: false))
  end
  start_container(container_name) if autostart
  container_name
end
delete_container(container_id) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 92
def delete_container(container_id)
  return unless container_exists? container_id
  stop_container container_id, force: true

  api.delete_container container_id
end
server_info() click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 27
def server_info
  api.server_info
end
start_container(container_id) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 54
def start_container(container_id)
  return if container_status(container_id) == "running"
  retry_forever do
    api.start_container(container_id, sync: false)
  end
  wait_for_status container_id, "running"
end
stop_container(container_id, options = {}) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 62
def stop_container(container_id, options = {})
  return if container_status(container_id) == "stopped"
  if options[:force]
    api.stop_container(container_id, force: true)
  else
    last_id = nil
    use_last = false
    LXD.with_timeout_and_retries({ timeout: 0 }.merge(options)) do # timeout: 0 to enable retry functionality
      return if container_status(container_id) == "stopped"
      begin
        unless use_last
          # Keep resubmitting until the server complains (Stops will be ignored/hang if init is not yet listening for SIGPWR i.e. recently started)
          begin
            last_id = api.stop_container(container_id, sync: false)[:metadata][:id]
          rescue NexusSW::LXD::RestAPI::Error::BadRequest # Happens if a stop command has previously been accepted as well as other reasons.  handle that on next line
            # if we have a last_id then a prior stop command has successfully initiated so we'll just wait on that one
            raise unless last_id # rubocop:disable Metrics/BlockNesting
            use_last = true
          end
        end
        api.wait_for_operation last_id # , options[:retry_interval]
      rescue Faraday::TimeoutError => e
        return if container_status(container_id) == "stopped"
        raise Timeout::Retry.new e # if options[:retry_interval] # rubocop:disable Style/RaiseArgs
      end
    end
  end
  wait_for_status container_id, "stopped"
end
transport_for(container_name) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 31
def transport_for(container_name)
  Transport::Rest.new container_name, info: server_info, connection: api, driver_options: driver_options, rest_endpoint: rest_endpoint
end
update_container(container_name, container_options) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 49
def update_container(container_name, container_options)
  api.update_container(container_name, container_options)
  container(container_name)
end

Protected Instance Methods

wait_for_status(container_id, newstatus) click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 118
def wait_for_status(container_id, newstatus)
  loop do
    return if container_status(container_id) == newstatus
    sleep 0.5
  end
end

Private Instance Methods

retry_forever() { || ... } click to toggle source
# File lib/nexussw/lxd/driver/mixins/rest.rb, line 127
def retry_forever
  retval = yield
  LXD.with_timeout_and_retries timeout: 0 do
    begin
      api.wait_for_operation retval[:metadata][:id]
    rescue Faraday::TimeoutError => e
      raise Timeout::Retry.new e # rubocop:disable Style/RaiseArgs
    end
  end
end