knife-solo 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@ class Chef
14
14
  include KnifeSolo::SshCommand
15
15
  include KnifeSolo::KitchenCommand
16
16
 
17
- banner "knife prepare [user@]hostname [json] (options)"
17
+ banner "knife cook [user@]hostname [json] (options)"
18
18
 
19
19
  def run
20
20
  super
@@ -31,7 +31,7 @@ class Chef
31
31
 
32
32
  logging_arg = "-l debug" if config[:verbosity] > 0
33
33
  stream_command <<-BASH
34
- sudo chef-solo -c #{chef_path}/solo.rb \
34
+ #{sudo} chef-solo -c #{chef_path}/solo.rb \
35
35
  -j #{chef_path}/#{node_config} \
36
36
  #{logging_arg}
37
37
  BASH
@@ -1,6 +1,7 @@
1
1
  require 'chef/knife'
2
2
  require 'knife-solo/ssh_command'
3
3
  require 'knife-solo/kitchen_command'
4
+ require 'knife-solo/bootstraps'
4
5
 
5
6
  class Chef
6
7
  class Knife
@@ -14,10 +15,14 @@ class Chef
14
15
 
15
16
  def run
16
17
  super
17
- send("#{distro[:type]}_gem_install")
18
+ bootstrap.bootstrap!
18
19
  generate_node_config
19
20
  end
20
21
 
22
+ def bootstrap
23
+ KnifeSolo::Bootstraps.class_for_operating_system(operating_system()).new(self)
24
+ end
25
+
21
26
  def generate_node_config
22
27
  File.open(node_config, 'w') do |f|
23
28
  f.print <<-JSON.gsub(/^\s+/, '')
@@ -26,98 +31,14 @@ class Chef
26
31
  end unless node_config.exist?
27
32
  end
28
33
 
29
- def package_list
30
- @packages.join(' ')
31
- end
32
-
33
- def zypper_gem_install
34
- ui.msg("Installing required packages...")
35
- run_command("sudo zypper --non-interactive install ruby-devel make gcc rsync")
36
- gem_install
37
- end
38
-
39
- def emerge_gem_install
40
- ui.msg("Installing required packages...")
41
- run_command("sudo USE='-test' ACCEPT_KEYWORDS='~amd64' emerge -u chef")
42
- end
43
-
44
- def add_yum_repos
45
- ui.message("Adding EPEL and ELFF...")
46
- repo_url = "http://download.fedora.redhat.com"
47
- repo_path = "/pub/epel/5/i386/epel-release-5-4.noarch.rpm"
48
- result = run_command("sudo rpm -Uvh #{repo_url}#{repo_path}")
49
- installed = "package epel-release-5-4.noarch is already installed"
50
- raise result.stderr unless result.success? || result.stdout.match(installed)
51
-
52
- repo_url = "http://download.elff.bravenet.com"
53
- repo_path = "/5/i386/elff-release-5-3.noarch.rpm"
54
- result = run_command("sudo rpm -Uvh #{repo_url}#{repo_path}")
55
- installed = "package elff-release-5-3.noarch is already installed"
56
- raise result.stderr unless result.success? || result.stdout.match(installed)
57
- end
58
-
59
- def yum_gem_install
60
- ui.msg("Installing required packages...")
61
- @packages = %w(ruby ruby-shadow gcc gcc-c++ ruby-devel wget rsync)
62
- run_command("sudo yum -y install #{package_list}")
63
- gem_install
64
- end
65
-
66
- def debian_gem_install
67
- ui.msg "Updating apt caches..."
68
- run_command("sudo apt-get update")
69
-
70
- ui.msg "Installing required packages..."
71
- @packages = %w(ruby ruby-dev libopenssl-ruby irb
72
- build-essential wget ssl-cert rsync)
73
- run_command <<-BASH
74
- sudo DEBIAN_FRONTEND=noninteractive apt-get --yes install #{package_list}
75
- BASH
76
-
77
- gem_install
78
- end
79
-
80
- def gem_install
81
- ui.msg "Installing rubygems from source..."
82
- release = "rubygems-1.8.10"
83
- file = "#{release}.tgz"
84
- url = "http://production.cf.rubygems.org/rubygems/#{file}"
85
- run_command("wget #{url}")
86
- run_command("tar zxf #{file}")
87
- run_command("cd #{release} && sudo ruby setup.rb --no-format-executable")
88
- run_command("sudo rm -rf #{release} #{file}")
89
- run_command("sudo gem install --no-rdoc --no-ri chef")
34
+ def operating_system
35
+ @operating_system ||= begin
36
+ run_command('uname -s').stdout.strip
37
+ rescue
38
+ ""
39
+ end
90
40
  end
91
41
 
