knife-solo 0.1.0 → 0.2.0.pre1
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/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:
|