cluster_chef-knife 3.0.5

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 (42) hide show
  1. data/.gitignore +51 -0
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +63 -0
  4. data/Gemfile +18 -0
  5. data/LICENSE +201 -0
  6. data/README.md +332 -0
  7. data/Rakefile +92 -0
  8. data/TODO.md +8 -0
  9. data/VERSION +1 -0
  10. data/chefignore +41 -0
  11. data/cluster_chef-knife.gemspec +111 -0
  12. data/clusters/website_demo.rb +65 -0
  13. data/config/client.rb +59 -0
  14. data/lib/chef/knife/bootstrap/ubuntu10.04-basic.erb +78 -0
  15. data/lib/chef/knife/bootstrap/ubuntu10.04-cluster_chef.erb +139 -0
  16. data/lib/chef/knife/bootstrap/ubuntu11.10-cluster_chef.erb +128 -0
  17. data/lib/chef/knife/cluster_bootstrap.rb +69 -0
  18. data/lib/chef/knife/cluster_kick.rb +86 -0
  19. data/lib/chef/knife/cluster_kill.rb +73 -0
  20. data/lib/chef/knife/cluster_launch.rb +168 -0
  21. data/lib/chef/knife/cluster_list.rb +50 -0
  22. data/lib/chef/knife/cluster_proxy.rb +118 -0
  23. data/lib/chef/knife/cluster_show.rb +56 -0
  24. data/lib/chef/knife/cluster_ssh.rb +94 -0
  25. data/lib/chef/knife/cluster_start.rb +32 -0
  26. data/lib/chef/knife/cluster_stop.rb +37 -0
  27. data/lib/chef/knife/cluster_sync.rb +76 -0
  28. data/lib/chef/knife/generic_command.rb +66 -0
  29. data/lib/chef/knife/knife_common.rb +199 -0
  30. data/notes/aws_console_screenshot.jpg +0 -0
  31. data/rspec.watchr +29 -0
  32. data/spec/cluster_chef/cluster_spec.rb +13 -0
  33. data/spec/cluster_chef/facet_spec.rb +70 -0
  34. data/spec/cluster_chef/server_slice_spec.rb +19 -0
  35. data/spec/cluster_chef/server_spec.rb +112 -0
  36. data/spec/cluster_chef_spec.rb +193 -0
  37. data/spec/spec_helper/dummy_chef.rb +25 -0
  38. data/spec/spec_helper.rb +50 -0
  39. data/spec/test_config.rb +20 -0
  40. data/tasks/chef_config.rb +38 -0
  41. data/tasks/jeweler_use_alt_branch.rb +47 -0
  42. metadata +223 -0