92
- def issue
93
- run_command("cat /etc/issue").stdout
94
- end
95
-
96
- def distro
97
- @distro ||= case issue
98
- when %r{Debian GNU/Linux 5}
99
- {:type => "debian", :version => "lenny"}
100
- when %r{Debian GNU/Linux 6}
101
- {:type => "debian", :version => "squeeze"}
102
- when %r{Debian GNU/Linux wheezy}
103
- {:type => "debian", :version => "wheezy"}
104
- when %r{Ubuntu}
105
- version = run_command("lsb_release -cs").stdout.strip
106
- {:type => "debian", :version => version}
107
- when %r{CentOS}
108
- {:type => "yum", :version => "CentOS"}
109
- when %r{Red Hat Enterprise Linux}
110
- {:type => "yum", :version => "Red Hat"}
111
- when %r{Scientific Linux SL}
112
- {:type => "yum", :version => "Scientific Linux"}
113
- when %r{openSUSE 11.4}
114
- {:type => "zypper", :version => "openSUSE"}
115
- when %r{This is \\n\.\\O (\\s \\m \\r) \\t}
116
- {:type => "gentoo", :version => "Gentoo"}
117
- else
118
- raise "Distro not recognized from looking at /etc/issue. Please fork https://github.com/matschaffer/knife-solo and add support for your distro."
119
- end
120
- end
121
42
  end
122
43
  end
123
44
  end
