cloudbox-server 0.0.1

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 (147) hide show
  1. data/.yardopts +3 -0
  2. data/README.md +17 -0
  3. data/bin/cb-cluster-allocate +5 -0
  4. data/bin/cb-cluster-create +5 -0
  5. data/bin/cb-cluster-delete +5 -0
  6. data/bin/cb-cluster-desallocate +5 -0
  7. data/bin/cb-cluster-info +5 -0
  8. data/bin/cb-cluster-ls +5 -0
  9. data/bin/cb-node-destroy +5 -0
  10. data/bin/cb-node-detach +6 -0
  11. data/bin/cb-node-info +5 -0
  12. data/bin/cb-node-install +5 -0
  13. data/bin/cb-node-ls +5 -0
  14. data/bin/cb-service-add +5 -0
  15. data/bin/cb-service-component-add +5 -0
  16. data/bin/cb-service-component-delete +5 -0
  17. data/bin/cb-service-component-detach +5 -0
  18. data/bin/cb-service-conf-apply +5 -0
  19. data/bin/cb-service-conf-create +5 -0
  20. data/bin/cb-service-conf-get +5 -0
  21. data/bin/cb-service-conf-ls +5 -0
  22. data/bin/cb-service-follow-request +5 -0
  23. data/bin/cb-service-info +5 -0
  24. data/bin/cb-service-install +5 -0
  25. data/bin/cb-service-ls +5 -0
  26. data/bin/cb-service-start +5 -0
  27. data/bin/cb-service-stop +5 -0
  28. data/lib/command.rb +61 -0
  29. data/lib/command/ambari_add_host.rb +19 -0
  30. data/lib/command/ambari_cluster_command.rb +26 -0
  31. data/lib/command/ambari_cluster_component_command.rb +26 -0
  32. data/lib/command/ambari_cluster_component_host_command.rb +26 -0
  33. data/lib/command/ambari_cluster_create.rb +19 -0
  34. data/lib/command/ambari_cluster_host_command.rb +27 -0
  35. data/lib/command/ambari_cluster_list.rb +20 -0
  36. data/lib/command/ambari_cluster_service_command.rb +26 -0
  37. data/lib/command/ambari_cluster_service_host_command.rb +26 -0
  38. data/lib/command/ambari_command.rb +21 -0
  39. data/lib/command/ambari_create_cluster_configuration.rb +39 -0
  40. data/lib/command/ambari_get_cluster_configuration.rb +29 -0
  41. data/lib/command/ambari_host_list.rb +19 -0
  42. data/lib/command/ambari_install_cluster.rb +19 -0
  43. data/lib/command/ambari_install_component.rb +19 -0
  44. data/lib/command/ambari_install_host.rb +19 -0
  45. data/lib/command/ambari_install_host_component.rb +19 -0
  46. data/lib/command/ambari_install_host_components.rb +19 -0
  47. data/lib/command/ambari_install_service_components.rb +19 -0
  48. data/lib/command/ambari_service_add.rb +27 -0
  49. data/lib/command/ambari_service_component_add.rb +21 -0
  50. data/lib/command/ambari_service_component_delete.rb +21 -0
  51. data/lib/command/ambari_service_component_detach.rb +21 -0
  52. data/lib/command/ambari_service_component_info.rb +29 -0
  53. data/lib/command/ambari_service_conf_apply.rb +31 -0
  54. data/lib/command/ambari_service_conf_ls.rb +30 -0
  55. data/lib/command/ambari_service_delete.rb +21 -0
  56. data/lib/command/ambari_service_info.rb +20 -0
  57. data/lib/command/ambari_service_list.rb +21 -0
  58. data/lib/command/ambari_start_cluster.rb +19 -0
  59. data/lib/command/ambari_start_component.rb +19 -0
  60. data/lib/command/ambari_start_host.rb +19 -0
  61. data/lib/command/ambari_start_host_component.rb +19 -0
  62. data/lib/command/ambari_start_host_components.rb +19 -0
  63. data/lib/command/ambari_start_service_components.rb +19 -0
  64. data/lib/command/ambari_stop_cluster.rb +19 -0
  65. data/lib/command/ambari_stop_component.rb +19 -0
  66. data/lib/command/ambari_stop_host.rb +19 -0
  67. data/lib/command/ambari_stop_host_component.rb +19 -0
  68. data/lib/command/ambari_stop_host_components.rb +19 -0
  69. data/lib/command/ambari_stop_service_components.rb +19 -0
  70. data/lib/command/basic_command.rb +44 -0
  71. data/lib/command/cluster_create.rb +50 -0
  72. data/lib/command/cluster_delete.rb +30 -0
  73. data/lib/command/cluster_info.rb +30 -0
  74. data/lib/command/cluster_ls.rb +30 -0
  75. data/lib/command/crowbar_cluster_allocate.rb +42 -0
  76. data/lib/command/crowbar_command.rb +30 -0
  77. data/lib/command/crowbar_get_barclamps_list.rb +30 -0
  78. data/lib/command/crowbar_node_command.rb +21 -0
  79. data/lib/command/crowbar_node_list.rb +40 -0
  80. data/lib/command/crowbar_vcluster_command.rb +20 -0
  81. data/lib/command/filter.rb +15 -0
  82. data/lib/command/node_destroy.rb +58 -0
  83. data/lib/command/node_detach.rb +44 -0
  84. data/lib/command/node_info.rb +27 -0
  85. data/lib/command/node_install.rb +46 -0
  86. data/lib/command/node_reinstall.rb +44 -0
  87. data/lib/command/state_filter.rb +16 -0
  88. data/lib/common.rb +11 -0
  89. data/lib/common/cb-lib-node-erase-hard-disk.sh +29 -0
  90. data/lib/common/cloudbox_exceptions.rb +631 -0
  91. data/lib/common/cloudbox_logger.rb +81 -0
  92. data/lib/common/cloudbox_logger_mock.rb +43 -0
  93. data/lib/common/color.rb +267 -0
  94. data/lib/common/config_properties.rb +2027 -0
  95. data/lib/common/services_description.rb +192 -0
  96. data/lib/exec.rb +35 -0
  97. data/lib/exec/check_parameter.rb +208 -0
  98. data/lib/exec/cluster_allocate.rb +163 -0
  99. data/lib/exec/cluster_create.rb +99 -0
  100. data/lib/exec/cluster_delete.rb +38 -0
  101. data/lib/exec/cluster_desallocate.rb +37 -0
  102. data/lib/exec/cluster_info.rb +177 -0
  103. data/lib/exec/cluster_ls.rb +150 -0
  104. data/lib/exec/command_option.rb +222 -0
  105. data/lib/exec/executable_command.rb +194 -0
  106. data/lib/exec/node_destroy.rb +101 -0
  107. data/lib/exec/node_detach.rb +98 -0
  108. data/lib/exec/node_info.rb +280 -0
  109. data/lib/exec/node_install.rb +234 -0
  110. data/lib/exec/node_ls.rb +160 -0
  111. data/lib/exec/service_add.rb +224 -0
  112. data/lib/exec/service_component_add.rb +39 -0
  113. data/lib/exec/service_component_delete.rb +37 -0
  114. data/lib/exec/service_component_detach.rb +37 -0
  115. data/lib/exec/service_conf_apply.rb +57 -0
  116. data/lib/exec/service_conf_create.rb +80 -0
  117. data/lib/exec/service_conf_get.rb +165 -0
  118. data/lib/exec/service_conf_ls.rb +103 -0
  119. data/lib/exec/service_follow_request.rb +49 -0
  120. data/lib/exec/service_info.rb +346 -0
  121. data/lib/exec/service_install.rb +87 -0
  122. data/lib/exec/service_ls.rb +124 -0
  123. data/lib/exec/service_start.rb +110 -0
  124. data/lib/exec/service_stop.rb +112 -0
  125. data/lib/receiver.rb +14 -0
  126. data/lib/receiver/ambari_receiver.rb +812 -0
  127. data/lib/receiver/ambari_rest_api_connector.rb +599 -0
  128. data/lib/receiver/basic_receiver.rb +28 -0
  129. data/lib/receiver/connector.rb +28 -0
  130. data/lib/receiver/crowbar_receiver.rb +588 -0
  131. data/lib/receiver/crowbar_rest_api_connector.rb +518 -0
  132. data/lib/receiver/crowbar_shell_api.rb +643 -0
  133. data/lib/receiver/rest_api_connector.rb +275 -0
  134. data/resources/ambari-configurations/HBASE/default_hbase-site +33 -0
  135. data/resources/ambari-configurations/HDFS/default_hdfs-site +49 -0
  136. data/resources/ambari-configurations/HIVE/default_hive-site +33 -0
  137. data/resources/ambari-configurations/MAPREDUCE/default_mapred-site +72 -0
  138. data/resources/ambari-configurations/OOZIE/default_oozie-site +28 -0
  139. data/resources/ambari-configurations/WEBHCAT/default_webhcat-site +18 -0
  140. data/resources/ambari-configurations/ZOOKEEPER/default_zookeeper-site +8 -0
  141. data/resources/ambari-configurations/default_core-site +22 -0
  142. data/resources/ambari-configurations/default_global +141 -0
  143. data/resources/cloudbox-server.conf +10 -0
  144. data/spec/common/services_description.rb +130 -0
  145. data/spec/exec/check_parameter.rb +152 -0
  146. data/spec/exec/command_option_spec.rb +97 -0
  147. metadata +328 -0
