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
@@ -0,0 +1,50 @@
1
+
2
+ # just reuse existing thing
3
+
4
+ def __check_g5k_credentials_path__
5
+ home = Etc.getpwuid.dir
6
+ return File.join(home, '.g5k.yaml')
7
+ end
8
+
9
+ def __check_g5k_credentials__
10
+ path = __check_g5k_credentials_path__()
11
+ if File.exist?(path)
12
+ h = YAML.load_file(path)
13
+ mode = File::Stat.new(path).mode
14
+ raise "#{path} is accessible by other users" if (mode & 077 != 0)
15
+ else
16
+ return nil
17
+ end
18
+ if !h.is_a?(Hash) or h["user"].nil? or h["pass"].nil?
19
+ raise "bad credentials"
20
+ end
21
+ [ h["user"], h["pass"] ]
22
+ end
23
+
24
+ def __save_g5k_credentials__
25
+ path = __check_g5k_credentials_path__()
26
+ File.open(path, "w") do |f|
27
+ f.puts({
28
+ "user" => $g5k_user,
29
+ "pass" => $g5k_pass
30
+ }.to_yaml)
31
+ end
32
+ File.chmod(0600, path)
33
+ end
34
+
35
+ $g5k_creds = __check_g5k_credentials__()
36
+
37
+ if $g5k_creds.nil?
38
+ # no credentials
39
+ $g5k_user = var(:g5k_user, :str, :text => "Provide G5K username: ")
40
+ $g5k_pass = var(:g5k_pass, :pass, :text => "Provide G5K password: ")
41
+ $g5k_save = var(:g5k_save, :bool, :callback => proc { |x| __save_g5k_credentials__ if x }, :text => "Do you want to save these credentials?")
42
+ else
43
+ $g5k_user = set_var(:g5k_user, $g5k_creds.first)
44
+ $g5k_pass = set_var(:g5k_pass, $g5k_creds.last)
45
+ end
46
+
47
+ # hide the password
48
+ set_var(:g5k_pass, "*" * $g5k_pass.length)
49
+
50
+ require 'xpflow/with_g5k'
@@ -0,0 +1,140 @@
1
+
2
+ require 'sinatra/base'
3
+ require 'json'
4
+
5
+ class << Sinatra::Base
6
+
7
+ def quit!(server, handler_name)
8
+ server.respond_to?(:stop!) ? server.stop! : server.stop
9
+ end
10
+
11
+ # copy-pasted-adjusted from sinatra code (1.3.2-2 in Debian)
12
+ def _run_custom!(options={})
13
+ set options
14
+ set :logging, nil
15
+ handler = detect_rack_handler
16
+ handler_name = handler.name.gsub(/.*::/, '')
17
+ handler.run self, :Host => bind, :Port => port do |server|
18
+ @__quit__ = proc { || quit!(server, handler_name) }
19
+ server.threaded = settings.threaded if server.respond_to? :threaded=
20
+ set :running, true
21
+ yield server if block_given?
22
+ end
23
+ end
24
+
25
+ def run_custom!(options={})
26
+ # it may result in a race
27
+ # small note here:
28
+ # THERE MUST BE A SPECIAL PLACE
29
+ # IN HELL FOR PEOPLE DOING THINGS LIKE THIS!!!
30
+ handler = trap(:INT, 'DEFAULT') # take previous handler
31
+ trap(:INT, handler)
32
+ t = Thread.new(handler) do |h|
33
+ x = h
34
+ while x == h do
35
+ sleep 0.1
36
+ x = trap(:INT, &h)
37
+ end
38
+ # x is sinatra wicked handler
39
+ # let's overwrite it back
40
+ trap(:INT, &h)
41
+ end
42
+ _run_custom!(options)
43
+ end
44
+
45
+ def quit_custom!
46
+ return @__quit__.call()
47
+ end
48
+
49
+ public
50
+
51
+ # sets xpflow engine
52
+ def set_engine(engine)
53
+ $__gui_engine__ = engine
54
+ end
55
+
56
+ end
57
+
58
+
59
+ class Rest
60
+
61
+ attr_reader :engine
62
+
63
+ def initialize(engine)
64
+ @engine = engine
65
+ end
66
+
67
+ def activities
68
+ ns = @engine.get_global_namespace()
69
+ return ns.each.map do |name, o|
70
+ { :name => name, :info => o.info }
71
+ end.to_a
72
+ end
73
+
74
+ def active
75
+ h = @engine.spectator.info
76
+ h2 = []
77
+ h.each_pair do |k, v|
78
+ h2.push({ :name => k, :info => v })
79
+ end
80
+ return h2
81
+ end
82
+
83
+ end
84
+
85
+
86
+ class Controller < Sinatra::Base
87
+
88
+ set :port, 8080
89
+ set :public_folder, File.join(File.dirname(__FILE__), 'gui-files')
90
+
91
+ def rest
92
+ return Rest.new($__gui_engine__)
93
+ end
94
+
95
+ def json(obj)
96
+ content_type 'application/json', :charset => 'utf-8'
97
+ return obj.to_json
98
+ end
99
+
100
+ get '/__rest__/:method' do |m|
101
+ x = rest.send(m.to_sym)
102
+ json x
103
+ end
104
+
105
+ get '/' do
106
+ erb :index
107
+ end
108
+
109
+ end
110
+
111
+ if $0 == __FILE__
112
+
113
+ require 'xpflow'
114
+
115
+ process :main do
116
+ run :whatever
117
+ run :whatever
118
+ end
119
+
120
+ activity :whatever do |x|
121
+ sleep 10
122
+ log "cze"
123
+ end
124
+
125
+ Controller.set_engine($engine)
126
+
127
+ trap(:INT) do
128
+ puts 'Shutting everything down...'
129
+ Controller.quit_custom!
130
+ end
131
+
132
+ t = Thread.new do
133
+ Controller.run_custom!
134
+ end
135
+
136
+ $engine.execute_from_argv :main
137
+
138
+ t.join
139
+
140
+ end
@@ -0,0 +1,155 @@
1
+
2
+ # this is pulled in by the main xpflow command line tool
3
+
4
+ # a standard model for an experiment
5
+
6
+ NODES_OPTS = { :doc => "Resource acquisition" }
7
+ DEPLOYMENT_OPTS = { :doc => "Deployment", :idempotent => true }
8
+ COLLECTION_OPTS = { :doc => "Collection of results" }
9
+ ANALYSIS_OPTS = { :doc => "Data analysis" }
10
+ EXPERIMENT_OPTS = { :doc => "Experiment" }
11
+ STANDARD_OPTS = { :doc => "Experiment model" }
12
+
13
+ $engine.process :__reservation__, NODES_OPTS do |nodes|
14
+ value(nodes)
15
+ end
16
+
17
+ $engine.process :__deployment__, DEPLOYMENT_OPTS do |nodes|
18
+ value(nodes)
19
+ end
20
+
21
+ $engine.process :__collection__, COLLECTION_OPTS do
22
+ debug "Collecting results from nodes..."
23
+ save_all_results
24
+ end
25
+
26
+ $engine.process :__analysis__, ANALYSIS_OPTS do |exp_result|
27
+ value(exp_result)
28
+ end
29
+
30
+ $engine.activity :__install_node__, :doc => "Install a given node", :log_level => :none do |node|
31
+ node.install()
32
+ end
33
+
34
+ $engine.process :__install_nodes__, :doc => "Initial node setup", :log_level => :none do |nodes|
35
+ foreach nodes do |node|
36
+ debug "Installing ", node
37
+ run :__install_node__, node
38
+ end
39
+ count = (length_of nodes)
40
+ on(count > 0) do
41
+ bootstrap_taktuk(nodes)
42
+ end
43
+ # TODO: more parallel and more scalable
44
+ forall nodes, :pool => 10 do |node|
45
+ debug "Bootstrapping ", node
46
+ code(node) { |node| node.bootstrap }
47
+ end
48
+
49
+ # checking nodes - run a simple command everywhere
50
+ # be idempotent - if some nodes fail, retry them
51
+
52
+ run :__check_nodes__, nodes
53
+ value(nodes)
54
+ end
55
+
56
+ $engine.process :__check_nodes__, :doc => "Checking all nodes", :log_level => :none do |nodes|
57
+ results = execute_many nodes, "true", :idempotent => true
58
+ length = length_of results
59
+ debug "All nodes (#{length}) checked"
60
+ end
61
+
62
+ $engine.activity :__fix_node_list__ do |list|
63
+ (list.nil?) ? [] : list
64
+ end
65
+
66
+ $engine.process :__standard__, STANDARD_OPTS do |node_list|
67
+
68
+ flattened_node_list = run :__fix_node_list__, node_list
69
+
70
+ nodes = cache :__reservation__ do
71
+ run :__reservation__, flattened_node_list
72
+ end
73
+
74
+ nodes_list = run :__install_nodes__, nodes
75
+
76
+ # replace __reservation__ with a new set
77
+ set_scope :__nodes__, nodes_list
78
+
79
+ deployed = cache :__deployment__ do
80
+ run :__deployment__, nodes
81
+ end
82
+
83
+ exp_result = run :__experiment__, deployed
84
+ run :__collection__
85
+ run :__analysis__, exp_result
86
+
87
+ end
88
+
89
+ # helpers
90
+
91
+ def nodes(&block)
92
+ return $engine.process(:__reservation__, NODES_OPTS, &block)
93
+ end
94
+
95
+ def deployment(name = nil, &block)
96
+ if name.nil?
97
+ return $engine.process(:__deployment__, DEPLOYMENT_OPTS, &block)
98
+ else
99
+ return $engine.process(:__deployment__, DEPLOYMENT_OPTS) { |nodes| run(name, nodes) }
100
+ end
101
+ end
102
+
103
+ def body(&block)
104
+ return $engine.process(:__experiment__, EXPERIMENT_OPTS, &block)
105
+ end
106
+
107
+ def analysis(&block)
108
+ return $engine.process(:__analysis__, ANALYSIS_OPTS, &block)
109
+ end
110
+
111
+
112
+ # importer of subexperiments
113
+ # TODO: this is rather ugly!
114
+
115
+ def with_sublibrary()
116
+ exp = nil
117
+ begin
118
+ old_engine = $engine
119
+ exp = $engine = XPFlow::BasicLibrary.new
120
+ yield
121
+ ensure
122
+ $engine = old_engine
123
+ end
124
+ return exp
125
+ end
126
+
127
+ def import(name, path = nil, opts = {})
128
+ if path.nil?
129
+ return import_file(name)
130
+ end
131
+ lib = with_sublibrary do
132
+ Kernel.load(__FILE__, true)
133
+ Kernel.load(path)
134
+ end
135
+ $engine.import_library(name, lib)
136
+ return lib
137
+ end
138
+
139
+ def library(name, &block)
140
+ lib = with_sublibrary do
141
+ Kernel.load(__FILE__, true)
142
+ block.call
143
+ end
144
+ $engine.import_library(name, lib)
145
+ return lib
146
+ end
147
+
148
+ # includes the file as-it-is
149
+ def import_file(path)
150
+ return Kernel.load(path)
151
+ end
152
+
153
+ def experiment_entry(&block)
154
+ return $engine.process(:__standard__, &block)
155
+ end