ruby-cute 0.13 → 0.24
Sign up to get free protection for your applications and to get access to all the features.
- 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
|