xpflow 0.1b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/bin/xpflow +96 -0
  2. data/lib/colorado.rb +198 -0
  3. data/lib/json/add/core.rb +243 -0
  4. data/lib/json/add/rails.rb +8 -0
  5. data/lib/json/common.rb +423 -0
  6. data/lib/json/editor.rb +1369 -0
  7. data/lib/json/ext.rb +28 -0
  8. data/lib/json/pure/generator.rb +442 -0
  9. data/lib/json/pure/parser.rb +320 -0
  10. data/lib/json/pure.rb +15 -0
  11. data/lib/json/version.rb +8 -0
  12. data/lib/json.rb +62 -0
  13. data/lib/mime/types.rb +881 -0
  14. data/lib/mime-types.rb +3 -0
  15. data/lib/restclient/abstract_response.rb +106 -0
  16. data/lib/restclient/exceptions.rb +193 -0
  17. data/lib/restclient/net_http_ext.rb +55 -0
  18. data/lib/restclient/payload.rb +235 -0
  19. data/lib/restclient/raw_response.rb +34 -0
  20. data/lib/restclient/request.rb +316 -0
  21. data/lib/restclient/resource.rb +169 -0
  22. data/lib/restclient/response.rb +24 -0
  23. data/lib/restclient.rb +174 -0
  24. data/lib/xpflow/bash.rb +341 -0
  25. data/lib/xpflow/bundle.rb +113 -0
  26. data/lib/xpflow/cmdline.rb +249 -0
  27. data/lib/xpflow/collection.rb +122 -0
  28. data/lib/xpflow/concurrency.rb +79 -0
  29. data/lib/xpflow/data.rb +393 -0
  30. data/lib/xpflow/dsl.rb +816 -0
  31. data/lib/xpflow/engine.rb +574 -0
  32. data/lib/xpflow/ensemble.rb +135 -0
  33. data/lib/xpflow/events.rb +56 -0
  34. data/lib/xpflow/experiment.rb +65 -0
  35. data/lib/xpflow/exts/facter.rb +30 -0
  36. data/lib/xpflow/exts/g5k.rb +931 -0
  37. data/lib/xpflow/exts/g5k_use.rb +50 -0
  38. data/lib/xpflow/exts/gui.rb +140 -0
  39. data/lib/xpflow/exts/model.rb +155 -0
  40. data/lib/xpflow/graph.rb +1603 -0
  41. data/lib/xpflow/graph_xpflow.rb +251 -0
  42. data/lib/xpflow/import.rb +196 -0
  43. data/lib/xpflow/library.rb +349 -0
  44. data/lib/xpflow/logging.rb +153 -0
  45. data/lib/xpflow/manager.rb +147 -0
  46. data/lib/xpflow/nodes.rb +1250 -0
  47. data/lib/xpflow/runs.rb +773 -0
  48. data/lib/xpflow/runtime.rb +125 -0
  49. data/lib/xpflow/scope.rb +168 -0
  50. data/lib/xpflow/ssh.rb +186 -0
  51. data/lib/xpflow/stat.rb +50 -0
  52. data/lib/xpflow/stdlib.rb +381 -0
  53. data/lib/xpflow/structs.rb +369 -0
  54. data/lib/xpflow/taktuk.rb +193 -0
  55. data/lib/xpflow/templates/ssh-config.basic +14 -0
  56. data/lib/xpflow/templates/ssh-config.inria +18 -0
  57. data/lib/xpflow/templates/ssh-config.proxy +13 -0
  58. data/lib/xpflow/templates/taktuk +6590 -0
  59. data/lib/xpflow/templates/utils/batch +4 -0
  60. data/lib/xpflow/templates/utils/bootstrap +12 -0
  61. data/lib/xpflow/templates/utils/hostname +3 -0
  62. data/lib/xpflow/templates/utils/ping +3 -0
  63. data/lib/xpflow/templates/utils/rsync +12 -0
  64. data/lib/xpflow/templates/utils/scp +17 -0
  65. data/lib/xpflow/templates/utils/scp_many +8 -0
  66. data/lib/xpflow/templates/utils/ssh +3 -0
  67. data/lib/xpflow/templates/utils/ssh-interactive +4 -0
  68. data/lib/xpflow/templates/utils/taktuk +19 -0
  69. data/lib/xpflow/threads.rb +187 -0
  70. data/lib/xpflow/utils.rb +569 -0
  71. data/lib/xpflow/visual.rb +230 -0
  72. data/lib/xpflow/with_g5k.rb +7 -0
  73. data/lib/xpflow.rb +349 -0
  74. metadata +135 -0
