Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce AutoHCK::ResourceScope #227

Merged
merged 11 commits into from
Aug 13, 2023
9 changes: 5 additions & 4 deletions bin/auto_hck
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require './lib/config/sentry'

akihikodaki marked this conversation as resolved.
Show resolved Hide resolved
begin
require 'filelock'
require './lib/auxiliary/resource_scope'
require './lib/cli'
require './lib/project'
require './lib/trap'
Expand All @@ -25,8 +26,8 @@ begin
Thread.abort_on_exception = true
Thread.report_on_exception = false

@project = Project.new(cli)
begin
ResourceScope.open do |scope|
@project = Project.new(scope, cli)
Trap.project = @project
@project.run if @project.prepare
rescue StandardError => e
Expand All @@ -37,9 +38,9 @@ begin
@project.log_exception(e, 'fatal')
@project.handle_error
exit(1)
ensure
@project.close
end
rescue AutoHCKInterrupt
exit false
end
rescue StandardError => e
Sentry.capture_exception(e)
Expand Down
21 changes: 9 additions & 12 deletions lib/auxiliary/cmd_run.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'tempfile'
require_relative 'resource_scope'

# AutoHCK module
module AutoHCK
Expand Down Expand Up @@ -42,22 +43,18 @@ def wait_for_status(flags)
_, status = Process.wait2(@pid, flags)
return if status.nil?

begin
begin
@stdout.rewind
stdout = @stdout.read
ensure
@stdout.close
end
ResourceScope.open do |scope|
scope << @stdout
scope << @stderr

@stdout.rewind
stdout = @stdout.read
@stderr.rewind
stderr = @stderr.read
ensure
@stderr.close
end

@logger.info("Info dump:#{prep_log_stream(stdout)}") unless stdout.empty?
@logger.warn("Error dump:#{prep_log_stream(stderr)}") unless stderr.empty?
@logger.info("Info dump:#{prep_log_stream(stdout)}") unless stdout.empty?
@logger.warn("Error dump:#{prep_log_stream(stderr)}") unless stderr.empty?
end

yield status

Expand Down
7 changes: 3 additions & 4 deletions lib/auxiliary/id_gen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
module AutoHCK
# Id Generator class
class Idgen
def initialize(range, timeout)
def initialize(scope, range, timeout)
@db = './id_gen.db'
@range = range
@conn = SQLite3::Database.new @db.to_s
@threshold = timeout * 24 * 60 * 60
@conn = SQLite3::Database.new @db.to_s
scope << @conn
end

def load_data
Expand Down Expand Up @@ -55,8 +56,6 @@ def release(id)
1
rescue SQLite3::Exception
-1
ensure
@conn&.close
end

private
Expand Down
38 changes: 38 additions & 0 deletions lib/auxiliary/resource_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require './lib/exceptions'

module AutoHCK
# ResourceScope is a class that manages objects with close methods.
class ResourceScope
def initialize(resources)
@resources = resources
end

def <<(resource)
@resources << resource
self
end

def transaction
resources = []
self.class.open(resources) do |scope|
result = yield(scope)
@resources.concat resources
resources.clear
result
end
end

def self.open(resources = [])
scope = new(resources)
Thread.handle_interrupt(AutoHCKInterrupt => :never) do
Thread.handle_interrupt(AutoHCKInterrupt => :on_blocking) do
yield scope
end
ensure
resources.reverse_each(&:close)
end
end
end
end
13 changes: 6 additions & 7 deletions lib/engines/config_manager/config_manager.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'fileutils'
require './lib/auxiliary/resource_scope'
require './lib/resultuploaders/result_uploader'

# AutoHCK module
Expand Down Expand Up @@ -34,9 +35,11 @@ def tag
end

def run
@project.logger.info('Stating result uploader token initialization')
@result_uploader = ResultUploader.new(@project)
@result_uploader.ask_token
ResourceScope.open do |scope|
@project.logger.info('Stating result uploader token initialization')
@result_uploader = ResultUploader.new(scope, @project)
@result_uploader.ask_token
end
end

def drivers
Expand All @@ -50,9 +53,5 @@ def platform
def result_uploader_needed?
false
end

