vagrant-gpii-ci 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +44 -62
- data/gpii-ci.yml.template +44 -0
- data/lib/vagrant-gpii-ci/action/build_vagrantfile.rb +160 -0
- data/lib/vagrant-gpii-ci/action/init_environment.rb +7 -8
- data/lib/vagrant-gpii-ci/action/update_hosts.rb +138 -0
- data/lib/vagrant-gpii-ci/action.rb +8 -101
- data/lib/vagrant-gpii-ci/command/base.rb +1 -1
- data/lib/vagrant-gpii-ci/command/ci.rb +66 -0
- data/lib/vagrant-gpii-ci/command/init.rb +2 -2
- data/lib/vagrant-gpii-ci/command/test.rb +55 -47
- data/lib/vagrant-gpii-ci/plugin.rb +19 -16
- data/lib/vagrant-gpii-ci/version.rb +2 -2
- data/lib/vagrant-gpii-ci.rb +16 -3
- data/samples/gpii-linux/.gpii-ci.yml +25 -0
- data/samples/gpii-nexus/.gpii-ci.yml +26 -0
- data/samples/gpii-universal/.gpii-ci.yml +32 -0
- data/samples/gpii-windows/.gpii-ci.yml +33 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/vagrant/gpiici_spec.rb +12 -0
- data/{vagrant-cienv.gemspec → vagrant-gpiici.gemspec} +3 -3
- metadata +15 -32
- data/lib/envs/default.json +0 -20
- data/lib/envs/linux-desktop.json +0 -22
- data/lib/envs/production.yml +0 -33
- data/lib/provisioning/base-playbook.yml +0 -16
- data/lib/provisioning/couchdb-playbook.yml +0 -11
- data/lib/provisioning/couchdb-requirements.yml +0 -5
- data/lib/provisioning/couchdb-vagrant-vars.yml +0 -1
- data/lib/provisioning/gpii-linux-playbook.yml +0 -11
- data/lib/provisioning/gpii-linux-requirements.yml +0 -6
- data/lib/provisioning/gpii-linux-vagrant-vars.yml +0 -23
- data/lib/provisioning/nodejs-playbook.yml +0 -12
- data/lib/provisioning/nodejs-requirements.yml +0 -7
- data/lib/provisioning/nodejs-vagrant-vars.yml +0 -11
- data/lib/provisioning/preferences-playbook.yml +0 -13
- data/lib/provisioning/preferences-requirements.yml +0 -9
- data/lib/provisioning/preferences-vagrant-vars.yml +0 -5
- data/lib/vagrant-gpii-ci/config/config_folders.rb +0 -17
- data/lib/vagrant-gpii-ci/config/config_network.rb +0 -69
- data/lib/vagrant-gpii-ci/config/config_provider.rb +0 -40
- data/lib/vagrant-gpii-ci/config/config_provision.rb +0 -50
- data/qi.yml.template +0 -56
- data/samples/gpii-linux/.qi.yml +0 -22
- data/samples/gpii-linux-production/.qi.yml +0 -41
- data/samples/gpii-nexus/.qi.yml +0 -24
- data/samples/gpii-universal/.qi.yml +0 -27
- data/spec/vagrant/cienv_spec.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34f333fe7dab9d5a9d7cce696ee92c0393b9edd1
|
4
|
+
data.tar.gz: 5a57b071b54babf95d35a9783b270c0ebcaee40d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 805f875edb7a29b3c945932e0b4231faafa3a50db67b60fce0f6acee146666fad1ece7f96343bfba2fc041356def697e9d32dae748663e31b6d24c1ebe16ef2f
|
7
|
+
data.tar.gz: 6c7d40583bff99bbde2f97241987df40836005fc090730ab9a6db63b2cc98097db69a522c587f73cbf01df0d12dca64dc280d833f50bd1955a2252ea305100e0
|
data/README.md
CHANGED
@@ -1,94 +1,76 @@
|
|
1
|
-
Vagrant-
|
1
|
+
Vagrant-GPII-CI
|
2
2
|
=============
|
3
3
|
|
4
|
-
Vagrant-
|
5
|
-
Vagrantfile. It uses virtual machine definitions to spin up complete
|
4
|
+
Vagrant-GPII-CI is a vagrant plugin that is used to simplify the configuration stored in a Vagrantfile. It uses virtual machine definitions to spin up complete
|
6
5
|
enviroments where you can run tests or run your code.
|
7
6
|
|
8
7
|
Installation
|
9
8
|
------------
|
10
9
|
|
11
10
|
```
|
12
|
-
|
13
|
-
cp node_modules/vagrant-vmenv/Vagrantfile.template Vagrantfile
|
14
|
-
cp node_modules/vagrant-vmenv/qi.yml.template .qi.yml
|
11
|
+
vagrant plugin install vagrant-gpii-ci
|
15
12
|
```
|
16
13
|
|
17
|
-
The Vagrantfile acts as a pointer to the module, it shouldn't be modified. If
|
18
|
-
you want to make a change at the environment level do so in the [environment
|
19
|
-
configuration file](envs/), and if you want to configure how the applications
|
20
|
-
are deployed and tested do so in the [.qi.yml](qi.yml.template) file of your
|
21
|
-
repository.
|
22
|
-
|
23
14
|
Working with vms
|
24
15
|
----------------
|
25
16
|
|
17
|
+
No Vagrantfile is required if a file [.gpii-ci.yml](gpii-ci.yml.template) is found in the root of the repository.
|
18
|
+
|
19
|
+
The name of the file can be override using the environment variable `VAGRANT_CI_FILE`.
|
20
|
+
|
26
21
|
Commands:
|
27
22
|
|
28
|
-
* `vagrant up` to spin up the
|
29
|
-
* `vagrant destroy` to stop and destroy the vm.
|
30
|
-
* `vagrant
|
23
|
+
* `vagrant up [vm]` to spin up the defined in the .ci_env variable of the [.gpii-ci.yml](gpii-ci.yml.template) file.
|
24
|
+
* `vagrant destroy [vm]` to stop and destroy the vm.
|
25
|
+
* `vagrant reload [vm]` to stop and destroy the vm.
|
26
|
+
* `vagrant halt [vm]` to shutdown the vm without destroy it.
|
27
|
+
* `vagrant ci test [vm]` to run all the stages defined in the selected vm
|
28
|
+
|
31
29
|
|
32
30
|
Note:
|
33
31
|
|
34
|
-
*
|
35
|
-
application listed in the .qi.yml file.
|
36
|
-
* `vagrant provision` will exec the commands listed in the *test_cmds* variable
|
37
|
-
of each application listed in the .qi.yml file.
|
32
|
+
* The `vm` parameter is not necessary in environments with only one VM defined.
|
38
33
|
|
39
|
-
|
40
|
-
----------
|
34
|
+
Sample:
|
41
35
|
|
42
|
-
A VM can have multiple virtual NICs. Two types are avilable for each NIC: public
|
43
|
-
and private. The public NICs will be attached to the host's physical network,
|
44
|
-
the private NICs will be attached to a private network only visible between the
|
45
|
-
other VMs and the host. The IP address of a private network can be customized in
|
46
|
-
the definition of the VM. An example of the network definition of a VM can be:
|
47
36
|
|
48
37
|
```
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
38
|
+
.ci_env:
|
39
|
+
default: &default
|
40
|
+
cpu: 2 # number of cpus
|
41
|
+
memory: 2048 # amount of RAM memory
|
42
|
+
clone: true # use the linked_clone Vagrant feature
|
43
|
+
autostart: false # only start a VM when it's specfied in the command line
|
44
|
+
vms:
|
45
|
+
windows10: # name of the VM
|
46
|
+
<<: *default # referece of the common part
|
47
|
+
3d: true # enable 3D acceleration
|
48
|
+
sound: true # add a sound card to the VM
|
49
|
+
box: inclusivedesign/windows10-eval
|
50
|
+
windows81: # name of the VM
|
51
|
+
<<: *default # referece of the common part
|
52
|
+
box: inclusivedesign/windows81-eval-x64
|
53
|
+
windows7: # name of the VM
|
54
|
+
<<: *default # referece of the common part
|
55
|
+
box: inclusivedesign/windows7-eval-x64
|
55
56
|
```
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
this is very useful to point services between the VMs.
|
60
|
-
|
61
|
-
Forwarded ports
|
62
|
-
---------------
|
58
|
+
Networking
|
59
|
+
----------
|
63
60
|
|
64
|
-
|
65
|
-
variable is the source port to be mapped to the `host_port` variable. The
|
66
|
-
`guest_port` must be set in each port forward block, `host_port` and protocol are
|
67
|
-
optionals.
|
61
|
+
All the VMs have access to Internet using the gateway of the host through a NAT interface.
|
68
62
|
|
69
|
-
|
70
|
-
ports:
|
71
|
-
- guest_port: 8080
|
72
|
-
host_port: 8888
|
73
|
-
protocol: tcp
|
74
|
-
- guest_port: 8181
|
75
|
-
host_port: 9999
|
76
|
-
- guest_port:8081
|
77
|
-
```
|
63
|
+
In the case of multi VM environments, a additional NIC card is create in each VM with a private IP of a private network that all the VMs share. The IP range of this network is 192.168.50.0/24. The IP address are assigned to each VM starting by 10.
|
78
64
|
|
79
|
-
|
80
|
-
|
65
|
+
Mapped ports
|
66
|
+
---------------
|
81
67
|
|
82
|
-
|
83
|
-
|
84
|
-
the host to the path set in the *dest* variable in the VM.
|
68
|
+
The port mapping is configured in the VMs definition. The `mapped_ports`
|
69
|
+
variable is a list of ports that will be mapped from the VM to the host.
|
85
70
|
|
86
71
|
```
|
87
|
-
|
88
|
-
|
89
|
-
|
72
|
+
mapped_ports:
|
73
|
+
- 8080
|
74
|
+
- 8181
|
90
75
|
```
|
91
76
|
|
92
|
-
More samples definitions can be found either in the [envs](envs) directory or in
|
93
|
-
the [qi.yml.template](qi.yml.template).
|
94
|
-
|
@@ -0,0 +1,44 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
# The variables that start with a dot "." are ignored by gitlab-ci,
|
4
|
+
# but they are used by the vagrant-gpii-ci plugin
|
5
|
+
#
|
6
|
+
# .ci_env variable defines the settings of each VM. The common variables are in
|
7
|
+
# the section 'default' which will be reference later in each VM definition.
|
8
|
+
|
9
|
+
.ci_env:
|
10
|
+
default: &default
|
11
|
+
cpu: 2 # number of cpus
|
12
|
+
memory: 2048 # amount of RAM memory
|
13
|
+
clone: true # use the linked_clone Vagrant feature
|
14
|
+
autostart: false # only start the VM specfied in the command line
|
15
|
+
vms:
|
16
|
+
windows10: # name of the VM
|
17
|
+
<<: *default # referece of the common part
|
18
|
+
box: inclusivedesign/windows10-eval
|
19
|
+
windows81: # name of the VM
|
20
|
+
<<: *default # referece of the common part
|
21
|
+
box: inclusivedesign/windows81-eval-x64
|
22
|
+
windows7: # name of the VM
|
23
|
+
<<: *default # referece of the common part
|
24
|
+
box: inclusivedesign/windows7-eval-x64
|
25
|
+
|
26
|
+
stages: # Stages to perform when 'ci test' command is invoked
|
27
|
+
- setup # name of the first stage to execute
|
28
|
+
- test # name of the second stage to execute
|
29
|
+
|
30
|
+
setup_job:
|
31
|
+
stage: setup # name of the stage
|
32
|
+
script: # Only one multiline script to execute
|
33
|
+
- |
|
34
|
+
choco upgrade firefox googlechrome -y
|
35
|
+
$moduleLocation = Join-Path $env:SystemDrive "vagrant/provisioning/Provisioning.psm1"
|
36
|
+
$destinationDir = Join-Path $env:SystemDrive "tmp"
|
37
|
+
cp $moduleLocation $destinationDir
|
38
|
+
test_job:
|
39
|
+
stage: test # name of the stage
|
40
|
+
script: # One line per command to execute
|
41
|
+
- provisioning/Chocolatey.ps1
|
42
|
+
- provisioning/Npm.ps1
|
43
|
+
- provisioning/Build.ps1
|
44
|
+
- provisioning/Installer.ps1
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module GPIICi
|
5
|
+
module Action
|
6
|
+
class BuildVagrantfile
|
7
|
+
|
8
|
+
def initialize(app, env)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
@env = env
|
14
|
+
|
15
|
+
# The file .gpii-ci.yml can be override using this environment variable
|
16
|
+
ci_file ||= ENV["VAGRANT_CI_FILE"] if ENV.key?("VAGRANT_CI_FILE")
|
17
|
+
ci_file ||= ".gpii-ci.yml"
|
18
|
+
|
19
|
+
# Only if the ci_file is found the plugin will run
|
20
|
+
if File.exist?(project_home(@env).join(ci_file))
|
21
|
+
|
22
|
+
environment = @env[:env]
|
23
|
+
ci_definition = get_ci_definition (ci_file)
|
24
|
+
environment.instance_variable_set(:@ci_tests, get_ci_tests(ci_definition))
|
25
|
+
vagrantfile_proc = Proc.new do
|
26
|
+
Vagrant.configure(2) do |config|
|
27
|
+
build_vms_config(config, get_ci_environment(ci_definition))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# The Environment instance has been instantiated without a Vagrantfile
|
32
|
+
# that means that we need to store some internal variables and
|
33
|
+
# instantiate again the Vagrantfile instance with our previous code.
|
34
|
+
environment.instance_variable_set(:@root_path, project_home(@env))
|
35
|
+
environment.instance_variable_set(:@local_data_path, vagrant_home(@env))
|
36
|
+
# the cienv code will be the first item to check in the list of
|
37
|
+
# Vagrantfile sources
|
38
|
+
config_loader = environment.config_loader
|
39
|
+
config_loader.set(:cienv, vagrantfile_proc.call)
|
40
|
+
environment.instance_variable_set(:@vagrantfile, Vagrant::Vagrantfile.new(config_loader, [:cienv, :home, :root]))
|
41
|
+
|
42
|
+
end
|
43
|
+
@app.call(env)
|
44
|
+
end
|
45
|
+
|
46
|
+
def vagrant_home(env)
|
47
|
+
project_home(env).join(Vagrant::Environment::DEFAULT_LOCAL_DATA)
|
48
|
+
end
|
49
|
+
|
50
|
+
def project_home(env)
|
51
|
+
environment = env[:env]
|
52
|
+
environment.instance_variable_get(:@cwd)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_ci_tests(definition)
|
56
|
+
ci_tests = {}
|
57
|
+
definition[".ci_env"]["vms"].each do | vmname, vmdetails |
|
58
|
+
|
59
|
+
ci_tests["#{vmname}"] = {}
|
60
|
+
ci_tests["#{vmname}"]["shell"] = {}
|
61
|
+
definition["stages"].each do |stage|
|
62
|
+
definition.each do |stagename, stagecontent|
|
63
|
+
# Ignore the statements that start with a dot
|
64
|
+
next if stagename.start_with?(".") or stagename.eql?("stages") or not stagecontent["stage"].eql?(stage)
|
65
|
+
# Build the hash of tests for each VM
|
66
|
+
if stagecontent.include?("stage")
|
67
|
+
if vmdetails.include?("tags") and stagecontent.include?("tags")
|
68
|
+
ci_tests["#{vmname}"]["shell"][stagecontent["stage"]] = stagecontent["script"] \
|
69
|
+
if not (stagecontent["tags"] & vmdetails["tags"]).empty?
|
70
|
+
elsif not stagecontent.include?("tags")
|
71
|
+
ci_tests["#{vmname}"]["shell"][stagecontent["stage"]] = stagecontent["script"]
|
72
|
+
else
|
73
|
+
next
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
ci_tests
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_ci_definition(definition_file)
|
83
|
+
# load the definition file
|
84
|
+
ci_file = File.expand_path(project_home(@env).join(definition_file))
|
85
|
+
@ci_definition = YAML.load(File.read(ci_file))
|
86
|
+
end
|
87
|
+
|
88
|
+
# In the case of a multiVM environment, we need to connect the VMs using
|
89
|
+
# a private network
|
90
|
+
def inject_private_network_config(ci_environment_vms)
|
91
|
+
return ci_environment_vms if ci_environment_vms.count() == 1
|
92
|
+
int_id = 10
|
93
|
+
ci_environment_vms.each do |vm,config|
|
94
|
+
ci_environment_vms[vm]["private_ip"] = "192.168.50." + int_id.to_s
|
95
|
+
int_id += 1
|
96
|
+
end
|
97
|
+
ci_environment_vms
|
98
|
+
end
|
99
|
+
def get_ci_environment(definition)
|
100
|
+
ci_environment_vms = inject_private_network_config(definition[".ci_env"]["vms"])
|
101
|
+
#TODO: load additional yaml files to extend the definition of the vms
|
102
|
+
end
|
103
|
+
|
104
|
+
# Setup the provider using the definition of each VM.
|
105
|
+
def set_provider_config(vm_instance, ci_vm_definition)
|
106
|
+
|
107
|
+
vm_instance.vm.provider :virtualbox do |vm|
|
108
|
+
|
109
|
+
vm.linked_clone = ci_vm_definition["clone"] || false
|
110
|
+
|
111
|
+
vm.customize ["modifyvm", :id, "--memory", ci_vm_definition["memory"] ]
|
112
|
+
vm.customize ["modifyvm", :id, "--cpus", ci_vm_definition["cpu"] ]
|
113
|
+
|
114
|
+
if ci_vm_definition["3d"] == true then
|
115
|
+
vm.customize ["modifyvm", :id, "--vram", "128"]
|
116
|
+
vm.customize ["modifyvm", :id, "--accelerate3d", "on"]
|
117
|
+
end
|
118
|
+
|
119
|
+
if ci_vm_definition["sound"] == true then
|
120
|
+
vm.customize ["modifyvm", :id, "--audio", "null", "--audiocontroller", "hda"]
|
121
|
+
end
|
122
|
+
|
123
|
+
vm.customize ["modifyvm", :id, "--ioapic", "on"]
|
124
|
+
vm.customize ["setextradata", "global", "GUI/SuppressMessages", "all"]
|
125
|
+
|
126
|
+
vm.gui = ci_vm_definition["gui"] || true
|
127
|
+
end
|
128
|
+
|
129
|
+
vm_instance.vm.box = ci_vm_definition["box"]
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
def set_network_config(vm_instance, ci_vm_definition)
|
134
|
+
vm_instance.vm.network :private_network, ip: ci_vm_definition["private_ip"] if ci_vm_definition["private_ip"]
|
135
|
+
ci_vm_definition["mapped_ports"].each do |port|
|
136
|
+
vm_instance.vm.network "forwarded_port",
|
137
|
+
guest: port,
|
138
|
+
host: port,
|
139
|
+
protocol: "tcp",
|
140
|
+
auto_correct: true
|
141
|
+
end if ci_vm_definition["mapped_ports"]
|
142
|
+
end
|
143
|
+
|
144
|
+
def build_vms_config(vagrant_config, ci_environment_vms)
|
145
|
+
ci_environment_vms.each do |ci_vm_id, ci_vm_definition|
|
146
|
+
|
147
|
+
ci_autostart = true
|
148
|
+
ci_autostart = ci_vm_definition["autostart"] if ci_vm_definition.key?("autostart")
|
149
|
+
|
150
|
+
vagrant_config.vm.define ci_vm_id, autostart: ci_autostart do |vm_instance|
|
151
|
+
vm_instance.vm.hostname = ci_vm_id
|
152
|
+
set_provider_config(vm_instance, ci_vm_definition)
|
153
|
+
set_network_config(vm_instance, ci_vm_definition)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
require "log4r"
|
2
2
|
|
3
3
|
module VagrantPlugins
|
4
|
-
module
|
5
|
-
module
|
6
|
-
|
7
|
-
|
8
|
-
class InitEnvironment
|
4
|
+
module GPIICi
|
5
|
+
module Command
|
6
|
+
# This action sets up the GPII CI environment
|
7
|
+
class InitEnvironment < Vagrant.plugin("2", :command)
|
9
8
|
|
10
9
|
def initialize(app, env)
|
11
10
|
@app = app
|
12
|
-
@logger = Log4r::Logger.new("
|
11
|
+
@logger = Log4r::Logger.new("VagrantPlugins::GPIICi::action::init_environment")
|
13
12
|
end
|
14
13
|
|
15
14
|
def call(env)
|
16
|
-
|
17
|
-
|
15
|
+
@logger.info('This call does nothing yet')
|
16
|
+
#TODO: Create a .qi.yml file based on a template
|
18
17
|
@app.call(env)
|
19
18
|
end
|
20
19
|
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module GPIICi
|
3
|
+
module Action
|
4
|
+
class UpdateHosts
|
5
|
+
|
6
|
+
def initialize(app, env)
|
7
|
+
@global_env = global_env
|
8
|
+
@config = Util.get_config(@global_env)
|
9
|
+
@provider = provider
|
10
|
+
@logger = Log4r::Logger.new('vagrant::hostmanager::updater')
|
11
|
+
@logger.debug("init updater")
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_guest(machine)
|
15
|
+
return unless machine.communicate.ready?
|
16
|
+
|
17
|
+
if machine.config.vm.communicator == :winrm
|
18
|
+
windir = ""
|
19
|
+
machine.communicate.execute("echo %SYSTEMROOT%", {:shell => :cmd}) do |type, contents|
|
20
|
+
windir << contents.gsub("\r\n", '') if type == :stdout
|
21
|
+
end
|
22
|
+
realhostfile = "#{windir}\\System32\\drivers\\etc\\hosts.tmp"
|
23
|
+
else
|
24
|
+
realhostfile = '/tmp/hosts'
|
25
|
+
end
|
26
|
+
# download and modify file with Vagrant-managed entries
|
27
|
+
file = @global_env.tmp_path.join("hosts.#{machine.name}")
|
28
|
+
machine.communicate.download(realhostfile, file)
|
29
|
+
|
30
|
+
@logger.debug("file is: #{file.to_s}")
|
31
|
+
@logger.debug("class of file is: #{file.class}")
|
32
|
+
|
33
|
+
if update_file(file, machine, false)
|
34
|
+
if windir
|
35
|
+
machine.communicate.sudo("mv -force /tmp/hosts/hosts.#{machine.name} #{realhostfile}")
|
36
|
+
else
|
37
|
+
machine.communicate.sudo("cat /tmp/hosts >> #{realhostfile}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def update_file(file, resolving_machine = nil, include_id = true)
|
46
|
+
file = Pathname.new(file)
|
47
|
+
old_file_content = file.read
|
48
|
+
new_file_content = update_content(old_file_content, resolving_machine, include_id)
|
49
|
+
file.open('wb') { |io| io.write(new_file_content) }
|
50
|
+
old_file_content != new_file_content
|
51
|
+
end
|
52
|
+
|
53
|
+
def update_content(file_content, resolving_machine, include_id)
|
54
|
+
id = include_id ? " id: #{read_or_create_id}" : ""
|
55
|
+
header = "## vagrant-hostmanager-start#{id}\n"
|
56
|
+
footer = "## vagrant-hostmanager-end\n"
|
57
|
+
body = get_machines
|
58
|
+
.map { |machine| get_hosts_file_entry(machine, resolving_machine) }
|
59
|
+
.join
|
60
|
+
get_new_content(header, footer, body, file_content)
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_hosts_file_entry(machine, resolving_machine)
|
64
|
+
ip = get_ip_address(machine, resolving_machine)
|
65
|
+
host = machine.config.vm.hostname || machine.name
|
66
|
+
aliases = machine.config.hostmanager.aliases
|
67
|
+
if ip != nil
|
68
|
+
"#{ip}\t#{host}\n" + aliases.map{|a| "#{ip}\t#{a}"}.join("\n") + "\n"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_ip_address(machine, resolving_machine)
|
73
|
+
custom_ip_resolver = machine.config.hostmanager.ip_resolver
|
74
|
+
if custom_ip_resolver
|
75
|
+
custom_ip_resolver.call(machine, resolving_machine)
|
76
|
+
else
|
77
|
+
ip = nil
|
78
|
+
if machine.config.hostmanager.ignore_private_ip != true
|
79
|
+
machine.config.vm.networks.each do |network|
|
80
|
+
key, options = network[0], network[1]
|
81
|
+
ip = options[:ip] if key == :private_network
|
82
|
+
break if ip
|
83
|
+
end
|
84
|
+
end
|
85
|
+
ip || (machine.ssh_info ? machine.ssh_info[:host] : nil)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_machines
|
90
|
+
if @config.hostmanager.include_offline?
|
91
|
+
machines = @global_env.machine_names
|
92
|
+
else
|
93
|
+
machines = @global_env.active_machines
|
94
|
+
.select { |name, provider| provider == @provider }
|
95
|
+
.collect { |name, provider| name }
|
96
|
+
end
|
97
|
+
# Collect only machines that exist for the current provider
|
98
|
+
machines.collect do |name|
|
99
|
+
begin
|
100
|
+
machine = @global_env.machine(name, @provider)
|
101
|
+
rescue Vagrant::Errors::MachineNotFound
|
102
|
+
# ignore
|
103
|
+
end
|
104
|
+
machine
|
105
|
+
end
|
106
|
+
.reject(&:nil?)
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_new_content(header, footer, body, old_content)
|
110
|
+
if body.empty?
|
111
|
+
block = "\n"
|
112
|
+
else
|
113
|
+
block = "\n\n" + header + body + footer + "\n"
|
114
|
+
end
|
115
|
+
# Pattern for finding existing block
|
116
|
+
header_pattern = Regexp.quote(header)
|
117
|
+
footer_pattern = Regexp.quote(footer)
|
118
|
+
pattern = Regexp.new("\n*#{header_pattern}.*?#{footer_pattern}\n*", Regexp::MULTILINE)
|
119
|
+
# Replace existing block or append
|
120
|
+
old_content.match(pattern) ? old_content.sub(pattern, block) : old_content.rstrip + block
|
121
|
+
end
|
122
|
+
|
123
|
+
def read_or_create_id
|
124
|
+
file = Pathname.new("#{@global_env.local_data_path}/hostmanager/id")
|
125
|
+
if (file.file?)
|
126
|
+
id = file.read.strip
|
127
|
+
else
|
128
|
+
id = SecureRandom.uuid
|
129
|
+
file.dirname.mkpath
|
130
|
+
file.open('w') { |io| io.write(id) }
|
131
|
+
end
|
132
|
+
id
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
@@ -1,11 +1,8 @@
|
|
1
1
|
require "pathname"
|
2
|
-
require 'json'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
2
|
require "vagrant/action/builder"
|
6
3
|
|
7
4
|
module VagrantPlugins
|
8
|
-
module
|
5
|
+
module GPIICi
|
9
6
|
module Action
|
10
7
|
# Include the built-in modules so we can use them as top-level things.
|
11
8
|
include Vagrant::Action::Builtin
|
@@ -16,107 +13,17 @@ module VagrantPlugins
|
|
16
13
|
end
|
17
14
|
end
|
18
15
|
|
16
|
+
def self.build_vagrantfile
|
17
|
+
Vagrant::Action::Builder.new.tap do |b|
|
18
|
+
b.use BuildVagrantfile
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
19
22
|
# The autoload farm
|
20
23
|
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
21
24
|
autoload :InitEnvironment, action_root.join("init_environment")
|
25
|
+
autoload :BuildVagrantfile, action_root.join("build_vagrantfile")
|
22
26
|
|
23
|
-
class BuildVagrantfile
|
24
|
-
|
25
|
-
def gem_path
|
26
|
-
Pathname.new(File.dirname __dir__)
|
27
|
-
end
|
28
|
-
|
29
|
-
def project_home
|
30
|
-
environment = @env[:env]
|
31
|
-
environment.instance_variable_get(:@cwd)
|
32
|
-
end
|
33
|
-
|
34
|
-
def vagrant_home
|
35
|
-
project_home.join(Vagrant::Environment::DEFAULT_LOCAL_DATA)
|
36
|
-
end
|
37
|
-
|
38
|
-
def initialize(app, env)
|
39
|
-
@app = app
|
40
|
-
@env = env
|
41
|
-
environment = @env[:env]
|
42
|
-
|
43
|
-
# Only make all the magic if the .qi.yml definition file is found
|
44
|
-
return if !File.exist?(project_home.join(".qi.yml"))
|
45
|
-
|
46
|
-
require_relative "config/config_provider.rb"
|
47
|
-
require_relative "config/config_provision.rb"
|
48
|
-
require_relative "config/config_network.rb"
|
49
|
-
require_relative "config/config_folders.rb"
|
50
|
-
|
51
|
-
# $vagrant_vmenv_path = vagrant_home.to_s + "/provision-ci/"
|
52
|
-
|
53
|
-
# load the .qi.yml file
|
54
|
-
qi_file = File.expand_path (project_home.join(".qi.yml"))
|
55
|
-
qi_definition = YAML.load(File.read(qi_file))
|
56
|
-
|
57
|
-
# Copy enviroments and playbooks to home dir if needed
|
58
|
-
FileUtils.mkdir(vagrant_home) if !File.exist?(vagrant_home)
|
59
|
-
FileUtils.mkdir(vagrant_home.join('provision-ci')) if !File.exist?(vagrant_home.join('provision-ci'))
|
60
|
-
FileUtils.cp_r(gem_path.join('envs'), vagrant_home.join('provision-ci/envs')) if !File.exist?(vagrant_home.join('provision-ci/envs'))
|
61
|
-
FileUtils.cp_r(gem_path.join('provisioning'), vagrant_home.join('provision-ci/provisioning')) if !File.exist?(vagrant_home.join('provision-ci/provisioning'))
|
62
|
-
|
63
|
-
# load the environment based on "env_runtime" variable of .qi.yml
|
64
|
-
vagrant_env = qi_definition["env_runtime"] || "default"
|
65
|
-
environment_file = File.expand_path(vagrant_home.to_s + "/provision-ci/envs", File.dirname(__FILE__)) +
|
66
|
-
File::SEPARATOR + vagrant_env
|
67
|
-
if File.exists?(environment_file + ".json")
|
68
|
-
environment_ci = JSON.parse(File.read(environment_file + ".json"))
|
69
|
-
elsif File.exists?(environment_file + ".yml")
|
70
|
-
environment_ci = YAML.load(File.read(environment_file + ".yml"))
|
71
|
-
else
|
72
|
-
raise "Environment_ci config file not found, see envs directory\n #{environment_file}"
|
73
|
-
end
|
74
|
-
|
75
|
-
# build the host list of the VMs used, very useful to allow the communication
|
76
|
-
# between them based on the hostname and IP stored in the hosts file
|
77
|
-
build_hosts_list(environment_ci["vms"])
|
78
|
-
|
79
|
-
vagrantfile_proc = Proc.new do
|
80
|
-
Vagrant.configure(2) do |config|
|
81
|
-
|
82
|
-
environment_ci["vms"].each do |vm_id, vm_config|
|
83
|
-
|
84
|
-
config.vm.define vm_id, autostart: vm_config["autostart"] do |instance|
|
85
|
-
|
86
|
-
# Ansible handles this task better than Vagrant
|
87
|
-
#instance.vm.hostname = vm_id
|
88
|
-
|
89
|
-
config_provider(instance, vm_config, environment_ci["global"])
|
90
|
-
|
91
|
-
config_provision(instance, vm_config, vm_id, qi_definition["apps"], vagrant_home.join('provision-ci').to_s)
|
92
|
-
|
93
|
-
config_network(instance, vm_config)
|
94
|
-
|
95
|
-
config_folders(instance, vm_id, qi_definition["apps"], vagrant_home.join('provision-ci').to_s)
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# The Environment instance has been instantiated without a Vagrantfile
|
103
|
-
# that means that we need to store some internal variables and
|
104
|
-
# instantiate again the Vagrantfile instance with our previous code.
|
105
|
-
|
106
|
-
environment.instance_variable_set(:@root_path, project_home)
|
107
|
-
environment.instance_variable_set(:@local_data_path, vagrant_home)
|
108
|
-
|
109
|
-
# the cienv code will be the first item to check in the list of
|
110
|
-
# Vagrantfile sources
|
111
|
-
config_loader = environment.config_loader
|
112
|
-
config_loader.set(:cienv, vagrantfile_proc.call)
|
113
|
-
environment.instance_variable_set(:@vagrantfile, Vagrant::Vagrantfile.new(config_loader, [:cienv, :home, :root]))
|
114
|
-
|
115
|
-
end
|
116
|
-
def call(env)
|
117
|
-
@app.call(env)
|
118
|
-
end
|
119
|
-
end
|
120
27
|
end
|
121
28
|
end
|
122
29
|
end
|