vagrant-babushka 0.0.7 → 0.1.0
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.
- 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
|