vagrant-foodtaster-server 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/.gitignore +1 -0
- data/README.md +4 -1
- data/lib/vagrant-foodtaster-server/plugin.rb +11 -5
- data/lib/vagrant-foodtaster-server/server.rb +124 -109
- data/lib/vagrant-foodtaster-server/server_command.rb +20 -16
- data/lib/vagrant-foodtaster-server/version.rb +6 -2
- data/vagrant-foodtaster-server.gemspec +3 -2
- metadata +20 -3
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# Vagrant Foodtaster Server
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/vagrant-foodtaster-server)
|
4
|
+
|
3
5
|
[Foodtaster](http://github.com/mlapshin/foodtaster) is a tool for
|
4
6
|
testing Chef cookbooks using RSpec and Vagrant. This Vagrant plugin
|
5
|
-
allows Foodtaster to interact with Vagrant via simple DRb
|
7
|
+
allows Core Foodtaster library to interact with Vagrant via simple DRb
|
8
|
+
protocol.
|
6
9
|
|
7
10
|
## Installation
|
8
11
|
|
@@ -1,8 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Vagrant
|
2
|
+
module Foodtaster
|
3
|
+
module Server
|
4
|
+
class Plugin < Vagrant.plugin("2")
|
5
|
+
name "Foodtaster Server"
|
3
6
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
+
command 'foodtaster-server' do
|
8
|
+
require_relative 'server_command'
|
9
|
+
ServerCommand
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
7
13
|
end
|
8
14
|
end
|
@@ -1,159 +1,174 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
module Vagrant
|
2
|
+
module Foodtaster
|
3
|
+
module Server
|
4
|
+
class Server
|
5
|
+
def initialize(app, env)
|
6
|
+
@env = env
|
7
|
+
@app = app
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'sahara/session/virtualbox'
|
11
|
+
rescue LoadError
|
12
|
+
raise RuntimeError, <<-EOT.strip_heredoc
|
11
13
|
Cannot find `sahara' plugin. Please, make sure that `sahara' plugin is installed using command:
|
12
14
|
$ vagrant plugin list
|
13
15
|
|
14
16
|
If `sahara' plugin is not installed, install it:
|
15
17
|
$ vagrant plugin install sahara
|
16
18
|
EOT
|
17
|
-
|
18
|
-
|
19
|
+
end
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
def version
|
23
|
+
Vagrant::Foodtaster::Server::VERSION
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
def redirect_stdstreams(stdout, stderr)
|
27
|
+
$stdout = stdout
|
28
|
+
$stderr = stderr
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def make_initial_snapshot_on_vm(vm_name)
|
32
|
+
vm = get_vm(vm_name)
|
33
|
+
sahara_for(vm).on
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def start_vm(vm_name)
|
37
|
+
vm = get_vm(vm_name)
|
38
|
+
chef_run_list = get_chef_solo_run_list(vm)
|
39
|
+
provision_types = [:shell, :puppet]
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
unless chef_run_list.empty?
|
42
|
+
provision_types << :chef_solo
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
vm.action(:up,
|
46
|
+
provision_types: provision_types,
|
47
|
+
provision_enabled: true)
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
def vm_running?(vm_name)
|
51
|
+
vm = get_vm(vm_name)
|
52
|
+
vm.state.id.to_s == 'running'
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
def initial_snapshot_made_on_vm?(vm_name)
|
56
|
+
vm = get_vm(vm_name)
|
57
|
+
sahara_for(vm).is_snapshot_mode_on?
|
58
|
+
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
+
def rollback_vm(vm_name)
|
61
|
+
vm = get_vm(vm_name)
|
60
62
|
|
61
|
-
|
62
|
-
|
63
|
+
sahara_for(vm).rollback
|
64
|
+
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
+
def shutdown_vm(vm_name)
|
67
|
+
vm = get_vm(vm_name)
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
+
vm.action(:halt)
|
70
|
+
end
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
72
|
+
def vm_ip(vm_name)
|
73
|
+
vm = get_vm(vm_name)
|
74
|
+
networks = vm.config.vm.networks
|
75
|
+
private_network_conf = networks.find { |n| n.first == :private_network }
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
sahara = sahara_for(vm)
|
77
|
+
private_network_conf ? private_network_conf.last[:ip] : nil
|
78
|
+
end
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
+
def put_file_to_vm(vm_name, local_fn, vm_fn)
|
81
|
+
vm = get_vm(vm_name)
|
82
|
+
vm.communicate.upload(local_fn, vm_fn)
|
83
|
+
end
|
80
84
|
|
81
|
-
|
82
|
-
|
85
|
+
def get_file_from_vm(vm_name, vm_fn, local_fn)
|
86
|
+
vm = get_vm(vm_name)
|
87
|
+
vm.communicate.download(vm_fn, local_fn)
|
88
|
+
end
|
83
89
|
|
84
|
-
|
90
|
+
def vm_defined?(vm_name)
|
91
|
+
@env.machine_names.include?(vm_name)
|
92
|
+
end
|
85
93
|
|
86
|
-
|
94
|
+
def run_chef_on_vm(vm_name, current_run_config)
|
95
|
+
vm = get_vm(vm_name)
|
87
96
|
|
88
|
-
|
89
|
-
provisioner = provisioner_klass.new(vm, chef_solo_config.config)
|
97
|
+
validate_vm!(vm)
|
90
98
|
|
91
|
-
|
92
|
-
provisioner.configure(current_run_chef_solo_config)
|
99
|
+
chef_solo_config = vm.config.vm.provisioners.find { |p| p.name == :chef_solo }
|
93
100
|
|
94
|
-
|
95
|
-
|
96
|
-
rescue Exception
|
97
|
-
raise RuntimeError, "Chef Run failed on #{vm_name} with config #{current_run_config.inspect}"
|
98
|
-
end
|
99
|
-
end
|
101
|
+
provisioner_klass = Vagrant.plugin("2").manager.provisioners[:chef_solo]
|
102
|
+
provisioner = provisioner_klass.new(vm, chef_solo_config.config)
|
100
103
|
|
101
|
-
|
102
|
-
|
103
|
-
exec_result = {}
|
104
|
+
current_run_chef_solo_config = apply_current_run_config(vm.config, current_run_config)
|
105
|
+
provisioner.configure(current_run_chef_solo_config)
|
104
106
|
|
105
|
-
|
106
|
-
|
107
|
-
|
107
|
+
begin
|
108
|
+
provisioner.provision
|
109
|
+
rescue StandardError => e
|
110
|
+
raise RuntimeError, "Chef Run failed on #{vm_name} with config #{current_run_config.inspect}.\n\nOriginal Exception was:\n#{e.class.name}\n#{e.message}"
|
111
|
+
end
|
112
|
+
end
|
108
113
|
|
109
|
-
|
110
|
-
|
114
|
+
def execute_command_on_vm(vm_name, command)
|
115
|
+
vm = get_vm(vm_name)
|
116
|
+
exec_result = {}
|
111
117
|
|
112
|
-
|
118
|
+
exec_result[:exit_status] = vm.communicate.sudo(command, error_check: false) do |stream_type, data|
|
119
|
+
exec_result[stream_type] = exec_result[stream_type].to_s + data
|
120
|
+
end
|
113
121
|
|
114
|
-
|
115
|
-
|
116
|
-
|
122
|
+
exec_result
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
117
126
|
|
118
|
-
|
119
|
-
|
120
|
-
if c.name == :chef_solo
|
121
|
-
c.config.run_list
|
122
|
-
else
|
123
|
-
nil
|
127
|
+
def sahara_for(vm)
|
128
|
+
Sahara::Session::Virtualbox.new(vm)
|
124
129
|
end
|
125
|
-
end.compact.flatten
|
126
|
-
end
|
127
130
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
+
def get_chef_solo_run_list(vm)
|
132
|
+
vm.config.vm.provisioners.map do |c|
|
133
|
+
if c.name == :chef_solo
|
134
|
+
c.config.run_list
|
135
|
+
else
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
end.compact.flatten
|
139
|
+
end
|
140
|
+
|
141
|
+
def get_vm(vm_name)
|
142
|
+
@env.machine(vm_name, :virtualbox)
|
143
|
+
end
|
131
144
|
|
132
|
-
|
133
|
-
|
145
|
+
def validate_vm!(vm)
|
146
|
+
chef_solo_config = vm.config.vm.provisioners.find { |p| p.name == :chef_solo }
|
134
147
|
|
135
|
-
|
136
|
-
|
148
|
+
unless chef_solo_config
|
149
|
+
raise RuntimeError, <<-EOT.strip_heredoc
|
137
150
|
VM '#{vm.name}' doesn't have a configured chef-solo provisioner, which is requied by Foodtaster to run specs on this VM.
|
138
151
|
Please, add dummy chef-solo provisioner to your Vagrantfile, like this:
|
139
152
|
config.vm.provision :chef_solo do |chef|
|
140
153
|
chef.cookbooks_path = %w[site-cookbooks]
|
141
154
|
end
|
142
155
|
EOT
|
143
|
-
|
144
|
-
|
156
|
+
end
|
157
|
+
end
|
145
158
|
|
146
|
-
|
147
|
-
|
159
|
+
def apply_current_run_config(vm_config, current_run_config)
|
160
|
+
modified_config = vm_config.dup
|
148
161
|
|
149
|
-
|
150
|
-
|
151
|
-
|
162
|
+
provisioner_index = modified_config.vm.provisioners.find_index do |prov|
|
163
|
+
prov.name == :chef_solo
|
164
|
+
end
|
152
165
|
|
153
|
-
|
154
|
-
|
166
|
+
modified_config.vm.provisioners[provisioner_index].config.run_list = current_run_config[:run_list]
|
167
|
+
modified_config.vm.provisioners[provisioner_index].config.json = current_run_config[:json]
|
155
168
|
|
156
|
-
|
169
|
+
modified_config
|
170
|
+
end
|
171
|
+
end
|
157
172
|
end
|
158
173
|
end
|
159
174
|
end
|
@@ -1,26 +1,30 @@
|
|
1
1
|
require 'drb'
|
2
2
|
require_relative 'server'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Vagrant
|
5
|
+
module Foodtaster
|
6
|
+
module Server
|
7
|
+
class ServerCommand < Vagrant.plugin(2, :command)
|
8
|
+
def execute
|
9
|
+
argv = parse_options
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
port_number = argv.size == 0 ? 35672 : argv[0].to_i
|
12
|
+
DRb.start_service "druby://localhost:#{port_number}", Vagrant::Foodtaster::Server::Server.new(@app, @env)
|
13
|
+
DRb.thread.join
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
rescue RuntimeError, Errno::EADDRINUSE => e
|
16
|
+
write_formatted_exception_message(e)
|
17
|
+
rescue Interrupt
|
18
|
+
DRb.stop_service
|
19
|
+
end
|
18
20
|
|
19
|
-
|
21
|
+
private
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
def write_formatted_exception_message(e)
|
24
|
+
error = "#{e.message}\n\nServer Error Backtrace:\n #{e.backtrace.join("\n ")}"
|
25
|
+
@env.ui.error(error)
|
26
|
+
end
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -5,8 +5,8 @@ require 'vagrant-foodtaster-server/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "vagrant-foodtaster-server"
|
8
|
-
gem.version =
|
9
|
-
gem.authors = ["Mike Lapshin"]
|
8
|
+
gem.version = Vagrant::Foodtaster::Server::VERSION
|
9
|
+
gem.authors = ["Mike Lapshin", "Serzh Nechyporchuk"]
|
10
10
|
gem.email = ["mikhail.a.lapshin@gmail.com"]
|
11
11
|
gem.description = %q{A Foodtaster DRb server.}
|
12
12
|
gem.summary = %q{Foodtaster is a tool for testing Chef cookbooks using RSpec and Vagrant. This plugin allows Foodtaster to interact with Vagrant via simple DRb protocol. }
|
@@ -17,4 +17,5 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
|
+
gem.add_runtime_dependency 'sahara'
|
20
21
|
end
|
metadata
CHANGED
@@ -2,15 +2,32 @@
|
|
2
2
|
name: vagrant-foodtaster-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.8
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mike Lapshin
|
9
|
+
- Serzh Nechyporchuk
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
13
|
-
dependencies:
|
13
|
+
date: 2013-11-08 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
prerelease: false
|
17
|
+
type: :runtime
|
18
|
+
name: sahara
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0'
|
25
|
+
requirement: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
14
31
|
description: A Foodtaster DRb server.
|
15
32
|
email:
|
16
33
|
- mikhail.a.lapshin@gmail.com
|