<commit_before>require 'nexussw/lxd/driver/mixins/helpers/wait'
require 'nexussw/lxd/transport/rest'
require 'hyperkit'

module NexusSW
  module LXD
    class Driver
      module Mixins
        module Rest
          # 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
          # REQUEST_TIMEOUT = 120 # upstream default: 120
          def initialize(rest_endpoint, driver_options = {}, inner_driver = nil)
            @rest_endpoint = rest_endpoint
            @driver_options = driver_options
            hkoptions = (driver_options || {}).merge(
              api_endpoint: rest_endpoint,
              auto_sync: true
            )
            @hk = inner_driver || Hyperkit::Client.new(hkoptions)
          end

          attr_reader :hk, :rest_endpoint, :driver_options

          include Helpers::WaitMixin

          def server_info
            @server_info ||= hk.get('/1.0')[:metadata]
          end

          def transport_for(container_name)
            Transport::Rest.new container_name, info: server_info, connection: hk, driver_options: driver_options, rest_endpoint: rest_endpoint
          end

          def create_container(container_name, container_options = {})
            if container_exists?(container_name)
              start_container container_name # Start the container for Parity with the CLI
              return container_name
            end
            # parity note: CLI will run indefinitely rather than timeout hence the 0 timeout
            retry_forever do
              @hk.create_container(container_name, container_options.merge(sync: false))
            end
            start_container container_name
            container_name
          end

          def start_container(container_id)
            return if container_status(container_id) == 'running'
            retry_forever do
              @hk.start_container(container_id, sync: false)
            end
            wait_for_status container_id, 'running'
          end

          def stop_container(container_id, options = {})
            return if container_status(container_id) == 'stopped'
            if options[:force]
              @hk.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 = @hk.stop_container(container_id, sync: false)[:id]
                    rescue Hyperkit::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
                  @hk.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

          def delete_container(container_id)
            return unless container_exists? container_id
            stop_container container_id, force: true

            # ISSUE 17: something upstream is causing a double-tap on the REST endpoint
            begin
              @hk.delete_container container_id
            rescue ::Faraday::ConnectionFailed<commit_msg>well ok I guess it throws them both randomly #17<commit_after>require 'nexussw/lxd/driver/mixins/helpers/wait'
require 'nexussw/lxd/transport/rest'
require 'hyperkit'

module NexusSW
  module LXD
    class Driver
      module Mixins
        module Rest
          # 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
          # REQUEST_TIMEOUT = 120 # upstream default: 120
          def initialize(rest_endpoint, driver_options = {}, inner_driver = nil)
            @rest_endpoint = rest_endpoint
            @driver_options = driver_options
            hkoptions = (driver_options || {}).merge(
              api_endpoint: rest_endpoint,
              auto_sync: true
            )
            @hk = inner_driver || Hyperkit::Client.new(hkoptions)
          end

          attr_reader :hk, :rest_endpoint, :driver_options

          include Helpers::WaitMixin

          def server_info
            @server_info ||= hk.get('/1.0')[:metadata]
          end

          def transport_for(container_name)
            Transport::Rest.new container_name, info: server_info, connection: hk, driver_options: driver_options, rest_endpoint: rest_endpoint
          end

          def create_container(container_name, container_options = {})
            if container_exists?(container_name)
              start_container container_name # Start the container for Parity with the CLI
              return container_name
            end
            # parity note: CLI will run indefinitely rather than timeout hence the 0 timeout
            retry_forever do
              @hk.create_container(container_name, container_options.merge(sync: false))
            end
            start_container container_name
            container_name
          end

          def start_container(container_id)
            return if container_status(container_id) == 'running'
            retry_forever do
              @hk.start_container(container_id, sync: false)
            end
            wait_for_status container_id, 'running'
          end

          def stop_container(container_id, options = {})
            return if container_status(container_id) == 'stopped'
            if options[:force]
              @hk.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 = @hk.stop_container(container_id, sync: false)[:id]
                    rescue Hyperkit::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
                  @hk.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

          def delete_container(container_id)
            return unless container_exists? container_id
            stop_container container_id, force: true

            # ISSUE 17: something upstream is causing a double-tap on the REST endpoint
            begin
              @hk.delete_container container_id
            rescue ::Faraday::ConnectionFailed, ::Hyperkit::BadRequest
{'fraction_non_alphanumeric': 0.05834797891036907, 'fraction_numerical': 0.0035149384885764497, 'mean_word_length': 1.940406476059249, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7304260', 'n_tokens_mistral': 2174, 'n_tokens_neox': 2045, 'n_words': 663}