data/bin/xpflow ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ # Runs xpflow script
4
+
5
+ require('pathname')
6
+
7
+ def realpath(x)
8
+ Pathname.new(x).realpath.to_s
9
+ end
10
+
11
+ # code that magically switches ruby interpreter
12
+ if ENV.key?("__RUBY__")
13
+ __ruby__ = ENV["__RUBY__"]
14
+ __here__ = realpath(__FILE__)
15
+ ENV.delete("__RUBY__") # avoid infinite loop
16
+ begin
17
+ exec(__ruby__, __here__, *ARGV)
18
+ rescue Errno::ENOENT => e
19
+ puts "Could not launch with custom Ruby (#{e})."
20
+ end
21
+ exit 1
22
+ end
23
+
24
+ def get_lib_dir
25
+ f = __FILE__
26
+ f = File.readlink(f) if File.symlink?(f)
27
+ p = Pathname.new(File.dirname(f))
28
+ lib = File.join(p.realpath, '..', 'lib')
29
+ return Pathname.new(lib).realpath.to_s
30
+ end
31
+
32
+ $:.unshift(get_lib_dir)
33
+
34
+ #XSTART
35
+ require 'xpflow'
36
+ #XEND
37
+
38
+ def usage
39
+ puts "XPFlow (running on Ruby #{RUBY_VERSION})"
40
+ puts
41
+ puts "Usage:"
42
+ puts " xpflow <cmd> <workflow> [OPTIONS]"
43
+ puts
44
+ puts "Standard commands:"
45
+ puts " xpflow run <workflow> - run a workflow"
46
+ puts
47
+ end
48
+
49
+ def use(*args)
50
+
51
+ # TODO: this should be more sophisticated
52
+ # for now it's so so
53
+
54
+ args.each do |lib|
55
+ require "xpflow/exts/#{lib.to_s}_use"
56
+ end
57
+ end
58
+
59
+ if true
60
+
61
+ $original_argv = ARGV.clone
62
+
63
+ begin
64
+ $cmdline_options = XPFlow::Options.new(ARGV.dup)
65
+ $variables = $cmdline_options.vars
66
+ $engine.init_from_options($cmdline_options)
67
+ rescue XPFlow::CmdlineError => e
68
+ if e.ignore?
69
+ exit 0
70
+ else
71
+ Kernel.puts "Error while parsing cmdline: #{e}"
72
+ exit 1
73
+ end
74
+ end
75
+
76
+ $cmdline_options.includes.each do |filename|
77
+ filename = realpath(filename)
78
+ require(filename)
79
+ end
80
+
81
+ ok = nil
82
+ begin
83
+ XPFlow::TerminalThread.start_thread
84
+ _, ok = $cmdline_options.dispatch($engine)
85
+ rescue => e
86
+ Kernel.puts "Error while running : #{e}."
87
+ if $cmdline_options.verbose?
88
+ Kernel.puts "Backtrace:"
89
+ e.backtrace.each do |line|
90
+ Kernel.puts(" " + line)
91
+ end
92
+ end
93
+ ok = false
94
+ end
95
+ exit(ok ? 0 : 1)
96
+ end
data/lib/colorado.rb ADDED
@@ -0,0 +1,198 @@
1
+
2
+ # This simple library allows you to use
3
+ # colors with strings
4
+
5
+ module Colorado
6
+
7
+ COLORS = {
8
+ :red => 31,
9
+ :green => 32,
10
+ :yellow => 33,
11
+ :blue => 34,
12
+ :violet => 35,
13
+ :magenta => 36,
14
+ :white => 37,
15
+ :normal => 0
16
+ }
17
+
18
+ KEYS = COLORS.keys + COLORS.keys.map { |c| "#{c}!" }
19
+
20
+ module StringMix
21
+
22
+ Colorado::KEYS.each do |color|
23
+ define_method(color) do
24
+ return Colorado::Str.new(self, color)
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ module BaseMix
31
+
32
+ Colorado::KEYS.each do |color|
33
+ define_method(color) do
34
+ return self.plain.send(:color)
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ class Color
41
+
42
+ attr_reader :bold
43
+ attr_reader :color
44
+
45
+ def initialize(c)
46
+ @color = (c.is_a?(Color) ? c.color : c)
47
+ @bold = @color.to_s.end_with?('!')
48
+ @index = @color.to_s.chomp('!').to_sym
49
+ end
50
+
51
+ def code
52
+ return COLORS[@index]
53
+ end
54
+
55
+ def prefix
56
+ return '' if @index == :normal
57
+ return (@bold ? "\e[#{code};1m" : "\e[#{code}m")
58
+ end
59
+
60
+ def suffix
61
+ return '' if @index == :normal
62
+ return "\e[0m"
63
+ end
64
+
65
+ def to_s
66
+ return @color.to_s
67
+ end
68
+
69
+ def normal?
70
+ return @index == :normal
71
+ end
72
+
73
+ end
74
+
75
+ class Base
76
+
77
+ include BaseMix
78
+
79
+ attr_reader :color
80
+
81
+ def initialize(color)
82
+ @color = Color.new(color)
83
+ end
84
+
85
+ def +(s)
86
+ s = Str.new(s) if s.is_a?(String)
87
+ return Group.new(self.parts + s.parts)
88
+ end
89
+
90
+ end
91
+
92
+ class Str < Base
93
+
94
+ def initialize(s, color = :normal)
95
+ super(color)
96
+ raise "Already colorized: #{s}" if Colorado.colorized(s)
97
+ @s = s.to_s
98
+ end
99
+
100
+ def inspect
101
+ "<'#{@s}' in #{@color}>"
102
+ end
103
+
104
+ def plain
105
+ return @s
106
+ end
107
+
108
+ def parts
109
+ return [ self ]
110
+ end
111
+
112
+ def to_s
113
+ return "#{color.prefix}#{@s}#{color.suffix}"
114
+ end
115
+ end
116
+
117
+ class Group < Base
118
+
119
+ def initialize(array)
120
+ super(:normal)
121
+ @array = array
122
+ end
123
+
124
+ def exec(method)
125
+ return @array.map { |it| it.send(method) }
126
+ end
127
+
128
+ def parts
129
+ return exec(:parts).reduce(:+)
130
+ end
131
+
132
+ def plain
133
+ return exec(:plain).reduce(:+)
134
+ end
135
+
136
+ def inspect
137
+ return parts.inspect
138
+ end
139
+
140
+ def to_s
141
+ return exec(:to_s).reduce(:+)
142
+ end
143
+
144
+ end
145
+
146
+ def self.substitute(fmt, array)
147
+ parts = fmt.split(/%(.)/)
148
+ strings = []
149
+ idx = 0
150
+ parts.each_index do |i|
151
+ s = parts[i]
152
+ if i.even? # normal string
153
+ next if s == ''
154
+ strings.push(Str.new(s))
155
+ else
156
+ if s == 's'
157
+ strings.push(fix(array[idx]))
158
+ idx += 1
159
+ elsif s == '%'
160
+ strings.push(fix('%'))
161
+ else
162
+ raise "Error!"
163
+ end
164
+ end
165
+ end
166
+ return Group.new(strings)
167
+ end
168
+
169
+ def self.fix(x)
170
+ return x if x.is_a?(Base)
171
+ return Str.new(x.to_s)
172
+ end
173
+
174
+ def self.colorized(s)
175
+ return (!s.is_a?(Base) && s.to_s.include?("\e"))
176
+ end
177
+
178
+ end
179
+
180
+ class String
181
+
182
+ include Colorado::StringMix
183
+
184
+ alias old_addition :+
185
+ alias old_modulo :%
186
+
187
+ def +(x)
188
+ return Colorado::Str.new(self) + x if x.is_a?(Colorado::Base)
189
+ return old_addition(x)
190
+ end
191
+
192
+ def %(x)
193
+ return Colorado.substitute(self, [x]) if x.is_a?(Colorado::Base)
194
+ return Colorado.substitute(self, x) if (x.is_a?(Array) && x.any? { |el| el.is_a?(Colorado::Base) } )
195
+ return old_modulo(x)
196
+ end
197
+
198
+ end
@@ -0,0 +1,243 @@
1
+ # This file contains implementations of ruby core's custom objects for
2
+ # serialisation/deserialisation.
3
+
4
+ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
5
+ require 'json'
6
+ end
7
+ require 'date'
8
+
9
+ # Symbol serialization/deserialization
10
+ class Symbol
11
+ # Returns a hash, that will be turned into a JSON object and represent this
12
+ # object.
13
+ def as_json(*)
14
+ {
15
+ JSON.create_id => self.class.name,
16
+ 's' => to_s,
17
+ }
18
+ end
19
+
20
+ # Stores class name (Symbol) with String representation of Symbol as a JSON string.
21
+ def to_json(*a)
22
+ as_json.to_json(*a)
23
+ end
24
+
25
+ # Deserializes JSON string by converting the <tt>string</tt> value stored in the object to a Symbol
26
+ def self.json_create(o)
27
+ o['s'].to_sym
28
+ end
29
+ end
30
+
31
+ # Time serialization/deserialization
32
+ class Time
33
+
34
+ # Deserializes JSON string by converting time since epoch to Time
35
+ def self.json_create(object)
36
+ if usec = object.delete('u') # used to be tv_usec -> tv_nsec
37
+ object['n'] = usec * 1000
38
+ end
39
+ if respond_to?(:tv_nsec)
40
+ at(*object.values_at('s', 'n'))
41
+ else
42
+ at(object['s'], object['n'] / 1000)
43
+ end
44
+ end
45
+
46
+ # Returns a hash, that will be turned into a JSON object and represent this
47
+ # object.
48
+ def as_json(*)
49
+ {
50
+ JSON.create_id => self.class.name,
51
+ 's' => tv_sec,
52
+ 'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000
53
+ }
54
+ end
55
+
56
+ # Stores class name (Time) with number of seconds since epoch and number of
57
+ # microseconds for Time as JSON string
58
+ def to_json(*args)
59
+ as_json.to_json(*args)
60
+ end
61
+ end
62
+
63
+ # Date serialization/deserialization
64
+ class Date
65
+
66
+ # Deserializes JSON string by converting Julian year <tt>y</tt>, month
67
+ # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date.
68
+ def self.json_create(object)
69
+ civil(*object.values_at('y', 'm', 'd', 'sg'))
70
+ end
71
+
72
+ alias start sg unless method_defined?(:start)
73
+
74
+ # Returns a hash, that will be turned into a JSON object and represent this
75
+ # object.
76
+ def as_json(*)
77
+ {
78
+ JSON.create_id => self.class.name,
79
+ 'y' => year,
80
+ 'm' => month,
81
+ 'd' => day,
82
+ 'sg' => start,
83
+ }
84
+ end
85
+
86
+ # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day
87
+ # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
88
+ def to_json(*args)
89
+ as_json.to_json(*args)
90
+ end
91
+ end
92
+
93
+ # DateTime serialization/deserialization
94
+ class DateTime
95
+
96
+ # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
97
+ # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
98
+ # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime.
99
+ def self.json_create(object)
100
+ args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
101
+ of_a, of_b = object['of'].split('/')
102
+ if of_b and of_b != '0'
103
+ args << Rational(of_a.to_i, of_b.to_i)
104
+ else
105
+ args << of_a
106
+ end
107
+ args << object['sg']
108
+ civil(*args)
109
+ end
110
+
111
+ alias start sg unless method_defined?(:start)
112
+
113
+ # Returns a hash, that will be turned into a JSON object and represent this
114
+ # object.
115
+ def as_json(*)
116
+ {
117
+ JSON.create_id => self.class.name,
118
+ 'y' => year,
119
+ 'm' => month,
120
+ 'd' => day,
121
+ 'H' => hour,
122
+ 'M' => min,
123
+ 'S' => sec,
124
+ 'of' => offset.to_s,
125
+ 'sg' => start,
126
+ }
127
+ end
128
+
129
+ # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>,
130
+ # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
131
+ # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
132
+ def to_json(*args)
133
+ as_json.to_json(*args)
134
+ end
135
+ end
136
+
137
+ # Range serialization/deserialization
138
+ class Range
139
+
140
+ # Deserializes JSON string by constructing new Range object with arguments
141
+ # <tt>a</tt> serialized by <tt>to_json</tt>.
142
+ def self.json_create(object)
143
+ new(*object['a'])
144
+ end
145
+
146
+ # Returns a hash, that will be turned into a JSON object and represent this
147
+ # object.
148
+ def as_json(*)
149
+ {
150
+ JSON.create_id => self.class.name,
151
+ 'a' => [ first, last, exclude_end? ]
152
+ }
153
+ end
154
+
155
+ # Stores class name (Range) with JSON array of arguments <tt>a</tt> which
156
+ # include <tt>first</tt> (integer), <tt>last</tt> (integer), and
157
+ # <tt>exclude_end?</tt> (boolean) as JSON string.
158
+ def to_json(*args)
159
+ as_json.to_json(*args)
160
+ end
161
+ end
162
+
163
+ # Struct serialization/deserialization
164
+ class Struct
165
+
166
+ # Deserializes JSON string by constructing new Struct object with values
167
+ # <tt>v</tt> serialized by <tt>to_json</tt>.
168
+ def self.json_create(object)
169
+ new(*object['v'])
170
+ end
171
+
172
+ # Returns a hash, that will be turned into a JSON object and represent this
173
+ # object.
174
+ def as_json(*)
175
+ klass = self.class.name
176
+ klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
177
+ {
178
+ JSON.create_id => klass,
179
+ 'v' => values,
180
+ }
181
+ end
182
+
183
+ # Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string.
184
+ # Only named structs are supported.
185
+ def to_json(*args)
186
+ as_json.to_json(*args)
187
+ end
188
+ end
189
+
190
+ # Exception serialization/deserialization
191
+ class Exception
192
+
193
+ # Deserializes JSON string by constructing new Exception object with message
194
+ # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt>
195
+ def self.json_create(object)
196
+ result = new(object['m'])
197
+ result.set_backtrace object['b']
198
+ result
199
+ end
200
+
201
+ # Returns a hash, that will be turned into a JSON object and represent this
202
+ # object.
203
+ def as_json(*)
204
+ {
205
+ JSON.create_id => self.class.name,
206
+ 'm' => message,
207
+ 'b' => backtrace,
208
+ }
209
+ end
210
+
211
+ # Stores class name (Exception) with message <tt>m</tt> and backtrace array
212
+ # <tt>b</tt> as JSON string
213
+ def to_json(*args)
214
+ as_json.to_json(*args)
215
+ end
216
+ end
217
+
218
+ # Regexp serialization/deserialization
219
+ class Regexp
220
+
221
+ # Deserializes JSON string by constructing new Regexp object with source
222
+ # <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by
223
+ # <tt>to_json</tt>
224
+ def self.json_create(object)
225
+ new(object['s'], object['o'])
226
+ end
227
+
228
+ # Returns a hash, that will be turned into a JSON object and represent this
229
+ # object.
230
+ def as_json(*)
231
+ {
232
+ JSON.create_id => self.class.name,
233
+ 'o' => options,
234
+ 's' => source,
235
+ }
236
+ end
237
+
238
+ # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
239
+ # (Regexp or String) as JSON string
240
+ def to_json(*)
241
+ as_json.to_json
242
+ end
243
+ end
@@ -0,0 +1,8 @@
1
+ # This file used to implementations of rails custom objects for
2
+ # serialisation/deserialisation and is obsoleted now.
3
+
4
+ unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
5
+ require 'json'
6
+ end
7
+
8
+ $DEBUG and warn "required json/add/rails which is obsolete now!"