@@ -0,0 +1,90 @@
1
+ class OperatingSystemNotSupportedError < StandardError ; end
2
+
3
+ module KnifeSolo
4
+ module Bootstraps
5
+ class OperatingSystemNotImplementedError < StandardError
6
+ end
7
+
8
+ def self.class_exists_for?(os_name)
9
+ begin
10
+ true if self.class_for_operating_system(os_name).class == Class
11
+ rescue => exception
12
+ false
13
+ end
14
+ end
15
+
16
+ def self.class_for_operating_system(os_name)
17
+ begin
18
+ os_class_name = os_name.gsub(/\s/,'')
19
+ eval("KnifeSolo::Bootstraps::#{os_class_name}")
20
+ rescue
21
+ raise OperatingSystemNotImplementedError.new("#{os_name} not implemented. Feel free to add a bootstrap implementation in KnifeSolo::Bootstraps::#{os_class_name}")
22
+ end
23
+ end
24
+
25
+ module Delegates
26
+ def run_command(cmd)
27
+ prepare.run_command(cmd)
28
+ end
29
+
30
+ def ui
31
+ prepare.ui
32
+ end
33
+
34
+ def prepare
35
+ @prepare
36
+ end
37
+ end #Delegates
38
+
39
+ module InstallCommands
40
+
41
+ def bootstrap!
42
+ run_pre_bootstrap_checks()
43
+ send("#{distro[:type]}_install")
44
+ end
45
+
46
+ def distro
47
+ raise "implement distro detection for #{self.class.name}"
48
+ end
49
+
50
+ def gem_packages
51
+ raise "implement gem packages for #{self.class.name}"
52
+ end
53
+
54
+ def http_client_get_url(url)
55
+ "wget #{url}"
56
+ end
57
+
58
+ def gem_install
59
+ ui.msg "Installing rubygems from source..."
60
+ release = "rubygems-1.8.10"
61
+ file = "#{release}.tgz"
62
+ url = "http://production.cf.rubygems.org/rubygems/#{file}"
63
+ run_command(http_client_get_url(url))
64
+ run_command("tar zxf #{file}")
65
+ run_command("cd #{release} && sudo ruby setup.rb --no-format-executable")
66
+ run_command("sudo rm -rf #{release} #{file}")
67
+ run_command("sudo gem install --no-rdoc --no-ri #{gem_packages().join(' ')}")
68
+ end
69
+ end #InstallCommands
70
+
71
+ class Base
72
+ include KnifeSolo::Bootstraps::Delegates
73
+ include KnifeSolo::Bootstraps::InstallCommands
74
+
75
+ def initialize(prepare)
76
+ # instance of Chef::Knife::Prepare
77
+ @prepare = prepare
78
+ end
79
+
80
+ def run_pre_bootstrap_checks ; end
81
+ # run right before we run #{distro[:type]}_install method
82
+ # barf out here if need be
83
+ end
84
+
85
+ end # Bootstraps
86
+ end
87
+
88
+
89
+ # bootstrap classes for different OSes
90
+ Dir[File.dirname(__FILE__) + '/bootstraps/*.rb'].each {|p| require p}
@@ -0,0 +1,38 @@
1
+ module KnifeSolo::Bootstraps
2
+ class Darwin < Base
3
+
4
+ def issue
5
+ run_command("sw_vers -productVersion").stdout.strip
6
+ end
7
+
8
+ def gem_packages
9
+ ['chef']
10
+ end
11
+
12
+ def distro
13
+ case issue
14
+ when %r{10.5}
15
+ {:type => 'gem', :version => 'leopard'}
16
+ when %r{10.6}
17
+ {:type => 'gem', :version => 'snow_leopard'}
18
+ else
19
+ raise "OSX version #{issue} not supported"
20
+ end
21
+ end
22
+
23
+ def has_xcode_installed?
24
+ result = run_command("xcodebuild -version")
25
+ result.success?
26
+ end
27
+
28
+ def http_client_get_url(url)
29
+ filename = url.split("/").last
30
+ "curl '#{url}' >> #{filename}"
31
+ end
32
+
33
+ def run_pre_bootstrap_checks
34
+ raise 'xcode not installed, which is required to do anything. please install and run again.' unless has_xcode_installed?
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,102 @@
1
+ module KnifeSolo::Bootstraps
2
+ class Linux < Base
3
+
4
+ def issue
5
+ prepare.run_command("cat /etc/issue").stdout.strip
6
+ end
7
+
8
+ def package_list
9
+ @packages.join(' ')
10
+ end
11
+
12
+ def gem_packages
13
+ ['ruby-shadow','chef']
14
+ end
15
+
16
+ def http_client_get_url(url)
17
+ "wget #{url}"
18
+ end
19
+
20
+ def zypper_gem_install
21
+ ui.msg("Installing required packages...")
22
+ run_command("sudo zypper --non-interactive install ruby-devel make gcc rsync")
23
+ gem_install
24
+ end
25
+
26
+ def emerge_gem_install
27
+ ui.msg("Installing required packages...")
28
+ run_command("sudo USE='-test' ACCEPT_KEYWORDS='~amd64' emerge -u chef")
29
+ end
30
+
31
+ def add_yum_repos
32
+ repo_url = "http://rbel.co/"
33
+ if distro[:version] == "RHEL5"
34
+ repo_path = "/rbel5"
35
+ else
36
+ repo_path = "/rbel6"
37
+ end
38
+ installed = "is already installed"
39
+ result = run_command("#{sudo} rpm -Uvh #{repo_url}#{repo_path}")
40
+ raise result.stderr_or_stdout unless result.success? || result.stdout.match(installed)
41
+ end
42
+
43
+ def yum_install
44
+ ui.msg("Installing required packages...")
45
+ add_yum_repos
46
+ @packages = %w(rubygem-chef rsync)
47
+ run_command("#{sudo} yum -y install #{package_list}")
48
+ end
49
+
50
+ def debian_gem_install
51
+ ui.msg "Updating apt caches..."
52
+ run_command("sudo apt-get update")
53
+
54
+ ui.msg "Installing required packages..."
55
+ @packages = %w(ruby ruby-dev libopenssl-ruby irb
56
+ build-essential wget ssl-cert rsync)
57
+ run_command <<-BASH
58
+ sudo DEBIAN_FRONTEND=noninteractive apt-get --yes install #{package_list}
59
+ BASH
60
+
61
+ gem_install
62
+ end
63
+
64
+ def distro
65
+ return @distro if @distro
66
+ @distro = case issue
67
+ when %r{Debian GNU/Linux 5}
68
+ {:type => "debian_gem", :version => "lenny"}
69
+ when %r{Debian GNU/Linux 6}
70
+ {:type => "debian_gem", :version => "squeeze"}
71
+ when %r{Debian GNU/Linux wheezy}
72
+ {:type => "debian_gem", :version => "wheezy"}
73
+ when %r{Ubuntu}
74
+ version = run_command("lsb_release -cs").stdout.strip
75
+ {:type => "debian_gem", :version => version}
76
+ when %r{CentOS.*? 5}
77
+ {:type => "yum", :version => "RHEL5"}
78
+ when %r{CentOS.*? 6}
79
+ {:type => "yum", :version => "RHEL6"}
80
+ when %r{Red Hat Enterprise.*? 5}
81
+ {:type => "yum", :version => "RHEL5"}
82
+ when %r{Red Hat Enterprise.*? 6}
83
+ {:type => "yum", :version => "RHEL6"}
84
+ when %r{Scientific Linux.*? 5}
85
+ {:type => "yum", :version => "RHEL5"}
86
+ when %r{Scientific Linux.*? 6}
87
+ {:type => "yum", :version => "RHEL6"}
88
+ when %r{SUSE Linux Enterprise Server 11 SP1}
89
+ {:type => "zypper_gem", :version => "SLES11"}
90
+ when %r{openSUSE 11.4}
91
+ {:type => "zypper_gem", :version => "openSUSE"}
92
+ when %r{This is \\n\.\\O (\\s \\m \\r) \\t}
93
+ {:type => "gentoo_gem", :version => "Gentoo"}
94
+ else
95
+ raise "Distro not recognized from looking at /etc/issue. Please fork https://github.com/matschaffer/knife-solo and add support for your distro."
96
+ end
97
+ Chef::Log.debug("Distro detection yielded: #{@distro}")
98
+ @distro
99
+ end #issue
100
+
101
+ end
102
+ end
@@ -1,5 +1,5 @@
1
1
  module KnifeSolo
