taste_tester 0.0.7 → 0.0.8
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/bin/taste-tester +7 -2
- data/lib/taste_tester/client.rb +1 -0
- data/lib/taste_tester/commands.rb +10 -3
- data/lib/taste_tester/config.rb +8 -6
- data/lib/taste_tester/host.rb +8 -6
- data/lib/taste_tester/server.rb +35 -9
- data/lib/taste_tester/ssh.rb +1 -0
- data/lib/taste_tester/state.rb +34 -2
- data/lib/taste_tester/tunnel.rb +29 -7
- metadata +78 -68
data/bin/taste-tester
CHANGED
@@ -335,8 +335,13 @@ MODES:
|
|
335
335
|
TasteTester::Logging.verbosity = TasteTester::Config.verbosity
|
336
336
|
TasteTester::Logging.use_log_formatter = TasteTester::Config.timestamp
|
337
337
|
|
338
|
-
if
|
339
|
-
|
338
|
+
if TasteTester::Config.plugin_path
|
339
|
+
path = File.expand_path(TasteTester::Config.plugin_path)
|
340
|
+
unless File.exists?(path)
|
341
|
+
logger.error("Plugin not found (#{path})")
|
342
|
+
exit(1)
|
343
|
+
end
|
344
|
+
TasteTester::Hooks.get(path)
|
340
345
|
end
|
341
346
|
|
342
347
|
case mode.to_sym
|
data/lib/taste_tester/client.rb
CHANGED
@@ -108,7 +108,7 @@ module TasteTester
|
|
108
108
|
def self.untest
|
109
109
|
hosts = TasteTester::Config.servers
|
110
110
|
unless hosts
|
111
|
-
logger.
|
111
|
+
logger.error('You must provide a hostname')
|
112
112
|
exit(1)
|
113
113
|
end
|
114
114
|
server = TasteTester::Server.new
|
@@ -152,14 +152,21 @@ module TasteTester
|
|
152
152
|
if TasteTester::Config.force_upload
|
153
153
|
server.restart
|
154
154
|
else
|
155
|
-
server.start
|
155
|
+
server.start
|
156
156
|
end
|
157
157
|
client = TasteTester::Client.new(server)
|
158
158
|
client.skip_checks = true if TasteTester::Config.skip_checks
|
159
159
|
client.force = true if TasteTester::Config.force_upload
|
160
160
|
client.upload
|
161
161
|
rescue => exception
|
162
|
-
|
162
|
+
# We're trying to recover from common chef-zero errors
|
163
|
+
# Most of them happen due to half finished uploads, which leave
|
164
|
+
# chef-zero in undefined state
|
165
|
+
errors = [
|
166
|
+
'Cannot find a cookbook named',
|
167
|
+
'Connection reset by peer',
|
168
|
+
'Object not found',
|
169
|
+
]
|
163
170
|
if errors.any? { |e| exception.to_s.match(/#{e}/im) }
|
164
171
|
TasteTester::Config.force_upload = true
|
165
172
|
unless @already_retried
|
data/lib/taste_tester/config.rb
CHANGED
@@ -34,8 +34,8 @@ module TasteTester
|
|
34
34
|
role_dir 'roles'
|
35
35
|
databag_dir 'databags'
|
36
36
|
config_file '/etc/taste-tester-config.rb'
|
37
|
-
plugin_path
|
38
|
-
chef_zero_path
|
37
|
+
plugin_path nil
|
38
|
+
chef_zero_path nil
|
39
39
|
verbosity Logger::WARN
|
40
40
|
timestamp false
|
41
41
|
user 'root'
|
@@ -47,7 +47,9 @@ module TasteTester
|
|
47
47
|
chef_port_range [5000, 5500]
|
48
48
|
tunnel_port 4001
|
49
49
|
timestamp_file '/etc/chef/test_timestamp'
|
50
|
-
use_ssh_tunnels
|
50
|
+
use_ssh_tunnels false
|
51
|
+
use_ssl true
|
52
|
+
chef_zero_logging true
|
51
53
|
|
52
54
|
skip_pre_upload_hook false
|
53
55
|
skip_post_upload_hook false
|
@@ -63,7 +65,7 @@ module TasteTester
|
|
63
65
|
|
64
66
|
def self.relative_cookbook_dirs
|
65
67
|
cookbook_dirs.map do |x|
|
66
|
-
File.join(base_dir, x)
|
68
|
+
(base_dir && !base_dir.empty?) ? File.join(base_dir, x) : x
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
@@ -72,7 +74,7 @@ module TasteTester
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def self.relative_role_dir
|
75
|
-
File.join(base_dir, role_dir)
|
77
|
+
(base_dir && !base_dir.empty?) ? File.join(base_dir, role_dir) : x
|
76
78
|
end
|
77
79
|
|
78
80
|
def self.databags
|
@@ -80,7 +82,7 @@ module TasteTester
|
|
80
82
|
end
|
81
83
|
|
82
84
|
def self.relative_databag_dir
|
83
|
-
File.join(base_dir, databag_dir)
|
85
|
+
(base_dir && !base_dir.empty?) ? File.join(base_dir, databag_dir) : x
|
84
86
|
end
|
85
87
|
|
86
88
|
def self.chef_port
|
data/lib/taste_tester/host.rb
CHANGED
@@ -176,10 +176,11 @@ module TasteTester
|
|
176
176
|
private
|
177
177
|
|
178
178
|
def config
|
179
|
+
scheme = TasteTester::Config.use_ssl ? 'https' : 'http'
|
179
180
|
if TasteTester::Config.use_ssh_tunnels
|
180
|
-
url = "
|
181
|
+
url = "#{scheme}://localhost:#{@tunnel.port}"
|
181
182
|
else
|
182
|
-
url = "
|
183
|
+
url = "#{scheme}://#{@server.host}:#{TasteTester::State.port}"
|
183
184
|
end
|
184
185
|
ttconfig = <<-eos
|
185
186
|
# TasteTester by #{@user}
|
@@ -189,12 +190,13 @@ if Process.euid != 0
|
|
189
190
|
Process.exit!
|
190
191
|
end
|
191
192
|
|
192
|
-
log_level
|
193
|
-
log_location
|
194
|
-
chef_server_url
|
193
|
+
log_level :info
|
194
|
+
log_location STDOUT
|
195
|
+
chef_server_url '#{url}'
|
196
|
+
ssl_verify_mode :verify_none
|
195
197
|
Ohai::Config[:plugin_path] << '/etc/chef/ohai_plugins'
|
196
198
|
|
197
|
-
|
199
|
+
eos
|
198
200
|
|
199
201
|
extra = TasteTester::Hooks.test_remote_client_rb_extra_code(@name)
|
200
202
|
if extra
|
data/lib/taste_tester/server.rb
CHANGED
@@ -35,6 +35,7 @@ module TasteTester
|
|
35
35
|
@state = TasteTester::State.new
|
36
36
|
@ref_file = TasteTester::Config.ref_file
|
37
37
|
ref_dir = File.dirname(File.expand_path(@ref_file))
|
38
|
+
@log_file = "#{ref_dir}/chef-zero.log"
|
38
39
|
@zero_path = TasteTester::Config.chef_zero_path
|
39
40
|
unless File.directory?(ref_dir)
|
40
41
|
begin
|
@@ -47,6 +48,12 @@ module TasteTester
|
|
47
48
|
|
48
49
|
@user = ENV['USER']
|
49
50
|
|
51
|
+
# SSL and logging are obvious, but SSH is also required since it
|
52
|
+
# determines if we listen only on localhost or not
|
53
|
+
@need_restart = @state.ssl != TasteTester::Config.use_ssl ||
|
54
|
+
@state.logging != TasteTester::Config.chef_zero_logging ||
|
55
|
+
@state.ssh != TasteTester::Config.use_ssh_tunnels
|
56
|
+
|
50
57
|
# If we are using SSH tunneling listen on localhost, otherwise listen
|
51
58
|
# on all addresses - both v4 and v6. Note that on localhost, ::1 is
|
52
59
|
# v6-only, so we default to 127.0.0.1 instead.
|
@@ -65,8 +72,17 @@ module TasteTester
|
|
65
72
|
end
|
66
73
|
|
67
74
|
def start
|
68
|
-
|
69
|
-
|
75
|
+
if TasteTester::Server.running?
|
76
|
+
if @need_restart
|
77
|
+
logger.warn('Restarting taste-tester server for config change')
|
78
|
+
stop_chef_zero
|
79
|
+
@need_restart = false
|
80
|
+
else
|
81
|
+
return
|
82
|
+
end
|
83
|
+
else
|
84
|
+
logger.warn('Starting taste-tester server')
|
85
|
+
end
|
70
86
|
@state.wipe
|
71
87
|
write_config
|
72
88
|
start_chef_zero
|
@@ -82,6 +98,7 @@ module TasteTester
|
|
82
98
|
logger.warn('Restarting taste-tester server')
|
83
99
|
if TasteTester::Server.running?
|
84
100
|
stop_chef_zero
|
101
|
+
@state.ref = nil
|
85
102
|
end
|
86
103
|
write_config
|
87
104
|
start_chef_zero
|
@@ -116,6 +133,7 @@ module TasteTester
|
|
116
133
|
knife = BetweenMeals::Knife.new(
|
117
134
|
:logger => logger,
|
118
135
|
:user => @user,
|
136
|
+
:ssl => TasteTester::Config.use_ssl,
|
119
137
|
:host => @host,
|
120
138
|
:port => port,
|
121
139
|
:role_dir => TasteTester::Config.roles,
|
@@ -126,14 +144,18 @@ module TasteTester
|
|
126
144
|
end
|
127
145
|
|
128
146
|
def start_chef_zero
|
129
|
-
|
130
|
-
|
131
|
-
|
147
|
+
File.unlink(@log_file) if File.exists?(@log_file)
|
148
|
+
@state.update({
|
149
|
+
:port => TasteTester::Config.chef_port,
|
150
|
+
:ssl => TasteTester::Config.use_ssl,
|
151
|
+
:ssh => TasteTester::Config.use_ssh_tunnels,
|
152
|
+
:logging => TasteTester::Config.chef_zero_logging,
|
153
|
+
})
|
132
154
|
logger.info("Starting chef-zero of port #{@state.port}")
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
).run_command.error!
|
155
|
+
cmd = "#{chef_zero_path} --host #{@addr} --port #{@state.port} -d"
|
156
|
+
cmd << " --log-file #{@log_file}" if TasteTester::Config.chef_zero_logging
|
157
|
+
cmd << ' --ssl' if TasteTester::Config.use_ssl
|
158
|
+
Mixlib::ShellOut.new(cmd).run_command.error!
|
137
159
|
end
|
138
160
|
|
139
161
|
def stop_chef_zero
|
@@ -145,6 +167,10 @@ module TasteTester
|
|
145
167
|
end
|
146
168
|
|
147
169
|
def chef_zero_path
|
170
|
+
if TasteTester::Config.chef_zero_path
|
171
|
+
return TasteTester::Config.chef_zero_path
|
172
|
+
end
|
173
|
+
|
148
174
|
[
|
149
175
|
'/opt/chef/bin/chef-zero',
|
150
176
|
'/opt/chef/embedded/bin/chef-zero',
|
data/lib/taste_tester/ssh.rb
CHANGED
data/lib/taste_tester/state.rb
CHANGED
@@ -51,6 +51,30 @@ module TasteTester
|
|
51
51
|
write(:port, port)
|
52
52
|
end
|
53
53
|
|
54
|
+
def ssl
|
55
|
+
TasteTester::State.read(:ssl)
|
56
|
+
end
|
57
|
+
|
58
|
+
def ssl=(ssl)
|
59
|
+
write(:ssl, ssl)
|
60
|
+
end
|
61
|
+
|
62
|
+
def logging
|
63
|
+
TasteTester::State.read(:logging)
|
64
|
+
end
|
65
|
+
|
66
|
+
def logging=(logging)
|
67
|
+
write(:logging, logging)
|
68
|
+
end
|
69
|
+
|
70
|
+
def ssh
|
71
|
+
TasteTester::State.read(:ssh)
|
72
|
+
end
|
73
|
+
|
74
|
+
def ssh=(ssh)
|
75
|
+
write(:ssh, ssh)
|
76
|
+
end
|
77
|
+
|
54
78
|
def ref
|
55
79
|
TasteTester::State.read(:ref)
|
56
80
|
end
|
@@ -59,6 +83,10 @@ module TasteTester
|
|
59
83
|
write(:ref, ref)
|
60
84
|
end
|
61
85
|
|
86
|
+
def update(vals)
|
87
|
+
merge(vals)
|
88
|
+
end
|
89
|
+
|
62
90
|
def self.port
|
63
91
|
TasteTester::State.read(:port)
|
64
92
|
end
|
@@ -72,13 +100,17 @@ module TasteTester
|
|
72
100
|
|
73
101
|
private
|
74
102
|
|
75
|
-
def write(key,
|
103
|
+
def write(key, val)
|
104
|
+
merge({key => val})
|
105
|
+
end
|
106
|
+
|
107
|
+
def merge(vals)
|
76
108
|
begin
|
77
109
|
state = JSON.parse(File.read(TasteTester::Config.ref_file))
|
78
110
|
rescue
|
79
111
|
state = {}
|
80
112
|
end
|
81
|
-
state
|
113
|
+
state.merge!(vals)
|
82
114
|
ff = File.open(
|
83
115
|
TasteTester::Config.ref_file,
|
84
116
|
'w'
|
data/lib/taste_tester/tunnel.rb
CHANGED
@@ -44,13 +44,31 @@ module TasteTester
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def cmd
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
if TasteTester::Config.user != 'root'
|
48
|
+
pid = '$$'
|
49
|
+
else
|
50
|
+
pid = '\\$\\$'
|
51
|
+
end
|
52
|
+
cmds = "ps -p #{pid} -o pgid | grep -v PGID > #{TasteTester::Config.timestamp_file} &&" +
|
53
|
+
" touch -t #{TasteTester::Config.testing_end_time}" +
|
54
|
+
" #{TasteTester::Config.timestamp_file} && sleep #{@delta_secs}"
|
55
|
+
# As great as it would be to have ExitOnForwardFailure=yes,
|
56
|
+
# we had multiple cases of tunnels dying
|
57
|
+
# if -f and ExitOnForwardFailure are used together.
|
58
|
+
# In most cases the first request from chef was "breaking" the tunnel,
|
59
|
+
# in a way that port was still open, but subsequent requests were hanging.
|
60
|
+
# This is reproducible and should be looked into.
|
50
61
|
cmd = "ssh -T -o BatchMode=yes -o ConnectTimeout=#{@timeout} " +
|
62
|
+
'-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' +
|
51
63
|
'-o ServerAliveInterval=10 -o ServerAliveCountMax=6 ' +
|
52
|
-
"-f -R #{@port}:localhost:#{@server.port} "
|
53
|
-
|
64
|
+
"-f -R #{@port}:localhost:#{@server.port} "
|
65
|
+
if TasteTester::Config.user != 'root'
|
66
|
+
cc = Base64.encode64(cmds).gsub(/\n/, '')
|
67
|
+
cmd += "#{TasteTester::Config.user}@#{@host} \"echo '#{cc}' | base64" +
|
68
|
+
' --decode | sudo bash -x"'
|
69
|
+
else
|
70
|
+
cmd += "root@#{@host} \"#{cmds}\""
|
71
|
+
end
|
54
72
|
cmd
|
55
73
|
end
|
56
74
|
|
@@ -60,8 +78,12 @@ module TasteTester
|
|
60
78
|
# surround this in paryns, and make sure as a whole it evaluates
|
61
79
|
# to true so it doesn't mess up other things... even though this is
|
62
80
|
# the only thing we're currently executing in this SSH.
|
63
|
-
|
64
|
-
|
81
|
+
if TasteTester::Config.user != 'root'
|
82
|
+
sudo = 'sudo '
|
83
|
+
end
|
84
|
+
cmd = "( [ -s #{TasteTester::Config.timestamp_file} ]" +
|
85
|
+
" && #{sudo}kill -9 -- -\$(cat #{TasteTester::Config.timestamp_file}); true )"
|
86
|
+
ssh << cmd
|
65
87
|
ssh.run!
|
66
88
|
end
|
67
89
|
end
|
metadata
CHANGED
@@ -1,111 +1,121 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: taste_tester
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Phil Dibowitz
|
9
14
|
- Marcin Sawicki
|
10
15
|
autorequire:
|
11
16
|
bindir: bin
|
12
17
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
18
|
+
|
19
|
+
date: 2015-01-05 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
16
22
|
name: mixlib-config
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ! '>='
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '0'
|
23
|
-
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
|
26
|
-
none: false
|
27
|
-
requirements:
|
28
|
-
- - ! '>='
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: '0'
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
name: colorize
|
33
|
-
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
34
25
|
none: false
|
35
|
-
requirements:
|
36
|
-
- -
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
39
33
|
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: colorize
|
40
37
|
prerelease: false
|
41
|
-
|
42
|
-
none: false
|
43
|
-
requirements:
|
44
|
-
- - ! '>='
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '0'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: between_meals
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
|
-
requirements:
|
52
|
-
- -
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
55
47
|
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: between_meals
|
56
51
|
prerelease: false
|
57
|
-
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
53
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
63
|
description: Utility for testing Chef changes using chef-zero
|
64
64
|
email:
|
65
|
-
executables:
|
65
|
+
executables:
|
66
66
|
- taste-tester
|
67
67
|
extensions: []
|
68
|
-
|
68
|
+
|
69
|
+
extra_rdoc_files:
|
69
70
|
- README.md
|
70
71
|
- LICENSE
|
71
|
-
files:
|
72
|
+
files:
|
72
73
|
- README.md
|
73
74
|
- LICENSE
|
74
|
-
- lib/taste_tester/hooks.rb
|
75
|
-
- lib/taste_tester/logging.rb
|
76
|
-
- lib/taste_tester/commands.rb
|
77
|
-
- lib/taste_tester/tunnel.rb
|
78
75
|
- lib/taste_tester/host.rb
|
79
|
-
- lib/taste_tester/
|
76
|
+
- lib/taste_tester/ssh.rb
|
77
|
+
- lib/taste_tester/tunnel.rb
|
78
|
+
- lib/taste_tester/server.rb
|
80
79
|
- lib/taste_tester/client.rb
|
80
|
+
- lib/taste_tester/hooks.rb
|
81
81
|
- lib/taste_tester/config.rb
|
82
|
-
- lib/taste_tester/
|
83
|
-
- lib/taste_tester/
|
82
|
+
- lib/taste_tester/logging.rb
|
83
|
+
- lib/taste_tester/state.rb
|
84
|
+
- lib/taste_tester/commands.rb
|
84
85
|
- bin/taste-tester
|
85
86
|
- scripts/taste-untester
|
86
87
|
homepage: https://github.com/facebook/taste-tester
|
87
|
-
licenses:
|
88
|
+
licenses:
|
88
89
|
- Apache
|
89
90
|
post_install_message:
|
90
91
|
rdoc_options: []
|
91
|
-
|
92
|
+
|
93
|
+
require_paths:
|
92
94
|
- lib
|
93
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
96
|
none: false
|
95
|
-
requirements:
|
96
|
-
- -
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
|
99
|
-
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
105
|
none: false
|
101
|
-
requirements:
|
102
|
-
- -
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 3
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
105
113
|
requirements: []
|
114
|
+
|
106
115
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.8.
|
116
|
+
rubygems_version: 1.8.5
|
108
117
|
signing_key:
|
109
118
|
specification_version: 3
|
110
119
|
summary: Taste Tester
|
111
120
|
test_files: []
|
121
|
+
|