@@ -0,0 +1,643 @@
1
+ # This file is part of cloudbox-server project
2
+ # Author: mbr (INGENSI)
3
+ # Created: 21/08/13 16:28
4
+
5
+ # You are a good developer if you document this class
6
+
7
+ require 'common/color'
8
+ require 'receiver/connector'
9
+ require 'rubygems'
10
+ require 'common/cloudbox_exceptions'
11
+ require 'json'
12
+ require 'fileutils'
13
+ require 'pathname'
14
+ require 'net/scp'
15
+
16
+ module Receiver
17
+ # Allows to connects to an API Crowbar by the Shell command
18
+ # @author mbretaud
19
+ class CrowbarShellAPI < Connector
20
+
21
+ public
22
+ # Copy the Barclamp Vcluster for create a new vcluster
23
+ # @param [String] src The source of the barclamp
24
+ # @param [String] dest The destination of the new barclamp
25
+ # @param [String] cluster_name The name of the vcluster
26
+ # @param [String] network The network address
27
+ # @param [String] mask The mask address
28
+ # @param [String] vlan_id The id of the vlan
29
+ # @param [String] cpu The cpu weight
30
+ # @param [String] ram The ram capacity
31
+ # @param [String] description The description of the barclamp, it role
32
+ # @param [String] verbose The verbose command
33
+ # @author mbretaud
34
+ def copy_barclamp(src, dest, cluster_name, network, mask, vlan_id, cpu, ram, description, verbose)
35
+ vcluster_mask = "vclusterMask"
36
+ vcluster_network = "vclusterNetwork"
37
+ vcluster_id_vlan = "vclusterIdvlan"
38
+ vcluster_name = "vclusterName"
39
+ vcluster_ram = "vclusterRam"
40
+ vcluster_cpu = "vclusterCpu"
41
+ vcluster_desc = "vclusterDescription"
42
+
43
+ output = ""
44
+
45
+ if verbose == "-v"
46
+ verbose = true
47
+ else
48
+ verbose = false
49
+ end
50
+
51
+ unless File.directory?(src)
52
+ raise Common::DirectoryNotFound.new("Source directory doesn't exists or is not accessible")
53
+ end
54
+
55
+
56
+ if File.directory?(dest)
57
+ raise Common::DirectoryAlreadyExist.new("Destination directory already exists." )
58
+ end
59
+
60
+
61
+ unless FileUtils.mkdir_p(dest)
62
+ raise Common::DirectoryCreateError.new("An error occurred while trying to create destination directory.")
63
+ end
64
+
65
+ src_name = Pathname.new(src).basename
66
+ dest_name= Pathname.new(dest).basename
67
+
68
+ if verbose
69
+ output += "Copying barclamp from '#{src_name}' to '#{dest_name}'.\n"
70
+ output += "(#{src} -> #{dest})\n"
71
+ end
72
+
73
+ FileUtils.cp_r src + "/.", dest
74
+
75
+ if verbose
76
+ output += "Directories renaming...\n"
77
+ end
78
+
79
+ Dir.glob("#{dest}/**/*") do |dir|
80
+ if File.directory? dir
81
+ dirname = Pathname.new(dir).basename.to_s
82
+ if (match = dirname.match(/(.*)(#{src_name})(.*)/))
83
+ # @todo maybe replace name by nil because it is never used
84
+ before, name, after = match.captures
85
+ new_dir_path = Pathname.new(dir).parent.to_s + "/" + before + dest_name + after
86
+ if verbose
87
+ output += "Moving #{dir} to #{new_dir_path}.\n"
88
+ end
89
+ FileUtils.mv dir, new_dir_path
90
+ end
91
+ end
92
+ end
93
+
94
+ if verbose
95
+ output += "File renaming...\n"
96
+ end
97
+
98
+ Dir.glob("#{dest}/**/*") do |file|
99
+ unless File.directory? file
100
+ filename = Pathname.new(file).basename.to_s
101
+ if (match = filename.match(/(.*)(#{src_name})(.*)/))
102
+ # @todo maybe replace name by nil because it is never used
103
+ before, name, after = match.captures
104
+ new_file_path = Pathname.new(file).parent.to_s + "/" + before + dest_name + after
105
+ if verbose
106
+ output += "Moving #{file} to #{new_file_path}.\n"
107
+ end
108
+ FileUtils.mv file, new_file_path
109
+ file = new_file_path
110
+ end
111
+
112
+ f = File.read(file)
113
+ if filename == "default.rb" or filename == "bc-template-vcluster.json" or filename == "crowbar.yml"
114
+ content = f.gsub(/(#{vcluster_mask})/, mask.to_s)
115
+ content = content.gsub(/(#{vcluster_network})/, network.to_s)
116
+ content = content.gsub(/(#{vcluster_id_vlan})/, vlan_id.to_s)
117
+ content = content.gsub(/(#{vcluster_name})/, cluster_name.to_s)
118
+ content = content.gsub(/(#{vcluster_ram})/, ram.to_s)
119
+ content = content.gsub(/(#{vcluster_cpu})/, cpu.to_s)
120
+ content = content.gsub(/(#{vcluster_desc})/, description.to_s)
121
+ f = File.new(file, "w")
122
+ f.write(content)
123
+ f.close
124
+ end
125
+ f = File.read(file)
126
+ if f.match(/(.*)(#{src_name})(.*)/i)
127
+ if verbose
128
+ output += "Modifying file #{file}\n"
129
+ end
130
+ content = f.gsub(/(#{src_name})/, dest_name)
131
+ content = content.gsub(/(#{src_name.to_s.capitalize})/, dest_name.to_s.capitalize)
132
+ f = File.new(file, "w")
133
+ f.write(content)
134
+ f.close
135
+ end
136
+ end
137
+ end
138
+
139
+ if verbose
140
+ output += "Done\n"
141
+ end
142
+
143
+ return output
144
+ end
145
+
146
+ public
147
+ # Erase all data into all hard disks on the node and unmount partitions of /dev.
148
+ # @param node_name The name of the node
149
+ # @return out The output displays
150
+ # @author mbretaud
151
+ # @todo Change the way to execute the command "erase hard disk" (i.e. having a shell connector to execute shell commands to a distant node)
152
+ def erase_node_hard_disk(node_name)
153
+ @logger.info("Receiver::CrowbarShellApi Remove the node '#{node_name}' with crowbar...")
154
+
155
+ output = ""
156
+ begin
157
+ output += upload_file("cb-lib-node-erase-hard-disk.sh", File.dirname(__FILE__) + "/../common", "/root", node_name, "root", "crowbar") + "\n"
158
+ rescue => e
159
+ @logger.info("Receiver::CrowbarShellApi Error: Uploading the file 'cb-lib-node-erase-hard-disk.sh' into the node '#{node_name}'...")
160
+ @logger.debug(e.message)
161
+ raise Common::UploadError.new("Error: Uploading the file 'cb-lib-node-erase-hard-disk.sh' into the node '#{node_name}'!")
162
+ end
163
+
164
+ @logger.info("Receiver::CrowbarShellApi Uploading the file 'cb-lib-node-erase-hard-disk.sh' into the node '#{node_name}'...")
165
+
166
+ begin
167
+ execute_ssh("chmod 777 ~/cb-lib-node-erase-hard-disk.sh; ~/cb-lib-node-erase-hard-disk.sh", node_name, "root", "crowbar")
168
+ output += "Execute the file 'cb-lib-node-erase-hard-disk.sh' into the node '#{node_name}'!\n"
169
+ rescue => e
170
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '#{command}'")
171
+ @logger.debug(e.message)
172
+ output += "Error: Execute the file 'cb-lib-node-erase-hard-disk.sh' into the node '#{node_name}' : " + e.message + "\n"
173
+ raise Common::SSHError.new("Error: Execute the file 'cb-lib-node-erase-hard-disk.sh' into the node '#{node_name}' : " + e.message + "")
174
+ end
175
+
176
+ @logger.info("Receiver::CrowbarShellApi Changed the chmod of the file 'cb-lib-node-erase-hard-disk.sh'...")
177
+ @logger.info("Receiver::CrowbarShellApi Execute the file 'cb-lib-node-erase-hard-disk.sh'...")
178
+
179
+ return output
180
+ end
181
+
182
+ public
183
+ # Erase a node in the server Crowbar
184
+ # @param node_name The name of the node
185
+ # @author mbretaud
186
+ def erase_node_server(node_name)
187
+ command = "updatedb"
188
+ output = ""
189
+ begin
190
+ output += execute_shell_command(command) + "\n"
191
+ rescue => e
192
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
193
+ @logger.debug(e.message)
194
+ raise Common::EraseNodeError.new("Error: Erase the node '#{node_name}' in the server Crowbar.")
195
+ end
196
+
197
+ @logger.info("Receiver::CrowbarShellApi Executing the command '#{command}'...")
198
+
199
+ command = "locate #{node_name} | grep -v \"/var/lib/ganglia/rrds/Crowbar\" | grep -v \".rrd\""
200
+
201
+ begin
202
+ list_files = execute_shell_command(command)
203
+ list_files.each { |file|
204
+ if File.exist?(file)
205
+ File.chmod(0777, file)
206
+ File.delete(file)
207
+ end
208
+
209
+ if File.directory?(file)
210
+ FileUtils.rm_rf(file)
211
+ end
212
+ }
213
+ rescue => e
214
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
215
+ @logger.debug(e.message)
216
+ raise Common::EraseNodeError.new("Error: Erase the node '#{node_name}' in the server Crowbar.")
217
+
218
+ end
219
+
220
+ @logger.info("Receiver::CrowbarShellApi Executing the command '#{command}'...")
221
+ @logger.info("Receiver::CrowbarShellApi Erase the node '#{node_name}' in the server Crowbar...")
222
+
223
+ return output
224
+ end
225
+
226
+ public
227
+ # Execute a Shell command
228
+ # @param command The command to execute
229
+ # @return the return to the command
230
+ # @author mbretaud
231
+ def execute_shell_command(command)
232
+ @logger.info("Receiver::CrowbarShellApi Execute the command '#{command}'.")
233
+ begin
234
+ result = `#{command}`
235
+ if $?.to_i > 0
236
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '#{command}'")
237
+ @logger.error("Receiver::CrowbarShellApi Error: Install the barclamp to the server crowbar...")
238
+ raise Common::ExecuteShellError.new("Error: Execute the shell command '#{command}'")
239
+ end
240
+ rescue => e
241
+
242
+ @logger.info("Error: Executing the command '#{command}'")
243
+ @logger.debug(e.message)
244
+ raise Common::ExecuteShellError.new("Error: Executing the command '#{command}':#{e.message}")
245
+ end
246
+ return result
247
+ end
248
+
249
+ public
250
+ # Execute a SSH command
251
+ # @param command The command to execute
252
+ # @param host The ip of the host
253
+ # @param login The login of the host
254
+ # @param password the password of the host
255
+ # @return results The resultat of the execution of the command ssh
256
+ # @raise StandardError
257
+ # @raise TimeoutError
258
+ # @author mbretaud
259
+ def execute_ssh(command, host, login, password)
260
+ begin
261
+ results = {}
262
+
263
+ Timeout::timeout(2) do
264
+ begin
265
+ Net::SSH.start(host, login, :password => password) do |ssh|
266
+ results[command] = ssh.exec!(command)
267
+ end
268
+ rescue Net::SSH::HostKeyMismatch => e
269
+ e.remember_host!
270
+ retry
271
+ rescue StandardError => e
272
+ raise e
273
+ end
274
+ end
275
+
276
+ @logger.info("Receiver::CrowbarShellApi Execute the ssh command '#{command}'.")
277
+ return results
278
+ rescue Timeout::Error => e
279
+ @logger.info("Receiver::CrowbarShellApi Error: Execute the ssh command '#{command}'.")
280
+ @logger.info("Receiver::CrowbarShellApi Error: Timed out trying to get a connection.")
281
+ @logger.debug(e.message)
282
+ raise e
283
+ end
284
+ end
285
+
286
+ private
287
+ # Check is the variable is Json format
288
+ # @param data to check
289
+ # @author mbretaud
290
+ def is_json(data)
291
+ JSON.parse data
292
+ @logger.info("Receiver::CrowbarShellApi The data is a JSON format.")
293
+ return true
294
+ rescue JSON::ParserError => e
295
+ @logger.info("Receiver::CrowbarShellApi The data is not a JSON format.")
296
+ @logger.debug(e.message)
297
+ return false
298
+ end
299
+
300
+ public
301
+ # Install a node with crowbar
302
+ # @param node_name the name of node
303
+ # @return Boolean true is successful and false if error
304
+ # @author mbretaud
305
+ def node_install(node_name)
306
+ command = "crowbar_machines -U crowbar -P crowbar allocate #{node_name}"
307
+ begin
308
+ @logger.info("Receiver::CrowbarShellApi Install the node '#{node_name}' with crowbar...")
309
+ return execute_shell_command(command)
310
+ rescue => e
311
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
312
+ @logger.info("Receiver::CrowbarShellApi Error: Install the node '#{node_name}' with crowbar...")
313
+ @logger.debug(e.message)
314
+ raise Common::NodeInstallError.new("Execute the shell command '#{command}'.")
315
+ end
316
+ end
317
+
318
+ public
319
+ # display a information of node
320
+ # @param node_name the name of node
321
+ # @return Boolean true is successful and false if error
322
+ # @author mbretaud
323
+ def node_info(node_name)
324
+ command = "crowbar_machines show #{node_name}"
325
+ begin
326
+ @logger.info("Receiver::CrowbarShellApi Display informations of the node '#{node_name}' with crowbar...")
327
+ infos = execute_shell_command(command)
328
+ return JSON.parse(infos)
329
+ rescue => e
330
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
331
+ @logger.info("Receiver::CrowbarShellApi Error: Display informations of the node '#{node_name}' with crowbar...")
332
+ @logger.debug(e.message)
333
+ raise Common::NodeInfoError.new("Execute the shell command '#{command}'.")
334
+ end
335
+ end
336
+
337
+ public
338
+ # remove node of the crowbar admin
339
+ # @param node_name the name of node
340
+ # @author mbretaud
341
+ # @return Boolean true is successful and false if error
342
+ def node_delete(node_name)
343
+ command = "crowbar_machines -U crowbar -P crowbar delete #{node_name}"
344
+ begin
345
+ @logger.info("Receiver::CrowbarShellApi Remove the node '#{node_name}' with crowbar...")
346
+ return execute_shell_command(command)
347
+ rescue => e
348
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
349
+ @logger.info("Receiver::CrowbarShellApi Error: Remove the node '#{node_name}' with crowbar...")
350
+ @logger.debug(e.message)
351
+ raise Common::NodeDeleteError.new("Execute the shell command '#{command}'.")
352
+ end
353
+ end
354
+
355
+ public
356
+ # Retrieves the list of nodes according to the status.
357
+ # @param status The status wanted
358
+ # @return list_nodes_filter The list of node
359
+ # @author mbretaud
360
+ def node_list_nodes(status = nil)
361
+ @logger.info("Receiver::CrowbarShellApi : Retrieves the list of nodes according to the status '#{status}'.")
362
+ command = "crowbar_node_state -U crowbar -P crowbar status"
363
+ list_nodes = execute_shell_command(command)
364
+
365
+ hostname = `hostname -s`
366
+ cluster_name = `hostname`
367
+
368
+ if cluster_name.include? '.'
369
+ cluster_name = cluster_name.split('.')
370
+ cluster_name.delete_at(0)
371
+ cluster_name = ".#{cluster_name.collect { |e| e }.join('.').strip}"
372
+ else
373
+ cluster_name = ""
374
+ end
375
+
376
+ if is_list_empty(list_nodes)
377
+ @logger.info("Receiver::CrowbarShellApi Warning: The list of nodes is empty...")
378
+ return nil
379
+ else
380
+ list_nodes_filter = Array.new
381
+
382
+ list_nodes.each { |node|
383
+ node_name = node.split(" ").at(0).strip.to_s
384
+ status_node = node.split.drop(1).join(' ').strip.to_s
385
+
386
+ if node_name.strip.to_s != hostname.strip.to_s
387
+ if status.nil?
388
+ node_to_display = "#{node_name}#{cluster_name} #{status_node}"
389
+ list_nodes_filter << node_to_display
390
+ else
391
+ if status.strip.to_s == status_node.strip.to_s
392
+ node_to_display = "#{node_name}#{cluster_name} #{status_node}"
393
+ list_nodes_filter << node_to_display
394
+ end
395
+ end
396
+ end
397
+ }
398
+
399
+ return list_nodes_filter
400
+ end
401
+ end
402
+
403
+ private
404
+ # Check if the list is empty or not
405
+ # @param list The list of elements
406
+ # @return true The list is empty
407
+ # @author mbretaud
408
+ def is_list_empty(list) # @wtf so useless method xD
409
+ if !list.nil? && list.length > 0
410
+ return false
411
+ end
412
+ return true
413
+ end
414
+
415
+ public
416
+ # Reinstall a node with crowbar
417
+ # @param node_name the name of node
418
+ # @return Boolean true is successful and false if error
419
+ # @author mbretaud
420
+ def node_reinstall(node_name)
421
+ command = "crowbar_machines -U crowbar -P crowbar reinstall #{node_name}"
422
+ begin
423
+ @logger.info("Receiver::CrowbarShellApi Reinstall the node '#{node_name}' with crowbar...")
424
+ return execute_shell_command(command)
425
+ rescue => e
426
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
427
+ @logger.info("Receiver::CrowbarShellApi Error: Reinstall the node '#{node_name}' with crowbar...")
428
+ @logger.debug(e.message)
429
+ raise Common::NodeReinstallError.new("Error: Execute the shell command '#{command}'.")
430
+ end
431
+ end
432
+
433
+ # @todo WARNING: cluster_name never used
434
+ public
435
+ # Set the list of nodes to the proposal.
436
+ # @param cluster_name name of cluster
437
+ # @param barclamp_name name of barclamp
438
+ # @param node_list List of node
439
+ # @return Boolean true is successful and false if error
440
+ # @author mbretaud
441
+ def set_cluster_machine(cluster_name, barclamp_name, node_list)
442
+ @logger.info("Receiver::CrowbarShellApi Set the list of nodes to the proposal...")
443
+ output = ""
444
+
445
+ begin
446
+ command = "crowbar #{barclamp_name} proposal show default"
447
+ json = execute_shell_command(command)
448
+ p = JSON.parse(json)
449
+
450
+ node_list.each do |node|
451
+ unless p['deployment'][barclamp]['elements'][role].include? node
452
+ p['deployment'][barclamp]['elements'][role].push(node)
453
+ end
454
+
455
+ json = p.to_json
456
+ cmd = "crowbar #{barclamp_name} proposal edit default --data '#{json}"
457
+ execute_shell_command(cmd)
458
+ end
459
+ output += "Set the list of nodes to the proposal...\n"
460
+ return output
461
+ rescue => e
462
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the command '#{command}'")
463
+ @logger.info("Receiver::CrowbarShellApi Error: Set the list of nodes to the proposal...")
464
+ @logger.debug(e.message)
465
+ raise Common::SetClusterMachineError.new("Error: Execute the shell command '#{command}'.")
466
+ end
467
+ end
468
+
469
+ public
470
+ # reboot node with crowbar shell
471
+ # @param node_name the name of node
472
+ # @return Output of crowbar command
473
+ # @author mbretaud
474
+ def reboot_node(node_name)
475
+ begin
476
+ execute_ssh("/sbin/reboot", node_name, "root", "crowbar")
477
+ @logger.info("Receiver::CrowbarShellApi Reboot the node '#{node_name}'...")
478
+ return "Reboot the node '#{node_name}'...\n"
479
+ rescue => e
480
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '/sbin/reboot'")
481
+ @logger.info("Receiver::CrowbarShellApi Error: Reboot the node '#{node_name}'...")
482
+ @logger.debug(e.message)
483
+ raise Common::NodeRebootError.new("Error: Execute the shell command '#{command}'.")
484
+ end
485
+ end
486
+
487
+ # create proposal for a barclamp
488
+ # @param barclamp_name The name of barclamp
489
+ # @return boolean true is successful and false if error
490
+ def create_proposal(barclamp_name)
491
+ command = "crowbar #{barclamp_name} proposal create default" # @todo Copier coller FAIL
492
+ output = ""
493
+
494
+ begin
495
+ execute_shell_command(command)
496
+ @logger.info("Receiver::CrowbarShellApi Create the proposal 'default' for the barclamp '#{barclamp_name}'...")
497
+ rescue => e
498
+ @logger.info("Receiver::CrowbarShellApi Executing the ssh command '#{command}'")
499
+ @logger.info("Receiver::CrowbarShellApi Create the proposal 'default' for the barclamp '#{barclamp_name}'...")
500
+ @logger.debug(e.message)
501
+ raise Common::CreateProposalError.new("Execute the shell command '#{command}'.")
502
+ end
503
+
504
+ return "Execute the shell command '#{command}'.\n"
505
+ end
506
+
507
+ public
508
+ # install a barclamp to th server crowbar
509
+ # @param barclamp_name the name of barclamp
510
+ # @return the output of crowbar's command
511
+ # @author mbretaud
512
+ def reload_service(barclamp_name)
513
+ barclamps_path = "/opt/dell/barclamps"
514
+ output = ""
515
+
516
+ command = "barclamp_install.rb #{barclamps_path}/#{barclamp_name}"
517
+ begin
518
+ execute_shell_command(command)
519
+ @logger.info("Receiver::CrowbarShellApi Install the barclamp '#{barclamp_name}' to the server crowbar...")
520
+ rescue => e
521
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '#{command}'")
522
+ @logger.info("Receiver::CrowbarShellApi Error: Install the barclamp '#{barclamp_name}' to the server crowbar...")
523
+ @logger.debug(e.message)
524
+ raise Common::BarclampInstallError.new("Execute the shell command '#{command}'.")
525
+ return output
526
+ end
527
+
528
+ output += "Execute the shell command '#{command}'.\n"
529
+
530
+ command = "service crowbar restart"
531
+ begin
532
+ execute_shell_command(command)
533
+ @logger.info("Receiver::CrowbarShellApi Reboot the server crowbar...")
534
+ rescue => e
535
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '#{command}'")
536
+ @logger.info("Receiver::CrowbarShellApi Error: Reboot the server crowbar...")
537
+ @logger.debug(e.message)
538
+ raise Common::ReloadServiceError.new("Execute the shell command '#{command}'.")
539
+ end
540
+
541
+ output += "Execute the shell command '#{command}'.\n"
542
+
543
+ return output
544
+ end
545
+
546
+ public
547
+ # Upload a file to a remote server
548
+ # @param file_name The name of the file
549
+ # @param file_path The path of the file
550
+ # @param destination_path The destination path to upload
551
+ # @param host The ip of the host
552
+ # @param login The login of the host
553
+ # @param password The password of the host
554
+ # @raise SCPError
555
+ # @raise TimeoutError
556
+ # @author mbretaud
557
+ def upload_file(file_name, file_path, destination_path, host, login, password)
558
+ begin
559
+ Timeout::timeout(2) do
560
+ # use a persistent connection to transfer files
561
+ Net::SCP.start(host, login, :password => password) do |scp|
562
+ begin
563
+ # upload a file to a remote server
564
+ scp.upload! "#{file_path}/#{file_name}", destination_path
565
+ @logger.info("Receiver::CrowbarShellApi Upload the file '#{file_name}' to a remote server '#{host}'...")
566
+ rescue Net::SCP::Error => e
567
+ @logger.info("Receiver::CrowbarShellApi Error: Upload the file '#{file_name}' to a remote server '#{host}'.")
568
+ @logger.debug(e.message)
569
+ raise e
570
+ end
571
+ end
572
+ end
573
+ rescue Timeout::Error => e
574
+ @logger.info("Receiver::CrowbarShellApi Error: Timed out trying to get a connection to upload the file '#{file_name}'.")
575
+ @logger.debug(e.message)
576
+ raise e
577
+ end
578
+ return "Upload the file '#{file_name}' to a remote server '#{host}'...\n"
579
+ end
580
+
581
+
582
+ public
583
+ # Get the informations about the vcluster
584
+ # @param vcluster_name The name of the vlcuster
585
+ # @param proposal_name The name of the proposal
586
+ # @return The informations about the vcluster
587
+ # @raise Error Execute the shell command
588
+ # @author mbretaud
589
+ def vcluster_info(vcluster_name, proposal_name)
590
+ barclamp_name = "cb#{vcluster_name}"
591
+ command = "crowbar #{barclamp_name} proposal show #{proposal_name}"
592
+ begin
593
+ info_vcluster = execute_shell_command(command)
594
+
595
+ if is_json(info_vcluster)
596
+ @logger.info("Receiver::CrowbarShellApi Get the informations about the vcluster '#{vcluster_name}'...")
597
+ return JSON.parse(info_vcluster)
598
+ else
599
+ @logger.info("Receiver::CrowbarShellApi Error: The informations are not in JSON format...")
600
+ @logger.info("Receiver::CrowbarShellApi Error: Get the informations about the vcluster '#{vcluster_name}'...")
601
+ return nil
602
+ end
603
+ rescue => e
604
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '#{command}'")
605
+ @logger.info("Receiver::CrowbarShellApi Error: Get the informations about the vcluster '#{vcluster_name}'...")
606
+ @logger.debug(e.message)
607
+ raise Common::ClusterInfoError.new("The vcluster '#{vcluster_name}' doesn't exists or the proposal is not created.")
608
+ end
609
+ end
610
+
611
+ public
612
+ # Displays a list of vclusters
613
+ # @param vcluster_name The name of the vlcuster
614
+ # @param proposal_name The name of the proposal
615
+ # @return info_vcluster The informations about the vcluster
616
+ # @raise Error Execute the shell command
617
+ # @author mbretaud
618
+ def vcluster_ls(vcluster_name, proposal_name)
619
+ barclamp_name = "cb#{vcluster_name}"
620
+ command = "crowbar #{barclamp_name} proposal show #{proposal_name}"
621
+ begin
622
+ list_vcluster = execute_shell_command(command)
623
+ @logger.info("Receiver::CrowbarShellApi Get the list of vclusters...")
624
+ return JSON.parse(list_vcluster)
625
+ rescue => e
626
+ @logger.info("Receiver::CrowbarShellApi Error: Executing the ssh command '#{command}'")
627
+ @logger.info("Receiver::CrowbarShellApi Error: Get the list of vclusters...")
628
+ @logger.debug(e.message)
629
+ raise Common::ClusterLsError.new("The vcluster '#{vcluster_name}' doesn't exists or the proposal is not created.")
630
+ end
631
+ end
632
+
633
+ public
634
+ # Delete a vcluster
635
+ # @param vcluster_name The name of the vlcuster
636
+ # @return
637
+ # @raise
638
+ # @author mbretaud
639
+ def vcluster_delete(vcluster_name)
640
+ # @todo
641
+ end
642
+ end
643
+ end