From 5333158bdcd177b915dc4cef2a2805d9ee5a67af Mon Sep 17 00:00:00 2001 From: Samuel Beaulieu Date: Wed, 16 Sep 2020 11:23:01 -0500 Subject: [PATCH] (maint) Support any vmpooler for ABS via vmpooler_fallback Before this change, the fallback vmpooler for ABS had to be named 'vmpooler' and it only supported one. With this new code, users can set a key within an 'abs' service type called vmpooler_fallback that points to any other service configured in the ~/.vmfloaty.yml config file. If not set, the appropriate error message is returned, with an example configuration. Added the various use cases for the config to the unit tests --- lib/vmfloaty/abs.rb | 14 ++++----- lib/vmfloaty/service.rb | 4 +-- lib/vmfloaty/utils.rb | 12 +++++--- spec/vmfloaty/utils_spec.rb | 57 +++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 13 deletions(-) diff --git a/lib/vmfloaty/abs.rb b/lib/vmfloaty/abs.rb index 43734cd..164e7ff 100644 --- a/lib/vmfloaty/abs.rb +++ b/lib/vmfloaty/abs.rb @@ -210,7 +210,7 @@ class ABS end # Retrieve an OS from ABS. - def self.retrieve(verbose, os_types, token, url, user, options, _ondemand = nil) + def self.retrieve(verbose, os_types, token, url, user, config, _ondemand = nil) # # Contents of post must be like: # @@ -231,7 +231,7 @@ class ABS conn.headers['X-AUTH-TOKEN'] = token if token saved_job_id = DateTime.now.strftime('%Q') - vmpooler_config = Utils.get_vmpooler_service_config + vmpooler_config = Utils.get_vmpooler_service_config(config['vmpooler_fallback']) req_obj = { :resources => os_types, :job => { @@ -243,15 +243,15 @@ class ABS :vm_token => vmpooler_config['token'] # request with this token, on behalf of this user } - if options['priority'] - req_obj[:priority] = if options['priority'] == 'high' + if config['priority'] + req_obj[:priority] = if config['priority'] == 'high' 1 - elsif options['priority'] == 'medium' + elsif config['priority'] == 'medium' 2 - elsif options['priority'] == 'low' + elsif config['priority'] == 'low' 3 else - options['priority'].to_i + config['priority'].to_i end end diff --git a/lib/vmfloaty/service.rb b/lib/vmfloaty/service.rb index d512c4d..a0303c4 100644 --- a/lib/vmfloaty/service.rb +++ b/lib/vmfloaty/service.rb @@ -141,11 +141,11 @@ class Service def maybe_use_vmpooler if @service_object.is_a?(ABS.class) if !self.silent - FloatyLogger.info "The service in use is ABS, but the requested method should run against vmpooler directly, using vmpooler config from ~/.vmfloaty.yml" + FloatyLogger.info "The service in use is ABS, but the requested method should run against vmpooler directly, using fallback_vmpooler config from ~/.vmfloaty.yml" self.silent = true end - @config = Utils.get_vmpooler_service_config + @config = Utils.get_vmpooler_service_config(@config['vmpooler_fallback']) @service_object = Pooler end end diff --git a/lib/vmfloaty/utils.rb b/lib/vmfloaty/utils.rb index ed01ac6..391fd72 100644 --- a/lib/vmfloaty/utils.rb +++ b/lib/vmfloaty/utils.rb @@ -251,7 +251,7 @@ class Utils end # This method gets the vmpooler service configured in ~/.vmfloaty - def self.get_vmpooler_service_config + def self.get_vmpooler_service_config(vmpooler_fallback) config = Conf.read_config # The top-level url, user, and token values in the config file are treated as defaults service_config = { @@ -262,11 +262,15 @@ class Utils } # at a minimum, the url needs to be configured - if config['services'] && config['services']['vmpooler'] && config['services']['vmpooler']['url'] + if config['services'] && config['services'][vmpooler_fallback] && config['services'][vmpooler_fallback]['url'] # If the service is configured but some values are missing, use the top-level defaults to fill them in - service_config.merge! config['services']['vmpooler'] + service_config.merge! config['services'][vmpooler_fallback] else - raise ArgumentError, "Could not find a configured service named 'vmpooler' in ~/.vmfloaty.yml use this format:\nservices:\n vmpooler:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" + if vmpooler_fallback.nil? + raise ArgumentError, "The abs service should have a key named 'vmpooler_fallback' in ~/.vmfloaty.yml with a value that points to a vmpooler service name use this format:\nservices:\n myabs:\n url: 'http://abs.com'\n user: 'superman'\n token: 'kryptonite'\n vmpooler_fallback: 'myvmpooler'\n myvmpooler:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" + else + raise ArgumentError, "Could not find a configured service named '#{vmpooler_fallback}' in ~/.vmfloaty.yml use this format:\nservices:\n #{vmpooler_fallback}:\n url: 'http://vmpooler.com'\n user: 'superman'\n token: 'kryptonite'" + end end service_config diff --git a/spec/vmfloaty/utils_spec.rb b/spec/vmfloaty/utils_spec.rb index 4d31d24..e58fab2 100644 --- a/spec/vmfloaty/utils_spec.rb +++ b/spec/vmfloaty/utils_spec.rb @@ -247,4 +247,61 @@ describe Utils do Utils.pretty_print_hosts(nil, service, hostname) end end + + describe '#get_vmpooler_service_config' do + let(:Conf) { double } + it 'returns an error if the vmpooler_fallback is not setup' do + config = { + 'user' => 'foo', + 'services' => { + 'myabs' => { + 'url' => 'http://abs.com', + 'token' => 'krypto-night', + 'type' => 'abs' + } + } + } + allow(Conf).to receive(:read_config).and_return(config) + expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError) + end + it 'returns an error if the vmpooler_fallback is setup but cannot be found' do + config = { + 'user' => 'foo', + 'services' => { + 'myabs' => { + 'url' => 'http://abs.com', + 'token' => 'krypto-night', + 'type' => 'abs', + 'vmpooler_fallback' => 'myvmpooler' + } + } + } + allow(Conf).to receive(:read_config).and_return(config) + expect{Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])}.to raise_error(ArgumentError, /myvmpooler/) + end + it 'returns the vmpooler_fallback config' do + config = { + 'user' => 'foo', + 'services' => { + 'myabs' => { + 'url' => 'http://abs.com', + 'token' => 'krypto-night', + 'type' => 'abs', + 'vmpooler_fallback' => 'myvmpooler' + }, + 'myvmpooler' => { + 'url' => 'http://vmpooler.com', + 'token' => 'krypto-knight' + } + } + } + allow(Conf).to receive(:read_config).and_return(config) + expect(Utils.get_vmpooler_service_config(config['services']['myabs']['vmpooler_fallback'])).to include({ + 'url' => 'http://vmpooler.com', + 'token' => 'krypto-knight', + 'user' => 'foo', + 'type' => 'vmpooler' + }) + end + end end