2
2
  def self.version
3
- '0.0.5'
3
+ '0.0.6'
4
4
  end
5
5
  end
@@ -11,8 +11,11 @@ module KnifeSolo
11
11
  end
12
12
 
13
13
  def run
14
- all_present = required_files.inject(true) { |m, f| m && File.exists?(f) }
15
- raise OutOfKitchenError.new unless all_present
14
+ raise OutOfKitchenError.new unless required_files_present?
15
+ end
16
+
17
+ def required_files_present?
18
+ required_files.inject(true) { |m, f| m && File.exists?(f) }
16
19
  end
17
20
  end
18
21
  end
@@ -116,6 +116,23 @@ module KnifeSolo
116
116
  def success?
117
117
  exit_code == 0
118
118
  end
119
+
120
+ # Helper to use when raising exceptions since some operations
121
+ # (e.g., command not found) error on stdout
122
+ def stderr_or_stdout
123
+ return stderr unless stderr.empty?
124
+ stdout
125
+ end
126
+ end
127
+
128
+ def sudo
129
+ return @sudo if @sudo
130
+ if run_command("sudo -V").success?
131
+ @sudo = "sudo"
132
+ else
133
+ Chef::Log.debug("`sudo` not available on #{host}")
134
+ @sudo = ""
135
+ end
119
136
  end
120
137
 
121
138
  def stream_command(command)
@@ -125,6 +142,7 @@ module KnifeSolo
125
142
  def run_command(command, options={})
126
143
  detect_authentication_method
127
144
 
145
+ Chef::Log.debug("Running command #{command}")
128
146
  result = ExecResult.new
129
147
  command = command.sub(/^\s*sudo/, 'sudo -p \'knife sudo password: \'')
130
148
  Net::SSH.start(host, user, connection_options) do |ssh|
@@ -137,6 +155,7 @@ module KnifeSolo
137
155
  if data =~ /^knife sudo password: /
138
156
  ch.send_data("#{password}\n")
139
157
  else
158
+ Chef::Log.debug("#{command} stdout: #{data}")
140
159
  ui.stdout << data if options[:streaming]
141
160
  result.stdout << data
142
161
  end
@@ -144,6 +163,7 @@ module KnifeSolo
144
163
 
145
164
  channel.on_extended_data do |ch, type, data|
146
165
  next unless type == 1
166
+ Chef::Log.debug("#{command} stderr: #{data}")
147
167
  ui.stderr << data if options[:streaming]
148
168
  result.stderr << data
149
169
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-solo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-31 00:00:00.000000000Z
12
+ date: 2011-12-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70331323547300 !ruby/object:Gem::Requirement
16
+ requirement: &70322401955880 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70331323547300
24
+ version_requirements: *70322401955880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mocha
27
- requirement: &70331323543340 !ruby/object:Gem::Requirement
27
+ requirement: &70322401955420 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70331323543340
35
+ version_requirements: *70322401955420
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: virtualbox
38
- requirement: &70331323532360 !ruby/object:Gem::Requirement
38
+ requirement: &70322401954980 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70331323532360
46
+ version_requirements: *70322401954980
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: chef
49
- requirement: &70331323530880 !ruby/object:Gem::Requirement
49
+ requirement: &70322401978760 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.10.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70331323530880
57
+ version_requirements: *70322401978760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: net-ssh
60
- requirement: &70331323528620 !ruby/object:Gem::Requirement
60
+ requirement: &70322401978200 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: 2.1.3
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70331323528620
68
+ version_requirements: *70322401978200
69
69
  description: Handles bootstrapping, running chef solo, rsyncing cookbooks etc
70
70
  email: mat@schaffer.me
71
71
  executables: []
@@ -77,6 +77,9 @@ files:
77
77
  - lib/chef/knife/patches/parser.rb
78
78
  - lib/chef/knife/patches/search_patch.rb
79
79
  - lib/chef/knife/prepare.rb
80
+ - lib/knife-solo/bootstraps/darwin.rb
81
+ - lib/knife-solo/bootstraps/linux.rb
82
+ - lib/knife-solo/bootstraps.rb
80
83
  - lib/knife-solo/info.rb
81
84
  - lib/knife-solo/kitchen_command.rb
82
85
  - lib/knife-solo/ssh_command.rb
@@ -101,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
104
  version: '0'
102
105
  requirements: []
103
106
  rubyforge_project: nowarning
104
- rubygems_version: 1.8.6
107
+ rubygems_version: 1.8.10
105
108
  signing_key:
106
109
  specification_version: 3
107
110
  summary: A collection of knife plugins for dealing with chef solo