jashmenn-poolparty-extensions 0.1.0 → 0.1.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.
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
3
  :minor: 1
4
- :patch: 0
4
+ :patch: 1
@@ -57,6 +57,10 @@ module PoolParty
57
57
  def add_aliases
58
58
  has_bash_alias :name => "inspect-poolparty-recipes", :value => "vi /var/poolparty/dr_configure/chef/cookbooks/poolparty/recipes/default.rb"
59
59
  has_bash_alias :name => "cd-cookbooks", :value => "pushd /var/poolparty/dr_configure/chef/cookbooks/poolparty"
60
+
61
+ %w{instance-id local-hostname local-ipv4 public-hostname public-ipv4 security-groups}.each do |metaalias|
62
+ has_bash_alias :name => metaalias, :value => "curl http://169.254.169.254/latest/meta-data/#{metaalias}"
63
+ end
60
64
  end
61
65
 
62
66
  def add_binaries
@@ -41,6 +41,7 @@ module PoolParty
41
41
  module Plugin
42
42
  class Ganglia < Plugin
43
43
  def before_load(o={}, &block)
44
+ @monitored_features ||= {}
44
45
  do_once do
45
46
  install_dependencies
46
47
  download
@@ -143,6 +144,11 @@ module PoolParty
143
144
  has_service "gmetad", :enabled => true, :running => true, :supports => [:restart]
144
145
  end
145
146
 
147
+ def track(*features)
148
+ @monitored_features ||= {}
149
+ features.map {|f| @monitored_features[f] = true }
150
+ end
151
+
146
152
  def gmond_after_all_loaded
147
153
  has_variable "ganglia_cloud_name", :value => cloud_name
