Add additional disk for cStor to virtual deploy
[icn.git] / Vagrantfile
1 # -*- mode: ruby -*-
2 # vi: set ft=ruby :
3 require 'ipaddr'
4 require 'uri'
5 require 'yaml'
6
7 # IMPORTANT To bring up the machines, use the "--no-parallel" option
8 # to vagrant up.  This is to workaround dependencies between the jump
9 # machine and the machine pool machines.  Specifically, the pool
10 # machines will fail to come up until the baremetal network (created
11 # by vagrant from the jump machine definition) is up.
12
13 site = ENV['ICN_SITE'] || 'vm'
14 with_jenkins = ENV['WITH_JENKINS'] || false
15
16 # Calculate the baremetal network address from the bmcAddress (aka
17 # IPMI address) specified in the machine pool values.  IPMI in the
18 # virtual environment is emulated by virtualbmc listening on the host.
19 baremetal4_gw = '192.168.151.1'
20 baremetal4_netmask = '255.255.255.0'
21 baremetal6_gw = nil
22 baremetal6_prefix = nil
23 bmc_host = '192.168.121.1' # From the default vagrant-libvirt network
24 registry_mirrors = nil
25 Dir.glob("deploy/site/#{site}/deployment/*.yaml") do |file|
26   YAML.load_stream(File.read(file)) do |document|
27     values = document.fetch('spec', {}).fetch('values', {})
28     unless values['networkData'].nil? or values['networkData']['networks'].nil?
29       networks = values['networkData']['networks']
30       unless networks['ipv4'].nil?
31         networks['ipv4'].select {|name,network| network.fetch('link', name) == 'baremetal'}.each_value do |network|
32           if network.key?('gateway')
33             baremetal4_gw = network['gateway']
34           elsif network.key?('fromIPPool')
35             pool = network['fromIPPool']
36             if values['ipPools']["#{pool}"].key?('gateway')
37               baremetal4_gw = values['ipPools']["#{pool}"]['gateway']
38             end
39           end
40         end
41       end
42       unless networks['ipv6'].nil?
43         networks['ipv6'].select {|name,network| network.fetch('link', name) == 'baremetal'}.each_value do |network|
44           if network.key?('gateway')
45             baremetal6_gw = network['gateway']
46             baremetal6_prefix = 64
47           elsif network.key?('fromIPPool')
48             pool = network['fromIPPool']
49             if values['ipPools']["#{pool}"].key?('gateway')
50               baremetal6_gw = values['ipPools']["#{pool}"]['gateway']
51               baremetal6_prefix = 64
52             end
53           end
54         end
55       end
56     end
57     unless values['bmcAddress'].nil?
58       bmc_host = URI.parse(values['bmcAddress']).host
59     end
60     unless values['dockerRegistryMirrors'].nil?
61       registry_mirrors = values['dockerRegistryMirrors'].join(' ')
62     end
63   end
64 end
65
66 $post_up_message = <<MSG
67 ------------------------------------------------------
68
69 To get started with ICN:
70
71   $ vagrant ssh jump
72   vagrant@jump:~$ sudo su
73   root@jump:/home/vagrant# cd /icn
74   root@jump:/icn# make jump_server
75   root@jump:/icn# make vm_cluster
76
77 ------------------------------------------------------
78 MSG
79
80 #
81 # Networks
82 #
83 # The ICN baremetal network will be the vagrant management network.
84 # It is created automatically by vagrant.  The provisioning network
85 # will be a vagrant private network, and is required to be created by
86 # this script.  The IPMI network is created with virtualbmc.
87
88 #
89 # Machines
90 #
91 Vagrant.configure("2") do |config|
92   # The jump machine
93   config.vm.define 'jump' do |m|
94     # Note the apparent typo in the name below, it is correct as-is
95     m.vm.box = 'intergratedcloudnative/ubuntu2004'
96     m.vm.hostname = 'jump'
97     m.vm.synced_folder '.', '/icn', type: 'nfs'
98     m.vm.provider :libvirt do |libvirt|
99       libvirt.graphics_ip = '0.0.0.0'
100       libvirt.default_prefix = "#{site}-"
101       libvirt.cpu_mode = 'host-passthrough'
102       if with_jenkins
103         # With Jenkins and nested VMs increase cpus, memory
104         libvirt.cpus = 32
105         libvirt.memory = 65536
106       else
107         libvirt.cpus = 8
108         libvirt.memory = 24576
109       end
110       libvirt.nested = true
111     end
112
113     # The ICN baremetal network will be a vagrant private network
114     # created upon bringing up the jump machine
115     m.trigger.before [:up] do |trigger|
116       trigger.name = 'Creating baremetal network'
117       trigger.run = {inline: "./tools/vagrant/create_baremetal_network.sh #{site} #{baremetal4_gw} #{baremetal4_netmask} #{baremetal6_gw} #{baremetal6_prefix}"}
118     end
119     m.trigger.after [:destroy] do |trigger|
120       trigger.name = 'Destroying baremetal network'
121       trigger.run = {inline: "./tools/vagrant/destroy_baremetal_network.sh #{site}"}
122     end
123     m.vm.network :private_network,
124                  :libvirt__network_name => "#{site}-baremetal",
125                  :type => 'dhcp'
126
127     # The ICN provisioning network will be a vagrant private network
128     # created upon bringing up the jump machine
129     m.trigger.before [:up] do |trigger|
130       trigger.name = 'Creating provisioning network'
131       trigger.run = {inline: "./tools/vagrant/create_provisioning_network.sh #{site}"}
132     end
133     m.trigger.after [:destroy] do |trigger|
134       trigger.name = 'Destroying provisioning network'
135       trigger.run = {inline: "./tools/vagrant/destroy_provisioning_network.sh #{site}"}
136     end
137     m.vm.network :private_network,
138                  :libvirt__network_name => "#{site}-provisioning",
139                  :type => 'dhcp'
140
141     # BMC control of machines is provided by sushy-emulator on the host
142     m.trigger.after [:up] do |trigger|
143       trigger.name = 'Starting sushy for BMC network'
144       trigger.run = {inline: "./tools/vagrant/start_sushy.sh #{bmc_host}"}
145     end
146     m.trigger.after [:destroy] do |trigger|
147       trigger.name = 'Stopping sushy for BMC network'
148       trigger.run = {inline: "./tools/vagrant/stop_sushy.sh #{bmc_host}"}
149     end
150
151     m.trigger.after [:up] do |trigger|
152       trigger.name = 'Creating ICN user_config.sh'
153       trigger.run = {inline: "bash -c 'DOCKER_REGISTRY_MIRRORS=\"#{registry_mirrors}\" ./tools/vagrant/create_user_config.sh'"}
154     end
155     m.vm.provision 'Configuring ICN prerequisites', type: 'shell', privileged: true, inline: <<-SHELL
156       ssh-keygen -f "${HOME}/.ssh/id_rsa" -P "" <<<y
157       DEBIAN_FRONTEND=noninteractive apt-get install -y make
158     SHELL
159     m.vm.post_up_message = $post_up_message
160
161     if with_jenkins
162       # Set up a port forward for an instance of Jenkins
163       m.vm.network "forwarded_port", guest: 8080, host: 8080
164     end
165   end
166
167   # Look for any HelmReleases in the site directory with machineName in
168   # the values dictionary.  This will provide the values needed to
169   # create the machine pool.
170   legacy_machine_args = ""
171   Dir.glob("deploy/site/#{site}/deployment/*.yaml") do |file|
172     YAML.load_stream(File.read(file)) do |document|
173       values = document.fetch('spec', {}).fetch('values', {})
174       next if values['machineName'].nil? || values['bootMACAddress'].nil?
175       machine_name = values['machineName']
176       boot_mac_address = values['bootMACAddress']
177       baremetal_mac_address = nil
178       if values['networkData'] and
179           values['networkData']['links'] and
180           values['networkData']['links']['ethernets'] and
181           values['networkData']['links']['ethernets']['baremetal'] and
182           baremetal_mac_address = values['networkData']['links']['ethernets']['baremetal']['macAddress']
183       end
184       bmc_port = URI.parse(values['bmcAddress']).port
185       uuid = URI.parse(values['bmcAddress']).path.split('/').last
186       config.vm.define machine_name do |m|
187         m.vm.hostname = machine_name
188         m.vm.provider :libvirt do |libvirt|
189           libvirt.uuid = "#{uuid}"
190           libvirt.graphics_ip = '0.0.0.0'
191           libvirt.default_prefix = "#{site}-"
192           libvirt.cpu_mode = 'host-passthrough'
193           libvirt.cpus = 8
194           libvirt.memory = 16384
195           libvirt.nested = true
196           # The image will be provisioned by ICN so just create an empty
197           # disk for the machine
198           libvirt.storage :file, :size => 50, :type => 'raw', :cache => 'none'
199           # Create an additional disk for cStor
200           libvirt.storage :file, :size => 10, :type => 'raw', :cache => 'none'
201           # Management attach is false so that vagrant will not interfere
202           # with these machines: the jump server will manage them
203           # completely
204           libvirt.mgmt_attach = false
205         end
206         # The provisioning network must be listed first for PXE boot to
207         # the metal3/ironic provided image
208         m.vm.network :private_network,
209                      :libvirt__network_name => "#{site}-provisioning",
210                      :mac => boot_mac_address,
211                      :type => 'dhcp'
212         if baremetal_mac_address.nil?
213           m.vm.network :private_network,
214                        :libvirt__network_name => "#{site}-baremetal",
215                        :type => 'dhcp'
216         else
217           m.vm.network :private_network,
218                        :libvirt__network_name => "#{site}-baremetal",
219                        :mac => baremetal_mac_address,
220                        :type => 'dhcp'
221         end
222       end
223     end
224   end
225 end