ruby-cute 0.13 → 0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +20 -1
- data/README.md +12 -1
- data/bin/cute +2 -1
- data/bin/grd +701 -0
- data/debian/.gitattributes +3 -0
- data/debian/changelog +96 -0
- data/debian/control +22 -5
- data/debian/ruby-cute.docs +1 -1
- data/debian/rules +3 -11
- data/debian/watch +2 -2
- data/examples/distem-bootstrap +16 -22
- data/examples/g5k-tutorial.md +25 -18
- data/examples/g5k_exp_virt.rb +1 -1
- data/lib/cute/bash.rb +7 -7
- data/lib/cute/configparser.rb +14 -12
- data/lib/cute/execute.rb +6 -4
- data/lib/cute/extensions.rb +3 -4
- data/lib/cute/g5k_api.rb +56 -38
- data/lib/cute/net-ssh-exec3.rb +10 -7
- data/lib/cute/net-ssh.rb +2 -2
- data/lib/cute/net.rb +5 -7
- data/lib/cute/synchronization.rb +1 -3
- data/lib/cute/taktuk.rb +4 -5
- data/lib/cute/version.rb +1 -1
- data/ruby-cute.gemspec +6 -3
- data/spec/g5k_api_check_spec.rb +1 -1
- data/spec/g5k_api_spec.rb +2 -12
- data/spec/spec_helper.rb +1 -0
- data/test/test_execute.rb +0 -0
- metadata +54 -11
- data/debian/compat +0 -1
data/lib/cute/g5k_api.rb
CHANGED
@@ -24,7 +24,7 @@ module Cute
|
|
24
24
|
# - {Cute::G5K::Unauthorized} it means that there is an authentication problem.
|
25
25
|
# - {Cute::G5K::EventTimeout} this exception is triggered by the methods that wait for events such as:
|
26
26
|
# job submission and environment deployment.
|
27
|
-
class Error <
|
27
|
+
class Error < StandardError
|
28
28
|
attr_accessor :orig # Original exception
|
29
29
|
|
30
30
|
def initialize(message = nil, object = nil)
|
@@ -63,6 +63,7 @@ module Cute
|
|
63
63
|
#
|
64
64
|
# end
|
65
65
|
class BadRequest < Error
|
66
|
+
attr_accessor :inner_url, :inner_code, :inner_title, :inner_message
|
66
67
|
end
|
67
68
|
|
68
69
|
# It wraps all Restclient exceptions with http codes: 403, 405,406, 412, 415, 500, 502, 503 and 504.
|
@@ -205,7 +206,8 @@ module Cute
|
|
205
206
|
# @param user [String] user if authentication is needed
|
206
207
|
# @param pass [String] password if authentication is needed
|
207
208
|
# @param on_error [Symbol] option to deactivate the {Cute::G5K::RequestFailed RequestFailed} exceptions
|
208
|
-
|
209
|
+
# @param timeout [Integer] timeout for Rest request
|
210
|
+
def initialize(uri,api_version,user,pass,on_error,timeout)
|
209
211
|
@user = user
|
210
212
|
@pass = pass
|
211
213
|
@api_version = api_version.nil? ? "stable" : api_version
|
@@ -217,9 +219,8 @@ module Cute
|
|
217
219
|
@endpoint = "https://#{user_escaped}:#{pass_escaped}@#{uri.split("https://")[1]}"
|
218
220
|
end
|
219
221
|
|
220
|
-
machine =`uname -ov`.chop
|
221
222
|
@user_agent = "ruby-cute/#{VERSION} Ruby/#{RUBY_VERSION}"
|
222
|
-
@api = RestClient::Resource.new(@endpoint, :timeout =>
|
223
|
+
@api = RestClient::Resource.new(@endpoint, :timeout => timeout,:verify_ssl => false)
|
223
224
|
# some versions of restclient do not verify by default SSL certificates , :verify_ssl => true)
|
224
225
|
# SSL verify is disabled due to Grid'5000 API certificate problem
|
225
226
|
@on_error = on_error
|
@@ -241,7 +242,7 @@ module Cute
|
|
241
242
|
def get_json(path)
|
242
243
|
return G5KJSON.parse(get_raw(path))
|
243
244
|
end
|
244
|
-
|
245
|
+
|
245
246
|
# @return [String] the HTTP response
|
246
247
|
# @param path [String] this complements the URI to address to a specific resource
|
247
248
|
def get_raw(path)
|
@@ -320,7 +321,7 @@ module Cute
|
|
320
321
|
end
|
321
322
|
|
322
323
|
# Issues a Cute::G5K exception according to the http status code
|
323
|
-
def handle_exception(e,
|
324
|
+
def handle_exception(e, _req = nil)
|
324
325
|
puts("Error: #{$!}")
|
325
326
|
puts("Backtrace:\n\t"+e.backtrace.join("\n\t"))
|
326
327
|
if e.respond_to? :http_code
|
@@ -338,11 +339,24 @@ module Cute
|
|
338
339
|
case e.http_code
|
339
340
|
|
340
341
|
when 400
|
341
|
-
|
342
|
+
br = BadRequest.new("Bad request (error 400): #{e.http_body}", e)
|
343
|
+
if e.http_body =~ /^Request to ([^ ]*) failed with status 400: (.*)$/m
|
344
|
+
br.inner_url = $1
|
345
|
+
json = $2
|
346
|
+
begin
|
347
|
+
d = JSON::parse(json)
|
348
|
+
br.inner_code = d['code']
|
349
|
+
br.inner_title = d['title']
|
350
|
+
br.inner_message = d['message']
|
351
|
+
rescue JSON::ParserError
|
352
|
+
# Ignore error
|
353
|
+
end
|
354
|
+
end
|
355
|
+
raise br
|
342
356
|
when 404
|
343
|
-
raise NotFound.new("Resource not found", e)
|
357
|
+
raise NotFound.new("Resource not found (error 404): #{e.http_body}", e)
|
344
358
|
when 401
|
345
|
-
raise Unauthorized.new("Authentication problem",e)
|
359
|
+
raise Unauthorized.new("Authentication problem (error 401): #{e.http_body}",e)
|
346
360
|
else
|
347
361
|
if @on_error == :ignore
|
348
362
|
return nil
|
@@ -555,6 +569,7 @@ module Cute
|
|
555
569
|
# @option params [String] :password Password to access the REST API
|
556
570
|
# @option params [Symbol] :on_error Set to :ignore if you want to ignore {Cute::G5K::RequestFailed ResquestFailed} exceptions.
|
557
571
|
# @option params [Boolean] :debug Activate the debug mode
|
572
|
+
# @option params [Integer] :timeout Set the timeout in sec, default is 30 sec
|
558
573
|
def initialize(params={})
|
559
574
|
config = {}
|
560
575
|
default_file = "#{ENV['HOME']}/.grid5000_api.yml"
|
@@ -573,9 +588,10 @@ module Cute
|
|
573
588
|
@api_version = params[:version] || config["version"] || "stable"
|
574
589
|
@logger = nil
|
575
590
|
@debug = params[:debug] || false
|
591
|
+
@timeout = params[:timeout] || 30
|
576
592
|
|
577
593
|
begin
|
578
|
-
@g5k_connection = G5KRest.new(@uri,@api_version,@user,@pass,params[:on_error])
|
594
|
+
@g5k_connection = G5KRest.new(@uri,@api_version,@user,@pass,params[:on_error], @timeout)
|
579
595
|
rescue => e
|
580
596
|
|
581
597
|
msg_create_file = ""
|
@@ -701,7 +717,9 @@ module Cute
|
|
701
717
|
# @param site [String] a valid Grid'5000 site name
|
702
718
|
# @param uid [String] user name in Grid'5000
|
703
719
|
# @param states [Array] or [String] jobs state: running, waiting (multiple states can be specified)
|
704
|
-
|
720
|
+
# @param details [String] pass "resources=yes to the query to get the list of resources
|
721
|
+
# @param recurse [String] after fetching the list of jobs, fetch details about each job individualy
|
722
|
+
def get_jobs(site, uid = nil, states = nil, details = false, recurse = true)
|
705
723
|
|
706
724
|
parameters = []
|
707
725
|
if states then
|
@@ -709,12 +727,18 @@ module Cute
|
|
709
727
|
parameters.push("state=#{states.join(",")}")
|
710
728
|
end
|
711
729
|
parameters.push("user=#{uid}") if uid
|
712
|
-
parameters.push("limit=
|
730
|
+
parameters.push("limit=1000000")
|
731
|
+
parameters.push("resources=yes") if details
|
713
732
|
|
733
|
+
info(debug_cmd(api_uri("/sites/#{site}/jobs?#{parameters.join("&")}"),"GET"), :debug)
|
714
734
|
jobs = @g5k_connection.get_json(api_uri("/sites/#{site}/jobs?#{parameters.join("&")}")).items
|
715
|
-
|
716
|
-
|
717
|
-
|
735
|
+
if recurse
|
736
|
+
jobs.map! do |j|
|
737
|
+
info(debug_cmd(j.rel_self, "GET"), :debug)
|
738
|
+
@g5k_connection.get_json(j.rel_self)
|
739
|
+
end
|
740
|
+
end
|
741
|
+
jobs.to_a
|
718
742
|
end
|
719
743
|
|
720
744
|
# @return [Hash] the last 50 deployments performed in a Grid'5000 site
|
@@ -976,6 +1000,7 @@ module Cute
|
|
976
1000
|
# @option opts [String] :cmd The command to execute when the job starts (e.g. ./my-script.sh).
|
977
1001
|
# @option opts [String] :cluster Valid Grid'5000 cluster
|
978
1002
|
# @option opts [String] :queue A specific job queue
|
1003
|
+
# @option opts [String] :project A specific OAR project
|
979
1004
|
# @option opts [Array] :subnets 1) prefix_size, 2) number of subnets
|
980
1005
|
# @option opts [String] :env Environment name for {http://kadeploy3.gforge.inria.fr/ Kadeploy}
|
981
1006
|
# @option opts [String] :vlan VLAN type and number: kavlan-local, kavlan, kavlan-topo, etc
|
@@ -990,12 +1015,12 @@ module Cute
|
|
990
1015
|
# checking valid options
|
991
1016
|
valid_opts = [:site, :cluster, :switches, :cpus, :cores, :nodes, :walltime, :cmd,
|
992
1017
|
:type, :name, :subnets, :env, :vlan, :num_vlan,:properties, :resources,
|
993
|
-
:reservation, :wait, :keys, :queue, :env_user]
|
1018
|
+
:reservation, :wait, :keys, :queue, :project, :env_user]
|
994
1019
|
unre_opts = opts.keys - valid_opts
|
995
1020
|
raise ArgumentError, "Unrecognized option #{unre_opts}" unless unre_opts.empty?
|
996
1021
|
|
997
1022
|
nodes = opts.fetch(:nodes, 1)
|
998
|
-
walltime = opts
|
1023
|
+
walltime = opts[:walltime]
|
999
1024
|
site = opts[:site]
|
1000
1025
|
type = opts.fetch(:type, [])
|
1001
1026
|
name = opts.fetch(:name, 'rubyCute job')
|
@@ -1013,6 +1038,7 @@ module Cute
|
|
1013
1038
|
type = [type] if type.is_a?(Symbol)
|
1014
1039
|
keys = opts[:keys]
|
1015
1040
|
queue = opts[:queue]
|
1041
|
+
project = opts[:project]
|
1016
1042
|
vlan = opts[:vlan]
|
1017
1043
|
num_vlan = opts.fetch(:num_vlan, 1)
|
1018
1044
|
|
@@ -1027,14 +1053,11 @@ module Cute
|
|
1027
1053
|
raise ArgumentError, "VLAN type not available in site #{site}" unless available_vlans.include?(vlan)
|
1028
1054
|
end
|
1029
1055
|
|
1030
|
-
raise 'At least nodes
|
1031
|
-
|
1032
|
-
raise 'nodes should be an integer or a string containing either ALL or BEST' unless (nodes.is_a?(Fixnum) or ["ALL","BEST"].include?(nodes))
|
1056
|
+
raise 'At least nodes and site must be given' if [nodes, site].any? { |x| x.nil? }
|
1033
1057
|
|
1034
|
-
|
1035
|
-
walltime = walltime.to_time
|
1058
|
+
raise 'nodes should be an integer or a string containing either ALL or BEST' unless (nodes.is_a?(Integer) or ["ALL","BEST"].include?(nodes))
|
1036
1059
|
|
1037
|
-
command = "sleep
|
1060
|
+
command = "sleep infinity" if command.nil?
|
1038
1061
|
|
1039
1062
|
if resources == ""
|
1040
1063
|
resources = "/switch=#{switches}" unless switches.nil?
|
@@ -1043,14 +1066,16 @@ module Cute
|
|
1043
1066
|
resources += "/core=#{cores}" unless cores.nil?
|
1044
1067
|
|
1045
1068
|
if cluster
|
1046
|
-
resources = (cluster.is_a?(
|
1069
|
+
resources = (cluster.is_a?(Integer) ? "/cluster=#{cluster}" : "{cluster='#{cluster}'}") + resources
|
1047
1070
|
end
|
1048
1071
|
|
1049
1072
|
resources = "{type='#{vlan}'}/vlan=#{num_vlan}+" + resources unless vlan.nil?
|
1050
1073
|
resources = "slash_#{subnets[0]}=#{subnets[1]}+" + resources unless subnets.nil?
|
1051
1074
|
end
|
1052
1075
|
|
1053
|
-
|
1076
|
+
if walltime
|
1077
|
+
resources += ",walltime=#{walltime}" unless resources.include?("walltime")
|
1078
|
+
end
|
1054
1079
|
|
1055
1080
|
payload = {
|
1056
1081
|
'resources' => resources,
|
@@ -1058,12 +1083,13 @@ module Cute
|
|
1058
1083
|
'command' => command
|
1059
1084
|
}
|
1060
1085
|
|
1061
|
-
info "Reserving resources: #{resources} (
|
1086
|
+
info "Reserving resources: #{resources} (types: #{type.join(' ')}) (in #{site})"
|
1062
1087
|
|
1063
1088
|
payload['properties'] = properties unless properties.nil?
|
1064
1089
|
payload['types'] = type.map{ |t| t.to_s} unless type.nil?
|
1065
1090
|
type.map!{|t| t.to_sym} unless type.nil?
|
1066
1091
|
payload['queue'] = queue if queue
|
1092
|
+
payload['project'] = project if project
|
1067
1093
|
|
1068
1094
|
unless type.include?(:deploy)
|
1069
1095
|
if opts[:keys]
|
@@ -1073,18 +1099,10 @@ module Cute
|
|
1073
1099
|
|
1074
1100
|
if reservation
|
1075
1101
|
payload['reservation'] = reservation
|
1076
|
-
info "Starting this reservation at #{reservation}"
|
1077
1102
|
end
|
1078
1103
|
|
1079
|
-
|
1080
|
-
|
1081
|
-
r = @g5k_connection.post_json(api_uri("sites/#{site}/jobs"),payload) # This makes reference to the same class
|
1082
|
-
rescue Error => e
|
1083
|
-
info "Fail to submit job"
|
1084
|
-
info e.message
|
1085
|
-
e.http_body.split("\\n").each{ |line| info line}
|
1086
|
-
raise
|
1087
|
-
end
|
1104
|
+
info debug_cmd(api_uri("sites/#{site}/jobs"),"POST",payload.to_json), :debug
|
1105
|
+
r = @g5k_connection.post_json(api_uri("sites/#{site}/jobs"),payload) # This makes reference to the same class
|
1088
1106
|
|
1089
1107
|
job = @g5k_connection.get_json(r.rel_self)
|
1090
1108
|
job = wait_for_job(job) if opts[:wait] == true
|
@@ -1274,7 +1292,7 @@ module Cute
|
|
1274
1292
|
|
1275
1293
|
job["deploy"].map!{ |d| d.refresh(@g5k_connection) }
|
1276
1294
|
|
1277
|
-
filter.keep_if{ |
|
1295
|
+
filter.keep_if{ |_k,v| v} # removes nil values
|
1278
1296
|
if filter.empty?
|
1279
1297
|
status = job["deploy"].map{ |d| d["status"] }
|
1280
1298
|
else
|
@@ -1352,7 +1370,7 @@ module Cute
|
|
1352
1370
|
# @return [Array] machines that did not deploy successfully
|
1353
1371
|
# @param deploy_info [Hash] deployment structure information
|
1354
1372
|
def check_deployment(deploy_info)
|
1355
|
-
deploy_info["result"].select{ |
|
1373
|
+
deploy_info["result"].select{ |_p,v| v["state"] == "KO"}.keys
|
1356
1374
|
end
|
1357
1375
|
|
1358
1376
|
# Returns a valid URI using the current G5K API version.
|
data/lib/cute/net-ssh-exec3.rb
CHANGED
@@ -14,17 +14,18 @@ class Net::SSH::Connection::Session
|
|
14
14
|
res[:stderr] = ""
|
15
15
|
res[:exit_code] = nil
|
16
16
|
res[:exit_signal] = nil
|
17
|
+
ts = Time::now
|
17
18
|
open_channel do |channel|
|
18
|
-
channel.exec(command) do |
|
19
|
+
channel.exec(command) do |_ch, success|
|
19
20
|
unless success
|
20
21
|
abort "FAILED: couldn't execute command (ssh.channel.exec)"
|
21
22
|
end
|
22
|
-
channel.on_data do |
|
23
|
+
channel.on_data do |_ch,data|
|
23
24
|
print data unless o[:no_output]
|
24
25
|
res[:stdout]+=data
|
25
26
|
end
|
26
27
|
|
27
|
-
channel.on_extended_data do |
|
28
|
+
channel.on_extended_data do |_ch,_type,data|
|
28
29
|
print data unless o[:no_output]
|
29
30
|
if o[:merge_outputs]
|
30
31
|
res[:stdout]+=data
|
@@ -33,14 +34,16 @@ class Net::SSH::Connection::Session
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
channel.on_request("exit-status") do |
|
37
|
+
channel.on_request("exit-status") do |_ch,data|
|
37
38
|
res[:exit_code] = data.read_long
|
38
|
-
|
39
|
+
d = sprintf("%.1f", Time::now - ts)
|
40
|
+
puts "EXITCODE: #{res[:exit_code]} (duration: #{d}s)" unless o[:no_log]
|
39
41
|
end
|
40
42
|
|
41
|
-
channel.on_request("exit-signal") do |
|
43
|
+
channel.on_request("exit-signal") do |_ch, data|
|
42
44
|
res[:exit_signal] = data.read_long
|
43
|
-
|
45
|
+
d = sprintf("%.1f", Time::now - ts)
|
46
|
+
puts "EXITSIGNAL: #{res[:exit_signal]} (duration: #{d}s)" unless o[:no_log]
|
44
47
|
end
|
45
48
|
end
|
46
49
|
end
|
data/lib/cute/net-ssh.rb
CHANGED
@@ -115,7 +115,7 @@ module SessionActions
|
|
115
115
|
Multi.logger.debug("[#{c.connection.host}] #{data.strip}")
|
116
116
|
end
|
117
117
|
end
|
118
|
-
channel.on_extended_data do |c,
|
118
|
+
channel.on_extended_data do |c, _type, data|
|
119
119
|
if block
|
120
120
|
block.call(c, :stderr, data)
|
121
121
|
else
|
@@ -129,7 +129,7 @@ module SessionActions
|
|
129
129
|
results[c.connection.host][:status] = c[:exit_status]
|
130
130
|
if c[:exit_status] != 0
|
131
131
|
Multi.logger.info("execution of '#{command}' on #{c.connection.host}
|
132
|
-
failed with return status #{c[:exit_status]
|
132
|
+
failed with return status #{c[:exit_status]}")
|
133
133
|
if results[c.connection.host][:stdout]
|
134
134
|
Multi.logger.info("--- stdout dump ---")
|
135
135
|
Multi.logger.info(results[c.connection.host][:stdout])
|
data/lib/cute/net.rb
CHANGED
@@ -13,14 +13,12 @@ module Cute
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def Network::wait_open_port(host, port, timeout = 120)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
while now() < bound do
|
21
|
-
t = now()
|
16
|
+
now = -> { return Time.now.to_f }
|
17
|
+
bound = now.call + timeout
|
18
|
+
while now.call < bound do
|
19
|
+
t = now.call
|
22
20
|
return true if port_open?(host, port)
|
23
|
-
dt = now
|
21
|
+
dt = now.call - t
|
24
22
|
sleep(0.5 - dt) if dt < 0.5
|
25
23
|
end
|
26
24
|
return false
|
data/lib/cute/synchronization.rb
CHANGED
data/lib/cute/taktuk.rb
CHANGED
@@ -123,7 +123,6 @@ module Cute
|
|
123
123
|
yield taktuk_cmd
|
124
124
|
taktuk_cmd.loop unless taktuk_cmd.commands.empty?
|
125
125
|
taktuk_cmd.free! if taktuk_cmd
|
126
|
-
taktuk_cmd = nil
|
127
126
|
end
|
128
127
|
else
|
129
128
|
return taktuk_cmd
|
@@ -372,9 +371,9 @@ module Cute
|
|
372
371
|
def to_cmd
|
373
372
|
self.inject([]) do |ret,val|
|
374
373
|
if val =~ /^\[(.*)\]$/
|
375
|
-
ret
|
374
|
+
ret + ['[',Regexp.last_match(1).strip,']']
|
376
375
|
else
|
377
|
-
ret
|
376
|
+
ret + val.split(' ')
|
378
377
|
end
|
379
378
|
end
|
380
379
|
end
|
@@ -417,7 +416,7 @@ module Cute
|
|
417
416
|
|
418
417
|
@streams.types.each{ |name|
|
419
418
|
@args << '-o'
|
420
|
-
@args << "#{name
|
419
|
+
@args << "#{name}=#{@streams.to_cmd}"
|
421
420
|
}
|
422
421
|
|
423
422
|
connector = build_connector
|
@@ -563,7 +562,7 @@ module Cute
|
|
563
562
|
# tak.input(:file => "test_file.tar")
|
564
563
|
def input(opts = {})
|
565
564
|
mode = "broadcast"
|
566
|
-
@commands << "#{mode} input #{opts.keys.first
|
565
|
+
@commands << "#{mode} input #{opts.keys.first}"
|
567
566
|
@commands << "[ #{opts.values.first} ]"
|
568
567
|
@commands << ';'
|
569
568
|
end
|
data/lib/cute/version.rb
CHANGED
data/ruby-cute.gemspec
CHANGED
@@ -5,9 +5,9 @@ require 'cute/version'
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "ruby-cute"
|
7
7
|
s.version = Cute::VERSION
|
8
|
-
s.authors = ["Algorille
|
9
|
-
s.email = "
|
10
|
-
s.homepage = "http://ruby-cute.
|
8
|
+
s.authors = ["Algorille/Madynes/RESIST teams at Inria/LORIA"]
|
9
|
+
s.email = "lucas.nussbaum@inria.fr"
|
10
|
+
s.homepage = "http://ruby-cute.github.io/"
|
11
11
|
s.summary = "Critically Useful Tools for Experiments"
|
12
12
|
s.description = "Ruby library for controlling experiments"
|
13
13
|
s.required_rubygems_version = ">= 1.3.6"
|
@@ -26,7 +26,10 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_dependency 'rest-client', '>= 1.6'
|
27
27
|
s.add_dependency 'json', '>= 1.8'
|
28
28
|
s.add_dependency 'ipaddress', '>= 0.8'
|
29
|
+
s.add_dependency 'net-ssh', '>= 3.2'
|
29
30
|
s.add_dependency 'net-ssh-multi', '>= 1.2'
|
31
|
+
s.add_dependency 'net-scp', '>= 1.2'
|
32
|
+
s.add_dependency 'peach', '>= 0.5.1'
|
30
33
|
|
31
34
|
s.extra_rdoc_files = ['README.md', 'LICENSE']
|
32
35
|
s.license = 'CeCILL-B'
|
data/spec/g5k_api_check_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Cute::G5K::API do
|
6
6
|
|
7
|
-
subject {
|
7
|
+
subject { ENV['TEST_REAL'].nil?? Cute::G5K::API.new(:user => "test") : Cute::G5K::API.new() }
|
8
8
|
|
9
9
|
before :each do
|
10
10
|
if ENV['TEST_REAL']
|
data/spec/g5k_api_spec.rb
CHANGED
@@ -4,9 +4,9 @@ require 'spec_helper'
|
|
4
4
|
describe Cute::G5K::API do
|
5
5
|
|
6
6
|
if ENV['TEST_REAL']
|
7
|
-
subject {
|
7
|
+
subject { ENV['DEBUG'].nil?? Cute::G5K::API.new() : Cute::G5K::API.new(:debug => true) }
|
8
8
|
else
|
9
|
-
subject {
|
9
|
+
subject { ENV['DEBUG'].nil?? Cute::G5K::API.new(:user => "test") : Cute::G5K::API.new(:user => "test",:debug => true) }
|
10
10
|
end
|
11
11
|
|
12
12
|
let(:sites) { subject.site_uids}
|
@@ -79,15 +79,6 @@ describe Cute::G5K::API do
|
|
79
79
|
expect{subject.get_jobs("not-found")}.to raise_error(Cute::G5K::NotFound)
|
80
80
|
end
|
81
81
|
|
82
|
-
it "raises a bad request error" do
|
83
|
-
expect{ subject.reserve(:site => @rand_site, :resources =>"/slash_22=1+{nonsense}")}.to raise_error(Cute::G5K::BadRequest)
|
84
|
-
# expect{ subject.reserve(:site => @rand_site, :resources =>"{ib30g='YES'}/nodes=2")}.to raise_error(Cute::G5K::BadRequest)
|
85
|
-
end
|
86
|
-
|
87
|
-
it "raises a bad request using OAR API" do
|
88
|
-
expect{subject.reserve(:site => @rand_site, :resources =>"nodes=1",:keys => "~/jobkey_nonexisting")}.to raise_error(Cute::G5K::BadRequest)
|
89
|
-
end
|
90
|
-
|
91
82
|
# it "raises an exception at deploying" do
|
92
83
|
# expect{ subject.reserve(:site => @rand_site, :nodes => 1, :env => "nonsense")}.to raise_error(Cute::G5K::RequestFailed)
|
93
84
|
# end
|
@@ -199,7 +190,6 @@ describe Cute::G5K::API do
|
|
199
190
|
end
|
200
191
|
|
201
192
|
it "submit and does not wait for the reservation" do
|
202
|
-
cluster = subject.cluster_uids(@rand_site).first
|
203
193
|
job = subject.reserve(:site => @rand_site, :wait => false)
|
204
194
|
job = subject.wait_for_job(job, :wait_time => 600)
|
205
195
|
expect(job).to include('state' => "running")
|
data/spec/spec_helper.rb
CHANGED
@@ -30,6 +30,7 @@ class FakeG5KResponse < Hash
|
|
30
30
|
'nodes' => {"node1" => {"hard"=> "alive", "soft"=>"busy"}}
|
31
31
|
}
|
32
32
|
def initialize(num_items = 2)
|
33
|
+
super
|
33
34
|
MEDIA_TYPE.each { |key,value| self[key] = value}
|
34
35
|
self['items'] = []
|
35
36
|
num_items.times.each{ self['items'].push(MEDIA_TYPE) }
|
data/test/test_execute.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-cute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.24'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Algorille
|
8
|
-
autorequire:
|
7
|
+
- Algorille/Madynes/RESIST teams at Inria/LORIA
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0.8'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: net-ssh
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '3.2'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '3.2'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: net-ssh-multi
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,10 +178,39 @@ dependencies:
|
|
164
178
|
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
180
|
version: '1.2'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: net-scp
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '1.2'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '1.2'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: peach
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 0.5.1
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 0.5.1
|
167
209
|
description: Ruby library for controlling experiments
|
168
|
-
email:
|
210
|
+
email: lucas.nussbaum@inria.fr
|
169
211
|
executables:
|
170
212
|
- cute
|
213
|
+
- grd
|
171
214
|
extensions: []
|
172
215
|
extra_rdoc_files:
|
173
216
|
- README.md
|
@@ -181,8 +224,9 @@ files:
|
|
181
224
|
- README.md
|
182
225
|
- Rakefile
|
183
226
|
- bin/cute
|
227
|
+
- bin/grd
|
228
|
+
- debian/.gitattributes
|
184
229
|
- debian/changelog
|
185
|
-
- debian/compat
|
186
230
|
- debian/control
|
187
231
|
- debian/copyright
|
188
232
|
- debian/ruby-cute.docs
|
@@ -216,11 +260,11 @@ files:
|
|
216
260
|
- spec/taktuk_spec.rb
|
217
261
|
- test/test_bash.rb
|
218
262
|
- test/test_execute.rb
|
219
|
-
homepage: http://ruby-cute.
|
263
|
+
homepage: http://ruby-cute.github.io/
|
220
264
|
licenses:
|
221
265
|
- CeCILL-B
|
222
266
|
metadata: {}
|
223
|
-
post_install_message:
|
267
|
+
post_install_message:
|
224
268
|
rdoc_options: []
|
225
269
|
require_paths:
|
226
270
|
- lib
|
@@ -235,9 +279,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
279
|
- !ruby/object:Gem::Version
|
236
280
|
version: 1.3.6
|
237
281
|
requirements: []
|
238
|
-
|
239
|
-
|
240
|
-
signing_key:
|
282
|
+
rubygems_version: 3.3.15
|
283
|
+
signing_key:
|
241
284
|
specification_version: 4
|
242
285
|
summary: Critically Useful Tools for Experiments
|
243
286
|
test_files:
|
data/debian/compat
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
8
|