vagrant-flow 1.0.10 → 1.0.11
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/README.md +112 -16
- data/VAGRANT-FLOW +23 -0
- data/create_sample_hostfile_digitalocean_input-file.rb +25 -0
- data/create_sample_multiinit_input-file_digitalocean.rb +34 -0
- data/create_sample_playbook_input-file.rb +27 -0
- data/lib/vagrant-flow/command/digitalocean_api.rb +51 -0
- data/lib/vagrant-flow/command/hostfile.rb +87 -39
- data/lib/vagrant-flow/command/playbook.rb +127 -0
- data/lib/vagrant-flow/command/root.rb +5 -0
- data/lib/vagrant-flow/templates/multiinit.erb +17 -0
- data/lib/vagrant-flow/version.rb +1 -1
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d3ded31cb6dedca2fa9b995903b2efb9fbef217
|
4
|
+
data.tar.gz: 4877689ebcecd0ecf990a3245fbfe46518c4d040
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e64d23a40b362c4497bbbacbcd4bba7771cdb86385075d9c2ab8dba59b3b6d4b14373311cc15198f89353bb35d2527cc9c1a8bca836e94cf22f0a218bc1da64
|
7
|
+
data.tar.gz: 7edfa6e7af03f6ec087d2cfa3643ab5d7a46cf7c4180a96dc16f79f094c5f8518c99a05ab3bcb81907af2f22aa05caba4a0262647fca359815e080205f6eb956
|
data/README.md
CHANGED
@@ -1,29 +1,76 @@
|
|
1
1
|
# Vagrant-Flow
|
2
2
|
|
3
|
-
Vagrant
|
3
|
+
Vagrant-Flow enables a seamless development to production workflow.
|
4
4
|
|
5
|
+
Vagrant-Flow is a vagrant plugin which allows for a separation of ansible playbooks from vagrant, mimicing how development works. It enables the generates ansible inventory files, vagrant templates and inter-machine communication to easily prepare to run ansible playbooks and machine communication.
|
5
6
|
|
6
|
-
|
7
|
+
- This is part of [NeverwinterDP the Data Pipeline for Hadoop](https://github.com/DemandCube/NeverwinterDP)
|
7
8
|
|
8
|
-
`vagrant plugin install vagrant-flow`
|
9
9
|
|
10
|
+
## Installation
|
10
11
|
|
11
|
-
|
12
|
+
```
|
13
|
+
#This is so 'vagrant flow hostfile' can automatically connect to digital ocean machines
|
14
|
+
#Otherwise it will hang when dealing with remote hosts
|
15
|
+
echo "StrictHostKeyChecking no" >> ~/.ssh/config
|
12
16
|
|
13
|
-
|
17
|
+
#If you're on OSX
|
18
|
+
brew install curl-ca-bundle
|
14
19
|
|
15
|
-
gem 'vagrant-flow'
|
16
20
|
|
17
|
-
|
21
|
+
vagrant plugin install vagrant-digitalocean
|
22
|
+
vagrant plugin install vagrant-flow
|
23
|
+
```
|
18
24
|
|
19
|
-
|
25
|
+
## Contributing
|
20
26
|
|
21
|
-
|
27
|
+
See the [NeverwinterDP Guide to Contributing] (https://github.com/DemandCube/NeverwinterDP#how-to-contribute)
|
22
28
|
|
23
|
-
$ gem install vagrant-flow
|
24
29
|
|
25
30
|
* * *
|
26
31
|
|
32
|
+
## Usage and Specs
|
33
|
+
vagrant-flow has 1 command `flow` and the following subcommands:
|
34
|
+
|
35
|
+
```
|
36
|
+
multiinit
|
37
|
+
hostfile
|
38
|
+
ansibleinventory
|
39
|
+
playbook
|
40
|
+
```
|
41
|
+
|
42
|
+
- multiinit
|
43
|
+
- Creates a template Vagrantfile based on the machines you specify
|
44
|
+
- hostfile
|
45
|
+
- Creates a hostfile and copies it to each VM so that machine can talk to each other
|
46
|
+
- ansibleinventory
|
47
|
+
- Create a ansible machine inventory file so that you can use ansible to provision the machines
|
48
|
+
- playbook
|
49
|
+
- Uses a confile to run ansible-play book to provision one or more VM's
|
50
|
+
|
51
|
+
Example flow to be enabled
|
52
|
+
```
|
53
|
+
vagrant plugin install vagrant-flow
|
54
|
+
git clone http://github.com/DemandCube/DeveloperPlaybooks
|
55
|
+
mkdir devsetup
|
56
|
+
cd devsetup
|
57
|
+
vagrant flow multiinit -l boxname1:demandcube/centos-65_x86_64-VB-4.3.8,boxname2:demandcube/centos-65_x86_65-VB-4.3.8
|
58
|
+
vagrant up
|
59
|
+
vagrant flow hostfile
|
60
|
+
vagrant flow ansibleinventory
|
61
|
+
|
62
|
+
# Then
|
63
|
+
|
64
|
+
vagrant flow playbook
|
65
|
+
# or
|
66
|
+
ansible-playbook -i ansible-flow_inventoryfile ../DeveloperPlaybooks/site.yml
|
67
|
+
|
68
|
+
#communication test
|
69
|
+
vagrant ssh boxname1 ping boxname2
|
70
|
+
vagrant ssh boxname2 ping boxname1
|
71
|
+
```
|
72
|
+
|
73
|
+
|
27
74
|
# Usage
|
28
75
|
|
29
76
|
|
@@ -229,7 +276,46 @@ servergroup
|
|
229
276
|
```
|
230
277
|
|
231
278
|
* * *
|
279
|
+
##playbook
|
280
|
+
```
|
281
|
+
Usage: vagrant flow playbook [-hpf]
|
282
|
+
Reads in config from flow-playbook.yml by default to be able to run ansible-playbook more easily
|
232
283
|
|
284
|
+
-f, --file-playbook FILE (Optional) Use a specified playbook config file instead of default (flow-playbook.yml)
|
285
|
+
-p, --print-only (Optional) Don't actually ansible-playbook, but just output what would be run to STDOUT
|
286
|
+
-q, --quiet (Optional) Suppress output to STDOUT and STDERR
|
287
|
+
-h, --help Print this help
|
288
|
+
```
|
289
|
+
|
290
|
+
This will run ansible-playbook based on the config in flow-playbook.yml
|
291
|
+
```
|
292
|
+
vagrant flow playbook
|
293
|
+
```
|
294
|
+
|
295
|
+
This will run ansible-playbook based on the config in myOwnConfig.yml
|
296
|
+
```
|
297
|
+
vagrant flow playbook -f myOwnConfig.yml
|
298
|
+
```
|
299
|
+
|
300
|
+
This will not actually run ansible-playbook, but will only output the command it would run to STDOUT
|
301
|
+
```
|
302
|
+
vagrant flow playbook -p
|
303
|
+
```
|
304
|
+
The output from the above command using -p will look like this:
|
305
|
+
```
|
306
|
+
ansible-playbook -i vagrant-flow_ansible_inventory myPlaybooks/main.yml
|
307
|
+
```
|
308
|
+
|
309
|
+
###Expectations:
|
310
|
+
Example flow-playbook.yml file
|
311
|
+
```
|
312
|
+
---
|
313
|
+
:playbook: defaultplaybook.yml #Required
|
314
|
+
:inventory: vagrant-flow_ansible_inventory #Required
|
315
|
+
:pattern: '*' #Optional. Will be used in conjunction like so 'ansible-playbook -l [pattern] -i [inventory] -p [playbook]'
|
316
|
+
```
|
317
|
+
|
318
|
+
* * *
|
233
319
|
|
234
320
|
## Future Usage and Specs
|
235
321
|
Looking for vagrant-flow to have the following commands:
|
@@ -262,13 +348,7 @@ vagrant ssh frontend1 ping frontend2
|
|
262
348
|
vagrant ssh frontend2 ping frontend1
|
263
349
|
```
|
264
350
|
|
265
|
-
## Contributing
|
266
351
|
|
267
|
-
1. Fork it ( http://github.com/DemandCube/vagrant-flow/fork )
|
268
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
269
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
270
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
271
|
-
5. Create new Pull Request
|
272
352
|
|
273
353
|
|
274
354
|
## Development Flow
|
@@ -314,6 +394,22 @@ Creating a Gem
|
|
314
394
|
* Tutorial <>
|
315
395
|
* <http://railscasts.com/episodes/245-new-gem-with-bundler>
|
316
396
|
|
397
|
+
Below is how to install as a regular gem which won't work
|
398
|
+
|
399
|
+
Add this line to your application's Gemfile:
|
400
|
+
|
401
|
+
gem 'vagrant-flow'
|
402
|
+
|
403
|
+
And then execute:
|
404
|
+
|
405
|
+
$ bundle
|
406
|
+
|
407
|
+
Or install it yourself as:
|
408
|
+
|
409
|
+
$ gem install vagrant-flow
|
410
|
+
|
411
|
+
* * *
|
412
|
+
|
317
413
|
Commands
|
318
414
|
|
319
415
|
```
|
data/VAGRANT-FLOW
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
__ __ _____ _____ _ _ _______ ______ _ ______ __
|
2
|
+
\ \ / /\ / ____| __ \ /\ | \ | |__ __| | ____| | / __ \ \ / /
|
3
|
+
\ \ / / \ | | __| |__) | / \ | \| | | |______| |__ | | | | | \ \ /\ / /
|
4
|
+
\ \/ / /\ \| | |_ | _ / / /\ \ | . ` | | |______| __| | | | | | |\ \/ \/ /
|
5
|
+
\ / ____ \ |__| | | \ \ / ____ \| |\ | | | | | | |___| |__| | \ /\ /
|
6
|
+
\/_/ \_\_____|_| \_\/_/ \_\_| \_| |_| |_| |______\____/ \/ \/
|
7
|
+
/\
|
8
|
+
/ \
|
9
|
+
/ /\ \
|
10
|
+
/ ____ \
|
11
|
+
/_/___ \_\ _ _____ _
|
12
|
+
| __ \ | |/ ____| | |
|
13
|
+
| | | | ___ _ __ ___ __ _ _ __ __| | | _ _| |__ ___
|
14
|
+
| | | |/ _ \ '_ ` _ \ / _` | '_ \ / _` | | | | | | '_ \ / _ \
|
15
|
+
| |__| | __/ | | | | | (_| | | | | (_| | |___| |_| | |_) | __/
|
16
|
+
|_____/ \___|_| |_| |_|\__,_|_| |_|\__,_|\_____\__,_|_.__/ \___|
|
17
|
+
| __ \ (_) | |
|
18
|
+
| |__) | __ ___ _ ___ ___| |_
|
19
|
+
| ___/ '__/ _ \| |/ _ \/ __| __|
|
20
|
+
| | | | | (_) | | __/ (__| |_
|
21
|
+
|_| |_| \___/| |\___|\___|\__|
|
22
|
+
_/ |
|
23
|
+
|__/
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
###This shows how to make a valid configuration file in YAML format for vagrant-flow to consume with the ansible-inventory command
|
6
|
+
|
7
|
+
x = {
|
8
|
+
:api_key => "apikeygoeshere",
|
9
|
+
:client_id => "clientidgoeshere",
|
10
|
+
}
|
11
|
+
|
12
|
+
begin
|
13
|
+
File.open('hostfile_do.yml', 'w') {|f| f.write x.to_yaml }
|
14
|
+
rescue
|
15
|
+
warn "Could not write file hostfile_do.yml"
|
16
|
+
end
|
17
|
+
|
18
|
+
y = YAML.load(x.to_yaml)
|
19
|
+
|
20
|
+
y.each {|key,value|
|
21
|
+
puts key
|
22
|
+
puts value
|
23
|
+
puts "\n"
|
24
|
+
}
|
25
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
###This shows how to make a valid configuration file in YAML format for vagrant-flow to consume with the ansible-inventory command
|
6
|
+
x = {
|
7
|
+
:sshPrivateKeyPath =>"~/.ssh/id_rsa",
|
8
|
+
:digitalOceanApiKey => "digitaloceanapikeygoeshere",
|
9
|
+
:digitalOceanClientId => "digitaloceanclientidgoeshere",
|
10
|
+
:digitalOceanRegion => "San Francisco 1",
|
11
|
+
:intnetName=>"neverwinterDP",
|
12
|
+
"machines" => [
|
13
|
+
{"name"=>"sparkngin1", "url"=>"demandcube/centos-65_x86_64-VB-4.3.8", "digitalOceanImage"=>"CentOS 6.5 x64"},
|
14
|
+
{"name"=>"sparkngin2", "url"=>"demandcube/centos-65_x86_64-VB-4.3.8", "digitalOceanImage"=>"CentOS 6.5 x64"},
|
15
|
+
{"name"=>"jenkinsdp", "url"=>"demandcube/centos-65_x86_64-VB-4.3.8", "digitalOceanImage"=>"CentOS 6.5 x64"},
|
16
|
+
]
|
17
|
+
}
|
18
|
+
|
19
|
+
begin
|
20
|
+
File.open('multiinitconfig.yml', 'w') {|f|
|
21
|
+
f.write x.to_yaml
|
22
|
+
}
|
23
|
+
rescue
|
24
|
+
warn "Could not write file multiinit.yml"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
y = YAML.load(x.to_yaml)
|
29
|
+
|
30
|
+
y.each {|key,value|
|
31
|
+
puts key
|
32
|
+
puts value
|
33
|
+
puts "\n"
|
34
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
###This shows how to make a valid configuration file in YAML format for vagrant-flow to consume with the ansible-inventory command
|
6
|
+
x = {
|
7
|
+
:playbook => "defaultplaybook.yml",
|
8
|
+
:inventory => "vagrant-flow_ansible_inventory",
|
9
|
+
#:pattern => "*", #:pattern is optional
|
10
|
+
}
|
11
|
+
|
12
|
+
begin
|
13
|
+
File.open('flow-playbook.yml', 'w') {|f|
|
14
|
+
f.write x.to_yaml
|
15
|
+
}
|
16
|
+
rescue
|
17
|
+
warn "Could not write file flow-playbook.yml"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
y = YAML.load(x.to_yaml)
|
22
|
+
|
23
|
+
y.each {|key,value|
|
24
|
+
puts key
|
25
|
+
puts value
|
26
|
+
puts "\n"
|
27
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
class DigitalOcean_Api
|
6
|
+
|
7
|
+
def initialize(digitaloceanurl= 'https://api.digitalocean.com/droplets/?')
|
8
|
+
@DIGITALOCEAN_URL=digitaloceanurl
|
9
|
+
end
|
10
|
+
|
11
|
+
#getparams should be a hash that will get turned into a url
|
12
|
+
def makeApiCall(getparams)
|
13
|
+
url = @DIGITALOCEAN_URL
|
14
|
+
getparams.each {|key,val|
|
15
|
+
url+=key+"="+val+"&"
|
16
|
+
}
|
17
|
+
url = url.chomp("&")
|
18
|
+
|
19
|
+
response = Net::HTTP.get_response(URI.parse(url))
|
20
|
+
|
21
|
+
return JSON.parse(response.body)
|
22
|
+
end
|
23
|
+
|
24
|
+
#https://api.digitalocean.com/droplets/?client_id=xxxxxxx&api_key=yyyyyyyyyy
|
25
|
+
#returns parsed hash object from returned json
|
26
|
+
def showAllActiveDroplets(clientId,apiKey)
|
27
|
+
x = {
|
28
|
+
"client_id" => clientId,
|
29
|
+
"api_key" => apiKey,
|
30
|
+
}
|
31
|
+
return makeApiCall(x)
|
32
|
+
end
|
33
|
+
|
34
|
+
#Calls showAllActiveDroplets and then parses the info for just hostname and ip
|
35
|
+
def getHostNamesAndIps(clientId,apiKey)
|
36
|
+
hash = showAllActiveDroplets(clientId,apiKey)
|
37
|
+
returnHash = []
|
38
|
+
hash["droplets"].each {|droplet|
|
39
|
+
returnHash.push({
|
40
|
+
:hostname => droplet["name"],
|
41
|
+
:ip => droplet["ip_address"]
|
42
|
+
})
|
43
|
+
}
|
44
|
+
return returnHash
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
@@ -1,19 +1,25 @@
|
|
1
1
|
require "vagrant"
|
2
2
|
require 'optparse'
|
3
3
|
require 'tempfile'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
#Require my library for talking to digitalocean
|
7
|
+
require File.expand_path(File.dirname(__FILE__) ) +"/digitalocean_api"
|
4
8
|
|
5
9
|
module VagrantPlugins
|
6
10
|
module CommandVagrantFlow
|
7
11
|
module Command
|
8
12
|
class HostFile < Vagrant.plugin("2", :command)
|
9
|
-
|
13
|
+
@@begin_tag_line = "##BEGIN: ADDED BY NEVERWINTERDP'S VAGRANT-FLOW HOSTFILE COMMAND"
|
14
|
+
@@end_tag_line = "##END: ADDED BY NEVERWINTERDP'S VAGRANT-FLOW HOSTFILE COMMAND"
|
15
|
+
|
10
16
|
# Builtin from Command class
|
11
17
|
# Must override to provide a description
|
12
18
|
def self.synopsis
|
13
19
|
"Sets /etc/hosts so that all your machines can communicate with each other"
|
14
20
|
end
|
15
|
-
|
16
|
-
|
21
|
+
|
22
|
+
|
17
23
|
# Builtin from Command class
|
18
24
|
# Must override to provide core functionality
|
19
25
|
def execute
|
@@ -23,60 +29,86 @@ module VagrantPlugins
|
|
23
29
|
options[:provision_ignore_sentinel] = false
|
24
30
|
options[:nowrite] = false
|
25
31
|
options[:quiet] = false
|
26
|
-
|
27
|
-
|
32
|
+
options[:digitalocean] = false
|
33
|
+
options[:digitalocean_file] = "hostfile_do.yml"
|
34
|
+
|
35
|
+
#Parse option, look up OptionParser documentation
|
28
36
|
opts = OptionParser.new do |o|
|
29
37
|
# o.banner = "Usage: vagrant ansible-inventory [vm-name] [options] [-h]"
|
30
38
|
o.banner = "A NeverWinterDP technology from the Department of Badass.\n\n"+
|
31
39
|
"Usage: vagrant flow hostfile [-hnkq]\n"+
|
32
40
|
"Edits all your VMs /etc/hosts file to be able to find all the machines on your private network"
|
33
41
|
o.separator ""
|
34
|
-
|
42
|
+
|
35
43
|
o.on("-q", "--quiet", "(Optional) Suppress output to STDOUT and STDERR") do |f|
|
36
44
|
options[:quiet] = true
|
37
45
|
end
|
38
|
-
|
46
|
+
|
39
47
|
o.on("-n", "--no-write-hosts", "(Optional) Don't actually write a new hosts file to the guest machine") do |f|
|
40
48
|
options[:nowrite] = true
|
41
49
|
end
|
50
|
+
|
51
|
+
o.on("-d", "--digitalocean", "(Optional) Writes your digital ocean's hostnames and IP addresses to hosts file. Default file is hostfile_do.yml") do |f|
|
52
|
+
options[:digitalocean] = true
|
53
|
+
end
|
54
|
+
|
55
|
+
o.on("-o", "--digitaloceanfile FILE", "(Optional) File to read in for -d option instead of hostfile_do.yml") do |f|
|
56
|
+
options[:digitalocean_file] = f
|
57
|
+
end
|
42
58
|
end
|
43
59
|
argv = parse_options(opts)
|
44
60
|
return if !argv
|
45
61
|
|
46
62
|
|
63
|
+
|
47
64
|
hostinfo=[]
|
48
65
|
#Go through config
|
49
66
|
#Map hostnames to IP's
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
67
|
+
if options[:digitalocean]
|
68
|
+
config = YAML.load_file(options[:digitalocean_file])
|
69
|
+
digitalocean = DigitalOcean_Api.new()
|
70
|
+
hostinfo = digitalocean.getHostNamesAndIps(config[:client_id],config[:api_key])
|
71
|
+
else
|
72
|
+
with_target_vms(argv, :provider => options[:provider]) do |machine|
|
73
|
+
return unless machine.communicate.ready?
|
74
|
+
hostname = machine.config.vm.hostname
|
75
|
+
machine.config.vm.networks.each {|networks|
|
76
|
+
networks.each {|net|
|
77
|
+
if net.is_a?(Hash) and net.has_key?(:ip)
|
78
|
+
hostinfo.push(
|
79
|
+
{
|
80
|
+
:hostname=>hostname,
|
81
|
+
:ip=>net[:ip]
|
82
|
+
})
|
83
|
+
end
|
84
|
+
}
|
62
85
|
}
|
63
|
-
|
86
|
+
end
|
64
87
|
end
|
65
88
|
|
89
|
+
|
90
|
+
#Print out Hostname and IP
|
91
|
+
if not options[:quiet]
|
92
|
+
puts "HOSTS FILE INFO:"
|
93
|
+
hostinfo.each {|x|
|
94
|
+
puts x[:hostname]+": "+x[:ip]
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
66
98
|
#What we're going to add to the end of the guest's hostfile
|
67
99
|
#A combination of IP's and hostnames
|
68
|
-
toconcatenate="\n"+"
|
100
|
+
toconcatenate="\n"+@@begin_tag_line+"\n"
|
69
101
|
hostinfo.each {|x|
|
70
|
-
toconcatenate+=x[:ip]+" "+x[:hostname]+"\n"
|
102
|
+
toconcatenate += x[:ip]+" "+x[:hostname]+"\n"
|
71
103
|
}
|
72
|
-
|
73
|
-
|
104
|
+
toconcatenate += @@end_tag_line+"\n"
|
105
|
+
|
74
106
|
#Read in guest's current hosts file
|
75
107
|
#Append our new entries to it
|
76
108
|
#Write it out onto the guest's hosts file
|
77
109
|
with_target_vms(argv, :provider => options[:provider]) do |machine|
|
78
110
|
return unless machine.communicate.ready?
|
79
|
-
|
111
|
+
|
80
112
|
#This block of code was shamelessly stolen from
|
81
113
|
#https://github.com/smdahlen/vagrant-hostmanager/blob/master/lib/vagrant-hostmanager/hosts_file.rb
|
82
114
|
#Why reinvent the wheel?
|
@@ -87,35 +119,51 @@ module VagrantPlugins
|
|
87
119
|
elsif (machine.communicate.test("test -d $Env:SystemRoot"))
|
88
120
|
realhostfile = "#{ENV['WINDIR']}\\System32\\drivers\\etc\\hosts"
|
89
121
|
move_cmd = 'mv -force'
|
90
|
-
else
|
122
|
+
else
|
91
123
|
realhostfile = '/etc/hosts'
|
92
124
|
move_cmd = 'mv'
|
93
125
|
end
|
94
|
-
|
126
|
+
|
95
127
|
#Back to my code
|
96
128
|
#Grab Vagrant's temp file location
|
129
|
+
guesthostfilepath_original = @env.tmp_path.join("hosts."+machine.config.vm.hostname+".og")
|
97
130
|
guesthostfilepath = @env.tmp_path.join("hosts."+machine.config.vm.hostname)
|
131
|
+
|
98
132
|
#Download guest's hosts file
|
99
|
-
machine.communicate.download(realhostfile,
|
100
|
-
|
133
|
+
machine.communicate.download(realhostfile, guesthostfilepath_original)
|
134
|
+
|
135
|
+
#Skip everything between ##BEGIN and ##END
|
136
|
+
guesthostfile = File.open(guesthostfilepath, "w")
|
137
|
+
skip = false
|
138
|
+
File.open(guesthostfilepath_original, "r") do |infile|
|
139
|
+
while (line = infile.gets)
|
140
|
+
if line.strip() == @@begin_tag_line
|
141
|
+
skip = true
|
142
|
+
elsif line.strip() == @@end_tag_line
|
143
|
+
skip = false
|
144
|
+
else
|
145
|
+
guesthostfile.write(line) if not skip
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
101
150
|
#Append our hostname/IP info to the end of the hosts file
|
102
|
-
guesthostfile = File.open(guesthostfilepath,"a")
|
103
151
|
guesthostfile.write(toconcatenate)
|
104
152
|
guesthostfile.close()
|
105
|
-
|
106
|
-
if not options[:nowrite]
|
153
|
+
|
154
|
+
if not options[:nowrite]
|
107
155
|
#Upload updated hosts file to guest to temp location
|
108
156
|
machine.communicate.upload(guesthostfile.path, '/tmp/hosts')
|
109
157
|
#Move temp file over on top of hosts file
|
110
|
-
machine.communicate.sudo(move_cmd+" /tmp/hosts "+realhostfile)
|
158
|
+
machine.communicate.sudo(move_cmd+" /tmp/hosts "+realhostfile)
|
111
159
|
end
|
112
160
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
161
|
+
|
162
|
+
|
163
|
+
|
116
164
|
end
|
117
|
-
|
118
|
-
end
|
119
|
-
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
120
168
|
end
|
121
169
|
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#Flush stdout immediately
|
2
|
+
$stdout.sync = true
|
3
|
+
|
4
|
+
require "vagrant"
|
5
|
+
require 'optparse'
|
6
|
+
require 'yaml'
|
7
|
+
require 'pty'
|
8
|
+
|
9
|
+
module VagrantPlugins
|
10
|
+
module CommandVagrantFlow
|
11
|
+
module Command
|
12
|
+
class Playbook < Vagrant.plugin("2", :command)
|
13
|
+
|
14
|
+
# Builtin from Command class
|
15
|
+
# Must override to provide a description
|
16
|
+
def self.synopsis
|
17
|
+
"Runs ansible-playbook so you don't have to!"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Builtin from Command class
|
22
|
+
# Must override to provide core functionality
|
23
|
+
def execute
|
24
|
+
options = {}
|
25
|
+
options[:destroy_on_error] = true
|
26
|
+
options[:parallel] = false
|
27
|
+
options[:provision_ignore_sentinel] = false
|
28
|
+
options[:configfile] = "flow-playbook.yml"
|
29
|
+
options[:print] = false
|
30
|
+
options[:quiet] = false
|
31
|
+
|
32
|
+
#Parse option, look up OptionParser documentation
|
33
|
+
opts = OptionParser.new do |o|
|
34
|
+
o.banner = "A NeverWinterDP technology from the Department of Badass.\n\n"+
|
35
|
+
"Usage: vagrant flow playbook [-hfpq]\n"+
|
36
|
+
"Reads in config from flow-playbook.yml by default to be able to run ansible-playbook more easily"
|
37
|
+
o.separator ""
|
38
|
+
|
39
|
+
o.on("-f", "--file-playbook FILE", "(Optional) Use a specified playbook config file instead of default (flow-playbook.yml)") do |f|
|
40
|
+
options[:configfile] = f
|
41
|
+
end
|
42
|
+
|
43
|
+
o.on("-p", "--print-only", "(Optional) Don't actually ansible-playbook, but just output what would be run to STDOUT") do |f|
|
44
|
+
options[:print] = true
|
45
|
+
end
|
46
|
+
|
47
|
+
o.on("-q", "--quiet", "(Optional) Suppress output to STDOUT and STDERR") do |f|
|
48
|
+
options[:quiet] = true
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
argv = parse_options(opts)
|
53
|
+
return if !argv
|
54
|
+
|
55
|
+
config={}
|
56
|
+
begin
|
57
|
+
#Load YAML
|
58
|
+
config = YAML.load_file(options[:configfile])
|
59
|
+
rescue
|
60
|
+
#Give warning if no file could be found
|
61
|
+
if not options[:quiet]
|
62
|
+
warn "Could not open file: "+options[:configfile].to_s
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#Bail out if config is fubar
|
67
|
+
if not config.has_key?(:playbook)
|
68
|
+
if not options[:quiet]
|
69
|
+
warn options[:configfile].to_s+" is missing \":playbook\" key"
|
70
|
+
end
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
74
|
+
if not config.has_key?(:inventory)
|
75
|
+
if not options[:quiet]
|
76
|
+
warn options[:configfile].to_s+" is missing \":inventory\" key"
|
77
|
+
end
|
78
|
+
return
|
79
|
+
end
|
80
|
+
|
81
|
+
#Build the ansible-playbook command
|
82
|
+
command = "ansible-playbook "
|
83
|
+
if config.has_key?(:pattern)
|
84
|
+
command+= "-l "+config[:pattern]+" "
|
85
|
+
end
|
86
|
+
command+= "-i "+config[:inventory]+" "
|
87
|
+
command+= config[:playbook]
|
88
|
+
|
89
|
+
#If print is specified, only output the command
|
90
|
+
if options[:print]
|
91
|
+
#But only print if the quiet command isn't specified
|
92
|
+
if not options[:quiet]
|
93
|
+
puts command
|
94
|
+
end
|
95
|
+
else
|
96
|
+
|
97
|
+
|
98
|
+
#Run the command
|
99
|
+
#this fancy block of code outputs the output in real time
|
100
|
+
begin
|
101
|
+
PTY.spawn( "#{command}" ) do |stdin, stdout, pid|
|
102
|
+
begin
|
103
|
+
stdin.each { |line|
|
104
|
+
if not options[:quiet]
|
105
|
+
puts line
|
106
|
+
end
|
107
|
+
}
|
108
|
+
#This wait() is required to set the exit code
|
109
|
+
Process.wait(pid)
|
110
|
+
rescue Errno::EIO
|
111
|
+
end
|
112
|
+
end
|
113
|
+
rescue PTY::ChildExited
|
114
|
+
#If there was an error, throw an error ourselves
|
115
|
+
raise Vagrant::Errors::AnsibleFailed
|
116
|
+
end
|
117
|
+
|
118
|
+
#If there was an error, throw an error ourselves
|
119
|
+
raise Vagrant::Errors::AnsibleFailed if not $?.success?
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -19,11 +19,28 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|
19
19
|
<%= machine["name"]%>.vm.network :private_network, ip: "<%= machine["ip"]%>", virtualbox__intnet: "<%= @intnetName %>"
|
20
20
|
<%= machine["name"]%>.vm.hostname = "<%= machine["name"]%>"
|
21
21
|
|
22
|
+
#digitalOcean provider
|
23
|
+
<% if machine.has_key?("digitalOceanImage") and @digitalOceanApiKey and @digitalOceanClientId and @sshPrivateKeyPath and @digitalOceanRegion%>
|
24
|
+
<%= machine["name"]%>.vm.synced_folder ".", "/vagrant", disabled: true
|
25
|
+
config.vm.provider :digital_ocean do |provider, override|
|
26
|
+
override.ssh.private_key_path = '<%= @sshPrivateKeyPath %>'
|
27
|
+
provider.client_id = '<%= @digitalOceanClientId %>'
|
28
|
+
provider.api_key = '<%= @digitalOceanApiKey %>'
|
29
|
+
provider.private_networking = 'true'
|
30
|
+
provider.region = '<%= @digitalOceanRegion %>'
|
31
|
+
provider.image = '<%= machine["digitalOceanImage"] %>'
|
32
|
+
end
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
|
36
|
+
#VirtualBox provider
|
22
37
|
config.vm.provider :virtualbox do |vb|
|
23
38
|
vb.name = "<%= machine["name"]%>"
|
24
39
|
# vb.customize ["modifyvm", :id, "--memory", "1024"]
|
25
40
|
# vb.customize ["modifyvm", :id, "--cpus", "2"]
|
26
41
|
end
|
42
|
+
|
27
43
|
end
|
28
44
|
<% end %>
|
29
45
|
end
|
46
|
+
|
data/lib/vagrant-flow/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Morin
|
@@ -50,12 +50,18 @@ files:
|
|
50
50
|
- NEVERWINTERDP
|
51
51
|
- README.md
|
52
52
|
- Rakefile
|
53
|
+
- VAGRANT-FLOW
|
53
54
|
- create_sample_ansible-inventory_input-file.rb
|
55
|
+
- create_sample_hostfile_digitalocean_input-file.rb
|
54
56
|
- create_sample_multiinit_input-file.rb
|
57
|
+
- create_sample_multiinit_input-file_digitalocean.rb
|
58
|
+
- create_sample_playbook_input-file.rb
|
55
59
|
- lib/vagrant-flow.rb
|
56
60
|
- lib/vagrant-flow/command/ansibleinventory.rb
|
61
|
+
- lib/vagrant-flow/command/digitalocean_api.rb
|
57
62
|
- lib/vagrant-flow/command/hostfile.rb
|
58
63
|
- lib/vagrant-flow/command/multiinit.rb
|
64
|
+
- lib/vagrant-flow/command/playbook.rb
|
59
65
|
- lib/vagrant-flow/command/root.rb
|
60
66
|
- lib/vagrant-flow/plugin.rb
|
61
67
|
- lib/vagrant-flow/templates/multiinit.erb
|