def close
@project.logger.info('Closing helpers engine')
end
end
end
59 changes: 22 additions & 37 deletions lib/engines/hckinstall/hckinstall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require './lib/auxiliary/json_helper'
require './lib/auxiliary/host_helper'
require './lib/auxiliary/iso_helper'
require './lib/auxiliary/resource_scope'
require './lib/engines/hckinstall/setup_scripts_helper'

# AutoHCK module
Expand Down Expand Up @@ -194,18 +195,17 @@ def result_uploader_needed?
true
end

def run_studio(iso_list = [], snapshot: true)
def run_studio(scope, iso_list = [], keep_alive:, snapshot: true)
st_opts = {
keep_alive: keep_alive,
create_snapshot: snapshot,
attach_iso_list: iso_list
}

st = @project.setup_manager.create_studio
st.run(st_opts)
st
@project.setup_manager.run_studio(scope, st_opts)
end

def run_client(name, snapshot: true)
def run_client(scope, name, snapshot: true)
cl_opts = {
create_snapshot: snapshot,
attach_iso_list: [
Expand All @@ -214,53 +214,38 @@ def run_client(name, snapshot: true)
]
}

cl = @project.setup_manager.create_client(name)
cl.run(cl_opts)
cl
@project.setup_manager.run_client(scope, name, cl_opts)
end

def run_studio_installer
@project.setup_manager.create_studio_image

st = run_studio([
@setup_studio_iso,
@studio_iso_info['path']
], snapshot: false)
begin
Timeout.timeout(@studio_install_timeout) do
@logger.info('Waiting for studio installation finished')
sleep 5 while st.alive?
end
ensure
st.clean_last_run
ResourceScope.open do |scope|
st = run_studio(scope, [
@setup_studio_iso,
@studio_iso_info['path']
], keep_alive: false, snapshot: false)
@logger.info('Waiting for studio installation finished')
raise AutoHCKError, 'studio installation timed out' if st.wait(@studio_install_timeout).nil?
end
end

def run_client_installer(name)
def run_client_installer(scope, name)
@project.setup_manager.create_client_image(name)

run_client(name, snapshot: false)
run_client(scope, name, snapshot: false)
end

def run_clients_installer
st = run_studio
begin
cl = @clients_name.map { |c| run_client_installer(c) }
begin
Timeout.timeout(@client_install_timeout) do
cl.each do |client|
@logger.info("Waiting for #{client.name} installation finished")
while client.alive?
@project.setup_manager.keep_studio_alive
sleep 5
end
end
ResourceScope.open do |scope|
run_studio(scope, [], keep_alive: true)
cl = @clients_name.map { |c| [c, run_client_installer(scope, c)] }
Timeout.timeout(@client_install_timeout) do
cl.each do |name, client|
@logger.info("Waiting for #{name} installation finished")
client.wait
end
ensure
cl.each(&:clean_last_run)
end
ensure
st.clean_last_run
end
end

Expand Down
32 changes: 16 additions & 16 deletions lib/engines/hckinstall/setup_scripts_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,24 @@ def copy_extra_software(hck_setup_scripts_path, extra_software_path, sw_names)
def create_setup_scripts_config(hck_setup_scripts_path, config)
validate_setup_scripts_config(config)

args_file = File.open("#{hck_setup_scripts_path}/args.ps1", 'w')
config.each do |k, v|
key = k.to_s.upcase.gsub(/[^0-9a-z]/i, '')
case v
when true, false
value = "$#{v}"
when String
value = "'#{v}'"
when Integer
value = v
else
@logger.fatal("Unexpected value #{x} for config")
raise(AutoHCKError, "Unexpected value #{x} for config")
end
File.open("#{hck_setup_scripts_path}/args.ps1", 'w') do |args_file|
config.each do |k, v|
key = k.to_s.upcase.gsub(/[^0-9a-z]/i, '')
case v
when true, false
value = "$#{v}"
when String
value = "'#{v}'"
when Integer
value = v
else
@logger.fatal("Unexpected value #{x} for config")
raise(AutoHCKError, "Unexpected value #{x} for config")
end

args_file.write("$#{key} = #{value}\n")
args_file.write("$#{key} = #{value}\n")
end
end
args_file.close
end
end
end
Loading