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.
- data/.yardopts +3 -0
- data/README.md +17 -0
- data/bin/cb-cluster-allocate +5 -0
- data/bin/cb-cluster-create +5 -0
- data/bin/cb-cluster-delete +5 -0
- data/bin/cb-cluster-desallocate +5 -0
- data/bin/cb-cluster-info +5 -0
- data/bin/cb-cluster-ls +5 -0
- data/bin/cb-node-destroy +5 -0
- data/bin/cb-node-detach +6 -0
- data/bin/cb-node-info +5 -0
- data/bin/cb-node-install +5 -0
- data/bin/cb-node-ls +5 -0
- data/bin/cb-service-add +5 -0
- data/bin/cb-service-component-add +5 -0
- data/bin/cb-service-component-delete +5 -0
- data/bin/cb-service-component-detach +5 -0
- data/bin/cb-service-conf-apply +5 -0
- data/bin/cb-service-conf-create +5 -0
- data/bin/cb-service-conf-get +5 -0
- data/bin/cb-service-conf-ls +5 -0
- data/bin/cb-service-follow-request +5 -0
- data/bin/cb-service-info +5 -0
- data/bin/cb-service-install +5 -0
- data/bin/cb-service-ls +5 -0
- data/bin/cb-service-start +5 -0
- data/bin/cb-service-stop +5 -0
- data/lib/command.rb +61 -0
- data/lib/command/ambari_add_host.rb +19 -0
- data/lib/command/ambari_cluster_command.rb +26 -0
- data/lib/command/ambari_cluster_component_command.rb +26 -0
- data/lib/command/ambari_cluster_component_host_command.rb +26 -0
- data/lib/command/ambari_cluster_create.rb +19 -0
- data/lib/command/ambari_cluster_host_command.rb +27 -0
- data/lib/command/ambari_cluster_list.rb +20 -0
- data/lib/command/ambari_cluster_service_command.rb +26 -0
- data/lib/command/ambari_cluster_service_host_command.rb +26 -0
- data/lib/command/ambari_command.rb +21 -0
- data/lib/command/ambari_create_cluster_configuration.rb +39 -0
- data/lib/command/ambari_get_cluster_configuration.rb +29 -0
- data/lib/command/ambari_host_list.rb +19 -0
- data/lib/command/ambari_install_cluster.rb +19 -0
- data/lib/command/ambari_install_component.rb +19 -0
- data/lib/command/ambari_install_host.rb +19 -0
- data/lib/command/ambari_install_host_component.rb +19 -0
- data/lib/command/ambari_install_host_components.rb +19 -0
- data/lib/command/ambari_install_service_components.rb +19 -0
- data/lib/command/ambari_service_add.rb +27 -0
- data/lib/command/ambari_service_component_add.rb +21 -0
- data/lib/command/ambari_service_component_delete.rb +21 -0
- data/lib/command/ambari_service_component_detach.rb +21 -0
- data/lib/command/ambari_service_component_info.rb +29 -0
- data/lib/command/ambari_service_conf_apply.rb +31 -0
- data/lib/command/ambari_service_conf_ls.rb +30 -0
- data/lib/command/ambari_service_delete.rb +21 -0
- data/lib/command/ambari_service_info.rb +20 -0
- data/lib/command/ambari_service_list.rb +21 -0
- data/lib/command/ambari_start_cluster.rb +19 -0
- data/lib/command/ambari_start_component.rb +19 -0
- data/lib/command/ambari_start_host.rb +19 -0
- data/lib/command/ambari_start_host_component.rb +19 -0
- data/lib/command/ambari_start_host_components.rb +19 -0
- data/lib/command/ambari_start_service_components.rb +19 -0
- data/lib/command/ambari_stop_cluster.rb +19 -0
- data/lib/command/ambari_stop_component.rb +19 -0
- data/lib/command/ambari_stop_host.rb +19 -0
- data/lib/command/ambari_stop_host_component.rb +19 -0
- data/lib/command/ambari_stop_host_components.rb +19 -0
- data/lib/command/ambari_stop_service_components.rb +19 -0
- data/lib/command/basic_command.rb +44 -0
- data/lib/command/cluster_create.rb +50 -0
- data/lib/command/cluster_delete.rb +30 -0
- data/lib/command/cluster_info.rb +30 -0
- data/lib/command/cluster_ls.rb +30 -0
- data/lib/command/crowbar_cluster_allocate.rb +42 -0
- data/lib/command/crowbar_command.rb +30 -0
- data/lib/command/crowbar_get_barclamps_list.rb +30 -0
- data/lib/command/crowbar_node_command.rb +21 -0
- data/lib/command/crowbar_node_list.rb +40 -0
- data/lib/command/crowbar_vcluster_command.rb +20 -0
- data/lib/command/filter.rb +15 -0
- data/lib/command/node_destroy.rb +58 -0
- data/lib/command/node_detach.rb +44 -0
- data/lib/command/node_info.rb +27 -0
- data/lib/command/node_install.rb +46 -0
- data/lib/command/node_reinstall.rb +44 -0
- data/lib/command/state_filter.rb +16 -0
- data/lib/common.rb +11 -0
- data/lib/common/cb-lib-node-erase-hard-disk.sh +29 -0
- data/lib/common/cloudbox_exceptions.rb +631 -0
- data/lib/common/cloudbox_logger.rb +81 -0
- data/lib/common/cloudbox_logger_mock.rb +43 -0
- data/lib/common/color.rb +267 -0
- data/lib/common/config_properties.rb +2027 -0
- data/lib/common/services_description.rb +192 -0
- data/lib/exec.rb +35 -0
- data/lib/exec/check_parameter.rb +208 -0
- data/lib/exec/cluster_allocate.rb +163 -0
- data/lib/exec/cluster_create.rb +99 -0
- data/lib/exec/cluster_delete.rb +38 -0
- data/lib/exec/cluster_desallocate.rb +37 -0
- data/lib/exec/cluster_info.rb +177 -0
- data/lib/exec/cluster_ls.rb +150 -0
- data/lib/exec/command_option.rb +222 -0
- data/lib/exec/executable_command.rb +194 -0
- data/lib/exec/node_destroy.rb +101 -0
- data/lib/exec/node_detach.rb +98 -0
- data/lib/exec/node_info.rb +280 -0
- data/lib/exec/node_install.rb +234 -0
- data/lib/exec/node_ls.rb +160 -0
- data/lib/exec/service_add.rb +224 -0
- data/lib/exec/service_component_add.rb +39 -0
- data/lib/exec/service_component_delete.rb +37 -0
- data/lib/exec/service_component_detach.rb +37 -0
- data/lib/exec/service_conf_apply.rb +57 -0
- data/lib/exec/service_conf_create.rb +80 -0
- data/lib/exec/service_conf_get.rb +165 -0
- data/lib/exec/service_conf_ls.rb +103 -0
- data/lib/exec/service_follow_request.rb +49 -0
- data/lib/exec/service_info.rb +346 -0
- data/lib/exec/service_install.rb +87 -0
- data/lib/exec/service_ls.rb +124 -0
- data/lib/exec/service_start.rb +110 -0
- data/lib/exec/service_stop.rb +112 -0
- data/lib/receiver.rb +14 -0
- data/lib/receiver/ambari_receiver.rb +812 -0
- data/lib/receiver/ambari_rest_api_connector.rb +599 -0
- data/lib/receiver/basic_receiver.rb +28 -0
- data/lib/receiver/connector.rb +28 -0
- data/lib/receiver/crowbar_receiver.rb +588 -0
- data/lib/receiver/crowbar_rest_api_connector.rb +518 -0
- data/lib/receiver/crowbar_shell_api.rb +643 -0
- data/lib/receiver/rest_api_connector.rb +275 -0
- data/resources/ambari-configurations/HBASE/default_hbase-site +33 -0
- data/resources/ambari-configurations/HDFS/default_hdfs-site +49 -0
- data/resources/ambari-configurations/HIVE/default_hive-site +33 -0
- data/resources/ambari-configurations/MAPREDUCE/default_mapred-site +72 -0
- data/resources/ambari-configurations/OOZIE/default_oozie-site +28 -0
- data/resources/ambari-configurations/WEBHCAT/default_webhcat-site +18 -0
- data/resources/ambari-configurations/ZOOKEEPER/default_zookeeper-site +8 -0
- data/resources/ambari-configurations/default_core-site +22 -0
- data/resources/ambari-configurations/default_global +141 -0
- data/resources/cloudbox-server.conf +10 -0
- data/spec/common/services_description.rb +130 -0
- data/spec/exec/check_parameter.rb +152 -0
- data/spec/exec/command_option_spec.rb +97 -0
- 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
|