nuri 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +12 -0
  4. data/CHANGELOG +146 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +28 -0
  7. data/README.md +64 -0
  8. data/Rakefile +15 -0
  9. data/VERSION +1 -0
  10. data/bin/delete_modules +11 -0
  11. data/bin/install_agent +18 -0
  12. data/bin/install_module +65 -0
  13. data/bin/nuri +519 -0
  14. data/bin/nuri.old +183 -0
  15. data/bin/push_model +16 -0
  16. data/examples/.gitignore +3 -0
  17. data/examples/bonfire.sfp +95 -0
  18. data/examples/bonfire/epcc.sfp +43 -0
  19. data/examples/bonfire/epcc0.sfp +49 -0
  20. data/examples/bonfire/epcc2.sfp +52 -0
  21. data/examples/bonfire/epcc2a.sfp +25 -0
  22. data/examples/bonfire/inria.sfp +72 -0
  23. data/examples/bonfire/inria0.sfp +49 -0
  24. data/examples/bonfire/inria2.sfp +71 -0
  25. data/examples/bonfire/inria2a.sfp +44 -0
  26. data/examples/bonfire/inria2b.sfp +54 -0
  27. data/examples/bonfire/inria2c.sfp +62 -0
  28. data/examples/bonfire/inria2d.sfp +71 -0
  29. data/examples/bonfire/inria2e.sfp +80 -0
  30. data/examples/bonfire/main.sfp +33 -0
  31. data/examples/bonfire/old/bonfire-1-1-1.sfp +76 -0
  32. data/examples/bonfire/old/bonfire-1-10-1.sfp +77 -0
  33. data/examples/bonfire/old/bonfire-1-2-1.sfp +58 -0
  34. data/examples/bonfire/old/bonfire-1-3-1.sfp +61 -0
  35. data/examples/bonfire/old/bonfire-1-4-1.sfp +64 -0
  36. data/examples/bonfire/old/bonfire-1-5-1.sfp +67 -0
  37. data/examples/bonfire/old/bonfire-1-6-1.sfp +82 -0
  38. data/examples/bonfire/old/bonfire-1-7-1.sfp +82 -0
  39. data/examples/bonfire/old/bonfire-1-8-1.sfp +79 -0
  40. data/examples/bonfire/old/bonfire-1-9-1.sfp +83 -0
  41. data/examples/bonfire/old/wp-test1a.sfp +38 -0
  42. data/examples/bonfire/old/wp-test1b.sfp +18 -0
  43. data/examples/bonfire/old/wp-test1c.sfp +7 -0
  44. data/examples/bonfire/old/wp-test2.sfp +47 -0
  45. data/examples/bonfire/old3/bonfire-epcc.sfp +57 -0
  46. data/examples/bonfire/old3/bonfire-inria.sfp +72 -0
  47. data/examples/bonfire/old3/bonfire-master.sfp +18 -0
  48. data/examples/bonfire/old3/bonfire.sfp +23 -0
  49. data/examples/bonfire/old3/bonfire2.sfp +49 -0
  50. data/examples/bonfire/old3/bonfire3.sfp +76 -0
  51. data/examples/bonfire/old3/bonfire4.sfp +78 -0
  52. data/examples/bonfire/old3/bonfire5.sfp +34 -0
  53. data/examples/bonfire/old3/bonfire5b.sfp +84 -0
  54. data/examples/bonfire/old3/hpvm6.sfp +22 -0
  55. data/examples/bonfire/old3/model.json +1 -0
  56. data/examples/bonfire/old3/test0.sfp +16 -0
  57. data/examples/bonfire/old3/test1.sfp +5 -0
  58. data/examples/bonfire/old3/test10.sfp +5 -0
  59. data/examples/bonfire/old3/test2.sfp +18 -0
  60. data/examples/bonfire/old3/test3.sfp +10 -0
  61. data/examples/bonfire/old3/test4.sfp +11 -0
  62. data/examples/bonfire/old3/test5.sfp +18 -0
  63. data/examples/bonfire/old3/test6.sfp +19 -0
  64. data/examples/bonfire/old3/test7.sfp +34 -0
  65. data/examples/bonfire/old3/test8.sfp +5 -0
  66. data/examples/bonfire/old3/test9.sfp +16 -0
  67. data/examples/bonfire/old3/wordpress-test-cluster.sfp +38 -0
  68. data/examples/bonfire/old3/wordpress-test.sfp +22 -0
  69. data/examples/bonfire/old3/wp-test-2.sfp +49 -0
  70. data/examples/bonfire/test.sfp +13 -0
  71. data/examples/generator.rb +66 -0
  72. data/examples/hadoop2.sfp +20 -0
  73. data/examples/hpcloud.sfp +18 -0
  74. data/examples/run.rb +17 -0
  75. data/examples/test.inc +0 -0
  76. data/examples/test.sfp +11 -0
  77. data/lib/naas/d3.js +5 -0
  78. data/lib/naas/d3.v3.min.js +5 -0
  79. data/lib/naas/index.css +0 -0
  80. data/lib/naas/index.html +18 -0
  81. data/lib/naas/index.js +18 -0
  82. data/lib/naas/jquery-1.10.2.min.js +6 -0
  83. data/lib/naas/jquery.js +6 -0
  84. data/lib/naas/naas.rb +160 -0
  85. data/lib/nuri.rb +62 -0
  86. data/lib/nuri/choreographer.rb +151 -0
  87. data/lib/nuri/constraint_helper.rb +9 -0
  88. data/lib/nuri/directory.rb +40 -0
  89. data/lib/nuri/master.rb +725 -0
  90. data/lib/nuri/net_helper.rb +65 -0
  91. data/lib/nuri/orchestrator.rb +224 -0
  92. data/lib/nuri/server.rb +212 -0
  93. data/modules/.gitignore +4 -0
  94. data/modules/apache/apache.rb +255 -0
  95. data/modules/apache/apache.rb.old +167 -0
  96. data/modules/apache/apache.sfp +146 -0
  97. data/modules/apache/apache.sfp.future +100 -0
  98. data/modules/apache/load_balancer +20 -0
  99. data/modules/apache/model.json +1 -0
  100. data/modules/apache/test.sfp +8 -0
  101. data/modules/aptpackage/aptpackage.rb +82 -0
  102. data/modules/aptpackage/aptpackage.sfp +5 -0
  103. data/modules/bonfire/.gitignore +2 -0
  104. data/modules/bonfire/README.md +12 -0
  105. data/modules/bonfire/bonfire.rb +60 -0
  106. data/modules/bonfire/bonfire.sfp +9 -0
  107. data/modules/bonfire/config.yml +4 -0
  108. data/modules/bonfire/helper.rb +149 -0
  109. data/modules/bonfire/stresstest.rb +144 -0
  110. data/modules/bonfire/test.sfp +8 -0
  111. data/modules/client/client.rb +22 -0
  112. data/modules/client/client.sfp +14 -0
  113. data/modules/cloud/cloud.rb +11 -0
  114. data/modules/cloud/cloud.sfp +26 -0
  115. data/modules/file/file.rb +91 -0
  116. data/modules/file/file.sfp +9 -0
  117. data/modules/hadoop1/core-site.xml +17 -0
  118. data/modules/hadoop1/hadoop-env.sh +55 -0
  119. data/modules/hadoop1/hadoop1.rb +384 -0
  120. data/modules/hadoop1/hadoop1.sfp +93 -0
  121. data/modules/hadoop1/hdfs-site.xml +16 -0
  122. data/modules/hadoop1/mapred-site.xml +17 -0
  123. data/modules/hadoop2/core-site.xml +31 -0
  124. data/modules/hadoop2/hadoop-env.sh +77 -0
  125. data/modules/hadoop2/hadoop2.rb +401 -0
  126. data/modules/hadoop2/hadoop2.sfp +114 -0
  127. data/modules/hadoop2/hdfs-site.xml +47 -0
  128. data/modules/hadoop2/mapred-site.xml +71 -0
  129. data/modules/hadoop2/ports +14 -0
  130. data/modules/hadoop2/yarn-env.sh +112 -0
  131. data/modules/hadoop2/yarn-site.xml +107 -0
  132. data/modules/hpcloud/.gitignore +2 -0
  133. data/modules/hpcloud/README.md +16 -0
  134. data/modules/hpcloud/config.yml +3 -0
  135. data/modules/hpcloud/example.sfp +18 -0
  136. data/modules/hpcloud/hpcloud.rb +241 -0
  137. data/modules/hpcloud/hpcloud.sfp +22 -0
  138. data/modules/hpcloud/test.sfp +5 -0
  139. data/modules/install_module +65 -0
  140. data/modules/machine/machine.rb +95 -0
  141. data/modules/machine/machine.sfp +9 -0
  142. data/modules/mockcloud/mockcloud.rb +20 -0
  143. data/modules/mockcloud/mockcloud.sfp +6 -0
  144. data/modules/mysql/mysql.rb +118 -0
  145. data/modules/mysql/mysql.sfp +38 -0
  146. data/modules/mysql/test.sfp +3 -0
  147. data/modules/node/node.rb +8 -0
  148. data/modules/node/node.sfp +7 -0
  149. data/modules/object/object.rb +7 -0
  150. data/modules/object/object.sfp +1 -0
  151. data/modules/os/os.rb +38 -0
  152. data/modules/os/os.sfp +11 -0
  153. data/modules/package/package.rb +26 -0
  154. data/modules/package/package.sfp +22 -0
  155. data/modules/package/test.sfp +6 -0
  156. data/modules/service/model.json +1 -0
  157. data/modules/service/service.rb +50 -0
  158. data/modules/service/service.sfp +46 -0
  159. data/modules/service/test.sfp +6 -0
  160. data/modules/tarpackage/tarpackage.rb +93 -0
  161. data/modules/tarpackage/tarpackage.sfp +5 -0
  162. data/modules/vm/vm.rb +8 -0
  163. data/modules/vm/vm.sfp +18 -0
  164. data/modules/wordpress/wordpress.rb +98 -0
  165. data/modules/wordpress/wordpress.sfp +34 -0
  166. data/modules/wordpresscluster/wordpresscluster.rb +150 -0
  167. data/modules/wordpresscluster/wordpresscluster.sfp +74 -0
  168. data/nuri.gemspec +26 -0
  169. metadata +281 -0