148
154
  has_variable "ganglia_this_nodes_private_ip", :value => lambda{ %Q{%x[curl http://169.254.169.254/latest/meta-data/local-ipv4]}}
@@ -150,6 +156,7 @@ module PoolParty
150
156
 
151
157
  first_node = clouds[cloud_name].nodes(:status => 'running').first
152
158
 
159
+
153
160
  if first_node
154
161
  has_variable "ganglia_first_node_in_clusters_ip", :value => lambda { %Q{\`ping -c1 #{first_node[:private_dns_name]} | grep PING | awk -F '[()]' '{print $2 }'\`.strip}}
155
162
 
@@ -158,11 +165,26 @@ module PoolParty
158
165
  template "gmond.conf.erb"
159
166
  # calls get_exec("restart-gmond")
160
167
  end
168
+
169
+ enable_tracking_configs
170
+
161
171
  end
162
172
  has_service "gmond", :enabled => true, :running => true, :supports => [:restart]
163
173
 
164
174
  end
165
175
 
176
+ def enable_tracking_configs
177
+ if @monitored_features[:hadoop]
178
+ has_variable "hadoop_ganglia_monitoring_enabled", :value => true
179
+
180
+ # hmm, should maybe be mvd to hadoop plugin?
181
+ has_file(:name => "/usr/local/hadoop/conf/hadoop-metrics.properties") do
182
+ mode 0644
183
+ template "hadoop-metrics.properties.erb"
184
+ end
185
+ end
186
+ end
187
+
166
188
  # todo, add a verifier
167
189
  # telnet localhost 8649
168
190
 
@@ -0,0 +1,65 @@
1
+
2
+ # Configuration of the "dfs" context for null
3
+ dfs.class=org.apache.hadoop.metrics.spi.NullContext
4
+
5
+ # Configuration of the "dfs" context for file
6
+ #dfs.class=org.apache.hadoop.metrics.file.FileContext
7
+ #dfs.period=10
8
+ #dfs.fileName=/tmp/dfsmetrics.log
9
+
10
+ # Configuration of the "dfs" context for ganglia
11
+ # dfs.class=org.apache.hadoop.metrics.ganglia.GangliaContext
12
+ # dfs.period=10
13
+ # dfs.servers=localhost:8649
14
+
15
+
16
+ # Configuration of the "mapred" context for null
17
+ mapred.class=org.apache.hadoop.metrics.spi.NullContext
18
+
19
+ # Configuration of the "mapred" context for file
20
+ #mapred.class=org.apache.hadoop.metrics.file.FileContext
21
+ #mapred.period=10
22
+ #mapred.fileName=/tmp/mrmetrics.log
23
+
24
+ # Configuration of the "mapred" context for ganglia
25
+ # mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext
26
+ # mapred.period=10
27
+ # mapred.servers=localhost:8649
28
+
29
+
30
+ # Configuration of the "jvm" context for null
31
+ jvm.class=org.apache.hadoop.metrics.spi.NullContext
32
+
33
+ # Configuration of the "jvm" context for file
34
+ #jvm.class=org.apache.hadoop.metrics.file.FileContext
35
+ #jvm.period=10
36
+ #jvm.fileName=/tmp/jvmmetrics.log
37
+
38
+ # Configuration of the "jvm" context for ganglia
39
+ # jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext
40
+ # jvm.period=10
41
+ # jvm.servers=localhost:8649
42
+ #
43
+ <% if @node[:poolparty][:hadoop_ganglia_monitoring_enabled] %>
44
+
45
+ # The value in the udp_send_channel you use in your /etc/gmond.conf (look for the line which says mcast_join=<IP ADDRESS>).
46
+
47
+ # dfs.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
48
+ # dfs.period=10
49
+ # dfs.servers=<%= @node[:poolparty][:ganglia_first_node_in_clusters_ip] %>:8649
50
+
51
+ # mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
52
+ # mapred.period=10
53
+ # mapred.servers=<%= @node[:poolparty][:ganglia_first_node_in_clusters_ip] %>:8649
54
+
55
+ # jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
56
+ # jvm.period=10
57
+ # jvm.servers=<%= @node[:poolparty][:ganglia_first_node_in_clusters_ip] %>:8649
58
+
59
+ # rpc.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
60
+ # rpc.period=10
61
+ # rpc.servers=<%= @node[:poolparty][:ganglia_first_node_in_clusters_ip] %>:8649
62
+
63
+ <% end %>
64
+
65
+ # vim: ft=conf
@@ -0,0 +1,319 @@
1
+ =begin rdoc
2
+
3
+ == Overview
4
+ Install a hadoop cluster
5
+
6
+ == Requirements
7
+ You'll need apache and php enabled in your clouds.rb. For example:
8
+
9
+ apache do
10
+ enable_php5
11
+ end
12
+
13
+ == Bugs
14
+ This assumes your clouds are named "hadoop_master" and "hadoop_slave". That sucks. TODO: pass these in as variables
15
+
16
+ == References
17
+ =end
18
+
19
+
20
+
21
+ module PoolParty
22
+ module Plugin
23
+ class Hadoop < Plugin
24
+ def before_load(o={}, &block)
25
+ do_once do
26
+ install_jdk
27
+ # add_users_and_groups
28
+ create_keys
29
+ connect_keys
30
+ build
31
+ configure
32
+ format_hdfs
33
+ create_aliases
34
+ end
35
+ end
36
+
37
+ def perform_just_in_time_operations
38
+ create_reference_hosts
39
+ create_ssh_configs
40
+ create_master_and_slaves_files
41
+ end
42
+
43
+ def install_jdk
44
+ # accept the sun license agreements. see: http://www.davidpashley.com/blog/debian/java-license
45
+ has_exec "echo sun-java6-jdk shared/accepted-sun-dlj-v1-1 select true | /usr/bin/debconf-set-selections"
46
+ has_exec "echo sun-java6-jre shared/accepted-sun-dlj-v1-1 select true | /usr/bin/debconf-set-selections"
47
+ has_package(:name => "sun-java6-jdk")
48
+ has_file(:name => "/etc/jvm") do
49
+ mode 0644
50
+ template "jvm.conf"
51
+ end
52
+ end
53
+
54
+ def add_users_and_groups
55
+ has_group "hadoop", :action => :create
56
+ has_user "hadoop", :gid => "hadoop"
57
+ has_directory "/home/hadoop", :owner => "hadoop", :mode => "755"
58
+
59
+ # TODO - ssh key code below needs to turn into these lines. those should become plugins
60
+ # has_ssh_key :user => "hadoop", :name => "hadoop_id_rsa", :create => true
61
+ # has_authorized_key :user => "hadoop", :name => "hadoop_id_rsa"
62
+ end
63
+
64
+ def create_keys
65
+ unless File.exists?(hadoop_id_rsa)
66
+ FileUtils.mkdir_p(cloud_keys_dir)
67
+ cmd = "ssh-keygen -t rsa -N '' -f #{hadoop_id_rsa}" # todo, make into variables
68
+ puts cmd
69
+ `#{cmd}`
70
+ end
71
+ end
72
+
73
+ # everything below should become methods and/or plugins
74
+ def connect_keys
75
+ # has_exec "ssh-keygen -t rsa -N '' -f /home/hadoop/.ssh/id_rsa", :user => "hadoop", :not_if => "test -e /home/hadoop/.ssh/id_rsa"
76
+
77
+ # so annoying, chef/rsync/something doesn't copy over dotfiles, so upload it as non-dot
78
+ has_directory :name => "#{home_dir}/ssh"
79
+ has_directory :name => "#{home_dir}/.ssh"
80
+ has_file :name => "#{home_dir}/ssh/#{hadoop_id_rsa_base}", :content => open(hadoop_id_rsa).read
81
+ has_exec "mv #{home_dir}/ssh/hadoop_id_rsa #{home_dir}/.ssh/#{hadoop_id_rsa_base}"
82
+ has_exec "chmod 600 #{home_dir}/.ssh/#{hadoop_id_rsa_base}"
83
+ has_exec "chmod 700 #{home_dir}/.ssh"
84
+ has_exec "rm -rf #{home_dir}/ssh"
85
+
86
+ # setup authorized keys
87
+ has_exec "touch #{home_dir}/.ssh/authorized_keys"
88
+ has_exec "chmod 644 #{home_dir}/.ssh/authorized_keys"
89
+ has_exec "chown -R #{user} #{home_dir}/.ssh"
90
+ has_line_in_file :file => "#{home_dir}/.ssh/authorized_keys", :line => File.read("#{hadoop_id_rsa}.pub")
91
+ end
92
+
93
+ def create_reference_hosts
94
+ clouds[:hadoop_master].nodes(:status => 'running').each_with_index do |n, i|
95
+ # has_host(:name => "master#{i}", :ip => n.public_ip) # todo
96
+ # my_line_in_file("/etc/hosts", "#{n.public_ip} master#{i}")
97
+ has_exec "ghost modify master#{i} \`dig +short #{n[:private_dns_name]}\`"
98
+ end
99
+ clouds[:hadoop_slave].nodes(:status => 'running').each_with_index do |n, i|
100
+ # has_host(:name => "slave#{i}", :ip => n.public_ip) # todo
101
+ # my_line_in_file("/etc/hosts", "#{n.public_ip} slave#{i}")
102
+ has_exec "ghost modify slave#{i} \`dig +short #{n[:private_dns_name]}\`"
103
+ end
104
+ end
105
+
106
+ def create_ssh_configs
107
+ ssh_config = ""
108
+ clouds[:hadoop_master].nodes(:status => 'running').each_with_index do |n,i|
109
+ has_exec "ssh -o 'StrictHostKeyChecking no' -i #{home_dir}/.ssh/#{hadoop_id_rsa_base} master#{i} echo || :", :user => user, # verify the host key
110
+ :only_if => "grep master#{i} /etc/hosts"
111
+ end
112
+
113
+ clouds[:hadoop_slave].nodes(:status => 'running').each_with_index do |n,i|
114
+ has_exec "ssh -o 'StrictHostKeyChecking no' -i #{home_dir}/.ssh/#{hadoop_id_rsa_base} slave#{i} echo || :", :user => user, # verify the host key
115
+ :only_if => "grep slave#{i} /etc/hosts"
116
+ end
117
+
118
+ ssh_config << <<EOF
119
+ Host *
120
+ IdentityFile #{home_dir}/.ssh/#{hadoop_id_rsa_base}
121
+ EOF
122
+ has_exec "ssh -o 'StrictHostKeyChecking no' -i #{home_dir}/.ssh/#{hadoop_id_rsa_base} localhost echo", :user => user # verify the host key
123
+
124
+ has_file("#{home_dir}/ssh_config", :content => ssh_config)
125
+ has_exec "mv #{home_dir}/ssh_config #{home_dir}/.ssh/config"
126
+ has_exec "chmod 600 #{home_dir}/.ssh/config"
127
+ has_exec "chown #{user}:#{group} #{home_dir}/.ssh/config"
128
+ end
129
+
130
+ def build
131
+ has_directory "/usr/local/src"
132
+ has_exec "wget http://www.gossipcheck.com/mirrors/apache/hadoop/core/hadoop-0.20.0/hadoop-0.20.0.tar.gz -O /usr/local/src/hadoop-0.20.0.tar.gz",
133
+ :not_if => "test -e /usr/local/src/hadoop-0.20.0.tar.gz"
134
+ has_exec "cd /usr/local/src && tar -xzf hadoop-0.20.0.tar.gz",
135
+ :not_if => "test -e #{hadoop_install_dir}"
136
+ has_exec "mv /usr/local/src/hadoop-0.20.0 /usr/local/src/hadoop",
137
+ :not_if => "test -e #{hadoop_install_dir}"
138
+ has_exec "chown -R #{user}:#{group} /usr/local/src/hadoop",
139
+ :not_if => "test -e #{hadoop_install_dir}"
140
+ has_exec "mv /usr/local/src/hadoop #{hadoop_install_dir}",
141
+ :not_if => "test -e #{hadoop_install_dir}"
142
+ # apply https://issues.apache.org/jira/secure/attachment/12407207/HADOOP-4675-v7.patch for ganglia 3.1 support
143
+ end
144
+
145
+ def hadoop_install_dir
146
+ "/usr/local/hadoop"
147
+ end
148
+
149
+ def configure
150
+ has_file(:name => hadoop_install_dir/"conf/hadoop-env.sh") do
151
+ mode 0644
152
+ template "hadoop-env.sh"
153
+ end
154
+
155
+ has_variable "current_master", :value => "master0" # todo, could eventually be made more dynamic here
156
+
157
+ # puts "we have this many nodes in our pool: #{number_of_running_nodes_in_pool}"
158
+ # has_variable "number_of_nodes", :value => lambda { %Q{ %x[/usr/bin/cloud-list --short].split("\\n").size || 1 }}
159
+ has_variable "number_of_nodes", :value => 2 # todo
160
+
161
+ has_directory hadoop_data_dir, :owner => user, :mode => "755"
162
+ has_exec "chgrp -R #{group} #{hadoop_data_dir}"
163
+
164
+ %w{logs name data mapred temp}.each do |folder|
165
+ has_directory hadoop_data_dir/folder, :owner => user, :mode => "755"
166
+ end
167
+ has_directory hadoop_data_dir/:temp/:dfs/:data, :owner => user, :mode => "755"
168
+
169
+ %w{local system temp}.each do |folder|
170
+ has_directory hadoop_data_dir/:temp/:mapred/folder, :owner => user, :mode => "755"
171
+ end
172
+
173
+ has_variable "hadoop_data_dir", :value => hadoop_data_dir
174
+ has_variable "hadoop_mapred_dir", :value => hadoop_data_dir/:mapred
175
+
176
+ has_variable("hadoop_this_nodes_ip", :value => lambda{ %Q{%x[curl http://169.254.169.254/latest/meta-data/local-ipv4]}})
177
+
178
+ %w{core hdfs mapred}.each do |config|
179
+ has_file(:name => hadoop_install_dir/"conf/#{config}-site.xml") do
180
+ mode 0644
181
+ template "#{config}-site.xml.erb"
182
+ end
183
+ end
184
+
185
+ has_file(:name => hadoop_install_dir/"conf/log4j.properties") do
186
+ mode 0644
187
+ template "log4j.properties.erb"
188
+ end
189
+
190
+ end
191
+
192
+ def number_of_running_nodes_in_pool
193
+ # clouds.keys.inject(0) { |sum,cloud_name| sum = sum + clouds[cloud_name].nodes(:status => 'running').size; sum }
194
+ end
195
+
196
+ def configure_master
197
+ # create_master_and_slaves_files
198
+ end
199
+
200
+ def format_hdfs
201
+ has_directory hadoop_data_dir, :mode => "770"
202
+ has_exec "chown -R #{user}:#{group} #{hadoop_data_dir}"
203
+
204
+ has_exec "#{hadoop_install_dir}/bin/hadoop namenode -format",
205
+ # :not_if => "test -e #{hadoop_data_dir}/hadoop-hadoop/dfs",
206
+ :not_if => "test -e #{hadoop_data_dir}/dfs/name", # this line depends on if you have user-based data directories in core-site.xml
207
+ :user => user
208
+ end
209
+
210
+ # stuff for examples
211
+
212
+ def prep_example_job
213
+ download_sample_data
214
+ end
215
+
216
+ def run_example_job
217
+ start_hadoop
218
+ copy_sample_data_to_hdfs
219
+ start_the_job
220
+ end
221
+
222
+ def start_hadoop
223
+ has_exec hadoop_install_dir/"bin/start-all.sh",
224
+ :user => user
225
+ end
226
+
227
+ def download_sample_data
228
+ has_directory "/tmp/gutenberg", :mode => "770", :owner => user
229
+ # todo, create has_wget
230
+ has_exec "wget http://www.gutenberg.org/files/20417/20417.txt -O /tmp/gutenberg/outline-of-science.txt",
231
+ :not_if => "test -e /tmp/gutenberg/outline-of-science.txt"
232
+ has_exec "wget http://www.gutenberg.org/dirs/etext04/7ldvc10.txt -O /tmp/gutenberg/7ldvc10.txt",
233
+ :not_if => "test -e /tmp/gutenberg/7ldvc10.txt"
234
+ has_exec "wget http://www.gutenberg.org/files/4300/4300.txt -O /tmp/gutenberg/ulysses.txt",
235
+ :not_if => "test -e /tmp/gutenberg/ulysses.txt"
236
+ has_exec "chown -R #{user}:#{group} /tmp/gutenberg"
237
+ end
238
+
239
+ def copy_sample_data_to_hdfs
240
+ has_exec "#{hadoop_install_dir}/bin/hadoop dfs -rmr gutenberg", :user => user,
241
+ :only_if => "sudo -H -u #{user} #{hadoop_install_dir}/bin/hadoop dfs -ls gutenberg"
242
+ has_exec "#{hadoop_install_dir}/bin/hadoop dfs -rmr gutenberg-output", :user => user,
243
+ :only_if => "sudo -H -u #{user} #{hadoop_install_dir}/bin/hadoop dfs -ls gutenberg-output"
244
+ has_exec "#{hadoop_install_dir}/bin/hadoop dfs -copyFromLocal /tmp/gutenberg gutenberg",
245
+ :not_if => "sudo -H -u #{user} #{hadoop_install_dir}/bin/hadoop dfs -ls gutenberg | grep ulysses",
246
+ :user => user
247
+ end
248
+
249
+ def start_the_job
250
+ has_exec "#{hadoop_install_dir}/bin/hadoop jar #{hadoop_install_dir}/hadoop-0.20.0-examples.jar wordcount gutenberg gutenberg-output",
251
+ :user => user
252
+ end
253
+
254
+ def create_master_and_slaves_files
255
+ masters_file = ""
256
+ slaves_file = ""
257
+
258
+ clouds[:hadoop_master].nodes(:status => 'running').each_with_index do |n,i|
259
+ masters_file << "master#{i}\n"
260
+ # slaves_file << "master#{i}\n" # our masters are also slaves
261
+ end
262
+
263
+ clouds[:hadoop_slave].nodes(:status => 'running').each_with_index do |n, i|
264
+ slaves_file << "slave#{i}\n"
265
+ end
266
+
267
+ has_file(hadoop_install_dir/:conf/:masters, :content => masters_file)
268
+ has_file(hadoop_install_dir/:conf/:slaves, :content => slaves_file)
269
+ end
270
+
271
+ def create_aliases
272
+ has_bash_alias :name => "cd-hadoop", :value => "pushd /usr/local/hadoop"
273
+ end
274
+
275
+ private
276
+ def cloud_keys_dir
277
+ File.dirname(pool_specfile)/:keys
278
+ end
279
+
280
+ def hadoop_id_rsa
281
+ "#{cloud_keys_dir}/#{hadoop_id_rsa_base}"
282
+ end
283
+
284
+ def hadoop_id_rsa_base
285
+ "hadoop_id_rsa"
286
+ end
287
+
288
+ def hadoop_data_dir
289
+ "/mnt/hadoop-data"
290
+ end
291
+
292
+ def home_dir
293
+ "/root"
294
+ # or
295
+ # "/home/hadoop"
296
+ end
297
+
298
+ def user
299
+ "root"
300
+ # or
301
+ # hadoop
302
+ end
303
+
304
+ def group
305
+ "root"
306
+ # or
307
+ # hadoop
308
+ end
309
+
310
+ def my_line_in_file(file, line)
311
+ has_exec "line_in_#{file}_#{line.safe_quote}" do
312
+ command "grep -q \'#{line.safe_quote}\' #{file} || echo \'#{line.safe_quote}\' >> #{file}"
313
+ not_if "grep -q \'#{line.safe_quote}\' #{file}"
314
+ end
315
+ end
316
+
317
+ end
318
+ end
319
+ end