knife-solo 0.0.14 → 0.0.15
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/lib/chef/knife/cook.rb +34 -54
- data/lib/chef/knife/kitchen.rb +31 -6
- data/lib/chef/knife/prepare.rb +9 -14
- data/lib/chef/knife/wash_up.rb +1 -0
- data/lib/knife-solo/bootstraps.rb +11 -4
- data/lib/knife-solo/bootstraps/linux.rb +9 -4
- data/lib/knife-solo/info.rb +1 -1
- data/lib/knife-solo/kitchen_command.rb +1 -13
- data/lib/knife-solo/node_config_command.rb +40 -0
- data/lib/knife-solo/ssh_command.rb +29 -8
- metadata +3 -8
data/lib/chef/knife/cook.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
|
3
1
|
require 'chef/knife'
|
4
|
-
require 'chef/config'
|
5
|
-
require 'chef/cookbook/chefignore'
|
6
2
|
|
7
3
|
require 'knife-solo/ssh_command'
|
8
4
|
require 'knife-solo/kitchen_command'
|
5
|
+
require 'knife-solo/node_config_command'
|
9
6
|
require 'knife-solo/tools'
|
10
7
|
|
11
8
|
class Chef
|
@@ -14,13 +11,20 @@ class Chef
|
|
14
11
|
# Copyright 2009, Trotter Cashion
|
15
12
|
class Cook < Knife
|
16
13
|
OMNIBUS_EMBEDDED_PATHS = ["/opt/chef/embedded/bin", "/opt/opscode/embedded/bin"]
|
14
|
+
OMNIBUS_EMBEDDED_GEM_PATHS = ["/opt/chef/embedded/lib/ruby/gems/1.9.1", "/opt/opscode/embedded/lib/ruby/gems/1.9.1"]
|
17
15
|
CHEF_VERSION_CONSTRAINT = ">=0.10.4"
|
18
16
|
|
19
17
|
include KnifeSolo::SshCommand
|
20
18
|
include KnifeSolo::KitchenCommand
|
19
|
+
include KnifeSolo::NodeConfigCommand
|
21
20
|
include KnifeSolo::Tools
|
22
21
|
|
23
|
-
|
22
|
+
deps do
|
23
|
+
require 'chef/cookbook/chefignore'
|
24
|
+
require 'pathname'
|
25
|
+
KnifeSolo::SshCommand.load_deps
|
26
|
+
KnifeSolo::NodeConfigCommand.load_deps
|
27
|
+
end
|
24
28
|
|
25
29
|
banner "knife cook [user@]hostname [json] (options)"
|
26
30
|
|
@@ -34,53 +38,25 @@ class Chef
|
|
34
38
|
:boolean => false,
|
35
39
|
:description => "Only sync the cookbook - do not run Chef"
|
36
40
|
|
37
|
-
option :
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
+
option :why_run,
|
42
|
+
:short => '-W',
|
43
|
+
:long => '--why-run',
|
44
|
+
:boolean => true,
|
45
|
+
:description => "Enable whyrun mode"
|
41
46
|
|
42
|
-
option :syntax_check_only,
|
43
|
-
:long => '--syntax-check-only',
|
44
|
-
:boolean => true,
|
45
|
-
:description => "Only run syntax checks - do not run Chef"
|
46
|
-
|
47
47
|
def run
|
48
48
|
time('Run') do
|
49
49
|
validate_params!
|
50
50
|
super
|
51
|
-
check_syntax unless config[:skip_syntax_check]
|
52
|
-
return if config[:syntax_check_only]
|
53
51
|
Chef::Config.from_file('solo.rb')
|
54
52
|
check_chef_version unless config[:skip_chef_check]
|
53
|
+
generate_node_config
|
55
54
|
rsync_kitchen
|
56
55
|
add_patches
|
57
56
|
cook unless config[:sync_only]
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
|
-
def check_syntax
|
62
|
-
ui.msg('Checking cookbook syntax...')
|
63
|
-
chefignore.remove_ignores_from(Dir["**/*.rb"]).each do |recipe|
|
64
|
-
ok = system "ruby -c #{recipe} >/dev/null 2>&1"
|
65
|
-
raise "Syntax error in #{recipe}" if not ok
|
66
|
-
end
|
67
|
-
|
68
|
-
chefignore.remove_ignores_from(Dir["**/*.json"]).each do |json|
|
69
|
-
begin
|
70
|
-
require 'json'
|
71
|
-
# parse without instantiating Chef classes
|
72
|
-
JSON.parse File.read(json), :create_additions => false
|
73
|
-
rescue => error
|
74
|
-
raise "Syntax error in #{json}: #{error.message}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
Chef::Log.info "cookbook and json syntax is ok"
|
78
|
-
end
|
79
|
-
|
80
|
-
def node_config
|
81
|
-
@name_args[1] || super
|
82
|
-
end
|
83
|
-
|
84
60
|
def chef_path
|
85
61
|
Chef::Config.file_cache_path
|
86
62
|
end
|
@@ -103,26 +79,30 @@ class Chef
|
|
103
79
|
(%w{revision-deploys tmp '.*'} + chefignore.ignores).uniq
|
104
80
|
end
|
105
81
|
|
82
|
+
def debug?
|
83
|
+
config[:verbosity] and config[:verbosity] > 0
|
84
|
+
end
|
85
|
+
|
106
86
|
# Time a command
|
107
87
|
def time(msg)
|
108
|
-
return yield
|
109
|
-
|
88
|
+
return yield unless debug?
|
89
|
+
ui.msg "Starting '#{msg}'"
|
110
90
|
start = Time.now
|
111
91
|
yield
|
112
|
-
|
92
|
+
ui.msg "#{msg} finished in #{Time.now - start} seconds"
|
113
93
|
end
|
114
94
|
|
115
95
|
def rsync_kitchen
|
116
96
|
time('Rsync kitchen') do
|
117
97
|
cmd = %Q{rsync -rl --rsh="ssh #{ssh_args}" --delete #{rsync_exclude.collect{ |ignore| "--exclude #{ignore} " }.join} ./ :#{adjust_rsync_path(chef_path)}}
|
118
|
-
|
98
|
+
ui.msg cmd if debug?
|
119
99
|
system! cmd
|
120
100
|
end
|
121
101
|
end
|
122
102
|
|
123
103
|
def add_patches
|
124
104
|
run_portable_mkdir_p(patch_path)
|
125
|
-
Dir[Pathname.new(__FILE__).dirname.join("patches", "*.rb")].each do |patch|
|
105
|
+
Dir[Pathname.new(__FILE__).dirname.join("patches", "*.rb").to_s].each do |patch|
|
126
106
|
time(patch) do
|
127
107
|
system! %Q{rsync -rl --rsh="ssh #{ssh_args}" #{patch} :#{adjust_rsync_path(patch_path)}}
|
128
108
|
end
|
@@ -130,28 +110,28 @@ class Chef
|
|
130
110
|
end
|
131
111
|
|
132
112
|
def check_chef_version
|
133
|
-
ui.msg
|
113
|
+
ui.msg "Checking Chef version..."
|
134
114
|
result = run_command <<-BASH
|
135
115
|
export PATH="#{OMNIBUS_EMBEDDED_PATHS.join(":")}:$PATH"
|
116
|
+
export GEM_PATH="#{OMNIBUS_EMBEDDED_GEM_PATHS.join(":")}:$GEM_PATH"
|
136
117
|
ruby -rubygems -e "gem 'chef', '#{CHEF_VERSION_CONSTRAINT}'"
|
137
118
|
BASH
|
138
119
|
raise "Couldn't find Chef #{CHEF_VERSION_CONSTRAINT} on #{host}. Please run `#{$0} prepare #{ssh_args}` to ensure Chef is installed and up to date." unless result.success?
|
139
120
|
end
|
140
|
-
|
121
|
+
|
141
122
|
def cook
|
142
|
-
|
123
|
+
cmd = "sudo chef-solo -c #{chef_path}/solo.rb -j #{chef_path}/#{node_config}"
|
124
|
+
cmd << " -l debug" if debug?
|
125
|
+
cmd << " -N #{config[:chef_node_name]}" if config[:chef_node_name]
|
126
|
+
cmd << " -W" if config[:why_run]
|
143
127
|
|
144
|
-
stream_command
|
145
|
-
sudo chef-solo -c #{chef_path}/solo.rb \
|
146
|
-
-j #{chef_path}/#{node_config} \
|
147
|
-
#{logging_arg}
|
148
|
-
BASH
|
128
|
+
stream_command cmd
|
149
129
|
end
|
150
130
|
|
151
131
|
def validate_params!
|
152
|
-
validate_first_cli_arg_is_a_hostname!
|
132
|
+
validate_first_cli_arg_is_a_hostname!
|
153
133
|
end
|
154
|
-
|
134
|
+
|
155
135
|
end
|
156
136
|
end
|
157
137
|
end
|
data/lib/chef/knife/kitchen.rb
CHANGED
@@ -5,16 +5,41 @@ class Chef
|
|
5
5
|
class Kitchen < Knife
|
6
6
|
include FileUtils
|
7
7
|
|
8
|
+
deps do
|
9
|
+
require 'knife-solo/knife_solo_error'
|
10
|
+
end
|
11
|
+
|
8
12
|
banner "knife kitchen NAME or initialize current directory with '.'"
|
9
13
|
|
10
14
|
def run
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
raise KnifeSolo::KnifeSoloError.new(banner) unless base = @name_args.first
|
16
|
+
|
17
|
+
create_kitchen base
|
18
|
+
create_cupboards base, %w(nodes roles data_bags site-cookbooks cookbooks)
|
19
|
+
create_solo_config base
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def create_cupboards(base, dirs)
|
25
|
+
dirs.each do |dir|
|
26
|
+
cupboard_dir = File.join(base, dir)
|
27
|
+
unless File.exist?(cupboard_dir)
|
28
|
+
mkdir cupboard_dir
|
29
|
+
touch File.join(cupboard_dir, '.gitkeep')
|
30
|
+
end
|
16
31
|
end
|
17
|
-
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_kitchen(base)
|
35
|
+
mkdir base unless base == '.'
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_solo_config(base)
|
39
|
+
solo_file = File.join(base, 'solo.rb')
|
40
|
+
return if File.exist? solo_file
|
41
|
+
|
42
|
+
File.open(solo_file, 'w') do |f|
|
18
43
|
f << <<-RUBY.gsub(/^ {12}/, '')
|
19
44
|
file_cache_path "/tmp/chef-solo"
|
20
45
|
data_bag_path "/tmp/chef-solo/data_bags"
|
data/lib/chef/knife/prepare.rb
CHANGED
@@ -1,8 +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/
|
5
|
-
require 'knife-solo/knife_solo_error'
|
4
|
+
require 'knife-solo/node_config_command'
|
6
5
|
|
7
6
|
class Chef
|
8
7
|
class Knife
|
@@ -11,12 +10,15 @@ class Chef
|
|
11
10
|
class Prepare < Knife
|
12
11
|
include KnifeSolo::SshCommand
|
13
12
|
include KnifeSolo::KitchenCommand
|
13
|
+
include KnifeSolo::NodeConfigCommand
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
deps do
|
16
|
+
require 'knife-solo/bootstraps'
|
17
|
+
KnifeSolo::SshCommand.load_deps
|
18
|
+
KnifeSolo::NodeConfigCommand.load_deps
|
17
19
|
end
|
18
20
|
|
19
|
-
banner "knife prepare [user@]hostname (options)"
|
21
|
+
banner "knife prepare [user@]hostname [json] (options)"
|
20
22
|
|
21
23
|
option :omnibus_version,
|
22
24
|
:long => "--omnibus-version VERSION",
|
@@ -38,23 +40,16 @@ class Chef
|
|
38
40
|
end
|
39
41
|
|
40
42
|
def bootstrap
|
43
|
+
ui.msg "Bootstrapping Chef..."
|
41
44
|
KnifeSolo::Bootstraps.class_for_operating_system(operating_system()).new(self)
|
42
45
|
end
|
43
46
|
|
44
|
-
def generate_node_config
|
45
|
-
File.open(node_config, 'w') do |f|
|
46
|
-
f.print <<-JSON.gsub(/^\s+/, '')
|
47
|
-
{ "run_list": [] }
|
48
|
-
JSON
|
49
|
-
end unless node_config.exist?
|
50
|
-
end
|
51
|
-
|
52
47
|
def operating_system
|
53
48
|
@operating_system ||= run_command('uname -s').stdout.strip
|
54
49
|
end
|
55
50
|
|
56
51
|
def validate_params!
|
57
|
-
validate_first_cli_arg_is_a_hostname!
|
52
|
+
validate_first_cli_arg_is_a_hostname!
|
58
53
|
end
|
59
54
|
end
|
60
55
|
end
|
data/lib/chef/knife/wash_up.rb
CHANGED
@@ -66,7 +66,7 @@ module KnifeSolo
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def omnibus_install
|
69
|
-
url = prepare.config[:omnibus_url] || "
|
69
|
+
url = prepare.config[:omnibus_url] || "https://www.opscode.com/chef/install.sh"
|
70
70
|
file = File.basename(url)
|
71
71
|
http_client_get_url(url, file)
|
72
72
|
# `release_version` within install.sh will be installed if
|
@@ -78,13 +78,20 @@ module KnifeSolo
|
|
78
78
|
stream_command(install_command)
|
79
79
|
end
|
80
80
|
|
81
|
-
def
|
81
|
+
def yum_omnibus_install
|
82
|
+
omnibus_install
|
83
|
+
# Make sure we have rsync on builds that don't include it by default
|
84
|
+
# (for example Scientific Linux minimal)
|
85
|
+
run_command("sudo yum -y install rsync")
|
86
|
+
end
|
87
|
+
|
88
|
+
def debianoid_omnibus_install
|
82
89
|
omnibus_install
|
83
90
|
# Update to avoid out-of-date package caches
|
84
91
|
run_command("sudo apt-get update")
|
85
92
|
# Make sure we have rsync on builds that don't include it by default
|
86
|
-
# (
|
87
|
-
run_command("sudo apt-get install rsync")
|
93
|
+
# (for example linode's ubuntu 10.04 images)
|
94
|
+
run_command("sudo apt-get -y install rsync")
|
88
95
|
end
|
89
96
|
|
90
97
|
def gem_install
|
@@ -5,6 +5,11 @@ module KnifeSolo::Bootstraps
|
|
5
5
|
prepare.run_command("cat /etc/issue").stdout.strip || perepare.run_command("lsb_release -d -s").stdout.strip
|
6
6
|
end
|
7
7
|
|
8
|
+
def x86?
|
9
|
+
machine = run_command('uname -m').stdout.strip
|
10
|
+
%w{i686 x86 x86_64}.include?(machine)
|
11
|
+
end
|
12
|
+
|
8
13
|
def package_list
|
9
14
|
@packages.join(' ')
|
10
15
|
end
|
@@ -68,14 +73,14 @@ module KnifeSolo::Bootstraps
|
|
68
73
|
return @distro if @distro
|
69
74
|
@distro = case issue
|
70
75
|
when %r{Debian GNU/Linux 5}
|
71
|
-
{:type => "
|
76
|
+
{:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => "lenny"}
|
72
77
|
when %r{Debian GNU/Linux 6}
|
73
|
-
{:type => "
|
78
|
+
{:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => "squeeze"}
|
74
79
|
when %r{Debian GNU/Linux wheezy}
|
75
80
|
{:type => "debian_gem", :version => "wheezy"}
|
76
81
|
when %r{Ubuntu}i
|
77
82
|
version = run_command("lsb_release -cs").stdout.strip
|
78
|
-
{:type => "
|
83
|
+
{:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => version}
|
79
84
|
when %r{Linaro}
|
80
85
|
version = run_command("lsb_release -cs").stdout.strip
|
81
86
|
{:type => "debian_gem", :version => version}
|
@@ -94,7 +99,7 @@ module KnifeSolo::Bootstraps
|
|
94
99
|
when %r{Scientific Linux.*? 5}
|
95
100
|
{:type => "omnibus", :version => "RHEL5"}
|
96
101
|
when %r{Scientific Linux.*? 6}
|
97
|
-
{:type => "
|
102
|
+
{:type => "yum_omnibus", :version => "RHEL6"}
|
98
103
|
when %r{SUSE Linux Enterprise Server 11 SP1}
|
99
104
|
{:type => "zypper_gem", :version => "SLES11"}
|
100
105
|
when %r{openSUSE 11.4}
|
data/lib/knife-solo/info.rb
CHANGED
@@ -25,19 +25,7 @@ module KnifeSolo
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def warn_for_required_file(file)
|
28
|
-
|
28
|
+
ui.error "#{file} is a required file/directory"
|
29
29
|
end
|
30
|
-
|
31
|
-
def first_cli_arg_is_a_hostname?
|
32
|
-
@name_args.first =~ /\A([^@]+(?>@)[^@]+|[^@]+?(?!@))\z/
|
33
|
-
end
|
34
|
-
|
35
|
-
def validate_first_cli_arg_is_a_hostname!(error_class)
|
36
|
-
unless first_cli_arg_is_a_hostname?
|
37
|
-
ui.msg opt_parser.help
|
38
|
-
raise error_class.new "need to pass atleast a [user@]hostname as the first argument"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
30
|
end
|
43
31
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module KnifeSolo
|
2
|
+
module NodeConfigCommand
|
3
|
+
|
4
|
+
def self.load_deps
|
5
|
+
require 'pathname'
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.included(other)
|
9
|
+
other.class_eval do
|
10
|
+
# Lazy load our dependencies if the including class did not call
|
11
|
+
# Knife#deps yet. See KnifeSolo::SshCommand for more information.
|
12
|
+
deps { KnifeSolo::NodeConfigCommand.load_deps } unless @dependency_loader
|
13
|
+
|
14
|
+
option :chef_node_name,
|
15
|
+
:short => "-N NAME",
|
16
|
+
:long => "--node-name NAME",
|
17
|
+
:description => "The Chef node name for your new node"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def node_config
|
22
|
+
# host method must be defined by the including class
|
23
|
+
Pathname.new(@name_args[1] || "nodes/#{config[:chef_node_name] || host}.json")
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_node_config
|
27
|
+
if node_config.exist?
|
28
|
+
Chef::Log.debug "Node config '#{node_config}' already exists"
|
29
|
+
else
|
30
|
+
ui.msg "Generating node config '#{node_config}'..."
|
31
|
+
File.open(node_config, 'w') do |f|
|
32
|
+
f.print <<-JSON.gsub(/^\s+/, '')
|
33
|
+
{ "run_list": [] }
|
34
|
+
JSON
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -1,12 +1,26 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
|
3
1
|
module KnifeSolo
|
4
2
|
module SshCommand
|
3
|
+
|
4
|
+
def self.load_deps
|
5
|
+
require 'knife-solo/knife_solo_error'
|
6
|
+
require 'net/ssh'
|
7
|
+
end
|
8
|
+
|
5
9
|
def self.included(other)
|
6
|
-
other.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
other.class_eval do
|
11
|
+
# Lazy load our dependencies if the including class did not call
|
12
|
+
# Knife#deps yet. Later calls to #deps override previous ones, so if
|
13
|
+
# the outer class calls it, it should also call our #load_deps, i.e:
|
14
|
+
#
|
15
|
+
# Include KnifeSolo::SshCommand
|
16
|
+
#
|
17
|
+
# dep do
|
18
|
+
# require 'foo'
|
19
|
+
# require 'bar'
|
20
|
+
# KnifeSolo::SshCommand.load_deps
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
deps { KnifeSolo::SshCommand.load_deps } unless @dependency_loader
|
10
24
|
|
11
25
|
option :ssh_config,
|
12
26
|
:short => "-F CONFIG_FILE",
|
@@ -35,8 +49,15 @@ module KnifeSolo
|
|
35
49
|
end
|
36
50
|
end
|
37
51
|
|
38
|
-
def
|
39
|
-
|
52
|
+
def first_cli_arg_is_a_hostname?
|
53
|
+
@name_args.first =~ /\A([^@]+(?>@)[^@]+|[^@]+?(?!@))\z/
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate_first_cli_arg_is_a_hostname!
|
57
|
+
unless first_cli_arg_is_a_hostname?
|
58
|
+
ui.msg opt_parser.help
|
59
|
+
raise KnifeSoloError.new "need to pass atleast a [user@]hostname as the first argument"
|
60
|
+
end
|
40
61
|
end
|
41
62
|
|
42
63
|
def host_descriptor
|
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.
|
4
|
+
version: 0.0.15
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -116,6 +116,7 @@ files:
|
|
116
116
|
- lib/knife-solo/info.rb
|
117
117
|
- lib/knife-solo/kitchen_command.rb
|
118
118
|
- lib/knife-solo/knife_solo_error.rb
|
119
|
+
- lib/knife-solo/node_config_command.rb
|
119
120
|
- lib/knife-solo/ssh_command.rb
|
120
121
|
- lib/knife-solo/tools.rb
|
121
122
|
- lib/knife-solo.rb
|
@@ -131,18 +132,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
132
|
- - ! '>='
|
132
133
|
- !ruby/object:Gem::Version
|
133
134
|
version: '0'
|
134
|
-
segments:
|
135
|
-
- 0
|
136
|
-
hash: 3414347062334937427
|
137
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
136
|
none: false
|
139
137
|
requirements:
|
140
138
|
- - ! '>='
|
141
139
|
- !ruby/object:Gem::Version
|
142
140
|
version: '0'
|
143
|
-
segments:
|
144
|
-
- 0
|
145
|
-
hash: 3414347062334937427
|
146
141
|
requirements: []
|
147
142
|
rubyforge_project: nowarning
|
148
143
|
rubygems_version: 1.8.24
|