xpflow 0.1b

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.
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/lib/json/ext.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'json/common'
2
+
3
+ module JSON
4
+ # This module holds all the modules/classes that implement JSON's
5
+ # functionality as C extensions.
6
+ module Ext
7
+ begin
8
+ if defined?(RUBY_ENGINE) == 'constant' and RUBY_ENGINE == 'ruby' and RUBY_VERSION =~ /\A1\.9\./
9
+ require 'json/ext/1.9/parser'
10
+ require 'json/ext/1.9/generator'
11
+ elsif !defined?(RUBY_ENGINE) && RUBY_VERSION =~ /\A1\.8\./
12
+ require 'json/ext/1.8/parser'
13
+ require 'json/ext/1.8/generator'
14
+ else
15
+ require 'json/ext/parser'
16
+ require 'json/ext/generator'
17
+ end
18
+ rescue LoadError
19
+ require 'json/ext/parser'
20
+ require 'json/ext/generator'
21
+ end
22
+ $DEBUG and warn "Using Ext extension for JSON."
23
+ JSON.parser = Parser
24
+ JSON.generator = Generator
25
+ end
26
+
27
+ JSON_LOADED = true unless defined?(::JSON::JSON_LOADED)
28
+ end
@@ -0,0 +1,442 @@
1
+ module JSON
2
+ MAP = {
3
+ "\x0" => '\u0000',
4
+ "\x1" => '\u0001',
5
+ "\x2" => '\u0002',
6
+ "\x3" => '\u0003',
7
+ "\x4" => '\u0004',
8
+ "\x5" => '\u0005',
9
+ "\x6" => '\u0006',
10
+ "\x7" => '\u0007',
11
+ "\b" => '\b',
12
+ "\t" => '\t',
13
+ "\n" => '\n',
14
+ "\xb" => '\u000b',
15
+ "\f" => '\f',
16
+ "\r" => '\r',
17
+ "\xe" => '\u000e',
18
+ "\xf" => '\u000f',
19
+ "\x10" => '\u0010',
20
+ "\x11" => '\u0011',
21
+ "\x12" => '\u0012',
22
+ "\x13" => '\u0013',
23
+ "\x14" => '\u0014',
24
+ "\x15" => '\u0015',
25
+ "\x16" => '\u0016',
26
+ "\x17" => '\u0017',
27
+ "\x18" => '\u0018',
28
+ "\x19" => '\u0019',
29
+ "\x1a" => '\u001a',
30
+ "\x1b" => '\u001b',
31
+ "\x1c" => '\u001c',
32
+ "\x1d" => '\u001d',
33
+ "\x1e" => '\u001e',
34
+ "\x1f" => '\u001f',
35
+ '"' => '\"',
36
+ '\\' => '\\\\',
37
+ } # :nodoc:
38
+
39
+ # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with
40
+ # UTF16 big endian characters as \u????, and return it.
41
+ if defined?(::Encoding)
42
+ def utf8_to_json(string) # :nodoc:
43
+ string = string.dup
44
+ string << '' # XXX workaround: avoid buffer sharing
45
+ string.force_encoding(::Encoding::ASCII_8BIT)
46
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
47
+ string.force_encoding(::Encoding::UTF_8)
48
+ string
49
+ end
50
+
51
+ def utf8_to_json_ascii(string) # :nodoc:
52
+ string = string.dup
53
+ string << '' # XXX workaround: avoid buffer sharing
54
+ string.force_encoding(::Encoding::ASCII_8BIT)
55
+ string.gsub!(/["\\\x0-\x1f]/) { MAP[$&] }
56
+ string.gsub!(/(
57
+ (?:
58
+ [\xc2-\xdf][\x80-\xbf] |
59
+ [\xe0-\xef][\x80-\xbf]{2} |
60
+ [\xf0-\xf4][\x80-\xbf]{3}
61
+ )+ |
62
+ [\x80-\xc1\xf5-\xff] # invalid
63
+ )/nx) { |c|
64
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
65
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
66
+ s.gsub!(/.{4}/n, '\\\\u\&')
67
+ }
68
+ string.force_encoding(::Encoding::UTF_8)
69
+ string
70
+ rescue => e
71
+ raise GeneratorError, "Caught #{e.class}: #{e}"
72
+ end
73
+ else
74
+ def utf8_to_json(string) # :nodoc:
75
+ string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
76
+ end
77
+
78
+ def utf8_to_json_ascii(string) # :nodoc:
79
+ string = string.gsub(/["\\\x0-\x1f]/) { MAP[$&] }
80
+ string.gsub!(/(
81
+ (?:
82
+ [\xc2-\xdf][\x80-\xbf] |
83
+ [\xe0-\xef][\x80-\xbf]{2} |
84
+ [\xf0-\xf4][\x80-\xbf]{3}
85
+ )+ |
86
+ [\x80-\xc1\xf5-\xff] # invalid
87
+ )/nx) { |c|
88
+ c.size == 1 and raise GeneratorError, "invalid utf8 byte: '#{c}'"
89
+ s = JSON.iconv('utf-16be', 'utf-8', c).unpack('H*')[0]
90
+ s.gsub!(/.{4}/n, '\\\\u\&')
91
+ }
92
+ string
93
+ rescue => e
94
+ raise GeneratorError, "Caught #{e.class}: #{e}"
95
+ end
96
+ end
97
+ module_function :utf8_to_json, :utf8_to_json_ascii
98
+
99
+ module Pure
100
+ module Generator
101
+ # This class is used to create State instances, that are use to hold data
102
+ # while generating a JSON text from a Ruby data structure.
103
+ class State
104
+ # Creates a State object from _opts_, which ought to be Hash to create
105
+ # a new State instance configured by _opts_, something else to create
106
+ # an unconfigured instance. If _opts_ is a State object, it is just
107
+ # returned.
108
+ def self.from_state(opts)
109
+ case
110
+ when self === opts
111
+ opts
112
+ when opts.respond_to?(:to_hash)
113
+ new(opts.to_hash)
114
+ when opts.respond_to?(:to_h)
115
+ new(opts.to_h)
116
+ else
117
+ SAFE_STATE_PROTOTYPE.dup
118
+ end
119
+ end
120
+
121
+ # Instantiates a new State object, configured by _opts_.
122
+ #
123
+ # _opts_ can have the following keys:
124
+ #
125
+ # * *indent*: a string used to indent levels (default: ''),
126
+ # * *space*: a string that is put after, a : or , delimiter (default: ''),
127
+ # * *space_before*: a string that is put before a : pair delimiter (default: ''),
128
+ # * *object_nl*: a string that is put at the end of a JSON object (default: ''),
129
+ # * *array_nl*: a string that is put at the end of a JSON array (default: ''),
130
+ # * *check_circular*: is deprecated now, use the :max_nesting option instead,
131
+ # * *max_nesting*: sets the maximum level of data structure nesting in
132
+ # the generated JSON, max_nesting = 0 if no maximum should be checked.
133
+ # * *allow_nan*: true if NaN, Infinity, and -Infinity should be
134
+ # generated, otherwise an exception is thrown, if these values are
135
+ # encountered. This options defaults to false.
136
+ def initialize(opts = {})
137
+ @indent = ''
138
+ @space = ''
139
+ @space_before = ''
140
+ @object_nl = ''
141
+ @array_nl = ''
142
+ @allow_nan = false
143
+ @ascii_only = false
144
+ configure opts
145
+ end
146
+
147
+ # This string is used to indent levels in the JSON text.
148
+ attr_accessor :indent
149
+
150
+ # This string is used to insert a space between the tokens in a JSON
151
+ # string.
152
+ attr_accessor :space
153
+
154
+ # This string is used to insert a space before the ':' in JSON objects.
155
+ attr_accessor :space_before
156
+
157
+ # This string is put at the end of a line that holds a JSON object (or
158
+ # Hash).
159
+ attr_accessor :object_nl
160
+
161
+ # This string is put at the end of a line that holds a JSON array.
162
+ attr_accessor :array_nl
163
+
164
+ # This integer returns the maximum level of data structure nesting in
165
+ # the generated JSON, max_nesting = 0 if no maximum is checked.
166
+ attr_accessor :max_nesting
167
+
168
+ # This integer returns the current depth data structure nesting in the
169
+ # generated JSON.
170
+ attr_accessor :depth
171
+
172
+ def check_max_nesting # :nodoc:
173
+ return if @max_nesting.zero?
174
+ current_nesting = depth + 1
175
+ current_nesting > @max_nesting and
176
+ raise NestingError, "nesting of #{current_nesting} is too deep"
177
+ end
178
+
179
+ # Returns true, if circular data structures are checked,
180
+ # otherwise returns false.
181
+ def check_circular?
182
+ !@max_nesting.zero?
183
+ end
184
+
185
+ # Returns true if NaN, Infinity, and -Infinity should be considered as
186
+ # valid JSON and output.
187
+ def allow_nan?
188
+ @allow_nan
189
+ end
190
+
191
+ def ascii_only?
192
+ @ascii_only
193
+ end
194
+
195
+ # Configure this State instance with the Hash _opts_, and return
196
+ # itself.
197
+ def configure(opts)
198
+ @indent = opts[:indent] if opts.key?(:indent)
199
+ @space = opts[:space] if opts.key?(:space)
200
+ @space_before = opts[:space_before] if opts.key?(:space_before)
201
+ @object_nl = opts[:object_nl] if opts.key?(:object_nl)
202
+ @array_nl = opts[:array_nl] if opts.key?(:array_nl)
203
+ @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan)
204
+ @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only)
205
+ @depth = opts[:depth] || 0
206
+ if !opts.key?(:max_nesting) # defaults to 19
207
+ @max_nesting = 19
208
+ elsif opts[:max_nesting]
209
+ @max_nesting = opts[:max_nesting]
210
+ else
211
+ @max_nesting = 0
212
+ end
213
+ self
214
+ end
215
+ alias merge configure
216
+
217
+ # Returns the configuration instance variables as a hash, that can be
218
+ # passed to the configure method.
219
+ def to_h
220
+ result = {}
221
+ for iv in %w[indent space space_before object_nl array_nl allow_nan max_nesting ascii_only depth]
222
+ result[iv.intern] = instance_variable_get("@#{iv}")
223
+ end
224
+ result
225
+ end
226
+
227
+ # Generates a valid JSON document from object +obj+ and returns the
228
+ # result. If no valid JSON document can be created this method raises a
229
+ # GeneratorError exception.
230
+ def generate(obj)
231
+ result = obj.to_json(self)
232
+ if result !~ /\A\s*(?:\[.*\]|\{.*\})\s*\Z/m
233
+ raise GeneratorError, "only generation of JSON objects or arrays allowed"
234
+ end
235
+ result
236
+ end
237
+
238
+ # Return the value returned by method +name+.
239
+ def [](name)
240
+ __send__ name
241
+ end
242
+ end
243
+
244
+ module GeneratorMethods
245
+ module Object
246
+ # Converts this object to a string (calling #to_s), converts
247
+ # it to a JSON string, and returns the result. This is a fallback, if no
248
+ # special method #to_json was defined for some object.
249
+ def to_json(*) to_s.to_json end
250
+ end
251
+
252
+ module Hash
253
+ # Returns a JSON string containing a JSON object, that is unparsed from
254
+ # this Hash instance.
255
+ # _state_ is a JSON::State object, that can also be used to configure the
256
+ # produced JSON string output further.
257
+ # _depth_ is used to find out nesting depth, to indent accordingly.
258
+ def to_json(state = nil, *)
259
+ state = State.from_state(state)
260
+ state.check_max_nesting
261
+ json_transform(state)
262
+ end
263
+
264
+ private
265
+
266
+ def json_shift(state)
267
+ state.object_nl.empty? or return ''
268
+ state.indent * state.depth
269
+ end
270
+
271
+ def json_transform(state)
272
+ delim = ','
273
+ delim << state.object_nl
274
+ result = '{'
275
+ result << state.object_nl
276
+ depth = state.depth += 1
277
+ first = true
278
+ indent = !state.object_nl.empty?
279
+ each { |key,value|
280
+ result << delim unless first
281
+ result << state.indent * depth if indent
282
+ result << key.to_s.to_json(state)
283
+ result << state.space_before
284
+ result << ':'
285
+ result << state.space
286
+ result << value.to_json(state)
287
+ first = false
288
+ }
289
+ depth = state.depth -= 1
290
+ result << state.object_nl
291
+ result << state.indent * depth if indent if indent
292
+ result << '}'
293
+ result
294
+ end
295
+ end
296
+
297
+ module Array
298
+ # Returns a JSON string containing a JSON array, that is unparsed from
299
+ # this Array instance.
300
+ # _state_ is a JSON::State object, that can also be used to configure the
301
+ # produced JSON string output further.
302
+ def to_json(state = nil, *)
303
+ state = State.from_state(state)
304
+ state.check_max_nesting
305
+ json_transform(state)
306
+ end
307
+
308
+ private
309
+
310
+ def json_transform(state)
311
+ delim = ','
312
+ delim << state.array_nl
313
+ result = '['
314
+ result << state.array_nl
315
+ depth = state.depth += 1
316
+ first = true
317
+ indent = !state.array_nl.empty?
318
+ each { |value|
319
+ result << delim unless first
320
+ result << state.indent * depth if indent
321
+ result << value.to_json(state)
322
+ first = false
323
+ }
324
+ depth = state.depth -= 1
325
+ result << state.array_nl
326
+ result << state.indent * depth if indent
327
+ result << ']'
328
+ end
329
+ end
330
+
331
+ module Integer
332
+ # Returns a JSON string representation for this Integer number.
333
+ def to_json(*) to_s end
334
+ end
335
+
336
+ module Float
337
+ # Returns a JSON string representation for this Float number.
338
+ def to_json(state = nil, *)
339
+ state = State.from_state(state)
340
+ case
341
+ when infinite?
342
+ if state.allow_nan?
343
+ to_s
344
+ else
345
+ raise GeneratorError, "#{self} not allowed in JSON"
346
+ end
347
+ when nan?
348
+ if state.allow_nan?
349
+ to_s
350
+ else
351
+ raise GeneratorError, "#{self} not allowed in JSON"
352
+ end
353
+ else
354
+ to_s
355
+ end
356
+ end
357
+ end
358
+
359
+ module String
360
+ if defined?(::Encoding)
361
+ # This string should be encoded with UTF-8 A call to this method
362
+ # returns a JSON string encoded with UTF16 big endian characters as
363
+ # \u????.
364
+ def to_json(state = nil, *args)
365
+ state = State.from_state(state)
366
+ if encoding == ::Encoding::UTF_8
367
+ string = self
368
+ else
369
+ string = encode(::Encoding::UTF_8)
370
+ end
371
+ if state.ascii_only?
372
+ '"' << JSON.utf8_to_json_ascii(string) << '"'
373
+ else
374
+ '"' << JSON.utf8_to_json(string) << '"'
375
+ end
376
+ end
377
+ else
378
+ # This string should be encoded with UTF-8 A call to this method
379
+ # returns a JSON string encoded with UTF16 big endian characters as
380
+ # \u????.
381
+ def to_json(state = nil, *args)
382
+ state = State.from_state(state)
383
+ if state.ascii_only?
384
+ '"' << JSON.utf8_to_json_ascii(self) << '"'
385
+ else
386
+ '"' << JSON.utf8_to_json(self) << '"'
387
+ end
388
+ end
389
+ end
390
+
391
+ # Module that holds the extinding methods if, the String module is
392
+ # included.
393
+ module Extend
394
+ # Raw Strings are JSON Objects (the raw bytes are stored in an
395
+ # array for the key "raw"). The Ruby String can be created by this
396
+ # module method.
397
+ def json_create(o)
398
+ o['raw'].pack('C*')
399
+ end
400
+ end
401
+
402
+ # Extends _modul_ with the String::Extend module.
403
+ def self.included(modul)
404
+ modul.extend Extend
405
+ end
406
+
407
+ # This method creates a raw object hash, that can be nested into
408
+ # other data structures and will be unparsed as a raw string. This
409
+ # method should be used, if you want to convert raw strings to JSON
410
+ # instead of UTF-8 strings, e. g. binary data.
411
+ def to_json_raw_object
412
+ {
413
+ JSON.create_id => self.class.name,
414
+ 'raw' => self.unpack('C*'),
415
+ }
416
+ end
417
+
418
+ # This method creates a JSON text from the result of
419
+ # a call to to_json_raw_object of this String.
420
+ def to_json_raw(*args)
421
+ to_json_raw_object.to_json(*args)
422
+ end
423
+ end
424
+
425
+ module TrueClass
426
+ # Returns a JSON string for true: 'true'.
427
+ def to_json(*) 'true' end
428
+ end
429
+
430
+ module FalseClass
431
+ # Returns a JSON string for false: 'false'.
432
+ def to_json(*) 'false' end
433
+ end
434
+
435
+ module NilClass
436
+ # Returns a JSON string for nil: 'null'.
437
+ def to_json(*) 'null' end
438
+ end
439
+ end
440
+ end
441
+ end
442
+ end