data/Rakefile ADDED
@@ -0,0 +1,92 @@
1
+ #
2
+ # Rakefile for Cluster Chef Knife plugins
3
+ #
4
+ # Author:: Adam Jacob (<adam@opscode.com>)
5
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ require 'rubygems' unless defined?(Gem)
22
+ require 'bundler'
23
+ begin
24
+ Bundler.setup(:default, :development)
25
+ rescue Bundler::BundlerError => e
26
+ $stderr.puts e.message
27
+ $stderr.puts "Run `bundle install` to install missing gems"
28
+ exit e.status_code
29
+ end
30
+ require 'json'
31
+ require 'jeweler'
32
+ require 'rspec/core/rake_task'
33
+ require 'yard'
34
+
35
+ # Load constants from rake config file.
36
+ Dir[File.join(File.dirname(__FILE__), 'tasks', '*.rb')].sort.each{|f| p f ; require f }
37
+
38
+ $jeweler_push_from_branch = 'version_3'
39
+
40
+ # ---------------------------------------------------------------------------
41
+ #
42
+ # Jeweler -- release cluster_chef as a gem
43
+ #
44
+ Jeweler::Tasks.new do |gem|
45
+ gem.name = ENV['CLUSTER_CHEF_NAME'] || "cluster_chef-knife"
46
+ gem.homepage = "http://infochimps.com/labs"
47
+ gem.license = NEW_COOKBOOK_LICENSE.to_s
48
+ gem.summary = %Q{cluster_chef allows you to orchestrate not just systems but clusters of machines. It includes a powerful layer on top of knife and a collection of cloud cookbooks.}
49
+ gem.description = %Q{cluster_chef allows you to orchestrate not just systems but clusters of machines. It includes a powerful layer on top of knife and a collection of cloud cookbooks.}
50
+ gem.email = SSL_EMAIL_ADDRESS
51
+ gem.authors = ["Infochimps"]
52
+
53
+ ignores = File.readlines(".gitignore").grep(/^[^#]\S+/).map{|s| s.chomp }
54
+ dotfiles = [".gemtest", ".gitignore", ".rspec", ".yardopts"]
55
+ gem.files = dotfiles + Dir["**/*"].
56
+ reject{|f| f =~ %r{^cookbooks/} }.
57
+ reject{|f| File.directory?(f) }.
58
+ reject{|f| ignores.any?{|i| File.fnmatch(i, f) || File.fnmatch(i+'/*', f) || File.fnmatch(i+'/**/*', f) } }
59
+ gem.test_files = gem.files.grep(/^spec\//)
60
+ gem.require_paths = ['lib']
61
+
62
+ if gem.name == 'cluster_chef'
63
+ gem.files.reject!{|f| f =~ %r{^(cluster_chef-knife.gemspec|lib/chef/knife/)} }
64
+ else
65
+ gem.files.reject!{|f| f =~ %r{^(cluster_chef.gemspec|lib/cluster_chef)} }
66
+ end
67
+ end
68
+ Jeweler::RubygemsDotOrgTasks.new
69
+
70
+ # ---------------------------------------------------------------------------
71
+ #
72
+ # RSpec -- testing
73
+ #
74
+ RSpec::Core::RakeTask.new(:spec) do |spec|
75
+ spec.pattern = FileList['spec/**/*_spec.rb']
76
+ end
77
+
78
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
79
+ spec.pattern = 'spec/**/*_spec.rb'
80
+ spec.rcov = true
81
+ spec.rcov_opts = %w[ --exclude .rvm --no-comments --text-summary]
82
+ end
83
+
84
+ # ---------------------------------------------------------------------------
85
+ #
86
+ # Yard -- documentation
87
+ #
88
+ YARD::Rake::YardocTask.new
89
+
90
+ # ---------------------------------------------------------------------------
91
+
92
+ task :default => :spec
data/TODO.md ADDED
@@ -0,0 +1,8 @@
1
+ ### From Nathan
2
+ - syntactic sugar for ```server(0).fullname('blah')```
3
+
4
+ ### Knife commands
5
+
6
+ * knife cluster kick fails if service isn't running
7
+ * make clear directions for installing `cluster_chef` and its initial use.
8
+ * knife cluster launch should fail differently if you give it a facet that doesn't exist
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 3.0.5
data/chefignore ADDED
@@ -0,0 +1,41 @@
1
+ # Put files/directories that should be ignored in this file.
2
+ # Lines that start with '# ' are comments.
3
+
4
+ ## OS
5
+ .DS_Store
6
+ Icon?
7
+ nohup.out
8
+
9
+ ## EDITORS
10
+ \#*
11
+ .#*
12
+ *~
13
+ *.sw[a-z]
14
+ *.bak
15
+ REVISION
16
+ TAGS*
17
+ tmtags
18
+ *_flymake.*
19
+ *_flymake
20
+ *.tmproj
21
+ .project
22
+ .settings
23
+ mkmf.log
24
+
25
+ ## COMPILED
26
+ a.out
27
+ *.o
28
+ *.pyc
29
+ *.so
30
+
31
+ ## OTHER SCM
32
+ */.bzr/*
33
+ */.hg/*
34
+ */.svn/*
35
+
36
+ ## Don't send rspecs up in cookbook
37
+ .watchr
38
+ .rspec
39
+ spec/*
40
+ spec/fixtures/*
41
+
@@ -0,0 +1,111 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "cluster_chef-knife"
8
+ s.version = "3.0.5"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Infochimps"]
12
+ s.date = "2011-12-11"
13
+ s.description = "cluster_chef allows you to orchestrate not just systems but clusters of machines. It includes a powerful layer on top of knife and a collection of cloud cookbooks."
14
+ s.email = "coders@infochimps.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ ".rspec",
22
+ "CHANGELOG.md",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "README.md",
26
+ "Rakefile",
27
+ "TODO.md",
28
+ "VERSION",
29
+ "chefignore",
30
+ "cluster_chef-knife.gemspec",
31
+ "clusters/website_demo.rb",
32
+ "config/client.rb",
33
+ "lib/chef/knife/bootstrap/ubuntu10.04-basic.erb",
34
+ "lib/chef/knife/bootstrap/ubuntu10.04-cluster_chef.erb",
35
+ "lib/chef/knife/bootstrap/ubuntu11.10-cluster_chef.erb",
36
+ "lib/chef/knife/cluster_bootstrap.rb",
37
+ "lib/chef/knife/cluster_kick.rb",
38
+ "lib/chef/knife/cluster_kill.rb",
39
+ "lib/chef/knife/cluster_launch.rb",
40
+ "lib/chef/knife/cluster_list.rb",
41
+ "lib/chef/knife/cluster_proxy.rb",
42
+ "lib/chef/knife/cluster_show.rb",
43
+ "lib/chef/knife/cluster_ssh.rb",
44
+ "lib/chef/knife/cluster_start.rb",
45
+ "lib/chef/knife/cluster_stop.rb",
46
+ "lib/chef/knife/cluster_sync.rb",
47
+ "lib/chef/knife/generic_command.rb",
48
+ "lib/chef/knife/knife_common.rb",
49
+ "notes/aws_console_screenshot.jpg",
50
+ "rspec.watchr",
51
+ "spec/cluster_chef/cluster_spec.rb",
52
+ "spec/cluster_chef/facet_spec.rb",
53
+ "spec/cluster_chef/server_slice_spec.rb",
54
+ "spec/cluster_chef/server_spec.rb",
55
+ "spec/cluster_chef_spec.rb",
56
+ "spec/spec_helper.rb",
57
+ "spec/spec_helper/dummy_chef.rb",
58
+ "spec/test_config.rb",
59
+ "tasks/chef_config.rb",
60
+ "tasks/jeweler_use_alt_branch.rb"
61
+ ]
62
+ s.homepage = "http://infochimps.com/labs"
63
+ s.licenses = ["apachev2"]
64
+ s.require_paths = ["lib"]
65
+ s.rubygems_version = "1.8.11"
66
+ s.summary = "cluster_chef allows you to orchestrate not just systems but clusters of machines. It includes a powerful layer on top of knife and a collection of cloud cookbooks."
67
+ s.test_files = ["spec/cluster_chef/cluster_spec.rb", "spec/cluster_chef/facet_spec.rb", "spec/cluster_chef/server_slice_spec.rb", "spec/cluster_chef/server_spec.rb", "spec/cluster_chef_spec.rb", "spec/spec_helper/dummy_chef.rb", "spec/spec_helper.rb", "spec/test_config.rb"]
68
+
69
+ if s.respond_to? :specification_version then
70
+ s.specification_version = 3
71
+
72
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
73
+ s.add_runtime_dependency(%q<chef>, ["~> 0.10.4"])
74
+ s.add_runtime_dependency(%q<fog>, ["~> 1.1.1"])
75
+ s.add_runtime_dependency(%q<formatador>, ["~> 0.2.1"])
76
+ s.add_runtime_dependency(%q<gorillib>, ["~> 0.1.7"])
77
+ s.add_development_dependency(%q<bundler>, ["~> 1"])
78
+ s.add_development_dependency(%q<yard>, ["~> 0.6.7"])
79
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
80
+ s.add_development_dependency(%q<rspec>, ["~> 2.7.0"])
81
+ s.add_development_dependency(%q<configliere>, ["~> 0.4.8"])
82
+ s.add_development_dependency(%q<spork>, ["~> 0.9.0.rc5"])
83
+ s.add_development_dependency(%q<watchr>, ["~> 0.7"])
84
+ else
85
+ s.add_dependency(%q<chef>, ["~> 0.10.4"])
86
+ s.add_dependency(%q<fog>, ["~> 1.1.1"])
87
+ s.add_dependency(%q<formatador>, ["~> 0.2.1"])
88
+ s.add_dependency(%q<gorillib>, ["~> 0.1.7"])
89
+ s.add_dependency(%q<bundler>, ["~> 1"])
90
+ s.add_dependency(%q<yard>, ["~> 0.6.7"])
91
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
92
+ s.add_dependency(%q<rspec>, ["~> 2.7.0"])
93
+ s.add_dependency(%q<configliere>, ["~> 0.4.8"])
94
+ s.add_dependency(%q<spork>, ["~> 0.9.0.rc5"])
95
+ s.add_dependency(%q<watchr>, ["~> 0.7"])
96
+ end
97
+ else
98
+ s.add_dependency(%q<chef>, ["~> 0.10.4"])
99
+ s.add_dependency(%q<fog>, ["~> 1.1.1"])
100
+ s.add_dependency(%q<formatador>, ["~> 0.2.1"])
101
+ s.add_dependency(%q<gorillib>, ["~> 0.1.7"])
102
+ s.add_dependency(%q<bundler>, ["~> 1"])
103
+ s.add_dependency(%q<yard>, ["~> 0.6.7"])
104
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
105
+ s.add_dependency(%q<rspec>, ["~> 2.7.0"])
106
+ s.add_dependency(%q<configliere>, ["~> 0.4.8"])
107
+ s.add_dependency(%q<spork>, ["~> 0.9.0.rc5"])
108
+ s.add_dependency(%q<watchr>, ["~> 0.7"])
109
+ end
110
+ end
111
+
@@ -0,0 +1,65 @@
1
+ ClusterChef.cluster 'webserver_demo' do
2
+ cloud :ec2 do
3
+ defaults
4
+ availability_zones ['us-east-1d']
5
+ flavor 't1.micro' # change to something larger for serious use
6
+ backing 'ebs'
7
+ image_name 'natty'
8
+ bootstrap_distro 'ubuntu10.04-cluster_chef'
9
+ chef_client_script 'client.rb'
10
+ mount_ephemerals(:tags => { :scratch_dirs => true })
11
+ end
12
+
13
+ role "nfs_client"
14
+ recipe "package_set"
15
+
16
+ facet :webnode do
17
+ instances 6
18
+ role "nginx"
19
+ role "redis_client"
20
+ role "mysql_client"
21
+ role "elasticsearch_client"
22
+ role "awesome_website"
23
+ role "web_server" # this triggers opening appropriate ports
24
+ # Rotate nodes among availability zones
25
+ azs = ['us-east-1d', 'us-east-1b', 'us-east-1c']
26
+ (0...instances).each do |idx|
27
+ server(idx).cloud.availability_zones [azs[ idx % azs.length ]]
28
+ end
29
+ # Rote nodes among A/B testing groups
30
+ (0..instances).each do |idx|
31
+ server(idx).chef_node.normal[:split_testing] = ( (idx % 2 == 0) ? 'A' : 'B' )
32
+ end
33
+ end
34
+
35
+ facet :dbnode do
36
+ instances 2
37
+ role "mysql_server"
38
+ role "redis_client"
39
+ # burly master, wussier slaves
40
+ cloud.flavor "m1.large"
41
+ server(0) do
42
+ cloud.flavor "c1.xlarge"
43
+ end
44
+
45
+ volume(:data) do
46
+ size 50
47
+ keep true
48
+ device '/dev/sdi'
49
+ mount_point '/data/db'
50
+ mount_options 'defaults,nouuid,noatime'
51
+ fstype 'xfs'
52
+ snapshot_id 'snap-d9c1edb1'
53
+ end
54
+ end
55
+
56
+ facet :esnode do
57
+ instances 1
58
+ role "nginx"
59
+ role "redis_server"
60
+ role "elasticsearch_data_esnode"
61
+ role "elasticsearch_http_esnode"
62
+ #
63
+ cloud.flavor "m1.large"
64
+ end
65
+ end
data/config/client.rb ADDED
@@ -0,0 +1,59 @@
1
+ require "ohai"
2
+ require "json"
3
+
4
+ #
5
+ # Load configuration
6
+ #
7
+
8
+ def merge_safely hsh
9
+ hsh.merge!( yield ) rescue Mash.new
10
+ end
11
+
12
+ def create_file_if_empty(filename, str)
13
+ unless File.exists?(filename)
14
+ puts "Populating #{filename}" ;
15
+ File.open(filename, "w", 0600){|f| f.puts(str) }
16
+ end
17
+ end
18
+
19
+ def present?(config, key)
20
+ not config[key].to_s.empty?
21
+ end
22
+
23
+ # Start with a set of defaults
24
+ chef_config = Mash.new
25
+
26
+ # Extract client configuration from EC2 user-data
27
+ OHAI_INFO = Ohai::System.new
28
+ OHAI_INFO.all_plugins
29
+ merge_safely(chef_config){ JSON.parse(OHAI_INFO[:ec2][:userdata]) }
30
+
31
+ #
32
+ # Configure chef run
33
+ #
34
+
35
+ log_level :info
36
+ log_location STDOUT
37
+ node_name chef_config["node_name"] if chef_config["node_name"]
38
+ chef_server_url chef_config["chef_server"] if chef_config["chef_server"]
39
+ validation_client_name chef_config["validation_client_name"] if chef_config["validation_client_name"]
40
+ validation_key "/etc/chef/validation.pem"
41
+ client_key "/etc/chef/client.pem"
42
+ node_attrs_file "/etc/chef/first-boot.json"
43
+
44
+ # If the client file is missing, write the validation key out so chef-client can register
45
+ unless File.exists?(client_key)
46
+ if present?(chef_config, "client_key") then create_file_if_empty(client_key, chef_config["client_key"])
47
+ elsif present?(chef_config, "validation_key") then create_file_if_empty(validation_key, chef_config["validation_key"])
48
+ else warn "Yikes -- I have no client key or validation key!!"
49
+ end
50
+ end
51
+
52
+ reduced_chef_config = chef_config.reject{|k,v| k.to_s =~ /(_key|run_list)$/ }
53
+ unless File.exists?(node_attrs_file)
54
+ create_file_if_empty(node_attrs_file, JSON.pretty_generate(reduced_chef_config))
55
+ end
56
+ json_attribs node_attrs_file
57
+
58
+ Chef::Log.debug(JSON.generate(chef_config))
59
+ Chef::Log.info("=> chef client #{node_name} on #{chef_server_url} in cluster +#{chef_config["cluster_name"]}+")
@@ -0,0 +1,78 @@
1
+ bash -c '
2
+
3
+ # This is the ubuntu-10.04-gems script from opscode, but it installs the chef-client service and kicks off the first run of chef
4
+
5
+ set -v
6
+
7
+ <%= "export http_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
8
+ eval `cat /etc/lsb-release `
9
+ export DEBIAN_FRONTEND=noninteractive
10
+
11
+ if [ ! -f /usr/bin/chef-client ]; then
12
+ apt-get update
13
+ apt-get install -y ruby ruby1.8-dev build-essential wget libruby-extras libruby1.8-extras
14
+ cd /tmp
15
+ wget <%= "--proxy=on " if knife_config[:bootstrap_proxy] %>http://production.cf.rubygems.org/rubygems/rubygems-1.6.2.tgz
16
+ tar zxf rubygems-1.6.2.tgz
17
+ cd rubygems-1.6.2
18
+ ruby setup.rb --no-format-executable
19
+ fi
20
+
21
+ gem update --no-rdoc --no-ri
22
+ gem install ohai --no-rdoc --no-ri --verbose
23
+ gem install chef --no-rdoc --no-ri --verbose <%= bootstrap_version_string %>
24
+
25
+ echo -e "`date` \n\n**** \n**** Knifing in the chef client config files:\n****\n"
26
+ mkdir -p /etc/chef
27
+
28
+ (
29
+ cat <<'EOP'
30
+ <%= validation_key %>
31
+ EOP
32
+ ) > /tmp/validation.pem
33
+ awk NF /tmp/validation.pem > /etc/chef/validation.pem
34
+ rm /tmp/validation.pem
35
+
36
+ echo -e "`date` \n\n**** \n**** Creating chef client script:\n****\n"
37
+
38
+ (
39
+ cat <<'EOP'
40
+ <%= config_content %>
41
+ EOP
42
+ ) > /etc/chef/client.rb
43
+
44
+ (
45
+ cat <<'EOP'
46
+ <%= { "run_list" => @run_list, "cluster_name" => @config[:node].cluster_name, "facet_name" => @config[:node].facet_name, "facet_index" => @config[:node].facet_index }.to_json %>
47
+ EOP
48
+ ) > /etc/chef/first-boot.json
49
+
50
+ echo -e "`date` \n\n**** \n**** Adding chef client runit scripts:\n****\n"
51
+ service chef-client stop 2>/dev/null ; sleep 1 ; killall chef-client 2>/dev/null
52
+ mkdir -p /var/log/chef /var/chef /etc/sv/chef-client/log/main /etc/sv/chef-client/supervise
53
+ cat > /etc/sv/chef-client/log/run <<EOF
54
+ #!/bin/bash
55
+ exec svlogd -tt ./main
56
+ EOF
57
+ cat > /etc/sv/chef-client/run <<EOF
58
+ #!/bin/bash
59
+ exec 2>&1
60
+ exec /usr/bin/env chef-client -i 43200 -s 20 -L /var/log/chef/client.log
61
+ EOF
62
+ chmod +x /etc/sv/chef-client/log/run /etc/sv/chef-client/run
63
+ ln -nfs /usr/bin/sv /etc/init.d/chef-client
64
+
65
+ <%- if (@config[:bootstrap_runs_chef_client].to_s == 'true') || (@chef_config.knife[:bootstrap_runs_chef_client].to_s == 'true') %>
66
+ echo -e "`date` \n\n**** \n**** First run of chef:\n****\n"
67
+ <%= start_chef %>
68
+ <%- end %>
69
+
70
+ echo -e "`date` \n\n**** \n**** Cleanup:\n****\n"
71
+ updatedb
72
+
73
+ echo -e "`date` \n\n**** \n**** Enabling chef client service:\n****\n"
74
+ ln -nfs /etc/sv/chef-client /etc/service/chef-client
75
+ service chef-client start
76
+
77
+ echo -e "`date` \n\n**** \n**** Cluster Chef client bootstrap complete\n****\n"
78
+ '
@@ -0,0 +1,139 @@
1
+ bash -c '
2
+
3
+ # This is the ubuntu-10.04-gems script from opscode, but it
4
+ # * installs ruby 1.9.2, not 1.8.7
5
+ # * upgrades rubygems rather than installing from source
6
+ # * pushes the node identity into the first-boot.json
7
+ # * installs the chef-client service and kicks off the first run of chef
8
+
9
+ <%= (@config[:verbosity].to_i > 1 ? 'set -v' : '') %>
10
+
11
+ mkdir -p /tmp/knife-bootstrap ; chmod 700 /tmp/knife-bootstrap
12
+ cd /tmp/knife-bootstrap
13
+
14
+ RUBY_VERSION=1.9.2-p290
15
+
16
+ <%= "export http_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
17
+ eval `cat /etc/lsb-release `
18
+ export DEBIAN_FRONTEND=noninteractive
19
+
20
+ if [ ! -f /usr/bin/chef-client ]; then
21
+ echo -e "`date` \n\n**** \n**** apt update:\n****\n"
22
+ apt-get update
23
+ apt-get -y upgrade
24
+
25
+ echo -e "`date` \n\n**** \n**** Installing base packages:\n****\n"
26
+ apt-get install -y build-essential wget runit runit-services zlib1g-dev libssl-dev openssl libcurl4-openssl-dev libreadline6-dev libyaml-dev
27
+
28
+ echo -e "`date` \n\n**** \n**** Installing ruby version ${RUBY_VERSION}:\n****\n"
29
+
30
+ wget ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-${RUBY_VERSION}.tar.gz
31
+ tar xzf ruby-${RUBY_VERSION}.tar.gz
32
+ cd ruby-${RUBY_VERSION}
33
+ ./configure --with-ruby-version=${RUBY_VERSION} --prefix=/usr --program-suffix=${RUBY_VERSION}
34
+ make -j2
35
+ make install
36
+
37
+ sudo update-alternatives --remove-all gem && true
38
+ update-alternatives \
39
+ --install /usr/bin/ruby ruby /usr/bin/ruby${RUBY_VERSION} 400 \
40
+ --slave /usr/bin/ri ri /usr/bin/ri${RUBY_VERSION} \
41
+ --slave /usr/bin/irb irb /usr/bin/irb${RUBY_VERSION} \
42
+ --slave /usr/bin/erb erb /usr/bin/erb${RUBY_VERSION} \
43
+ --slave /usr/bin/gem gem /usr/bin/gem${RUBY_VERSION} \
44
+ --slave /usr/share/man/man1/ruby.1.gz ruby.1.gz \
45
+ /usr/share/man/man1/ruby${RUBY_VERSION}.1
46
+
47
+ if ruby -e "exit(%x{gem --version} < \"1.6.2\" ? 0 : -1 )" ; then
48
+ echo -e "`date` \n\n**** \n**** Updating rubygems:\n****\n"
49
+ gem install --no-rdoc --no-ri rubygems-update --version=1.6.2
50
+ update_rubygems --version=1.6.2
51
+ fi
52
+
53
+ echo -e "`date` \n\n**** \n**** Installing chef:\n****\n"
54
+ gem install ohai --no-rdoc --no-ri
55
+ gem install chef --no-rdoc --no-ri <%= bootstrap_version_string %>
56
+ gem install --no-rdoc --no-ri extlib json ruby-shadow right_aws
57
+
58
+ else # no chef-client
59
+ echo -e "`date` \n\n**** \n**** Chef is present -- skipping apt/ruby/chef installation\n****\n"
60
+ fi
61
+
62
+ # fix a bug in chef that prevents debugging template errors
63
+ bad_template_file='/usr/lib/ruby/gems/1.9.2-p290/gems/chef-0.10.4/lib/chef/mixin/template.rb'
64
+ if echo "0505c482b8b0b333ac71bbc8a1795d19 $bad_template_file" | md5sum -c - 2>/dev/null ; then
65
+ curl https://github.com/mrflip/chef/commit/655a1967253a8759afb54f30b818bbcb7c309198.patch | sudo patch $bad_template_file
66
+ fi
67
+
68
+ echo -e "`date` \n\n**** \n**** Knifing in the chef client config files:\n****\n"
69
+ mkdir -p /etc/chef
70
+
71
+ <%- if @config[:client_key] %>
72
+ (
73
+ cat <<'EOP'
74
+ <%= @config[:client_key] %>
75
+ EOP
76
+ ) > /tmp/knife-bootstrap/client.pem
77
+ awk NF /tmp/knife-bootstrap/client.pem > /etc/chef/client.pem
78
+ <%- else %>
79
+ (
80
+ cat <<'EOP'
81
+ <%= validation_key %>
82
+ EOP
83
+ ) > /tmp/knife-bootstrap/validation.pem
84
+ awk NF /tmp/knife-bootstrap/validation.pem > /etc/chef/validation.pem
85
+ <%- end %>
86
+
87
+ echo -e "`date` \n\n**** \n**** Nuking our temp files:\n****\n"
88
+
89
+ cd /tmp
90
+ # rm -rf /tmp/knife-bootstrap
91
+
92
+ echo -e "`date` \n\n**** \n**** Creating chef client script:\n****\n"
93
+
94
+ (
95
+ cat <<'EOP'
96
+ <%= config_content %>
97
+ <%= @config[:node].chef_client_script_content %>
98
+ EOP
99
+ ) > /etc/chef/client.rb
100
+
101
+ (
102
+ cat <<'EOP'
103
+ <%= { "run_list" => @run_list, "cluster_name" => @config[:node].cluster_name, "facet_name" => @config[:node].facet_name, "facet_index" => @config[:node].facet_index }.to_json %>
104
+ EOP
105
+ ) > /etc/chef/first-boot.json
106
+
107
+ echo -e "`date` \n\n**** \n**** Adding chef client runit scripts:\n****\n"
108
+ service chef-client stop >/dev/null 2>&1 ; sleep 1 ; killall chef-client 2>/dev/null ; true
109
+ mkdir -p /var/log/chef /var/chef /etc/service /etc/sv/chef-client/{log/main,supervise}
110
+ cat > /etc/sv/chef-client/log/run <<EOF
111
+ #!/bin/bash
112
+ exec svlogd -tt ./main
113
+ EOF
114
+ cat > /etc/sv/chef-client/run <<EOF
115
+ #!/bin/bash
116
+ exec 2>&1
117
+ exec /usr/bin/env chef-client -i 43200 -s 20 -L /var/log/chef/client.log
118
+ EOF
119
+ chmod +x /etc/sv/chef-client/log/run /etc/sv/chef-client/run
120
+ ln -nfs /usr/bin/sv /etc/init.d/chef-client
121
+
122
+ service chef-client stop ; true
123
+
124
+ <%- if (@config[:bootstrap_runs_chef_client].to_s == 'true') || (@chef_config.knife[:bootstrap_runs_chef_client].to_s == 'true') %>
125
+ echo -e "`date` \n\n**** \n**** First run of chef:\n****\n"
126
+ set -e
127
+ <%= start_chef %>
128
+ set +e
129
+ <%- end %>
130
+
131
+ echo -e "`date` \n\n**** \n**** Cleanup:\n****\n"
132
+ updatedb
133
+
134
+ echo -e "`date` \n\n**** \n**** Enabling chef client service:\n****\n"
135
+ ln -nfs /etc/sv/chef-client /etc/service/chef-client
136
+ service chef-client start
137
+
138
+ echo -e "`date` \n\n**** \n**** Cluster Chef client bootstrap complete\n****\n"
139
+ '