vagrant-gpii-ci 0.0.1 → 0.0.3
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 +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
|