vagrant-babushka 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +49 -3
- data/lib/vagrant-babushka/config.rb +41 -1
- data/lib/vagrant-babushka/dep.rb +6 -12
- data/lib/vagrant-babushka/plugin.rb +1 -1
- data/lib/vagrant-babushka/provisioner.rb +209 -45
- data/lib/vagrant-babushka/version.rb +1 -1
- data/spec/unit/vagrant-babushka/config_spec.rb +46 -9
- data/spec/unit/vagrant-babushka/dep_spec.rb +8 -22
- data/spec/unit/vagrant-babushka/provisioner_spec.rb +122 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c21e99dc53da017ce744dbf00984705e537fa75
|
4
|
+
data.tar.gz: 5aa688d0cc3af642b21eacebeb4c07f193b864bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ec88c85577ce6a0907153e08a347cd4c4e4a958b7a70c20da4f69cf1cd8d0f709f19727ecba563b03dcc74776a49d42b33af873d0b0de7952ce345ac1e92e6c
|
7
|
+
data.tar.gz: cc858b966ce45dceb6b23d9d7b37e195f7d70054492a35dc2d4b9eda73af6ae47166c159dad423236a21b0102ffafef5b3e39be49c4cdd83dd47db526cfb9a48
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,16 @@ Based on a [plugin concept][3] by @tcurdt.
|
|
10
10
|
[3]: <https://github.com/tcurdt/vagrant-boxes/blob/master/plugins/babushka_provisioner.rb>
|
11
11
|
|
12
12
|
|
13
|
+
## Requirements
|
14
|
+
|
15
|
+
* Vagrant 1.1+
|
16
|
+
* cURL on the virtual machine (will be installed if missing on Ubuntu)
|
17
|
+
|
18
|
+
Note: The latest version of this plugin has only been tested on Ubuntu
|
19
|
+
virtual machines. Please open a GitHub issue if it doesn't work for you
|
20
|
+
or your operating system.
|
21
|
+
|
22
|
+
|
13
23
|
## Installation
|
14
24
|
|
15
25
|
```bash
|
@@ -25,6 +35,9 @@ Add a Babushka provision block to your project's Vagrantfile:
|
|
25
35
|
config.vm.provision :babushka do |babushka|
|
26
36
|
# Set the Git branch of Babushka to install on the guest (defaults to master)
|
27
37
|
babushka.bootstrap_branch = 'master'
|
38
|
+
# ...or set the URL of the bootstrap script directly
|
39
|
+
babushka.bootstrap_url = 'https://example.com/babushka-bootstrap'
|
40
|
+
|
28
41
|
|
29
42
|
# Share a directory of local Babushka deps with the VM
|
30
43
|
# This example shares the '.deps/' directory (relative to this
|
@@ -32,6 +45,7 @@ config.vm.provision :babushka do |babushka|
|
|
32
45
|
# directory of the main SSH user on the guest)
|
33
46
|
babushka.local_deps_path = '.deps'
|
34
47
|
|
48
|
+
|
35
49
|
# Meet a local dep
|
36
50
|
# Assuming a dep named 'htop' is defined in a file under './.deps'
|
37
51
|
babushka.meet 'htop'
|
@@ -40,9 +54,9 @@ config.vm.provision :babushka do |babushka|
|
|
40
54
|
# Assuming source 'tcurdt' has a dep named 'rbenv system'
|
41
55
|
babushka.meet 'rbenv system', :source => 'tcurdt'
|
42
56
|
|
43
|
-
# Also, you can set
|
57
|
+
# Also, you can set values for deps' parameters
|
44
58
|
babushka.meet 'rbenv system', :params => {:key => "value"}
|
45
|
-
#
|
59
|
+
# ...and for remote deps:
|
46
60
|
babushka.meet 'rbenv system', :source => 'tcurdt', :params => {:key => "value"}
|
47
61
|
|
48
62
|
|
@@ -56,8 +70,34 @@ config.vm.provision :babushka do |babushka|
|
|
56
70
|
# Assuming source 'tcurdt' has a dep named 'rbenv system'
|
57
71
|
babushka.remote_dep 'tcurdt', 'rbenv system'
|
58
72
|
|
59
|
-
# Also, you can set
|
73
|
+
# Also, you can set values for deps' parameters, using a hash as the last parameter
|
60
74
|
babushka.remote_dep 'tcurdt', 'rbenv system', :path => '/opt/rbenv'
|
75
|
+
|
76
|
+
|
77
|
+
# Set options for the Babushka run
|
78
|
+
|
79
|
+
# Enable/disable colorised (ANSI) output from Babushka
|
80
|
+
# The default value is inherited from Vagrant's current setting
|
81
|
+
babushka.color = true
|
82
|
+
|
83
|
+
# Enable Babushka's debug mode (defaults to false)
|
84
|
+
babushka.debug = true
|
85
|
+
|
86
|
+
# Only do a "dry run", don't meet any deps (defaults to false)
|
87
|
+
babushka.dry_run = true
|
88
|
+
|
89
|
+
# Show parameter values passed to deps (defaults to false)
|
90
|
+
babushka.show_args = true
|
91
|
+
|
92
|
+
# Enable silent mode, no output (defaults to false)
|
93
|
+
babushka.silent = true
|
94
|
+
|
95
|
+
# Enable/disable updating sources before running their deps (defaults to true)
|
96
|
+
babushka.update = false
|
97
|
+
|
98
|
+
# These options can be overridden on particular deps, for example:
|
99
|
+
babushka.meet 'rbenv system', :source => 'tcurdt', :update => false
|
100
|
+
babushka.meet 'htop', :color => false
|
61
101
|
end
|
62
102
|
```
|
63
103
|
|
@@ -71,6 +111,12 @@ end
|
|
71
111
|
5. Create new Pull Request
|
72
112
|
|
73
113
|
|
114
|
+
## Testing
|
115
|
+
|
116
|
+
1. `bundle install`
|
117
|
+
2. `bundle exec rspec`
|
118
|
+
|
119
|
+
|
74
120
|
## Thanks
|
75
121
|
|
76
122
|
[patcon](https://github.com/patcon)
|
@@ -2,15 +2,32 @@ module VagrantPlugins
|
|
2
2
|
module Babushka
|
3
3
|
# Main configuration object for Vagrant Babushka provisioner
|
4
4
|
class Config < Vagrant.plugin("2", :config)
|
5
|
-
|
5
|
+
# Configuration keys that are used as Babushka command-line args
|
6
|
+
ARGUMENTS = [
|
7
|
+
:color,
|
8
|
+
:debug,
|
9
|
+
:dry_run,
|
10
|
+
:show_args,
|
11
|
+
:silent,
|
12
|
+
:update,
|
13
|
+
]
|
14
|
+
|
15
|
+
attr_accessor :deps, :local_deps_path, :bootstrap_branch, :bootstrap_url
|
6
16
|
attr_reader :messages
|
7
17
|
|
18
|
+
# Command-line argument options
|
19
|
+
attr_accessor *ARGUMENTS
|
20
|
+
|
8
21
|
def initialize
|
9
22
|
super
|
10
23
|
@deps = []
|
11
24
|
@local_deps_path = UNSET_VALUE
|
12
25
|
@bootstrap_branch = UNSET_VALUE
|
26
|
+
@bootstrap_url = UNSET_VALUE
|
13
27
|
@messages = []
|
28
|
+
|
29
|
+
# Reset all argument values to UNSET_VALUE
|
30
|
+
ARGUMENTS.each {|a| self.send "#{a}=".to_sym, UNSET_VALUE }
|
14
31
|
end
|
15
32
|
|
16
33
|
# This is called as a last-minute hook that allows the
|
@@ -21,6 +38,29 @@ module VagrantPlugins
|
|
21
38
|
@deps = [] if @deps == UNSET_VALUE
|
22
39
|
@local_deps_path = nil if @local_deps_path == UNSET_VALUE
|
23
40
|
@bootstrap_branch = nil if @bootstrap_branch == UNSET_VALUE
|
41
|
+
|
42
|
+
# Setup bootstrap URL if not set
|
43
|
+
if @bootstrap_url == UNSET_VALUE
|
44
|
+
@bootstrap_url = "https://babushka.me/up"
|
45
|
+
@bootstrap_url += "/#{@bootstrap_branch}" if @bootstrap_branch
|
46
|
+
end
|
47
|
+
|
48
|
+
# Set defaults for command-line arguments
|
49
|
+
@color = nil if @color == UNSET_VALUE
|
50
|
+
@debug = false if @debug == UNSET_VALUE
|
51
|
+
@dry_run = false if @dry_run == UNSET_VALUE
|
52
|
+
@show_args = false if @show_args == UNSET_VALUE
|
53
|
+
@silent = false if @silent == UNSET_VALUE
|
54
|
+
@update = true if @update == UNSET_VALUE
|
55
|
+
end
|
56
|
+
|
57
|
+
# Retrieves a Hash of the command-line argument config values
|
58
|
+
#
|
59
|
+
# The returned Hash will have command-line argument names for
|
60
|
+
# keys, and the value for the argument as the corresponding
|
61
|
+
# value.
|
62
|
+
def arguments
|
63
|
+
ARGUMENTS.inject(Hash.new) {|hash, key| hash.merge({key => send(key)}) }
|
24
64
|
end
|
25
65
|
|
26
66
|
# Meets a local dep on the guest
|
data/lib/vagrant-babushka/dep.rb
CHANGED
@@ -52,13 +52,13 @@ module VagrantPlugins
|
|
52
52
|
@options[:params] || Hash.new
|
53
53
|
end
|
54
54
|
|
55
|
-
#
|
55
|
+
# Retrieves the command-line arguments for the dep
|
56
56
|
#
|
57
|
-
# This
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
# This returns a hash including all the Babushka command-line
|
58
|
+
# arguments (to override the global settings) when meeting this
|
59
|
+
# dep.
|
60
|
+
def arguments
|
61
|
+
@options.select {|key, value| Config::ARGUMENTS.include? key }
|
62
62
|
end
|
63
63
|
|
64
64
|
def ==(other)
|
@@ -71,12 +71,6 @@ module VagrantPlugins
|
|
71
71
|
def state
|
72
72
|
[@dep_name, @options[:params], @options[:source]]
|
73
73
|
end
|
74
|
-
|
75
|
-
private
|
76
|
-
# Alias for Shellwords.escape
|
77
|
-
def escape(string)
|
78
|
-
Shellwords.escape(string.to_s)
|
79
|
-
end
|
80
74
|
end
|
81
75
|
end
|
82
76
|
end
|
@@ -1,84 +1,248 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module VagrantPlugins
|
2
4
|
module Babushka
|
3
5
|
# The main implementation class for the Babushka provisioner
|
4
6
|
class Provisioner < Vagrant.plugin("2", :provisioner)
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
# Exception raised if cURL isn't on the VM and can't be installed
|
9
|
+
class CurlMissing < Vagrant::Errors::VagrantError
|
10
|
+
error_message <<-END.gsub(/ {8}|\n\Z/, "")
|
11
|
+
cURL couldn't be found on the VM, and this plugin doesn't
|
12
|
+
know how to install it on the guest OS.
|
13
|
+
|
14
|
+
Try installing it manually, or consider adding the
|
15
|
+
functionality to the plugin and opening a pull request.
|
16
|
+
END
|
8
17
|
end
|
9
18
|
|
19
|
+
# Allow delegation of methods to an accessor
|
20
|
+
extend Forwardable
|
21
|
+
|
22
|
+
# Delegate some methods to @machine (to reduce boilerplate)
|
23
|
+
delegate [:communicate, :env, :name] => :@machine
|
24
|
+
delegate :ui => :env
|
25
|
+
|
26
|
+
attr_accessor :username, :group
|
27
|
+
|
28
|
+
# Called with the root configuration of the machine so the
|
29
|
+
# provisioner can add some configuration on top of the machine.
|
30
|
+
#
|
31
|
+
# During this step, and this step only, the provisioner should
|
32
|
+
# modify the root machine configuration to add any additional
|
33
|
+
# features it may need. Examples include sharing folders,
|
34
|
+
# networking, and so on. This step is guaranteed to be called
|
35
|
+
# before any of those steps are done so the provisioner may do
|
36
|
+
# that.
|
10
37
|
def configure(root_config)
|
11
38
|
@username = root_config.ssh.username || root_config.ssh.default.username
|
12
|
-
|
13
|
-
if @config.local_deps_path
|
14
|
-
local_path = @config.local_deps_path
|
15
|
-
remote_path = "/home/#{@username}/babushka-deps"
|
16
|
-
opts = {id: 'babushka_deps', nfs: false}
|
17
|
-
root_config.vm.synced_folder local_path, remote_path, opts
|
18
|
-
end
|
39
|
+
share_local_deps(root_config) if config.local_deps_path
|
19
40
|
end
|
20
41
|
|
21
42
|
# This is the method called when the actual provisioning should
|
22
43
|
# be done. The communicator is guaranteed to be ready at this
|
23
44
|
# point, and any shared folders or networds are already set up.
|
24
45
|
def provision
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
46
|
+
detect_ssh_group
|
47
|
+
render_messages
|
48
|
+
prepare
|
49
|
+
do_babushka_run
|
50
|
+
end
|
51
|
+
|
52
|
+
# Shares local deps with the virtual machine
|
53
|
+
def share_local_deps(root_config)
|
54
|
+
local_path = config.local_deps_path
|
55
|
+
remote_path = "~#{escape username}/babushka-deps"
|
56
|
+
opts = {:id => 'babushka_deps', :nfs => false}
|
57
|
+
root_config.vm.synced_folder local_path, remote_path, opts
|
58
|
+
end
|
59
|
+
|
60
|
+
# Determines and saves the name of the SSH user's primary group
|
61
|
+
def detect_ssh_group
|
62
|
+
@group = ""
|
63
|
+
|
64
|
+
# Save stdout into @group
|
65
|
+
communicate.execute("id -gn #{escape username}") do |type, data|
|
66
|
+
@group += data if type == :stdout
|
29
67
|
end
|
68
|
+
|
69
|
+
# Remove trailing newline from command output
|
70
|
+
@group.gsub! /\n\Z/, ""
|
30
71
|
end
|
31
72
|
|
32
|
-
private
|
33
73
|
# Renders the messages to the log output
|
34
74
|
#
|
35
75
|
# The config object maintains a list of "messages" to be shown
|
36
76
|
# when provisioning occurs, since there's no way to show messages
|
37
77
|
# at the time of configuration actually occurring. This displays
|
38
78
|
# the messages that were saved.
|
39
|
-
def render_messages
|
40
|
-
|
79
|
+
def render_messages
|
80
|
+
config.messages.each do |(level, info, caller)|
|
41
81
|
info = "vagrant-babushka: #{info}"
|
42
82
|
info += "\nIn #{caller.first}" unless caller.nil?
|
43
|
-
|
83
|
+
ui.send level.to_sym, info.to_s, :scope => name
|
44
84
|
end
|
45
85
|
end
|
46
86
|
|
47
|
-
#
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
87
|
+
# Performs preparation necessary before Babushka can be invoked
|
88
|
+
#
|
89
|
+
# Installs Babushka if it's not available. If Babushka needs to
|
90
|
+
# be installed, cURL will be installed first so that Babushka
|
91
|
+
# can be downloaded over HTTPS (as wget may not support HTTPS).
|
92
|
+
def prepare
|
93
|
+
unless in_path? "babushka"
|
94
|
+
# Install cURL first to ensure we can download over HTTPS
|
95
|
+
install_curl! unless in_path? "curl"
|
96
|
+
create_destination!
|
97
|
+
install_babushka!
|
98
|
+
ui.info "\n\n\n"
|
99
|
+
end
|
55
100
|
end
|
56
101
|
|
57
|
-
#
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
102
|
+
# Invokes Babushka on the virtual machine to meet requested deps
|
103
|
+
#
|
104
|
+
# Since Babushka can only meet one dep at a time, if multiple
|
105
|
+
# deps are in the meet list (the user has requested multiple
|
106
|
+
# deps to be run) then we have to have multiple invokations,
|
107
|
+
# once for each dep.
|
108
|
+
def do_babushka_run
|
109
|
+
if config.deps.empty?
|
110
|
+
ui.warn <<-END.gsub(/ {12}|\n\Z/, ""), :scope => name
|
111
|
+
Didn't find any Babushka deps to be met on the VM.
|
112
|
+
Add some to your Vagrantfile: babushka.meet 'my dep'
|
113
|
+
END
|
114
|
+
else
|
115
|
+
ui.info "Provisioning VM using Babushka...", :scope => name
|
116
|
+
config.deps.each do |dep|
|
117
|
+
ui.info "Meeting Babushka dep '#{dep.id}'", :scope => name
|
118
|
+
ui.info "Executing '#{command_for(dep).strip}'...", :scope => name
|
119
|
+
communicate.execute command_for(dep), &log_stdout
|
120
|
+
end
|
121
|
+
end
|
63
122
|
end
|
64
123
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
124
|
+
private
|
125
|
+
# Determines if the virtual machine has a command in its $PATH
|
126
|
+
#
|
127
|
+
# command: The name of the command to look for
|
128
|
+
def in_path?(command)
|
129
|
+
communicate.test("which #{escape command}").tap do |result|
|
130
|
+
if result
|
131
|
+
ui.info "'#{command}' found on guest", :scope => name
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
71
135
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
136
|
+
# Installs cURL on the virtual machine
|
137
|
+
def install_curl!
|
138
|
+
raise CurlMissing.new unless in_path? "apt-get"
|
139
|
+
ui.info "Installing cURL package on VM...", :scope => name
|
140
|
+
communicate.sudo "apt-get --quiet --assume-yes install curl"
|
141
|
+
end
|
142
|
+
|
143
|
+
# Creates the Babushka installation directory on the VM
|
144
|
+
#
|
145
|
+
# This will create the directory (as root), then set up the
|
146
|
+
# permissions on it to belong to the SSH user's primary group,
|
147
|
+
# and give the group read and write privileges. The permissions
|
148
|
+
# are also adjusted on /usr/local/bin, so Babushka can symlink
|
149
|
+
# itself into the PATH.
|
150
|
+
def create_destination!
|
151
|
+
ui.info "Creating Babushka directory...", :scope => name
|
152
|
+
communicate.sudo [
|
153
|
+
# Create directory, and parent directories if also missing
|
154
|
+
"mkdir -p /usr/local/babushka",
|
155
|
+
|
156
|
+
# Change Babushka directory's group to user's primary group
|
157
|
+
"chgrp #{escape group} /usr/local/babushka /usr/local/bin",
|
158
|
+
|
159
|
+
# Add read/write privileges where Babushka needs them
|
160
|
+
"chmod g+rw /usr/local/babushka /usr/local/bin",
|
161
|
+
].join(" && ")
|
79
162
|
end
|
80
|
-
end
|
81
163
|
|
164
|
+
# Installs Babushka on the virtual machine
|
165
|
+
def install_babushka!
|
166
|
+
ui.info <<-END.gsub(/ {12}|\n\Z/, ""), :scope => name
|
167
|
+
Installing Babushka via bootstrap script at \
|
168
|
+
#{config.bootstrap_url}...
|
169
|
+
END
|
170
|
+
|
171
|
+
unless config.bootstrap_url =~ %r[^https://]
|
172
|
+
ui.warn "WARNING: Using non-SSL source", :scope => name
|
173
|
+
end
|
174
|
+
|
175
|
+
# Log stdout straight to Vagrant's output
|
176
|
+
communicate.execute install_babushka_command, &log_stdout
|
177
|
+
end
|
178
|
+
|
179
|
+
# The command used to install Babushka on the virtual machine
|
180
|
+
def install_babushka_command
|
181
|
+
%Q[#{vars} sh -c "`#{vars} curl #{escape config.bootstrap_url}`"]
|
182
|
+
end
|
183
|
+
|
184
|
+
# Retrieves the environment variables to use for VM commands
|
185
|
+
#
|
186
|
+
# Extracts the HTTPS proxy from the host environment variables
|
187
|
+
#
|
188
|
+
# Returns a string that can be used as a prefix to a command in
|
189
|
+
# order to assign the variables for that command.
|
190
|
+
def vars
|
191
|
+
proxy_env = ENV.select {|k, _| /https_proxy/i.match(k) }
|
192
|
+
proxy_env.map{|k, v| "#{escape k}=#{escape v}" }.join(" ")
|
193
|
+
end
|
194
|
+
|
195
|
+
# A block that logs stdout, when passed to a communicator
|
196
|
+
#
|
197
|
+
# type: The stream where the output in data came from, one of
|
198
|
+
# :stdout or :stderr
|
199
|
+
# data: The echoed data as a string
|
200
|
+
def log_stdout
|
201
|
+
lambda do |type, data|
|
202
|
+
ui.info data, :new_line => false if type == :stdout
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Creates a command string to use for a dep on the command line
|
207
|
+
#
|
208
|
+
# This will return a string which can be used as a command to
|
209
|
+
# run Babushka to meet a particular dep.
|
210
|
+
#
|
211
|
+
# * dep: The Dep to generate the command string for
|
212
|
+
def command_for(dep)
|
213
|
+
[
|
214
|
+
vars, "babushka", "meet",
|
215
|
+
args_for(dep), # Babushka command-line arguments
|
216
|
+
escape(dep.id), # Identifier for the dep to be met
|
217
|
+
dep.params.map {|k, v| "#{escape k}=#{escape v}" },
|
218
|
+
].flatten.join(" ")
|
219
|
+
end
|
220
|
+
|
221
|
+
# Generates the Babushka command-line arguments for a dep
|
222
|
+
#
|
223
|
+
# Given a dep, this method merges the configuration options for
|
224
|
+
# the specific dep with the configuration of the provisioner as
|
225
|
+
# "defaults" if values aren't set on the dep itself.
|
226
|
+
#
|
227
|
+
# * dep: The Dep to generate the command string for
|
228
|
+
def args_for(dep)
|
229
|
+
result = config.arguments.merge(dep.arguments)
|
230
|
+
result[:color] = ui.is_a? Vagrant::UI::Colored if result[:color].nil?
|
231
|
+
[
|
232
|
+
'--defaults', # Must use defaults -- stdin not connected
|
233
|
+
result[:color] ? '--color' : '--no-color',
|
234
|
+
result[:debug] ? '--debug' : nil,
|
235
|
+
result[:dry_run] ? '--dry-run' : nil,
|
236
|
+
result[:show_args] ? '--show-args' : nil,
|
237
|
+
result[:silent] ? '--silent' : nil,
|
238
|
+
result[:update] ? '--update' : nil,
|
239
|
+
].compact.join(" ") # Remove nil values and concatenate
|
240
|
+
end
|
241
|
+
|
242
|
+
# Alias for Shellwords.escape
|
243
|
+
def escape(string)
|
244
|
+
Shellwords.escape(string.to_s)
|
245
|
+
end
|
82
246
|
end
|
83
247
|
end
|
84
248
|
end
|
@@ -3,28 +3,63 @@ require "spec_helper"
|
|
3
3
|
describe VagrantPlugins::Babushka::Config do
|
4
4
|
let(:unset_value) { described_class::UNSET_VALUE }
|
5
5
|
let(:config) { described_class.new }
|
6
|
+
subject { config }
|
6
7
|
|
7
8
|
context "with default configuration" do
|
8
|
-
before {
|
9
|
+
before { config.finalize! }
|
9
10
|
its(:deps) { should eq [] }
|
10
11
|
its(:local_deps_path) { should be_nil }
|
11
12
|
its(:bootstrap_branch) { should be_nil }
|
12
13
|
end
|
13
14
|
|
14
15
|
describe "#local_deps_path" do
|
15
|
-
before {
|
16
|
+
before { config.local_deps_path = '.deps'; config.finalize! }
|
16
17
|
its(:local_deps_path) { should eq '.deps' }
|
17
18
|
end
|
18
19
|
|
19
20
|
describe "#bootstrap_branch" do
|
20
|
-
before {
|
21
|
+
before { config.bootstrap_branch = 'new'; config.finalize! }
|
21
22
|
its(:bootstrap_branch) { should eq 'new' }
|
23
|
+
its(:bootstrap_url) { should eq 'https://babushka.me/up/new' }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#bootstrap_url" do
|
27
|
+
before do
|
28
|
+
config.bootstrap_url = 'https://example.com/foo'
|
29
|
+
config.finalize!
|
30
|
+
end
|
31
|
+
|
32
|
+
its(:bootstrap_url) { should eq 'https://example.com/foo' }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#arguments" do
|
36
|
+
before do
|
37
|
+
config.color = false
|
38
|
+
config.debug = true
|
39
|
+
config.dry_run = true
|
40
|
+
config.bootstrap_url = double "bootstrap_url"
|
41
|
+
config.finalize!
|
42
|
+
end
|
43
|
+
|
44
|
+
subject { config.arguments }
|
45
|
+
|
46
|
+
specify "set values should override defaults" do
|
47
|
+
expect(subject).to eq({
|
48
|
+
:color => false,
|
49
|
+
:debug => true,
|
50
|
+
:dry_run => true,
|
51
|
+
:show_args => false,
|
52
|
+
:silent => false,
|
53
|
+
:update => true,
|
54
|
+
})
|
55
|
+
end
|
22
56
|
end
|
23
57
|
|
24
58
|
describe "#local_dep" do
|
25
59
|
before do
|
26
|
-
|
27
|
-
|
60
|
+
config.local_dep 'foobar', :baz => :qux
|
61
|
+
config.local_dep 'testme', :one => :two
|
62
|
+
config.finalize!
|
28
63
|
end
|
29
64
|
|
30
65
|
it "should store the deps correctly" do
|
@@ -37,8 +72,9 @@ describe VagrantPlugins::Babushka::Config do
|
|
37
72
|
|
38
73
|
describe "#remote_dep" do
|
39
74
|
before do
|
40
|
-
|
41
|
-
|
75
|
+
config.remote_dep 'user1', 'foobar', :baz => :qux
|
76
|
+
config.remote_dep 'user2', 'testme', :one => :two
|
77
|
+
config.finalize!
|
42
78
|
end
|
43
79
|
|
44
80
|
it "should store the deps correctly" do
|
@@ -51,8 +87,9 @@ describe VagrantPlugins::Babushka::Config do
|
|
51
87
|
|
52
88
|
describe "#meet" do
|
53
89
|
before {
|
54
|
-
|
55
|
-
|
90
|
+
config.meet 'test1', :source => 'user1', :params => {:abc => :def}
|
91
|
+
config.meet 'test2', :source => 'user2', :params => {:ghi => :jkl}
|
92
|
+
config.finalize!
|
56
93
|
}
|
57
94
|
|
58
95
|
it "should store the deps correctly" do
|
@@ -21,11 +21,6 @@ describe VagrantPlugins::Babushka::Dep do
|
|
21
21
|
it { should be_nil }
|
22
22
|
end
|
23
23
|
|
24
|
-
describe "#command" do
|
25
|
-
subject { dep.command }
|
26
|
-
it { should eq "the\\ dep" }
|
27
|
-
end
|
28
|
-
|
29
24
|
context "with source" do
|
30
25
|
let(:options) { {:source => source} }
|
31
26
|
let(:source) { double "source", :to_s => "the source" }
|
@@ -39,11 +34,6 @@ describe VagrantPlugins::Babushka::Dep do
|
|
39
34
|
subject { dep.source }
|
40
35
|
it { should eq source.to_s }
|
41
36
|
end
|
42
|
-
|
43
|
-
describe "#command" do
|
44
|
-
subject { dep.command }
|
45
|
-
it { should eq "the\\ source:the\\ dep" }
|
46
|
-
end
|
47
37
|
end
|
48
38
|
|
49
39
|
context "with params" do
|
@@ -52,22 +42,18 @@ describe VagrantPlugins::Babushka::Dep do
|
|
52
42
|
|
53
43
|
describe "#params" do
|
54
44
|
subject { dep.params }
|
55
|
-
|
56
|
-
|
57
|
-
describe "#command" do
|
58
|
-
subject { dep.command }
|
59
|
-
it { should eq "the\\ dep foo=bar baz=qux" }
|
45
|
+
it { should be params }
|
60
46
|
end
|
61
47
|
end
|
62
48
|
|
63
|
-
context "with
|
64
|
-
let(:options) { {:
|
65
|
-
let(:
|
66
|
-
let(:source) { double "source"
|
49
|
+
context "with arguments" do
|
50
|
+
let(:options) { {:color => color, :source => source} }
|
51
|
+
let(:color) { double "color" }
|
52
|
+
let(:source) { double "source" }
|
67
53
|
|
68
|
-
describe "#
|
69
|
-
subject { dep.
|
70
|
-
it { should eq
|
54
|
+
describe "#arguments" do
|
55
|
+
subject { dep.arguments }
|
56
|
+
it { should eq({:color => color}) }
|
71
57
|
end
|
72
58
|
end
|
73
59
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe VagrantPlugins::Babushka::Provisioner do
|
4
|
+
let(:config) { double "config" }
|
5
|
+
let(:machine) { double "machine", :name => "the name", :communicate => communicate, :env => env }
|
6
|
+
let(:communicate) { double "communicate" }
|
7
|
+
let(:env) { double "env", :ui => ui }
|
8
|
+
let(:ui) { double "ui" }
|
9
|
+
let(:provisioner) { described_class.new machine, config }
|
10
|
+
subject { provisioner }
|
11
|
+
|
12
|
+
describe "#share_local_deps" do
|
13
|
+
let(:root_config) { double "root config", :vm => vm }
|
14
|
+
let(:config) { double "config", :local_deps_path => local_deps_path }
|
15
|
+
let(:local_deps_path) { double "local deps path", :to_s => "the local deps" }
|
16
|
+
let(:vm) { double "root config.vm" }
|
17
|
+
|
18
|
+
it "should configure the directory to be shared" do
|
19
|
+
expect(config).to receive(:local_deps_path).and_return(local_deps_path)
|
20
|
+
expect(vm).to receive(:synced_folder).with(local_deps_path, "~the\\ user/babushka-deps", {:id => 'babushka_deps', :nfs => false})
|
21
|
+
provisioner.username = double "username", :to_s => "the user"
|
22
|
+
provisioner.share_local_deps root_config
|
23
|
+
subject
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#detect_ssh_group" do
|
28
|
+
let(:username) { double "username", :to_s => 'the user' }
|
29
|
+
|
30
|
+
before do
|
31
|
+
provisioner.username = username
|
32
|
+
expect(communicate).to receive(:execute).with("id -gn the\\ user").and_yield(:stdout, "test\n")
|
33
|
+
subject.detect_ssh_group
|
34
|
+
end
|
35
|
+
|
36
|
+
its(:group) { should eq "test" }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#render_messages" do
|
40
|
+
let(:config) { double "config", :messages => messages }
|
41
|
+
let(:messages) do
|
42
|
+
[
|
43
|
+
[:warn, "foo bar baz"],
|
44
|
+
[:info, "one two three", ['file x line y']],
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should output the mesages" do
|
49
|
+
expect(ui).to receive(:send).with(:warn, "vagrant-babushka: foo bar baz", :scope => "the name")
|
50
|
+
expect(ui).to receive(:send).with(:info, "vagrant-babushka: one two three\nIn file x line y", :scope => "the name")
|
51
|
+
subject.render_messages
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#prepare" do
|
56
|
+
context "with Babushka not yet installed" do
|
57
|
+
it "should install cURL and Babushka" do
|
58
|
+
expect(provisioner).to receive(:in_path?).with("babushka").and_return(false)
|
59
|
+
expect(provisioner).to receive(:in_path?).with("curl").and_return(false)
|
60
|
+
expect(provisioner).to receive(:install_curl!)
|
61
|
+
expect(provisioner).to receive(:create_destination!)
|
62
|
+
expect(provisioner).to receive(:install_babushka!)
|
63
|
+
expect(ui).to receive(:info).with("\n\n\n")
|
64
|
+
subject.prepare
|
65
|
+
end
|
66
|
+
|
67
|
+
context "with cURL already installed" do
|
68
|
+
it "should install Babushka" do
|
69
|
+
expect(provisioner).to receive(:in_path?).with("babushka").and_return(false)
|
70
|
+
expect(provisioner).to receive(:in_path?).with("curl").and_return(true)
|
71
|
+
expect(provisioner).to_not receive(:install_curl!)
|
72
|
+
expect(provisioner).to receive(:create_destination!)
|
73
|
+
expect(provisioner).to receive(:install_babushka!)
|
74
|
+
expect(ui).to receive(:info).with("\n\n\n")
|
75
|
+
subject.prepare
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with Babushka already installed" do
|
81
|
+
it "should not do anything" do
|
82
|
+
expect(provisioner).to receive(:in_path?).with("babushka").and_return(true)
|
83
|
+
expect(provisioner).to_not receive(:install_babushka!)
|
84
|
+
subject.prepare
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#do_babushka_run" do
|
90
|
+
let(:deps) { Array.new }
|
91
|
+
let(:config) { double "config", :deps => deps }
|
92
|
+
|
93
|
+
context "with no deps specified" do
|
94
|
+
it "should log a warning" do
|
95
|
+
expect(ui).to receive(:warn).with(<<-END.gsub(/ {10}|\n\Z/, ""), :scope => "the name")
|
96
|
+
Didn't find any Babushka deps to be met on the VM.
|
97
|
+
Add some to your Vagrantfile: babushka.meet 'my dep'
|
98
|
+
END
|
99
|
+
subject.do_babushka_run
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "with deps specified" do
|
104
|
+
let(:deps) { [dep1, dep2] }
|
105
|
+
let(:dep1) { double "dep 1", :id => "the dep 1" }
|
106
|
+
let(:dep2) { double "dep 2", :id => "the dep 2" }
|
107
|
+
|
108
|
+
it "should meet the deps" do
|
109
|
+
expect(ui).to receive(:info).with("Provisioning VM using Babushka...", :scope => "the name")
|
110
|
+
expect(ui).to receive(:info).with("Meeting Babushka dep 'the dep 1'", :scope => "the name")
|
111
|
+
expect(ui).to receive(:info).with("Executing 'foo'...", :scope => "the name")
|
112
|
+
expect(ui).to receive(:info).with("Meeting Babushka dep 'the dep 2'", :scope => "the name")
|
113
|
+
expect(ui).to receive(:info).with("Executing 'bar'...", :scope => "the name")
|
114
|
+
expect(provisioner).to receive(:command_for).with(dep1).twice().and_return("foo")
|
115
|
+
expect(communicate).to receive(:execute).with("foo")
|
116
|
+
expect(provisioner).to receive(:command_for).with(dep2).twice().and_return("bar")
|
117
|
+
expect(communicate).to receive(:execute).with("bar")
|
118
|
+
subject.do_babushka_run
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-babushka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Valgis
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- spec/spec_helper.rb
|
91
91
|
- spec/unit/vagrant-babushka/config_spec.rb
|
92
92
|
- spec/unit/vagrant-babushka/dep_spec.rb
|
93
|
+
- spec/unit/vagrant-babushka/provisioner_spec.rb
|
93
94
|
- vagrant-babushka.gemspec
|
94
95
|
homepage: https://github.com/vvalgis/vagrant-babushka
|
95
96
|
licenses:
|
@@ -119,3 +120,4 @@ test_files:
|
|
119
120
|
- spec/spec_helper.rb
|
120
121
|
- spec/unit/vagrant-babushka/config_spec.rb
|
121
122
|
- spec/unit/vagrant-babushka/dep_spec.rb
|
123
|
+
- spec/unit/vagrant-babushka/provisioner_spec.rb
|