knife-solo 0.1.0 → 0.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +34 -0
- data/Rakefile +1 -2
- data/lib/chef/knife/solo_bootstrap.rb +3 -3
- data/lib/chef/knife/solo_clean.rb +1 -1
- data/lib/chef/knife/solo_cook.rb +53 -19
- data/lib/chef/knife/solo_init.rb +41 -11
- data/lib/chef/knife/solo_prepare.rb +11 -7
- data/lib/knife-solo/bootstraps.rb +1 -5
- data/lib/knife-solo/bootstraps/linux.rb +9 -17
- data/lib/knife-solo/gitignore.rb +26 -0
- data/lib/knife-solo/info.rb +1 -1
- data/lib/knife-solo/node_config_command.rb +3 -3
- data/lib/knife-solo/ssh_command.rb +20 -4
- data/lib/knife-solo/tools.rb +4 -0
- data/test/bootstraps_test.rb +18 -18
- data/test/gitignore_test.rb +60 -0
- data/test/integration/cases/apache2_bootstrap.rb +1 -1
- data/test/integration/cases/apache2_cook.rb +2 -4
- data/test/integration/debian6_bootstrap_test.rb +17 -0
- data/test/integration/debian7_bootstrap_test.rb +21 -0
- data/test/node_config_command_test.rb +23 -0
- data/test/solo_cook_test.rb +87 -10
- data/test/solo_init_test.rb +37 -0
- data/test/solo_prepare_test.rb +11 -9
- data/test/ssh_command_test.rb +20 -1
- data/test/support/integration_test.rb +9 -2
- data/test/support/test_case.rb +2 -0
- metadata +22 -10
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
# 0.2.0: _Not released yet_
|
2
|
+
|
3
|
+
## Changes and new features
|
4
|
+
|
5
|
+
* Support Chef 11 (#183)
|
6
|
+
* Rename Cook command's `--skip-chef-check` option to `--no-chef-check (#162)
|
7
|
+
* Rename `--ssh-identity` option to `--identity-file` (#178)
|
8
|
+
* Add `--ssh-user option` (#179)
|
9
|
+
* Add `--no-librarian` option to bootstrap and cook commands (#180)
|
10
|
+
* Generate Cheffile and .gitignore on `knife solo init --librarian` (#182)
|
11
|
+
* Windows client compatibility (#156, #91)
|
12
|
+
* Support unknown/unreleased Debian versions by using the
|
13
|
+
gem installer (#172)
|
14
|
+
* Drop support for Debian 5.0 Lenny (#172)
|
15
|
+
* Integration tests for Debian 6 and 7 (74c6ed1 - f299a6)
|
16
|
+
* Travis tests for both Chef 10 and 11 (#183)
|
17
|
+
|
18
|
+
## Fixes
|
19
|
+
|
20
|
+
* Fix Debian 7.0 Wheezy support by using gem installer (#172)
|
21
|
+
* Fix compatibility with Ruby 1.8.7 on work station (#170)
|
22
|
+
* Fix Chef version checking if sudo promts password (#190)
|
23
|
+
* Fix compatibility (net-ssh dependency) with Chef 10.20.0 and 11.2.0 (#188)
|
24
|
+
* Other fixes: #166, #168, #173
|
25
|
+
|
26
|
+
## Thanks to our contributors!
|
27
|
+
|
28
|
+
* [Russell Cardullo][russellcardullo]
|
29
|
+
* "[tknerr][]"
|
30
|
+
* [Shaun Dern][smdern]
|
31
|
+
|
1
32
|
# 0.1.0: January 12, 2013
|
2
33
|
|
3
34
|
## Changes and new features
|
@@ -228,8 +259,11 @@ And a special thanks to [Teemu Matilainen][tmatilai] who is now on the list of d
|
|
228
259
|
[rmoriz]: https://github.com/rmoriz
|
229
260
|
[rosstimson]: https://github.com/rosstimson
|
230
261
|
[rubiojr]: https://github.com/rubiojr
|
262
|
+
[russellcardullo]: https://github.com/russellcardullo
|
231
263
|
[ryandub]: https://github.com/ryandub
|
232
264
|
[skyeagle]: https://github.com/skyeagle
|
265
|
+
[smdern]: https://github.com/smdern
|
266
|
+
[tknerr]: https://github.com/tknerr
|
233
267
|
[tmatilai]: https://github.com/tmatilai
|
234
268
|
[vjpr]: https://github.com/vjpr
|
235
269
|
[zeph]: https://github.com/zeph
|
data/Rakefile
CHANGED
@@ -18,7 +18,7 @@ task :manifest do
|
|
18
18
|
git_files = `git ls-files`.split("\n")
|
19
19
|
|
20
20
|
File.open('Manifest.txt', 'w') do |f|
|
21
|
-
f.puts
|
21
|
+
f.puts((git_files - MANIFEST_IGNORES).join("\n"))
|
22
22
|
end
|
23
23
|
end
|
24
24
|
task :release => :manifest
|
@@ -76,4 +76,3 @@ end
|
|
76
76
|
desc "Alias for test:units"
|
77
77
|
task :test => ['test:units']
|
78
78
|
task :default => :test
|
79
|
-
|
@@ -21,7 +21,7 @@ class Chef
|
|
21
21
|
|
22
22
|
# Use (some) options from prepare and cook commands
|
23
23
|
self.options = SoloPrepare.options
|
24
|
-
[:sync_only, :why_run].each { |opt| option opt, SoloCook.options[opt] }
|
24
|
+
[:librarian, :sync_only, :why_run].each { |opt| option opt, SoloCook.options[opt] }
|
25
25
|
|
26
26
|
def run
|
27
27
|
validate!
|
@@ -30,12 +30,12 @@ class Chef
|
|
30
30
|
prepare.run
|
31
31
|
|
32
32
|
cook = command_with_same_args(SoloCook)
|
33
|
-
cook.config[:
|
33
|
+
cook.config[:chef_check] = false
|
34
34
|
cook.run
|
35
35
|
end
|
36
36
|
|
37
37
|
def validate!
|
38
|
-
|
38
|
+
validate_ssh_options!
|
39
39
|
validate_kitchen!
|
40
40
|
end
|
41
41
|
|
data/lib/chef/knife/solo_cook.rb
CHANGED
@@ -10,9 +10,7 @@ class Chef
|
|
10
10
|
# Approach ported from spatula (https://github.com/trotter/spatula)
|
11
11
|
# Copyright 2009, Trotter Cashion
|
12
12
|
class SoloCook < Knife
|
13
|
-
|
14
|
-
OMNIBUS_EMBEDDED_GEM_PATHS ||= %w[/opt/chef/embedded/lib/ruby/gems/1.9.1 /opt/opscode/embedded/lib/ruby/gems/1.9.1]
|
15
|
-
CHEF_VERSION_CONSTRAINT ||= ">=0.10.4"
|
13
|
+
CHEF_VERSION_CONSTRAINT = ">=0.10.4" unless defined? CHEF_VERSION_CONSTRAINT
|
16
14
|
|
17
15
|
include KnifeSolo::SshCommand
|
18
16
|
include KnifeSolo::KitchenCommand
|
@@ -30,14 +28,24 @@ class Chef
|
|
30
28
|
|
31
29
|
banner "knife solo cook [USER@]HOSTNAME [JSON] (options)"
|
32
30
|
|
31
|
+
option :chef_check,
|
32
|
+
:long => '--no-chef-check',
|
33
|
+
:description => 'Skip the Chef version check on the node',
|
34
|
+
:default => true
|
35
|
+
|
33
36
|
option :skip_chef_check,
|
34
37
|
:long => '--skip-chef-check',
|
35
|
-
:description => '
|
38
|
+
:description => 'Deprecated. Replaced with --no-chef-check.'
|
36
39
|
|
37
40
|
option :sync_only,
|
38
41
|
:long => '--sync-only',
|
39
42
|
:description => 'Only sync the cookbook - do not run Chef'
|
40
43
|
|
44
|
+
option :librarian,
|
45
|
+
:long => '--no-librarian',
|
46
|
+
:description => 'Skip librarian-chef install',
|
47
|
+
:default => true
|
48
|
+
|
41
49
|
option :why_run,
|
42
50
|
:short => '-W',
|
43
51
|
:long => '--why-run',
|
@@ -45,11 +53,16 @@ class Chef
|
|
45
53
|
|
46
54
|
def run
|
47
55
|
time('Run') do
|
56
|
+
if config[:skip_chef_check]
|
57
|
+
ui.warn '`--skip-chef-check` is deprecated, please use `--no-chef-check`.'
|
58
|
+
config[:chef_check] = false
|
59
|
+
end
|
60
|
+
|
48
61
|
validate!
|
49
62
|
Chef::Config.from_file('solo.rb')
|
50
|
-
check_chef_version
|
63
|
+
check_chef_version if config[:chef_check]
|
51
64
|
generate_node_config
|
52
|
-
librarian_install
|
65
|
+
librarian_install if config[:librarian]
|
53
66
|
rsync_kitchen
|
54
67
|
add_patches
|
55
68
|
cook unless config[:sync_only]
|
@@ -57,7 +70,7 @@ class Chef
|
|
57
70
|
end
|
58
71
|
|
59
72
|
def validate!
|
60
|
-
|
73
|
+
validate_ssh_options!
|
61
74
|
validate_kitchen!
|
62
75
|
end
|
63
76
|
|
@@ -71,15 +84,29 @@ class Chef
|
|
71
84
|
|
72
85
|
# cygwin rsync path must be adjusted to work
|
73
86
|
def adjust_rsync_path(path)
|
74
|
-
return path unless windows_node?
|
75
87
|
path.gsub(/^(\w):/) { "/cygdrive/#{$1}" }
|
76
88
|
end
|
77
89
|
|
90
|
+
def adjust_rsync_path_on_node(path)
|
91
|
+
return path unless windows_node?
|
92
|
+
adjust_rsync_path(path)
|
93
|
+
end
|
94
|
+
|
95
|
+
def adjust_rsync_path_on_client(path)
|
96
|
+
return path unless windows_client?
|
97
|
+
adjust_rsync_path(path)
|
98
|
+
end
|
99
|
+
|
100
|
+
# see http://stackoverflow.com/questions/5798807/rsync-permission-denied-created-directories-have-no-permissions
|
101
|
+
def rsync_permissions
|
102
|
+
'--chmod=ugo=rwX' if windows_client?
|
103
|
+
end
|
104
|
+
|
78
105
|
def patch_path
|
79
106
|
Array(Chef::Config.cookbook_path).first + "/chef_solo_patches/libraries"
|
80
107
|
end
|
81
108
|
|
82
|
-
def
|
109
|
+
def rsync_excludes
|
83
110
|
(%w{revision-deploys tmp '.*'} + chefignore.ignores).uniq
|
84
111
|
end
|
85
112
|
|
@@ -109,9 +136,7 @@ class Chef
|
|
109
136
|
|
110
137
|
def rsync_kitchen
|
111
138
|
time('Rsync kitchen') do
|
112
|
-
|
113
|
-
ui.msg cmd if debug?
|
114
|
-
system! cmd
|
139
|
+
rsync('./', chef_path, '--delete')
|
115
140
|
end
|
116
141
|
end
|
117
142
|
|
@@ -119,19 +144,28 @@ class Chef
|
|
119
144
|
run_portable_mkdir_p(patch_path)
|
120
145
|
Dir[Pathname.new(__FILE__).dirname.join("patches", "*.rb").to_s].each do |patch|
|
121
146
|
time(patch) do
|
122
|
-
|
147
|
+
rsync(patch, patch_path)
|
123
148
|
end
|
124
149
|
end
|
125
150
|
end
|
126
151
|
|
152
|
+
def rsync(source_path, target_path, extra_opts = '')
|
153
|
+
cmd = %Q{rsync -rl #{rsync_permissions} --rsh="ssh #{ssh_args}" #{extra_opts} #{rsync_excludes.collect{ |ignore| "--exclude #{ignore} " }.join} #{adjust_rsync_path_on_client(source_path)} :#{adjust_rsync_path_on_node(target_path)}}
|
154
|
+
ui.msg cmd if debug?
|
155
|
+
system! cmd
|
156
|
+
end
|
157
|
+
|
127
158
|
def check_chef_version
|
128
159
|
ui.msg "Checking Chef version..."
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
160
|
+
unless Gem::Requirement.new(CHEF_VERSION_CONSTRAINT).satisfied_by? Gem::Version.new(chef_version)
|
161
|
+
raise "Couldn't find Chef #{CHEF_VERSION_CONSTRAINT} on #{host}. Please run `knife solo prepare #{ssh_args}` to ensure Chef is installed and up to date."
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Parses "Chef: x.y.z" from the chef-solo version output
|
166
|
+
def chef_version
|
167
|
+
v = run_command('sudo chef-solo --version').stdout.split(':')
|
168
|
+
v[0].strip == 'Chef' ? v[1].strip : ''
|
135
169
|
end
|
136
170
|
|
137
171
|
def cook
|
data/lib/chef/knife/solo_init.rb
CHANGED
@@ -5,27 +5,41 @@ class Chef
|
|
5
5
|
class SoloInit < Knife
|
6
6
|
include FileUtils
|
7
7
|
|
8
|
+
deps do
|
9
|
+
require 'knife-solo/gitignore'
|
10
|
+
end
|
11
|
+
|
8
12
|
banner "knife solo init DIRECTORY"
|
9
13
|
|
14
|
+
option :git,
|
15
|
+
:long => '--no-git',
|
16
|
+
:description => 'Do not generate .gitignore',
|
17
|
+
:default => true
|
18
|
+
|
19
|
+
option :librarian,
|
20
|
+
:long => '--librarian',
|
21
|
+
:description => 'Initialize Librarian'
|
22
|
+
|
10
23
|
def run
|
24
|
+
@base = @name_args.first
|
11
25
|
validate!
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
create_solo_config
|
26
|
+
create_kitchen
|
27
|
+
create_cupboards %w[nodes roles data_bags site-cookbooks cookbooks]
|
28
|
+
librarian_init if config[:librarian]
|
29
|
+
create_solo_config
|
16
30
|
end
|
17
31
|
|
18
32
|
def validate!
|
19
|
-
unless @
|
33
|
+
unless @base
|
20
34
|
show_usage
|
21
35
|
ui.fatal "You must specify a directory. Use '.' to initialize the current one."
|
22
36
|
exit 1
|
23
37
|
end
|
24
38
|
end
|
25
39
|
|
26
|
-
def create_cupboards(
|
40
|
+
def create_cupboards(dirs)
|
27
41
|
dirs.each do |dir|
|
28
|
-
cupboard_dir = File.join(base, dir)
|
42
|
+
cupboard_dir = File.join(@base, dir)
|
29
43
|
unless File.exist?(cupboard_dir)
|
30
44
|
mkdir cupboard_dir
|
31
45
|
touch File.join(cupboard_dir, '.gitkeep')
|
@@ -33,12 +47,12 @@ class Chef
|
|
33
47
|
end
|
34
48
|
end
|
35
49
|
|
36
|
-
def create_kitchen
|
37
|
-
mkdir base unless base == '.'
|
50
|
+
def create_kitchen
|
51
|
+
mkdir @base unless @base == '.'
|
38
52
|
end
|
39
53
|
|
40
|
-
def create_solo_config
|
41
|
-
solo_file = File.join(base, 'solo.rb')
|
54
|
+
def create_solo_config
|
55
|
+
solo_file = File.join(@base, 'solo.rb')
|
42
56
|
return if File.exist? solo_file
|
43
57
|
|
44
58
|
File.open(solo_file, 'w') do |f|
|
@@ -52,6 +66,22 @@ class Chef
|
|
52
66
|
RUBY
|
53
67
|
end
|
54
68
|
end
|
69
|
+
|
70
|
+
def librarian_init
|
71
|
+
cheffile = File.join(@base, 'Cheffile')
|
72
|
+
unless File.exist?(cheffile)
|
73
|
+
File.open(cheffile, 'w') do |f|
|
74
|
+
f.puts("site 'http://community.opscode.com/api/v1'")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
gitignore %w[/cookbooks/ /tmp/librarian/]
|
78
|
+
end
|
79
|
+
|
80
|
+
def gitignore(*entries)
|
81
|
+
if config[:git]
|
82
|
+
KnifeSolo::Gitignore.new(@base).add(*entries)
|
83
|
+
end
|
84
|
+
end
|
55
85
|
end
|
56
86
|
end
|
57
87
|
end
|
@@ -20,10 +20,6 @@ class Chef
|
|
20
20
|
|
21
21
|
banner "knife solo prepare [USER@]HOSTNAME [JSON] (options)"
|
22
22
|
|
23
|
-
option :omnibus_version,
|
24
|
-
:long => '--omnibus-version VERSION',
|
25
|
-
:description => 'The version of Omnibus to install'
|
26
|
-
|
27
23
|
option :omnibus_url,
|
28
24
|
:long => '--omnibus-url URL',
|
29
25
|
:description => 'URL to download install.sh from'
|
@@ -32,24 +28,32 @@ class Chef
|
|
32
28
|
:long => '--omnibus-options "OPTIONS"',
|
33
29
|
:description => 'Pass options to the install.sh script'
|
34
30
|
|
31
|
+
option :omnibus_version,
|
32
|
+
:long => '--omnibus-version VERSION',
|
33
|
+
:description => 'The version of Omnibus to install'
|
34
|
+
|
35
35
|
def run
|
36
|
+
if config[:omnibus_version]
|
37
|
+
config[:omnibus_options] = "#{config[:omnibus_options]} -v #{config[:omnibus_version]}".strip
|
38
|
+
end
|
39
|
+
|
36
40
|
validate!
|
37
41
|
bootstrap.bootstrap!
|
38
42
|
generate_node_config
|
39
43
|
end
|
40
44
|
|
41
45
|
def validate!
|
42
|
-
|
46
|
+
validate_ssh_options!
|
43
47
|
validate_kitchen!
|
44
48
|
end
|
45
49
|
|
46
50
|
def bootstrap
|
47
51
|
ui.msg "Bootstrapping Chef..."
|
48
|
-
KnifeSolo::Bootstraps.class_for_operating_system(operating_system
|
52
|
+
KnifeSolo::Bootstraps.class_for_operating_system(operating_system).new(self)
|
49
53
|
end
|
50
54
|
|
51
55
|
def operating_system
|
52
|
-
|
56
|
+
run_command('uname -s').stdout.strip
|
53
57
|
end
|
54
58
|
end
|
55
59
|
end
|
@@ -69,12 +69,8 @@ module KnifeSolo
|
|
69
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
|
-
# `release_version` within install.sh will be installed if
|
73
|
-
# `omnibus_version` is not provided.
|
74
|
-
install_command = "sudo bash #{file}"
|
75
|
-
install_command << " -v #{prepare.config[:omnibus_version]}" if prepare.config[:omnibus_version]
|
76
|
-
install_command << " #{prepare.config[:omnibus_options]}" if prepare.config[:omnibus_options]
|
77
72
|
|
73
|
+
install_command = "sudo bash #{file} #{prepare.config[:omnibus_options]}"
|
78
74
|
stream_command(install_command)
|
79
75
|
end
|
80
76
|
|
@@ -10,6 +10,10 @@ module KnifeSolo::Bootstraps
|
|
10
10
|
%w{i686 x86 x86_64}.include?(machine)
|
11
11
|
end
|
12
12
|
|
13
|
+
def lsb_release_codename
|
14
|
+
run_command("lsb_release -cs").stdout.strip
|
15
|
+
end
|
16
|
+
|
13
17
|
def package_list
|
14
18
|
@packages.join(' ')
|
15
19
|
end
|
@@ -18,12 +22,6 @@ module KnifeSolo::Bootstraps
|
|
18
22
|
['ruby-shadow','chef']
|
19
23
|
end
|
20
24
|
|
21
|
-
def zypper_gem_install
|
22
|
-
ui.msg("Installing required packages...")
|
23
|
-
run_command("sudo zypper --non-interactive install ruby-devel make gcc rsync")
|
24
|
-
gem_install
|
25
|
-
end
|
26
|
-
|
27
25
|
def emerge_gem_install
|
28
26
|
ui.msg("Installing required packages...")
|
29
27
|
run_command("sudo USE='-test' ACCEPT_KEYWORDS='~amd64' emerge -u chef")
|
@@ -72,20 +70,14 @@ module KnifeSolo::Bootstraps
|
|
72
70
|
def distro
|
73
71
|
return @distro if @distro
|
74
72
|
@distro = case issue
|
75
|
-
when %r{Debian GNU/Linux 5}
|
76
|
-
{:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => "lenny"}
|
77
73
|
when %r{Debian GNU/Linux 6}
|
78
|
-
{:type =>
|
79
|
-
when %r{Debian
|
80
|
-
{:type =>
|
81
|
-
when %r{Debian GNU/Linux wheezy}
|
82
|
-
{:type => "debian_gem", :version => "wheezy"}
|
74
|
+
{:type => (x86? ? "debianoid_omnibus" : "debian_gem"), :version => "squeeze"}
|
75
|
+
when %r{Debian}
|
76
|
+
{:type => "debian_gem", :version => lsb_release_codename}
|
83
77
|
when %r{Ubuntu}i
|
84
|
-
|
85
|
-
{:type => if x86? then "debianoid_omnibus" else "debian_gem" end, :version => version}
|
78
|
+
{:type => (x86? ? "debianoid_omnibus" : "debian_gem"), :version => lsb_release_codename}
|
86
79
|
when %r{Linaro}
|
87
|
-
|
88
|
-
{:type => "debian_gem", :version => version}
|
80
|
+
{:type => "debian_gem", :version => lsb_release_codename}
|
89
81
|
when %r{CentOS.*? 5}
|
90
82
|
{:type => "yum_omnibus", :version => "RHEL5"}
|
91
83
|
when %r{CentOS.*? 6}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module KnifeSolo
|
2
|
+
class Gitignore
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :ignore_file
|
6
|
+
|
7
|
+
def initialize(dir)
|
8
|
+
@ignore_file = File.join(dir, '.gitignore')
|
9
|
+
end
|
10
|
+
|
11
|
+
def each
|
12
|
+
if File.exist? ignore_file
|
13
|
+
File.new(ignore_file).each do |line|
|
14
|
+
yield line.chomp
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add(*new_entries)
|
20
|
+
new_entries = (entries + new_entries.flatten).uniq
|
21
|
+
File.open(ignore_file, 'w') do |f|
|
22
|
+
f.puts new_entries
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/knife-solo/info.rb
CHANGED
@@ -23,12 +23,12 @@ module KnifeSolo
|
|
23
23
|
:proc => lambda { |o| o.split(/[\s,]+/) },
|
24
24
|
:default => []
|
25
25
|
|
26
|
-
option :
|
26
|
+
option :json_attributes,
|
27
27
|
:short => '-j JSON_ATTRIBS',
|
28
28
|
:long => '--json-attributes',
|
29
29
|
:description => 'A JSON string to be added to node config (if it does not exist)',
|
30
30
|
:proc => lambda { |o| JSON.parse(o) },
|
31
|
-
:default =>
|
31
|
+
:default => nil
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -43,7 +43,7 @@ module KnifeSolo
|
|
43
43
|
else
|
44
44
|
ui.msg "Generating node config '#{node_config}'..."
|
45
45
|
File.open(node_config, 'w') do |f|
|
46
|
-
attributes = config[:first_boot_attributes] || {}
|
46
|
+
attributes = config[:json_attributes] || config[:first_boot_attributes] || {}
|
47
47
|
run_list = { :run_list => config[:run_list] || [] }
|
48
48
|
f.print attributes.merge(run_list).to_json
|
49
49
|
end
|
@@ -26,14 +26,23 @@ module KnifeSolo
|
|
26
26
|
:long => '--ssh-config-file CONFIG_FILE',
|
27
27
|
:description => 'Alternate location for ssh config file'
|
28
28
|
|
29
|
+
option :ssh_user,
|
30
|
+
:short => '-x USERNAME',
|
31
|
+
:long => '--ssh-user USERNAME',
|
32
|
+
:description => 'The ssh username'
|
33
|
+
|
29
34
|
option :ssh_password,
|
30
35
|
:short => '-P PASSWORD',
|
31
36
|
:long => '--ssh-password PASSWORD',
|
32
37
|
:description => 'The ssh password'
|
33
38
|
|
34
39
|
option :ssh_identity,
|
35
|
-
:short => '-i FILE',
|
36
40
|
:long => '--ssh-identity FILE',
|
41
|
+
:description => 'Deprecated. Replaced with --identity-file.'
|
42
|
+
|
43
|
+
option :identity_file,
|
44
|
+
:short => '-i IDENTITY_FILE',
|
45
|
+
:long => '--identity-file FILE',
|
37
46
|
:description => 'The ssh identity file'
|
38
47
|
|
39
48
|
option :ssh_port,
|
@@ -52,12 +61,19 @@ module KnifeSolo
|
|
52
61
|
@name_args.first =~ /\A([^@]+(?>@)[^@]+|[^@]+?(?!@))\z/
|
53
62
|
end
|
54
63
|
|
55
|
-
def
|
64
|
+
def validate_ssh_options!
|
65
|
+
if config[:ssh_identity]
|
66
|
+
ui.warn '`--ssh-identity` is deprecated, please use `--identity-file`.'
|
67
|
+
config[:identity_file] ||= config[:ssh_identity]
|
68
|
+
end
|
56
69
|
unless first_cli_arg_is_a_hostname?
|
57
70
|
show_usage
|
58
71
|
ui.fatal "You must specify [<user>@]<hostname> as the first argument"
|
59
72
|
exit 1
|
60
73
|
end
|
74
|
+
if config[:ssh_user]
|
75
|
+
host_descriptor[:user] ||= config[:ssh_user]
|
76
|
+
end
|
61
77
|
end
|
62
78
|
|
63
79
|
def host_descriptor
|
@@ -101,7 +117,7 @@ module KnifeSolo
|
|
101
117
|
options = config_file_options
|
102
118
|
options[:port] = config[:ssh_port] if config[:ssh_port]
|
103
119
|
options[:password] = config[:ssh_password] if config[:ssh_password]
|
104
|
-
options[:keys] = [config[:
|
120
|
+
options[:keys] = [config[:identity_file]] if config[:identity_file]
|
105
121
|
options
|
106
122
|
end
|
107
123
|
|
@@ -125,7 +141,7 @@ module KnifeSolo
|
|
125
141
|
def ssh_args
|
126
142
|
host_arg = [user, host].compact.join('@')
|
127
143
|
config_arg = "-F #{config[:ssh_config]}" if config[:ssh_config]
|
128
|
-
ident_arg = "-i #{config[:
|
144
|
+
ident_arg = "-i #{config[:identity_file]}" if config[:identity_file]
|
129
145
|
port_arg = "-p #{config[:ssh_port]}" if config[:ssh_port]
|
130
146
|
|
131
147
|
[host_arg, config_arg, ident_arg, port_arg].compact.join(' ')
|
data/lib/knife-solo/tools.rb
CHANGED
data/test/bootstraps_test.rb
CHANGED
@@ -16,40 +16,31 @@ end
|
|
16
16
|
class BootstrapsTest < TestCase
|
17
17
|
def test_bootstrap_class_exists_for
|
18
18
|
assert_equal true, KnifeSolo::Bootstraps.class_exists_for?('Stub OS')
|
19
|
-
|
20
19
|
assert_equal false, KnifeSolo::Bootstraps.class_exists_for?('Mythical OS')
|
21
20
|
end
|
22
21
|
|
23
22
|
def test_distro_raises_if_not_implemented
|
24
|
-
bootstrap = bootstrap_instance()
|
25
|
-
|
26
23
|
assert_raises RuntimeError do
|
27
|
-
|
24
|
+
bootstrap_instance.distro()
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
31
28
|
def test_gem_packages_raises_if_not_implemented
|
32
|
-
bootstrap = bootstrap_instance()
|
33
|
-
|
34
29
|
assert_raises RuntimeError do
|
35
|
-
|
30
|
+
bootstrap_instance.gem_packages()
|
36
31
|
end
|
37
32
|
end
|
38
33
|
|
39
34
|
def test_bootstrap_calls_appropriate_install_method
|
40
|
-
bootstrap =
|
35
|
+
bootstrap = bootstrap_instance
|
41
36
|
bootstrap.stubs(:distro).returns({:type => 'disco_gem'})
|
42
|
-
|
43
37
|
bootstrap.expects(:disco_gem_install)
|
44
|
-
|
45
38
|
bootstrap.bootstrap!
|
46
39
|
end
|
47
40
|
|
48
41
|
def test_bootstrap_calls_pre_bootstrap_checks
|
49
42
|
bootstrap = KnifeSolo::Bootstraps::StubOS2.new(mock)
|
50
|
-
|
51
43
|
bootstrap.expects(:run_pre_bootstrap_checks)
|
52
|
-
|
53
44
|
bootstrap.bootstrap!
|
54
45
|
end
|
55
46
|
|
@@ -62,9 +53,7 @@ class BootstrapsTest < TestCase
|
|
62
53
|
|
63
54
|
def test_darwin_checks_for_xcode_install_and_barfs_if_missing
|
64
55
|
bootstrap = KnifeSolo::Bootstraps::Darwin.new(mock)
|
65
|
-
# don't want to actually run anything
|
66
56
|
bootstrap.stubs(:gem_install)
|
67
|
-
|
68
57
|
bootstrap.expects(:has_xcode_installed?).returns(false)
|
69
58
|
|
70
59
|
assert_raises RuntimeError do
|
@@ -73,10 +62,21 @@ class BootstrapsTest < TestCase
|
|
73
62
|
end
|
74
63
|
|
75
64
|
def test_omnibus_install_methdod
|
76
|
-
bootstrap =
|
65
|
+
bootstrap = bootstrap_instance
|
77
66
|
bootstrap.stubs(:distro).returns({:type => "omnibus"})
|
78
|
-
|
79
67
|
bootstrap.expects(:omnibus_install)
|
68
|
+
bootstrap.bootstrap!
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_passes_omnibus_options
|
72
|
+
bootstrap = bootstrap_instance
|
73
|
+
bootstrap.stubs(:distro).returns({:type => "omnibus"})
|
74
|
+
bootstrap.stubs(:http_client_get_url)
|
75
|
+
|
76
|
+
options = "-v 10.16.4"
|
77
|
+
matcher = regexp_matches(/\s#{Regexp.quote(options)}(\s|$)/)
|
78
|
+
bootstrap.prepare.stubs(:config).returns({:omnibus_options => options})
|
79
|
+
bootstrap.prepare.expects(:stream_command).with(matcher).returns(SuccessfulResult.new)
|
80
80
|
|
81
81
|
bootstrap.bootstrap!
|
82
82
|
end
|
@@ -84,7 +84,7 @@ class BootstrapsTest < TestCase
|
|
84
84
|
# ***
|
85
85
|
|
86
86
|
def bootstrap_instance
|
87
|
-
|
88
|
-
KnifeSolo::Bootstraps::StubOS.new(
|
87
|
+
prepare = mock('Knife::Chef::SoloPrepare')
|
88
|
+
KnifeSolo::Bootstraps::StubOS.new(prepare)
|
89
89
|
end
|
90
90
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
|
4
|
+
require 'knife-solo/gitignore'
|
5
|
+
|
6
|
+
class GitignoreTest < TestCase
|
7
|
+
include KitchenHelper
|
8
|
+
|
9
|
+
def test_creates_with_one_entry
|
10
|
+
outside_kitchen do
|
11
|
+
KnifeSolo::Gitignore.new('.').add("foo")
|
12
|
+
assert_equal "foo\n", IO.read('.gitignore')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_creates_with_multiple_entries
|
17
|
+
outside_kitchen do
|
18
|
+
KnifeSolo::Gitignore.new('.').add("foo", "/bar")
|
19
|
+
assert_equal "foo\n/bar\n", IO.read('.gitignore')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_creates_with_array
|
24
|
+
outside_kitchen do
|
25
|
+
KnifeSolo::Gitignore.new('.').add(%w[foo/ bar])
|
26
|
+
assert_equal "foo/\nbar\n", IO.read('.gitignore')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_appends_new_entries
|
31
|
+
outside_kitchen do
|
32
|
+
File.open(".gitignore", "w") do |f|
|
33
|
+
f.puts "foo"
|
34
|
+
end
|
35
|
+
KnifeSolo::Gitignore.new('.').add(["bar.*"])
|
36
|
+
assert_equal "foo\nbar.*\n", IO.read('.gitignore')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_appends_only_new_entries
|
41
|
+
outside_kitchen do
|
42
|
+
File.open(".gitignore", "w") do |f|
|
43
|
+
f.puts "*.foo"
|
44
|
+
end
|
45
|
+
KnifeSolo::Gitignore.new('.').add("!foo", "*.foo")
|
46
|
+
assert_equal "*.foo\n!foo\n", IO.read('.gitignore')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_appends_only_if_any_new_entries
|
51
|
+
outside_kitchen do
|
52
|
+
File.open(".gitignore", "w") do |f|
|
53
|
+
f.puts "!foo"
|
54
|
+
f.puts "/bar/*.baz"
|
55
|
+
end
|
56
|
+
KnifeSolo::Gitignore.new('.').add(["!foo", "/bar/*.baz"])
|
57
|
+
assert_equal "!foo\n/bar/*.baz\n", IO.read('.gitignore')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -8,7 +8,7 @@ module Apache2Bootstrap
|
|
8
8
|
|
9
9
|
def test_apache2
|
10
10
|
write_cheffile
|
11
|
-
assert_subcommand "bootstrap --run-list=recipe[apache2]"
|
11
|
+
assert_subcommand "bootstrap --run-list=recipe[apache2] #{omnibus_options}"
|
12
12
|
assert_match default_apache_message, http_response
|
13
13
|
end
|
14
14
|
end
|
@@ -3,10 +3,8 @@
|
|
3
3
|
module Apache2Cook
|
4
4
|
def write_cheffile
|
5
5
|
File.open('Cheffile', 'w') do |f|
|
6
|
-
f.
|
7
|
-
|
8
|
-
cookbook 'apache2'
|
9
|
-
CHEF
|
6
|
+
f.puts "site 'http://community.opscode.com/api/v1'"
|
7
|
+
f.puts "cookbook 'apache2'"
|
10
8
|
end
|
11
9
|
end
|
12
10
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
|
3
|
+
class Debian6BootstrapTest < IntegrationTest
|
4
|
+
def user
|
5
|
+
"admin"
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_id
|
9
|
+
"ami-4d20a724"
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_server
|
13
|
+
# Do nothing as `solo bootstrap` will do everything
|
14
|
+
end
|
15
|
+
|
16
|
+
include Apache2Bootstrap
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
|
3
|
+
class Debian7BootstrapTest < IntegrationTest
|
4
|
+
def user
|
5
|
+
"admin"
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_id
|
9
|
+
"ami-0c8b1d65"
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_server
|
13
|
+
# Do nothing as `solo bootstrap` will do everything
|
14
|
+
end
|
15
|
+
|
16
|
+
def default_apache_message
|
17
|
+
/It works!/
|
18
|
+
end
|
19
|
+
|
20
|
+
include Apache2Bootstrap
|
21
|
+
end
|
@@ -85,6 +85,29 @@ class NodeConfigCommandTest < TestCase
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
def test_generates_a_node_config_with_specified_json_attributes
|
89
|
+
in_kitchen do
|
90
|
+
foo_json = '"foo":99'
|
91
|
+
ignored_json = '"bar":"ignored"'
|
92
|
+
|
93
|
+
cmd = command(@host)
|
94
|
+
cmd.config[:json_attributes] = JSON.parse("{#{foo_json}}")
|
95
|
+
cmd.config[:first_boot_attributes] = JSON.parse("{#{ignored_json}}")
|
96
|
+
cmd.generate_node_config
|
97
|
+
assert_match "{#{foo_json},\"run_list\":[]}", cmd.node_config.read
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_generates_a_node_config_with_specified_first_boot_attributes
|
102
|
+
in_kitchen do
|
103
|
+
foo_json = '"foo":null'
|
104
|
+
cmd = command(@host)
|
105
|
+
cmd.config[:first_boot_attributes] = JSON.parse("{#{foo_json}}")
|
106
|
+
cmd.generate_node_config
|
107
|
+
assert_match "{#{foo_json},\"run_list\":[]}", cmd.node_config.read
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
88
111
|
def test_generates_a_node_config_with_specified_run_list_and_attributes
|
89
112
|
in_kitchen do
|
90
113
|
foo_json = '"foo":"bar"'
|
data/test/solo_cook_test.rb
CHANGED
@@ -17,13 +17,15 @@ class SoloCookTest < TestCase
|
|
17
17
|
include ValidationHelper::ValidationTests
|
18
18
|
|
19
19
|
def test_gets_destination_path_from_chef_config
|
20
|
-
|
21
|
-
|
20
|
+
cmd = command
|
21
|
+
Chef::Config.file_cache_path "/foo/chef-solo"
|
22
|
+
assert_equal "/foo/chef-solo", cmd.chef_path
|
22
23
|
end
|
23
24
|
|
24
25
|
def test_gets_patch_path_from_chef_config
|
25
|
-
|
26
|
-
|
26
|
+
cmd = command
|
27
|
+
Chef::Config.cookbook_path ["/bar/chef-solo/cookbooks"]
|
28
|
+
assert_equal "/bar/chef-solo/cookbooks/chef_solo_patches/libraries", cmd.patch_path
|
27
29
|
end
|
28
30
|
|
29
31
|
def test_chefignore_is_valid_object
|
@@ -35,14 +37,14 @@ class SoloCookTest < TestCase
|
|
35
37
|
file_to_ignore = "dummy.txt"
|
36
38
|
File.open(file_to_ignore, 'w') {|f| f.puts "This file should be ignored"}
|
37
39
|
File.open("chefignore", 'w') {|f| f.puts file_to_ignore}
|
38
|
-
assert command.
|
40
|
+
assert command.rsync_excludes.include?(file_to_ignore), "#{file_to_ignore} should have been excluded"
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
44
|
def test_does_not_run_librarian_if_no_cheffile
|
43
45
|
in_kitchen do
|
44
46
|
Librarian::Action::Install.any_instance.expects(:run).never
|
45
|
-
command.
|
47
|
+
command("somehost").run
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
@@ -50,7 +52,77 @@ class SoloCookTest < TestCase
|
|
50
52
|
in_kitchen do
|
51
53
|
File.open("Cheffile", 'w') {}
|
52
54
|
Librarian::Action::Install.any_instance.expects(:run)
|
53
|
-
command.
|
55
|
+
command("somehost").run
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_does_not_run_librarian_if_denied_by_option
|
60
|
+
in_kitchen do
|
61
|
+
File.open("Cheffile", 'w') {}
|
62
|
+
Librarian::Action::Install.any_instance.expects(:run).never
|
63
|
+
command("somehost", "--no-librarian").run
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_validates_chef_version
|
68
|
+
in_kitchen do
|
69
|
+
cmd = command("somehost")
|
70
|
+
cmd.expects(:check_chef_version)
|
71
|
+
cmd.run
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_does_not_validate_chef_version_if_denied_by_option
|
76
|
+
in_kitchen do
|
77
|
+
cmd = command("somehost", "--no-chef-check")
|
78
|
+
cmd.expects(:check_chef_version).never
|
79
|
+
cmd.run
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_accept_valid_chef_version
|
84
|
+
in_kitchen do
|
85
|
+
cmd = command("somehost")
|
86
|
+
cmd.unstub(:check_chef_version)
|
87
|
+
cmd.stubs(:chef_version).returns("11.2.0")
|
88
|
+
cmd.run
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_barks_if_chef_not_found
|
93
|
+
in_kitchen do
|
94
|
+
cmd = command("somehost")
|
95
|
+
cmd.unstub(:check_chef_version)
|
96
|
+
cmd.stubs(:chef_version).returns("")
|
97
|
+
assert_raises RuntimeError do
|
98
|
+
cmd.run
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_parses_chef_version_output
|
104
|
+
version_string = "\r\nChef: 11.2.0\r\n"
|
105
|
+
cmd = command("somehost")
|
106
|
+
cmd.stubs(:run_command).returns(OpenStruct.new(:stdout => version_string))
|
107
|
+
assert_equal '11.2.0', cmd.chef_version
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_barks_if_chef_too_old
|
111
|
+
in_kitchen do
|
112
|
+
cmd = command("somehost")
|
113
|
+
cmd.unstub(:check_chef_version)
|
114
|
+
cmd.stubs(:chef_version).returns("0.8.0")
|
115
|
+
assert_raises RuntimeError do
|
116
|
+
cmd.run
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_does_not_cook_if_sync_only_specified
|
122
|
+
in_kitchen do
|
123
|
+
cmd = command("somehost", "--sync-only")
|
124
|
+
cmd.expects(:cook).never
|
125
|
+
cmd.run
|
54
126
|
end
|
55
127
|
end
|
56
128
|
|
@@ -69,15 +141,20 @@ class SoloCookTest < TestCase
|
|
69
141
|
in_kitchen do
|
70
142
|
cmd = command("somehost", cook_option)
|
71
143
|
cmd.expects(:stream_command).with(matcher).returns(SuccessfulResult.new)
|
72
|
-
cmd.
|
144
|
+
cmd.run
|
73
145
|
|
74
146
|
cmd = command("somehost")
|
75
147
|
cmd.expects(:stream_command).with(Not(matcher)).returns(SuccessfulResult.new)
|
76
|
-
cmd.
|
148
|
+
cmd.run
|
77
149
|
end
|
78
150
|
end
|
79
151
|
|
80
152
|
def command(*args)
|
81
|
-
knife_command(Chef::Knife::SoloCook, *args)
|
153
|
+
cmd = knife_command(Chef::Knife::SoloCook, *args)
|
154
|
+
cmd.stubs(:check_chef_version)
|
155
|
+
cmd.stubs(:rsync_kitchen)
|
156
|
+
cmd.stubs(:add_patches)
|
157
|
+
cmd.stubs(:stream_command).returns(SuccessfulResult.new)
|
158
|
+
cmd
|
82
159
|
end
|
83
160
|
end
|
data/test/solo_init_test.rb
CHANGED
@@ -34,6 +34,43 @@ class SoloInitTest < TestCase
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
def test_wont_create_cheffile_by_default
|
38
|
+
in_kitchen do
|
39
|
+
refute File.exist?("Cheffile")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_creates_cheffile_if_specified
|
44
|
+
outside_kitchen do
|
45
|
+
command("foo", "--librarian").run
|
46
|
+
assert File.exist?("foo/Cheffile")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_wont_overwrite_cheffile
|
51
|
+
outside_kitchen do
|
52
|
+
File.open("Cheffile", "w") do |f|
|
53
|
+
f << "testdata"
|
54
|
+
end
|
55
|
+
command(".", "--librarian").run
|
56
|
+
assert_equal "testdata", IO.read("Cheffile")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_creates_gitignore_for_librarian
|
61
|
+
outside_kitchen do
|
62
|
+
command("bar", "--librarian").run
|
63
|
+
assert File.exist?("bar/.gitignore")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_wont_create_gitignore_for_librarian_if_denied
|
68
|
+
outside_kitchen do
|
69
|
+
command(".", "--librarian", "--no-git").run
|
70
|
+
refute File.exist?(".gitignore")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
37
74
|
def command(*args)
|
38
75
|
knife_command(Chef::Knife::SoloInit, *args)
|
39
76
|
end
|
data/test/solo_prepare_test.rb
CHANGED
@@ -12,17 +12,22 @@ class SoloPrepareTest < TestCase
|
|
12
12
|
@host = 'someuser@somehost.domain.com'
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def test_combines_omnibus_options
|
16
16
|
in_kitchen do
|
17
|
-
|
18
|
-
|
17
|
+
bootstrap_instance = mock('mock OS bootstrap instance')
|
18
|
+
bootstrap_instance.stubs(:bootstrap!)
|
19
|
+
|
20
|
+
run_command = command(@host, "--omnibus-version", "0.10.8-3", "--omnibus-options", "-s")
|
21
|
+
run_command.stubs(:bootstrap).returns(bootstrap_instance)
|
22
|
+
run_command.run
|
23
|
+
|
24
|
+
assert_match "-s -v 0.10.8-3", run_command.config[:omnibus_options]
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
22
28
|
def test_run_raises_if_operating_system_is_not_supported
|
23
29
|
in_kitchen do
|
24
30
|
run_command = command(@host)
|
25
|
-
run_command.stubs(:required_files_present?).returns(true)
|
26
31
|
run_command.stubs(:operating_system).returns('MythicalOS')
|
27
32
|
assert_raises KnifeSolo::Bootstraps::OperatingSystemNotImplementedError do
|
28
33
|
run_command.run
|
@@ -32,14 +37,11 @@ class SoloPrepareTest < TestCase
|
|
32
37
|
|
33
38
|
def test_run_calls_bootstrap
|
34
39
|
in_kitchen do
|
35
|
-
run_command = command(@host)
|
36
40
|
bootstrap_instance = mock('mock OS bootstrap instance')
|
37
|
-
run_command.stubs(:required_files_present?).returns(true)
|
38
|
-
run_command.stubs(:operating_system).returns('MythicalOS')
|
39
|
-
run_command.stubs(:bootstrap).returns(bootstrap_instance)
|
40
|
-
|
41
41
|
bootstrap_instance.expects(:bootstrap!)
|
42
42
|
|
43
|
+
run_command = command(@host)
|
44
|
+
run_command.stubs(:bootstrap).returns(bootstrap_instance)
|
43
45
|
run_command.run
|
44
46
|
end
|
45
47
|
end
|
data/test/ssh_command_test.rb
CHANGED
@@ -19,6 +19,18 @@ class SshCommandTest < TestCase
|
|
19
19
|
assert_equal "test", command("10.0.0.1").user
|
20
20
|
end
|
21
21
|
|
22
|
+
def test_takes_user_from_options
|
23
|
+
cmd = command("10.0.0.1", "--ssh-user=test")
|
24
|
+
cmd.validate_ssh_options!
|
25
|
+
assert_equal "test", cmd.user
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_takes_user_as_arg
|
29
|
+
cmd = command("test@10.0.0.1", "--ssh-user=ignored")
|
30
|
+
cmd.validate_ssh_options!
|
31
|
+
assert_equal "test", cmd.user
|
32
|
+
end
|
33
|
+
|
22
34
|
def test_host_regex_rejects_invalid_hostnames
|
23
35
|
%w[@name @@name.com name@ name@@ joe@@example.com joe@name@example.com].each do |invalid|
|
24
36
|
cmd = command(invalid)
|
@@ -77,12 +89,19 @@ class SshCommandTest < TestCase
|
|
77
89
|
assert_equal "#{ENV['USER']}@10.0.0.1", cmd.ssh_args
|
78
90
|
|
79
91
|
cmd = command("usertest@10.0.0.1", "--ssh-config-file=myconfig")
|
92
|
+
cmd.validate_ssh_options!
|
80
93
|
assert_equal "usertest@10.0.0.1 -F myconfig", cmd.ssh_args
|
81
94
|
|
82
95
|
cmd = command("usertest@10.0.0.1", "--ssh-identity=my_rsa")
|
96
|
+
cmd.validate_ssh_options!
|
97
|
+
assert_equal "usertest@10.0.0.1 -i my_rsa", cmd.ssh_args
|
98
|
+
|
99
|
+
cmd = command("usertest@10.0.0.1", "--identity-file=my_rsa")
|
100
|
+
cmd.validate_ssh_options!
|
83
101
|
assert_equal "usertest@10.0.0.1 -i my_rsa", cmd.ssh_args
|
84
102
|
|
85
103
|
cmd = command("usertest@10.0.0.1", "--ssh-port=222")
|
104
|
+
cmd.validate_ssh_options!
|
86
105
|
assert_equal "usertest@10.0.0.1 -p 222", cmd.ssh_args
|
87
106
|
end
|
88
107
|
|
@@ -90,7 +109,7 @@ class SshCommandTest < TestCase
|
|
90
109
|
cmd = command
|
91
110
|
cmd.ui.expects(:err).with(regexp_matches(/hostname.*argument/))
|
92
111
|
$stdout.stubs(:puts)
|
93
|
-
assert_exits { cmd.
|
112
|
+
assert_exits { cmd.validate_ssh_options! }
|
94
113
|
end
|
95
114
|
|
96
115
|
def command(*args)
|
@@ -15,7 +15,7 @@ class IntegrationTest < TestCase
|
|
15
15
|
# Returns a name for the current test's server
|
16
16
|
# that should be fairly unique.
|
17
17
|
def server_name
|
18
|
-
"
|
18
|
+
"knife-solo_#{self.class}"
|
19
19
|
end
|
20
20
|
|
21
21
|
# Shortcut to access the test runner
|
@@ -72,7 +72,14 @@ class IntegrationTest < TestCase
|
|
72
72
|
|
73
73
|
# The prepare command to use on this server
|
74
74
|
def prepare_command
|
75
|
-
"prepare"
|
75
|
+
"prepare #{omnibus_options}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def omnibus_options
|
79
|
+
return "" if ENV['CHEF_VERSION'].to_s.empty?
|
80
|
+
|
81
|
+
v = `knife --version`.split(':')
|
82
|
+
v[0].strip == 'Chef' ? "--omnibus-version=#{v[1].strip}" : ''
|
76
83
|
end
|
77
84
|
|
78
85
|
# Provides the path to the runner's key file
|
data/test/support/test_case.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-solo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0.pre1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mat Schaffer
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -128,7 +128,7 @@ dependencies:
|
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
none: false
|
130
130
|
requirements:
|
131
|
-
- -
|
131
|
+
- - ! '>='
|
132
132
|
- !ruby/object:Gem::Version
|
133
133
|
version: '10.12'
|
134
134
|
type: :runtime
|
@@ -136,7 +136,7 @@ dependencies:
|
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
137
|
none: false
|
138
138
|
requirements:
|
139
|
-
- -
|
139
|
+
- - ! '>='
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '10.12'
|
142
142
|
- !ruby/object:Gem::Dependency
|
@@ -144,17 +144,23 @@ dependencies:
|
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
145
145
|
none: false
|
146
146
|
requirements:
|
147
|
-
- -
|
147
|
+
- - ! '>='
|
148
148
|
- !ruby/object:Gem::Version
|
149
149
|
version: 2.2.2
|
150
|
+
- - <
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '3.0'
|
150
153
|
type: :runtime
|
151
154
|
prerelease: false
|
152
155
|
version_requirements: !ruby/object:Gem::Requirement
|
153
156
|
none: false
|
154
157
|
requirements:
|
155
|
-
- -
|
158
|
+
- - ! '>='
|
156
159
|
- !ruby/object:Gem::Version
|
157
160
|
version: 2.2.2
|
161
|
+
- - <
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '3.0'
|
158
164
|
- !ruby/object:Gem::Dependency
|
159
165
|
name: librarian
|
160
166
|
requirement: !ruby/object:Gem::Requirement
|
@@ -199,6 +205,7 @@ files:
|
|
199
205
|
- lib/knife-solo/bootstraps/linux.rb
|
200
206
|
- lib/knife-solo/bootstraps/sun_os.rb
|
201
207
|
- lib/knife-solo/deprecated_command.rb
|
208
|
+
- lib/knife-solo/gitignore.rb
|
202
209
|
- lib/knife-solo/info.rb
|
203
210
|
- lib/knife-solo/kitchen_command.rb
|
204
211
|
- lib/knife-solo/node_config_command.rb
|
@@ -206,11 +213,14 @@ files:
|
|
206
213
|
- lib/knife-solo/tools.rb
|
207
214
|
- test/bootstraps_test.rb
|
208
215
|
- test/deprecated_command_test.rb
|
216
|
+
- test/gitignore_test.rb
|
209
217
|
- test/integration/cases/apache2_bootstrap.rb
|
210
218
|
- test/integration/cases/apache2_cook.rb
|
211
219
|
- test/integration/cases/empty_cook.rb
|
212
220
|
- test/integration/cases/encrypted_data_bag.rb
|
213
221
|
- test/integration/centos5_6_test.rb
|
222
|
+
- test/integration/debian6_bootstrap_test.rb
|
223
|
+
- test/integration/debian7_bootstrap_test.rb
|
214
224
|
- test/integration/gentoo2011_test.rb
|
215
225
|
- test/integration/omnios_r151004_test.rb
|
216
226
|
- test/integration/scientific_linux_63_test.rb
|
@@ -258,9 +268,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
258
268
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
259
269
|
none: false
|
260
270
|
requirements:
|
261
|
-
- - ! '
|
271
|
+
- - ! '>'
|
262
272
|
- !ruby/object:Gem::Version
|
263
|
-
version:
|
273
|
+
version: 1.3.1
|
264
274
|
requirements: []
|
265
275
|
rubyforge_project:
|
266
276
|
rubygems_version: 1.8.24
|
@@ -270,11 +280,14 @@ summary: A collection of knife plugins for dealing with chef solo
|
|
270
280
|
test_files:
|
271
281
|
- test/bootstraps_test.rb
|
272
282
|
- test/deprecated_command_test.rb
|
283
|
+
- test/gitignore_test.rb
|
273
284
|
- test/integration/cases/apache2_bootstrap.rb
|
274
285
|
- test/integration/cases/apache2_cook.rb
|
275
286
|
- test/integration/cases/empty_cook.rb
|
276
287
|
- test/integration/cases/encrypted_data_bag.rb
|
277
288
|
- test/integration/centos5_6_test.rb
|
289
|
+
- test/integration/debian6_bootstrap_test.rb
|
290
|
+
- test/integration/debian7_bootstrap_test.rb
|
278
291
|
- test/integration/gentoo2011_test.rb
|
279
292
|
- test/integration/omnios_r151004_test.rb
|
280
293
|
- test/integration/scientific_linux_63_test.rb
|
@@ -307,4 +320,3 @@ test_files:
|
|
307
320
|
- test/support/test_case.rb
|
308
321
|
- test/support/validation_helper.rb
|
309
322
|
- test/test_helper.rb
|
310
|
-
has_rdoc:
|