@@ -0,0 +1,2 @@
1
+ *.pem
2
+ *.bak
@@ -0,0 +1,16 @@
1
+ HPCloud module
2
+ --------------
3
+
4
+ Required Ruby Gems:
5
+ - fog
6
+ - json
7
+
8
+ To use:
9
+ - Copy your VM's SSH private key to filename 'hpcloud.pem'.
10
+ - Edit file 'config.yml' by filling in
11
+ - access_key
12
+ - secret_key
13
+ - tenant_id
14
+ Those information can be found in your HPCloud account (menu API Keys of HPCloud console).
15
+ - Set 'key_name' value.
16
+ - Replace any necessary default values of HPCloud's attributes such as zone, image_id, flavour_id, etc.
@@ -0,0 +1,3 @@
1
+ access_key:
2
+ secret_key:
3
+ tenant_id:
@@ -0,0 +1,18 @@
1
+ include "../node/node.sfp"
2
+ include "../hpcloud/hpcloud.sfp"
3
+ include "../vm/vm.sfp"
4
+ include "../apache/apache.sfp"
5
+
6
+ proxy isa Node {
7
+ sfpAddress is "localhost"
8
+ hpcloud isa HPCloud {
9
+ key_name is "herrykey"
10
+ }
11
+ }
12
+
13
+ vm1 isa VM {
14
+ created = true
15
+ apache isa Apache {
16
+ running is true
17
+ }
18
+ }
@@ -0,0 +1,241 @@
1
+ require 'rubygems'
2
+ require 'thread'
3
+ require 'json'
4
+ require 'fog'
5
+ require 'yaml'
6
+ require 'net/ssh'
7
+
8
+ ##############################
9
+ #
10
+ # Order of config file for credentials:
11
+ # 1) <HOME_DIRECTORY>/.hpcloud
12
+ # 2) <MODULE_DIRECTORY>/config.yml
13
+ #
14
+ #
15
+ # Order of SSH key file
16
+ # 1) <HOME_DIRECTORY>/.ssh/<KEY_PAIR_NAME>.pem
17
+ # 2) <HOME_DIRECTORY>/.ssh/<KEY_PAIR_NAME>
18
+ # 3) <MODULE_DIRECTORY>/<KEY_PAIR_NAME>.pem
19
+ # 4) <MODULE_DIRECTORY>/<KEY_PAIR_NAME>
20
+ # 5) <MODULE_DIRECTORY>/hpcloud.pem
21
+ #
22
+ ##############################
23
+
24
+ class Sfp::Module::HPCloud
25
+ include Sfp::Resource
26
+
27
+ ### Sleep time in waiting a task to be finished - default: 5s
28
+ SleepTime = 5
29
+
30
+ ### Number of tries in waiting a task to be finished - default: 120 (10 minutes)
31
+ Tries = 600 / SleepTime
32
+
33
+ def initialize
34
+ @conn = nil
35
+ end
36
+
37
+ def update_state
38
+ to_model
39
+
40
+ @state['running'] = running?
41
+ @state['vms'] = get_vms
42
+ end
43
+
44
+ ##############################
45
+ #
46
+ # Action methods (see hpcloud.sfp and cloud.sfp)
47
+ #
48
+ ##############################
49
+
50
+ def create_vm(params={})
51
+ return false if not self.running?
52
+
53
+ ### determine VM's name
54
+ name = params['vm'].sub(/^\$\./, '')
55
+
56
+ log.info "Creating VM #{name} [WAIT]"
57
+
58
+ ### check if VM is already exist
59
+ if get_vms.has_key?(name)
60
+ log.info "VM #{name} is already exist - Creating VM #{name} [OK]"
61
+ return true
62
+ end
63
+
64
+ ### populate VM parameters
65
+ vm_model = resolve_model(params['vm'])
66
+ flavor = (vm_model['flavor'].to_s.length > 0 ? vm_model['flavor'].to_s : @model['vm_flavor'])
67
+ image = (vm_model['image'].to_s.length > 0 ? vm_model['image'].to_s : @model['vm_image'])
68
+ security_group = (vm_model['security_group'].to_s.length > 0 ? vm_model['security_group'].to_s : @model['vm_security_group'])
69
+ ssh_key_name = (vm_model['ssh_key_name'].to_s.length > 0 ? vm_model['ssh_key_name'].to_s : @model['vm_ssh_key_name'])
70
+ ssh_key_file = self.ssh_key_file(ssh_key_name)
71
+
72
+ ### check SSH key file
73
+ if ssh_key_file.nil?
74
+ log.info "SSH key file '#{ssh_key_file}' is not available! #{ssh_key_name} - Creating VM #{name} [Failed]"
75
+ return false
76
+ end
77
+
78
+ ### if not exist, then create the VM
79
+ created = false
80
+ begin
81
+ ### submit create VM request
82
+ vm = @conn.servers.create({
83
+ :name => name,
84
+ :flavor_id => flavor,
85
+ :image_id => image,
86
+ :key_name => ssh_key_name,
87
+ :security_groups => [security_group],
88
+ :metadata => {'name' => name},
89
+ })
90
+
91
+ ### set SSH config
92
+ vm.username = 'ubuntu'
93
+ vm.private_key_path = ssh_key_file
94
+
95
+ ### wait until SSH is enabled
96
+ vm.wait_for { ready? and sshable? }
97
+
98
+ ### install sfpagent
99
+ created = (vm.ready? and vm.sshable? and install_agent(vm, name, ssh_key_file))
100
+
101
+ rescue Exception => exp
102
+ log.info "#{exp}\n#{exp.backtrace.join("\n")}"
103
+ end
104
+
105
+ if not created
106
+ log.error "Creating VM #{name} [Failed]"
107
+
108
+ ### delete if any error occured
109
+ delete_vm(params)
110
+ else
111
+ log.info "Creating VM #{name} [OK]"
112
+ end
113
+
114
+ created
115
+ end
116
+
117
+ def delete_vm(params={})
118
+ return false if not self.running?
119
+
120
+ ### determine VM's name
121
+ name = params['vm'].sub(/^\$\./, '')
122
+
123
+ ### check if VM is not exist
124
+ return true if !get_vms.has_key?(name)
125
+
126
+ ### delete if VM with given name exists
127
+ @conn.servers.each { |s|
128
+ if s.name == name
129
+ @conn.delete_server(s.id)
130
+ break
131
+ end
132
+ }
133
+
134
+ ### wait until the VM is completely deleted
135
+ tries = Tries
136
+ deleted = false
137
+ while not deleted and tries > 0
138
+ begin
139
+ deleted = !get_vms.has_key?(name)
140
+ break if deleted
141
+ rescue
142
+ end
143
+ log.info "VM:#{name} has been deleted."
144
+ tries -= 1
145
+ sleep SleepTime
146
+ end
147
+
148
+ deleted
149
+ end
150
+
151
+ ##############################
152
+ #
153
+ # Helper methods
154
+ #
155
+ ##############################
156
+
157
+ protected
158
+ def config_file
159
+ return Dir.home + '/.hpcloud' if ::File.exist?(Dir.home + '/.hpcloud')
160
+ ::File.dirname(__FILE__) + '/config.yml'
161
+ end
162
+
163
+ def read_config
164
+ return {} if not ::File.exist?(config_file)
165
+ return YAML.load_file(config_file)
166
+ end
167
+
168
+ def ssh_key_file(key_name)
169
+ file = Dir.home + '/.ssh/' + key_name + '.pem'
170
+ return file if ::File.exist?(file)
171
+
172
+ file = Dir.home + '/.ssh/' + key_name
173
+ return file if ::File.exist?(file)
174
+
175
+ file = File.dirname(__FILE__) + '/' + key_name + '.pem'
176
+ return file if ::File.exist?(file)
177
+
178
+ file = File.dirname(__FILE__) + '/' + key_name
179
+ return file if ::File.exist?(file)
180
+
181
+ file = File.dirname(__FILE__) + '/hpcloud.pem'
182
+ return file if ::File.exist?(file)
183
+
184
+ nil
185
+ end
186
+
187
+ def running?
188
+ return true if not @conn.nil?
189
+ begin
190
+ config = self.read_config
191
+ @conn = Fog::Compute.new({
192
+ :provider => "HP",
193
+ :hp_tenant_id => config['tenant_id'],
194
+ :hp_access_key => config['access_key'],
195
+ :hp_secret_key => config['secret_key'],
196
+ :hp_auth_uri => @model['auth_uri'],
197
+ :hp_avl_zone => @model['zone']
198
+ })
199
+ rescue Exception => exp
200
+ log.error "#{exp}\n#{exp.backtrace.join("\n")}"
201
+ @conn = nil
202
+ end
203
+ return !!@conn
204
+ end
205
+
206
+ def get_vms
207
+ return {} if not running?
208
+ vms = {}
209
+ @conn.servers.each { |s|
210
+ vms[s.name] = {
211
+ 'running' => s.ready?,
212
+ 'ip' => s.public_ip_address
213
+ }
214
+ }
215
+ vms
216
+ end
217
+
218
+ def install_agent(vm, name, ssh_key_file=nil, ssh_user="ubuntu")
219
+ log.info "Installing agent in VM #{name} [WAIT]"
220
+
221
+ result = vm.ssh(['sudo apt-get update',
222
+ 'sudo apt-get -y install sudo ruby1.9.1 ruby1.9.1-dev libz-dev libaugeas-ruby1.9.1 make gcc libxml2-dev libxslt-dev libreadline-dev',
223
+ 'sudo gem install sfp sfpagent fog --no-ri --no-rdoc && sudo sfpagent -s'])
224
+
225
+ if result
226
+ Net::SSH.start(vm.public_ip_address, ssh_user, :keys => [ssh_key_file]) do |ssh|
227
+ log.info ssh.exec!('sudo sfpagent -s')
228
+ result = (ssh.exec!('sudo sfpagent -a') =~ /Agent is running/)
229
+ end
230
+ end
231
+
232
+ if !result
233
+ log.error "Installing agent in VM #{name} [Failed]"
234
+ else
235
+ log.info "Installing agent in VM #{name} [OK]"
236
+ end
237
+
238
+ result
239
+ end
240
+ end
241
+
@@ -0,0 +1,22 @@
1
+ include "../cloud/cloud.sfp"
2
+
3
+ schema HPCloud extends Cloud {
4
+ final description = "HPCloud US West Zone 2"
5
+ final auth_uri = "https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/"
6
+ final zone = "az-2.region-a.geo-1"
7
+
8
+ // default SSH username
9
+ final vm_username = "ubuntu"
10
+
11
+ // small instance
12
+ final vm_flavor = "100"
13
+
14
+ // Ubuntu 12.04 image
15
+ final vm_image = "67074"
16
+
17
+ // key pair which will be used to SSH to VM
18
+ final vm_ssh_key_name = "default"
19
+
20
+ // security group of the VM
21
+ final vm_security_group = "default"
22
+ }
@@ -0,0 +1,5 @@
1
+ include "hpcloud.sfp"
2
+
3
+ a isa HPCloud {
4
+
5
+ }
@@ -0,0 +1,65 @@
1
+ #!/bin/bash
2
+
3
+ DefaultPort=1314
4
+
5
+ # verify the arguments
6
+ if [[ "$1" == "" ]] || [[ "$2" == "" ]]; then
7
+ echo "Usage: install_module <address> [port] <module-name> ..."
8
+ exit 1
9
+ fi
10
+
11
+ # set the agent's address
12
+ address=$1
13
+ shift
14
+
15
+ # set the agent's port number
16
+ re='^[0-9]+$'
17
+ if [[ $1 =~ $re ]]; then
18
+ port=$1
19
+ shift
20
+ else
21
+ port=$DefaultPort
22
+ fi
23
+
24
+ # set a template command for sending the modules
25
+ cmd="curl -s -i -X PUT $address:$port/modules"
26
+
27
+ # setup directory for temporary files
28
+ dir="/tmp/"$(date +%s%N)"$RANDOM"
29
+ mkdir -p $dir
30
+
31
+ # for every module in the arguments:
32
+ # - archive the module's files to a temporary file
33
+ # - update the sending command by adding the module
34
+ # if the module is not exist then the program will
35
+ # set missing_module flag and then break from the loop
36
+ missing_module=0
37
+ for module in "$@" ; do
38
+ if [[ -d "$module" ]]; then
39
+ tar cvzhf $dir/$module.tgz $module 1>/dev/null
40
+ cmd="$cmd -F $module=@$dir/$module.tgz"
41
+ else
42
+ echo "Module $module is not exist!"
43
+ missing_module=`expr $missing_module + 1`
44
+ fi
45
+ done
46
+
47
+ if [[ $missing_module == 0 ]]; then
48
+ # execute the sending command there is no missing module
49
+ result=`$cmd`
50
+ re='.*HTTP/1\.1 200 OK.*'
51
+ if ! [[ $result =~ $re ]]; then
52
+ missing_module=`expr $missing_module + 1`
53
+ fi
54
+ fi
55
+
56
+ # delete directory that holds temporary files
57
+ rm -rf $dir
58
+
59
+ if [[ $missing_module == 0 ]]; then
60
+ echo "status: ok"
61
+ else
62
+ echo "status: failed"
63
+ fi
64
+
65
+ exit $missing_module
@@ -0,0 +1,95 @@
1
+ class Sfp::Module::Machine
2
+ include Sfp::Resource
3
+
4
+ def update_state
5
+ to_model
6
+
7
+ @state['sfpAddress'] = @model['sfpAddress']
8
+ @state['sfpPort'] = @model['sfpPort']
9
+ @state['created'] = true
10
+
11
+ data = `dmidecode | grep -i product`.strip
12
+ if data.length <= 0
13
+ @state['hypervisor'] = 'N/A'
14
+ else
15
+ @state['hypervisor'] = data.split("\n")[0].split(":", 2)[1].to_s.strip.downcase
16
+ end
17
+
18
+ @state["cpus"] = (File.exist?('/proc/cpuinfo') ? `cat /proc/cpuinfo | grep processor | wc -l`.strip.to_i : -1)
19
+ @state['memory'] = (`which free`.strip != '' ? `free`.split("\n")[1].split(" ")[1] : -1)
20
+
21
+ @state['disk'] = get_disk_state
22
+ end
23
+
24
+ ##############################
25
+ #
26
+ # Helper methods
27
+ #
28
+ ##############################
29
+
30
+ protected
31
+
32
+ # generate the disks' state, try to automatically mount the disk to target directory
33
+ #
34
+ def get_disk_state
35
+ def generate_state
36
+ disk = {}
37
+ # get disks UUID
38
+ uuids = {}
39
+ `blkid`.each_line do |line|
40
+ line.strip!
41
+ next if line.length <= 0
42
+ device, info = line.split(':', 2)
43
+ info = info.split(' ')
44
+ uuids[device] = info[0].split('=', 2)[1].gsub(/"/, '')
45
+ end
46
+
47
+ # read fstab
48
+ `df -l`.each_line do |line|
49
+ line.strip!
50
+ next if line.length <= 0
51
+ data = line.split(' ')
52
+ if data[0][0..4] == '/dev/'
53
+ name = 'root'
54
+ if data[5] != '/'
55
+ model = (@model['disk'].is_a?(Hash) ? @model['disk'].select { |k,v| v['mount'] == data[5] if k[0] != '_' } : {})
56
+ name = (model.length > 0 ? model.keys.first : "uuid_#{uuids[data[0]]}")
57
+ end
58
+ disk[name] = {
59
+ 'size' => (data[1].to_f / 1000.0).to_i,
60
+ 'mount' => data[5],
61
+ 'uuid' => uuids[data[0]]
62
+ }
63
+ end
64
+ end
65
+ disk
66
+ end
67
+
68
+ disk = generate_state
69
+
70
+ if @model['disk'].is_a?(Hash)
71
+ names = @model['disk'].keys.sort { |x,y| x <=> y }
72
+ device = "/dev/vdb"
73
+ # format unformatted disks, mount unmount disks
74
+ names.each { |name|
75
+ next if name[0] == '_' or disk.has_key?(name)
76
+ spec = @model['disk'][name]
77
+ status = `file -s #{device}`
78
+ if not (status =~ /ERROR/)
79
+ target = spec['mount'].to_s.strip
80
+ # format the disk if not yet formatted
81
+ system "mkfs.ext4 #{device}" if not (status =~ /.+ filesystem data/)
82
+ # create target directory if not exist
83
+ system "mkdir -p #{target}" if !File.exist? target
84
+ # add fstab record
85
+ system "sed -i '/^#{device}/d' /etc/fstab"
86
+ system "echo '#{device} #{target} ext4 defaults 0 0' >> /etc/fstab"
87
+ end
88
+ device = device.next
89
+ }
90
+ system 'mount -a'
91
+ end
92
+
93
+ generate_state
94
+ end
95
+ end