taste_tester 0.0.8 → 0.0.9
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/README.md +10 -4
- data/bin/taste-tester +36 -18
- data/lib/taste_tester/client.rb +5 -4
- data/lib/taste_tester/commands.rb +6 -5
- data/lib/taste_tester/config.rb +12 -6
- data/lib/taste_tester/hooks.rb +5 -3
- data/lib/taste_tester/host.rb +35 -23
- data/lib/taste_tester/logging.rb +3 -3
- data/lib/taste_tester/server.rb +11 -11
- data/lib/taste_tester/ssh.rb +9 -6
- data/lib/taste_tester/state.rb +7 -7
- data/lib/taste_tester/tunnel.rb +16 -13
- metadata +55 -13
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Taste Tester
|
2
2
|
|
3
|
+
[](http://travis-ci.org/facebook/taste-tester)
|
4
|
+
|
3
5
|
## Intro
|
4
6
|
Ohai!
|
5
7
|
|
@@ -38,8 +40,9 @@ See the help for futher information.
|
|
38
40
|
|
39
41
|
## Prerequisites
|
40
42
|
|
41
|
-
* Taste Tester assumes that /etc/chef/client.rb on your
|
42
|
-
that your real config is /etc/chef/client-prod.rb
|
43
|
+
* Taste Tester assumes that /etc/chef/client.rb and /etc/chef/client.pem on your
|
44
|
+
servers is a symlink and that your real config is /etc/chef/client-prod.rb and
|
45
|
+
/etc/chef/client-prod.pem, respectively.
|
43
46
|
|
44
47
|
* Taste Tester assumes that it's generally safe to "go back" to production. I.e.
|
45
48
|
We set things up so you can set a cronjob to un-taste-test a server after the
|
@@ -47,7 +50,10 @@ desired amount of time, which means it must be (relatively) safe to revert
|
|
47
50
|
back.
|
48
51
|
|
49
52
|
* Taste Tester assumes you use a setup similar to grocery-delivery in
|
50
|
-
production. Specifically that you don't use versions or environments.
|
53
|
+
production. Specifically that you don't use versions or environments.
|
54
|
+
|
55
|
+
* Taste Tester assumes you have password-less SSH authentication to the hosts
|
56
|
+
you want to test on, i.e. SSH public/private keys, SSH certificates, Kerberos
|
51
57
|
|
52
58
|
## Dependencies
|
53
59
|
|
@@ -79,7 +85,7 @@ standard Ruby.
|
|
79
85
|
All command-line options are available in the config file:
|
80
86
|
* debug (bool, default: `false`)
|
81
87
|
* timestamp (bool, default: `false`)
|
82
|
-
* config_file (string, default: `/etc/
|
88
|
+
* config_file (string, default: `/etc/taste-tester-config.rb`)
|
83
89
|
* plugin_path (string, default: `/etc/taste-tester-plugin.rb`)
|
84
90
|
* repo (string, default: `#{ENV['HOME']}/ops`)
|
85
91
|
* testing_time (int, default: `3600`)
|
data/bin/taste-tester
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#!/
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
3
3
|
|
4
4
|
# Copyright 2013-present Facebook
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
8
8
|
# You may obtain a copy of the License at
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# Unless required by applicable law or agreed to in writing, software
|
13
13
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
14
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -18,10 +18,6 @@
|
|
18
18
|
$LOAD_PATH.unshift(File.dirname(File.realpath(__FILE__)) + '/../lib')
|
19
19
|
|
20
20
|
# rubocop:disable UnusedBlockArgument, AlignParameters
|
21
|
-
if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
|
22
|
-
puts 'Please disable RVM before running taste-tester'
|
23
|
-
exit(1)
|
24
|
-
end
|
25
21
|
|
26
22
|
require 'rubygems'
|
27
23
|
require 'time'
|
@@ -43,6 +39,15 @@ end
|
|
43
39
|
# Command line parsing and param descriptions
|
44
40
|
module TasteTester
|
45
41
|
verify = 'Verify your changes were actually applied as intended!'.red
|
42
|
+
|
43
|
+
# Do an initial read of the config file if it's in the default place, so
|
44
|
+
# that if people override chef_client_command the help message is correct.
|
45
|
+
if File.exists?(File.expand_path(TasteTester::Config.config_file))
|
46
|
+
TasteTester::Config.from_file(
|
47
|
+
File.expand_path(TasteTester::Config.config_file)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
46
51
|
cmd = TasteTester::Config.chef_client_command
|
47
52
|
description = <<-EOF
|
48
53
|
Welcome to taste-tester!
|
@@ -50,17 +55,17 @@ Welcome to taste-tester!
|
|
50
55
|
Usage: taste-tester <mode> [<options>]
|
51
56
|
|
52
57
|
TLDR; Most common usage is:
|
53
|
-
vi cookbooks/...
|
54
|
-
taste-tester test -s [host]
|
55
|
-
ssh root@[host]
|
56
|
-
#{format('%-28s', " #{cmd}")}
|
57
|
-
vi cookbooks/...
|
58
|
-
taste-tester upload
|
59
|
-
ssh root@[host]
|
60
|
-
#{format('%-28s', " #{cmd}")}
|
58
|
+
vi cookbooks/... # Make your changes and commit locally
|
59
|
+
taste-tester test -s [host] # Put host in test mode
|
60
|
+
ssh root@[host] # Log on host
|
61
|
+
#{format('%-28s', " #{cmd}")} # Run chef and watch it break
|
62
|
+
vi cookbooks/... # Fix your cookbooks
|
63
|
+
taste-tester upload # Upload the diff
|
64
|
+
ssh root@[host] # Log on host
|
65
|
+
#{format('%-28s', " #{cmd}")} # Run chef and watch it succeed
|
61
66
|
<#{verify}>
|
62
|
-
taste-tester untest [host]
|
63
|
-
|
67
|
+
taste-tester untest -s [host] # Put host back in production
|
68
|
+
# (optional - will revert itself after 1 hour)
|
64
69
|
|
65
70
|
And you're done! See the above wiki page for more details.
|
66
71
|
|
@@ -247,6 +252,13 @@ MODES:
|
|
247
252
|
options[:repo] = dir
|
248
253
|
end
|
249
254
|
|
255
|
+
opts.on(
|
256
|
+
'--repo-type TYPE',
|
257
|
+
'Override repo type, default is auto.'
|
258
|
+
) do |type|
|
259
|
+
options[:repo_type] = type
|
260
|
+
end
|
261
|
+
|
250
262
|
opts.on(
|
251
263
|
'-R', '--roles ROLE[,ROLE]', Array,
|
252
264
|
'Specific roles to upload. Intended mostly for debugging,' +
|
@@ -279,6 +291,12 @@ MODES:
|
|
279
291
|
options[:use_ssh_tunnels] = s
|
280
292
|
end
|
281
293
|
|
294
|
+
opts.on(
|
295
|
+
'-e', '--ssh CMD', 'SSH command to use, defaults to "ssh".'
|
296
|
+
) do |c|
|
297
|
+
options[:ssh_command] = c
|
298
|
+
end
|
299
|
+
|
282
300
|
opts.on('--skip-repo-checks', 'Skip repository sanity checks') do
|
283
301
|
options[:skip_repo_checks] = true
|
284
302
|
end
|
data/lib/taste_tester/client.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -30,6 +30,8 @@ module TasteTester
|
|
30
30
|
attr_accessor :force, :skip_checks
|
31
31
|
|
32
32
|
def initialize(server)
|
33
|
+
path = File.expand_path(TasteTester::Config.repo)
|
34
|
+
logger.warn("Using #{path}")
|
33
35
|
@server = server
|
34
36
|
@knife = BetweenMeals::Knife.new(
|
35
37
|
:logger => logger,
|
@@ -62,7 +64,6 @@ module TasteTester
|
|
62
64
|
def upload
|
63
65
|
checks unless @skip_checks
|
64
66
|
|
65
|
-
logger.warn("Using #{TasteTester::Config.repo}")
|
66
67
|
logger.info("Last commit: #{@repo.head_rev} " +
|
67
68
|
"'#{@repo.last_msg.split("\n").first}'" +
|
68
69
|
" by #{@repo.last_author[:email]}")
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -155,7 +155,7 @@ module TasteTester
|
|
155
155
|
server.start
|
156
156
|
end
|
157
157
|
client = TasteTester::Client.new(server)
|
158
|
-
client.skip_checks = true if TasteTester::Config.
|
158
|
+
client.skip_checks = true if TasteTester::Config.skip_repo_checks
|
159
159
|
client.force = true if TasteTester::Config.force_upload
|
160
160
|
client.upload
|
161
161
|
rescue => exception
|
@@ -174,8 +174,9 @@ module TasteTester
|
|
174
174
|
retry
|
175
175
|
end
|
176
176
|
end
|
177
|
-
logger.error(
|
177
|
+
logger.error('Upload failed')
|
178
178
|
logger.error(exception.to_s)
|
179
|
+
logger.error(exception.backtrace.join("\n"))
|
179
180
|
exit 1
|
180
181
|
end
|
181
182
|
end
|
data/lib/taste_tester/config.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -28,7 +28,7 @@ module TasteTester
|
|
28
28
|
extend BetweenMeals::Util
|
29
29
|
|
30
30
|
repo "#{ENV['HOME']}/ops"
|
31
|
-
repo_type '
|
31
|
+
repo_type 'auto'
|
32
32
|
base_dir 'chef'
|
33
33
|
cookbook_dirs ['cookbooks']
|
34
34
|
role_dir 'roles'
|
@@ -48,8 +48,10 @@ module TasteTester
|
|
48
48
|
tunnel_port 4001
|
49
49
|
timestamp_file '/etc/chef/test_timestamp'
|
50
50
|
use_ssh_tunnels false
|
51
|
+
ssh_command 'ssh'
|
51
52
|
use_ssl true
|
52
53
|
chef_zero_logging true
|
54
|
+
chef_config_path '/etc/chef'
|
53
55
|
|
54
56
|
skip_pre_upload_hook false
|
55
57
|
skip_post_upload_hook false
|
@@ -74,7 +76,7 @@ module TasteTester
|
|
74
76
|
end
|
75
77
|
|
76
78
|
def self.relative_role_dir
|
77
|
-
(base_dir && !base_dir.empty?) ? File.join(base_dir, role_dir) :
|
79
|
+
(base_dir && !base_dir.empty?) ? File.join(base_dir, role_dir) : role_dir
|
78
80
|
end
|
79
81
|
|
80
82
|
def self.databags
|
@@ -82,7 +84,11 @@ module TasteTester
|
|
82
84
|
end
|
83
85
|
|
84
86
|
def self.relative_databag_dir
|
85
|
-
|
87
|
+
if base_dir && !base_dir.empty?
|
88
|
+
File.join(base_dir, databag_dir)
|
89
|
+
else
|
90
|
+
databag_dir
|
91
|
+
end
|
86
92
|
end
|
87
93
|
|
88
94
|
def self.chef_port
|
data/lib/taste_tester/hooks.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -16,6 +16,8 @@
|
|
16
16
|
|
17
17
|
require 'taste_tester/logging'
|
18
18
|
require 'between_meals/util'
|
19
|
+
require 'between_meals/repo/hg'
|
20
|
+
require 'between_meals/repo/git'
|
19
21
|
|
20
22
|
module TasteTester
|
21
23
|
# Hooks placeholders
|
data/lib/taste_tester/host.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -39,8 +39,10 @@ module TasteTester
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def runchef
|
42
|
-
logger.warn("Running '#{TasteTester::Config.
|
43
|
-
|
42
|
+
logger.warn("Running '#{TasteTester::Config.chef_client_command}' " +
|
43
|
+
"on #{@name}")
|
44
|
+
cmd = "#{TasteTester::Config.ssh_command} " +
|
45
|
+
"#{TasteTester::Config.user}@#{@name} "
|
44
46
|
if TasteTester::Config.user != 'root'
|
45
47
|
cc = Base64.encode64(cmds).gsub(/\n/, '')
|
46
48
|
cmd += "\"echo '#{cc}' | base64 --decode | sudo bash -x\""
|
@@ -58,12 +60,12 @@ module TasteTester
|
|
58
60
|
io.close
|
59
61
|
$CHILD_STATUS.to_i
|
60
62
|
end
|
61
|
-
logger.warn("Finished #{TasteTester::Config.
|
63
|
+
logger.warn("Finished #{TasteTester::Config.chef_client_command}" +
|
62
64
|
" on #{@name} with status #{status}")
|
63
65
|
if status == 0
|
64
|
-
msg = "#{TasteTester::Config.
|
65
|
-
|
66
|
-
|
66
|
+
msg = "#{TasteTester::Config.chef_client_command} was successful" +
|
67
|
+
' - please log to the host and confirm all the intended' +
|
68
|
+
' changes were made'
|
67
69
|
logger.error msg.upcase
|
68
70
|
end
|
69
71
|
end
|
@@ -88,10 +90,11 @@ module TasteTester
|
|
88
90
|
ssh << "touch -t #{TasteTester::Config.testing_end_time}" +
|
89
91
|
" #{TasteTester::Config.timestamp_file}"
|
90
92
|
ssh << "echo -n '#{@serialized_config}' | base64 --decode" +
|
91
|
-
|
92
|
-
ssh <<
|
93
|
-
ssh <<
|
94
|
-
|
93
|
+
" > #{TasteTester::Config.chef_config_path}/client-taste-tester.rb"
|
94
|
+
ssh << "rm -vf #{TasteTester::Config.chef_config_path}/client.rb"
|
95
|
+
ssh << "( ln -vs #{TasteTester::Config.chef_config_path}" +
|
96
|
+
"/client-taste-tester.rb #{TasteTester::Config.chef_config_path}/" +
|
97
|
+
'client.rb; true )'
|
95
98
|
ssh.run!
|
96
99
|
|
97
100
|
# Then run any other stuff they wanted
|
@@ -113,19 +116,26 @@ module TasteTester
|
|
113
116
|
if TasteTester::Config.use_ssh_tunnels
|
114
117
|
TasteTester::Tunnel.kill(@name)
|
115
118
|
end
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
119
|
+
[
|
120
|
+
"rm -vf #{TasteTester::Config.chef_config_path}/client.rb",
|
121
|
+
"rm -vf #{TasteTester::Config.chef_config_path}/client-taste-tester.rb",
|
122
|
+
"ln -vs #{TasteTester::Config.chef_config_path}/client-prod.rb " +
|
123
|
+
"#{TasteTester::Config.chef_config_path}/client.rb",
|
124
|
+
"rm -vf #{TasteTester::Config.chef_config_path}/client.pem",
|
125
|
+
"ln -vs #{TasteTester::Config.chef_config_path}/client-prod.pem " +
|
126
|
+
"#{TasteTester::Config.chef_config_path}/client.pem",
|
127
|
+
"rm -vf #{TasteTester::Config.timestamp_file}",
|
128
|
+
'logger -t taste-tester Returning server to production',
|
129
|
+
].each do |cmd|
|
130
|
+
ssh << cmd
|
131
|
+
end
|
123
132
|
ssh.run!
|
124
133
|
end
|
125
134
|
|
126
135
|
def who_is_testing
|
127
136
|
ssh = TasteTester::SSH.new(@name)
|
128
|
-
ssh << 'grep "^# TasteTester by"
|
137
|
+
ssh << 'grep "^# TasteTester by"' +
|
138
|
+
" #{TasteTester::Config.chef_config_path}/client.rb"
|
129
139
|
output = ssh.run
|
130
140
|
if output.first == 0
|
131
141
|
user = output.last.match(/# TasteTester by (.*)$/)
|
@@ -136,7 +146,7 @@ module TasteTester
|
|
136
146
|
|
137
147
|
# Legacy FB stuff, remove after migration. Safe for everyone else.
|
138
148
|
ssh = TasteTester::SSH.new(@name)
|
139
|
-
ssh <<
|
149
|
+
ssh << "file #{TasteTester::Config.chef_config_path}/client.rb"
|
140
150
|
output = ssh.run
|
141
151
|
if output.first == 0
|
142
152
|
user = output.last.match(/client-(.*)-(taste-tester|test).rb/)
|
@@ -182,6 +192,7 @@ module TasteTester
|
|
182
192
|
else
|
183
193
|
url = "#{scheme}://#{@server.host}:#{TasteTester::State.port}"
|
184
194
|
end
|
195
|
+
# rubocop:disable Metrics/LineLength
|
185
196
|
ttconfig = <<-eos
|
186
197
|
# TasteTester by #{@user}
|
187
198
|
# Prevent people from screwing up their permissions
|
@@ -194,9 +205,10 @@ log_level :info
|
|
194
205
|
log_location STDOUT
|
195
206
|
chef_server_url '#{url}'
|
196
207
|
ssl_verify_mode :verify_none
|
197
|
-
Ohai::Config[:plugin_path] << '/
|
208
|
+
Ohai::Config[:plugin_path] << '#{TasteTester::Config.chef_config_path}/ohai_plugins'
|
198
209
|
|
199
210
|
eos
|
211
|
+
# rubocop:enable Metrics/LineLength
|
200
212
|
|
201
213
|
extra = TasteTester::Hooks.test_remote_client_rb_extra_code(@name)
|
202
214
|
if extra
|
data/lib/taste_tester/logging.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
data/lib/taste_tester/server.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -51,8 +51,8 @@ module TasteTester
|
|
51
51
|
# SSL and logging are obvious, but SSH is also required since it
|
52
52
|
# determines if we listen only on localhost or not
|
53
53
|
@need_restart = @state.ssl != TasteTester::Config.use_ssl ||
|
54
|
-
|
55
|
-
|
54
|
+
@state.logging != TasteTester::Config.chef_zero_logging ||
|
55
|
+
@state.ssh != TasteTester::Config.use_ssh_tunnels
|
56
56
|
|
57
57
|
# If we are using SSH tunneling listen on localhost, otherwise listen
|
58
58
|
# on all addresses - both v4 and v6. Note that on localhost, ::1 is
|
@@ -146,11 +146,11 @@ module TasteTester
|
|
146
146
|
def start_chef_zero
|
147
147
|
File.unlink(@log_file) if File.exists?(@log_file)
|
148
148
|
@state.update({
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
+
})
|
154
154
|
logger.info("Starting chef-zero of port #{@state.port}")
|
155
155
|
cmd = "#{chef_zero_path} --host #{@addr} --port #{@state.port} -d"
|
156
156
|
cmd << " --log-file #{@log_file}" if TasteTester::Config.chef_zero_logging
|
@@ -177,7 +177,7 @@ module TasteTester
|
|
177
177
|
].each do |path|
|
178
178
|
return path if File.exist?(path)
|
179
179
|
end
|
180
|
-
logger.error(
|
180
|
+
logger.error('chef-zero not found')
|
181
181
|
exit(1)
|
182
182
|
end
|
183
183
|
end
|
data/lib/taste_tester/ssh.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -46,7 +46,9 @@ module TasteTester
|
|
46
46
|
error = <<-MSG
|
47
47
|
SSH returned error while connecting to #{TasteTester::Config.user}@#{@host}
|
48
48
|
The host might be broken or your SSH access is not working properly
|
49
|
-
Try doing
|
49
|
+
Try doing
|
50
|
+
#{TasteTester::Config.ssh_command} -v #{TasteTester::Config.user}@#{@host}
|
51
|
+
and come back once that works
|
50
52
|
MSG
|
51
53
|
# rubocop:enable LineLength
|
52
54
|
error.lines.each { |x| logger.error x.strip }
|
@@ -61,8 +63,9 @@ MSG
|
|
61
63
|
logger.info("Will run: '#{cmd}' on #{@host}")
|
62
64
|
end
|
63
65
|
cmds = @cmds.join(' && ')
|
64
|
-
cmd = "
|
65
|
-
|
66
|
+
cmd = "#{TasteTester::Config.ssh_command} " +
|
67
|
+
"-T -o BatchMode=yes -o ConnectTimeout=#{@timeout} " +
|
68
|
+
"#{TasteTester::Config.user}@#{@host} "
|
66
69
|
if TasteTester::Config.user != 'root'
|
67
70
|
cc = Base64.encode64(cmds).gsub(/\n/, '')
|
68
71
|
cmd += "\"echo '#{cc}' | base64 --decode | sudo bash -x\""
|
data/lib/taste_tester/state.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -25,12 +25,12 @@ module TasteTester
|
|
25
25
|
# State of taste-tester processes
|
26
26
|
class State
|
27
27
|
include TasteTester::Config
|
28
|
-
|
28
|
+
extend TasteTester::Logging
|
29
29
|
include ::BetweenMeals::Util
|
30
30
|
|
31
31
|
def initialize
|
32
32
|
ref_dir = File.dirname(File.expand_path(
|
33
|
-
|
33
|
+
TasteTester::Config.ref_file
|
34
34
|
))
|
35
35
|
unless File.directory?(ref_dir)
|
36
36
|
begin
|
@@ -93,7 +93,7 @@ module TasteTester
|
|
93
93
|
|
94
94
|
def wipe
|
95
95
|
if TasteTester::Config.ref_file &&
|
96
|
-
|
96
|
+
File.exists?(TasteTester::Config.ref_file)
|
97
97
|
File.delete(TasteTester::Config.ref_file)
|
98
98
|
end
|
99
99
|
end
|
@@ -101,7 +101,7 @@ module TasteTester
|
|
101
101
|
private
|
102
102
|
|
103
103
|
def write(key, val)
|
104
|
-
merge({key => val})
|
104
|
+
merge({ key => val })
|
105
105
|
end
|
106
106
|
|
107
107
|
def merge(vals)
|
data/lib/taste_tester/tunnel.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
|
2
2
|
|
3
3
|
# Copyright 2013-present Facebook
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
7
7
|
# You may obtain a copy of the License at
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Unless required by applicable law or agreed to in writing, software
|
12
12
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
13
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -28,7 +28,7 @@ module TasteTester
|
|
28
28
|
@timeout = timeout
|
29
29
|
if TasteTester::Config.testing_until
|
30
30
|
@delta_secs = TasteTester::Config.testing_until.strftime('%s').to_i -
|
31
|
-
|
31
|
+
Time.now.strftime('%s').to_i
|
32
32
|
else
|
33
33
|
@delta_secs = TasteTester::Config.testing_time
|
34
34
|
end
|
@@ -49,23 +49,25 @@ module TasteTester
|
|
49
49
|
else
|
50
50
|
pid = '\\$\\$'
|
51
51
|
end
|
52
|
-
cmds = "ps -p #{pid} -o pgid | grep -v PGID
|
53
|
-
|
54
|
-
|
52
|
+
cmds = "ps -p #{pid} -o pgid | grep -v PGID" +
|
53
|
+
" > #{TasteTester::Config.timestamp_file} &&" +
|
54
|
+
" touch -t #{TasteTester::Config.testing_end_time}" +
|
55
|
+
" #{TasteTester::Config.timestamp_file} && sleep #{@delta_secs}"
|
55
56
|
# As great as it would be to have ExitOnForwardFailure=yes,
|
56
57
|
# we had multiple cases of tunnels dying
|
57
58
|
# if -f and ExitOnForwardFailure are used together.
|
58
59
|
# In most cases the first request from chef was "breaking" the tunnel,
|
59
60
|
# in a way that port was still open, but subsequent requests were hanging.
|
60
61
|
# This is reproducible and should be looked into.
|
61
|
-
cmd = "
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
cmd = "#{TasteTester::Config.ssh_command} " +
|
63
|
+
"-T -o BatchMode=yes -o ConnectTimeout=#{@timeout} " +
|
64
|
+
'-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' +
|
65
|
+
'-o ServerAliveInterval=10 -o ServerAliveCountMax=6 ' +
|
66
|
+
"-f -R #{@port}:localhost:#{@server.port} "
|
65
67
|
if TasteTester::Config.user != 'root'
|
66
68
|
cc = Base64.encode64(cmds).gsub(/\n/, '')
|
67
69
|
cmd += "#{TasteTester::Config.user}@#{@host} \"echo '#{cc}' | base64" +
|
68
|
-
|
70
|
+
' --decode | sudo bash -x"'
|
69
71
|
else
|
70
72
|
cmd += "root@#{@host} \"#{cmds}\""
|
71
73
|
end
|
@@ -82,7 +84,8 @@ module TasteTester
|
|
82
84
|
sudo = 'sudo '
|
83
85
|
end
|
84
86
|
cmd = "( [ -s #{TasteTester::Config.timestamp_file} ]" +
|
85
|
-
|
87
|
+
" && #{sudo}kill -9 -- " +
|
88
|
+
"-\$(cat #{TasteTester::Config.timestamp_file}); true )"
|
86
89
|
ssh << cmd
|
87
90
|
ssh.run!
|
88
91
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taste_tester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 9
|
10
|
+
version: 0.0.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Phil Dibowitz
|
@@ -16,10 +16,10 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2015-
|
19
|
+
date: 2015-11-26 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
22
|
+
name: between_meals >= 0.0.6
|
23
23
|
prerelease: false
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
36
|
+
name: mixlib-config
|
37
37
|
prerelease: false
|
38
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
@@ -47,7 +47,7 @@ dependencies:
|
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id002
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
50
|
+
name: colorize
|
51
51
|
prerelease: false
|
52
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
@@ -60,6 +60,48 @@ dependencies:
|
|
60
60
|
version: "0"
|
61
61
|
type: :runtime
|
62
62
|
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rubocop
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: chef-zero
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: knife-solo
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :development
|
104
|
+
version_requirements: *id006
|
63
105
|
description: Utility for testing Chef changes using chef-zero
|
64
106
|
email:
|
65
107
|
executables:
|
@@ -73,15 +115,15 @@ files:
|
|
73
115
|
- README.md
|
74
116
|
- LICENSE
|
75
117
|
- lib/taste_tester/host.rb
|
76
|
-
- lib/taste_tester/ssh.rb
|
77
|
-
- lib/taste_tester/tunnel.rb
|
78
|
-
- lib/taste_tester/server.rb
|
79
118
|
- lib/taste_tester/client.rb
|
80
119
|
- lib/taste_tester/hooks.rb
|
81
|
-
- lib/taste_tester/config.rb
|
82
|
-
- lib/taste_tester/logging.rb
|
83
|
-
- lib/taste_tester/state.rb
|
84
120
|
- lib/taste_tester/commands.rb
|
121
|
+
- lib/taste_tester/state.rb
|
122
|
+
- lib/taste_tester/ssh.rb
|
123
|
+
- lib/taste_tester/server.rb
|
124
|
+
- lib/taste_tester/tunnel.rb
|
125
|
+
- lib/taste_tester/logging.rb
|
126
|
+
- lib/taste_tester/config.rb
|
85
127
|
- bin/taste-tester
|
86
128
|
- scripts/taste-untester
|
87
129
|
homepage: https://github.com/facebook/taste-tester
|