Add link to BMH states documentation
[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 baremetal_cidr = nil
20 registry_mirrors = nil
21 Dir.glob("deploy/site/#{site}/*.yaml") do |file|
22   YAML.load_stream(File.read(file)) do |document|
23     values = document.fetch('spec', {}).fetch('values', {})
24     unless values['bmcAddress'].nil?
25       bmc_host = URI.parse(values['bmcAddress']).host
26       baremetal_cidr = "#{IPAddr.new(bmc_host).mask(24)}/24"
27     end
28     unless values['dockerRegistryMirrors'].nil?
29       registry_mirrors = values['dockerRegistryMirrors'].join(' ')
30     end
31   end
32 end
33 if baremetal_cidr.nil?
34   puts "Missing bmcAddress value in site definition, can't determine baremetal network address"
35   exit 1
36 end
37
38 $post_up_message = <<MSG
39 ------------------------------------------------------
40
41 To get started with ICN:
42
43   $ vagrant ssh jump
44   vagrant@jump:~$ sudo su
45   root@jump:/home/vagrant# cd /icn
46   root@jump:/icn# make jump_server
47   root@jump:/icn# make vm_cluster
48
49 ------------------------------------------------------
50 MSG
51
52 #
53 # Networks
54 #
55 # The ICN baremetal network will be the vagrant management network.
56 # It is created automatically by vagrant.  The provisioning network
57 # will be a vagrant private network, and is required to be created by
58 # this script.  The IPMI network is created with virtualbmc.
59
60 #
61 # Machines
62 #
63 Vagrant.configure("2") do |config|
64   # The jump machine
65   config.vm.define 'jump' do |m|
66     # Note the apparent typo in the name below, it is correct as-is
67     m.vm.box = 'intergratedcloudnative/ubuntu2004'
68     m.vm.hostname = 'jump'
69     m.vm.synced_folder '.', '/icn', type: 'nfs'
70     m.vm.provider :libvirt do |libvirt|
71       libvirt.graphics_ip = '0.0.0.0'
72       libvirt.default_prefix = "#{site}-"
73       libvirt.cpu_mode = 'host-passthrough'
74       if with_jenkins
75         # With Jenkins and nested VMs increase cpus, memory
76         libvirt.cpus = 32
77         libvirt.memory = 65536
78       else
79         libvirt.cpus = 8
80         libvirt.memory = 24576
81       end
82       libvirt.nested = true
83
84       # The ICN baremetal network is the vagrant management network,
85       # and is created by vagrant for us
86       libvirt.management_network_name = "#{site}-baremetal"
87       libvirt.management_network_address = baremetal_cidr
88       libvirt.management_network_autostart = true
89     end
90
91     # The ICN provisioning network will be a vagrant private network
92     # created upon bringing up the jump machine
93     m.trigger.before [:up] do |trigger|
94       trigger.name = 'Creating provisioning network'
95       trigger.run = {inline: "./tools/vagrant/create_provisioning_network.sh #{site}"}
96     end
97     m.trigger.after [:destroy] do |trigger|
98       trigger.name = 'Destroying provisioning network'
99       trigger.run = {inline: "./tools/vagrant/destroy_provisioning_network.sh #{site}"}
100     end
101     m.vm.network :private_network,
102                  :libvirt__network_name => "#{site}-provisioning",
103                  :type => 'dhcp'
104
105     # IPMI control of machines is provided by vbmc on the host
106     m.trigger.after [:up] do |trigger|
107       trigger.name = 'Starting virtualbmc for IPMI network'
108       trigger.run = {inline: "./tools/vagrant/start_vbmc.sh"}
109     end
110     m.trigger.after [:destroy] do |trigger|
111       trigger.name = 'Stopping virtualbmc for IPMI network'
112       trigger.run = {inline: "./tools/vagrant/stop_vbmc.sh"}
113     end
114
115     m.trigger.after [:up] do |trigger|
116       trigger.name = 'Creating ICN user_config.sh'
117       trigger.run = {inline: "bash -c 'DOCKER_REGISTRY_MIRRORS=\"#{registry_mirrors}\" ./tools/vagrant/create_user_config.sh'"}
118     end
119     m.vm.provision 'Configuring ICN prerequisites', type: 'shell', privileged: true, inline: <<-SHELL
120       ssh-keygen -f "${HOME}/.ssh/id_rsa" -P "" <<<y
121       DEBIAN_FRONTEND=noninteractive apt-get install -y make
122     SHELL
123     m.vm.post_up_message = $post_up_message
124
125     if with_jenkins
126       # Set up a port forward for an instance of Jenkins
127       m.vm.network "forwarded_port", guest: 8080, host: 8080
128     end
129   end
130
131   # Look for any HelmReleases in the site directory with machineName in
132   # the values dictionary.  This will provide the values needed to
133   # create the machine pool.
134   legacy_machine_args = ""
135   Dir.glob("deploy/site/#{site}/*.yaml") do |file|
136     YAML.load_stream(File.read(file)) do |document|
137       values = document.fetch('spec', {}).fetch('values', {})
138       next if values['machineName'].nil? || values['bootMACAddress'].nil?
139       machine_name = values['machineName']
140       boot_mac_address = values['bootMACAddress']
141       bmc_port = URI.parse(values['bmcAddress']).port
142       config.vm.define machine_name do |m|
143         m.vm.hostname = machine_name
144         m.vm.provider :libvirt do |libvirt|
145           libvirt.graphics_ip = '0.0.0.0'
146           libvirt.default_prefix = "#{site}-"
147           libvirt.cpu_mode = 'host-passthrough'
148           libvirt.cpus = 8
149           libvirt.memory = 16384
150           libvirt.nested = true
151           # The image will be provisioned by ICN so just create an empty
152           # disk for the machine
153           libvirt.storage :file, :size => 50, :type => 'raw', :cache => 'none'
154           # Management attach is false so that vagrant will not interfere
155           # with these machines: the jump server will manage them
156           # completely
157           libvirt.mgmt_attach = false
158         end
159         # The provisioning network must be listed first for PXE boot to
160         # the metal3/ironic provided image
161         m.vm.network :private_network,
162                      :libvirt__network_name => "#{site}-provisioning",
163                      :mac => boot_mac_address,
164                      :type => 'dhcp'
165         m.vm.network :private_network,
166                      :libvirt__network_name => "#{site}-baremetal",
167                      :type => 'dhcp'
168
169         # IPMI control
170         m.trigger.after [:up] do |trigger|
171           trigger.name = 'Adding machine to IPMI network'
172           trigger.run = {inline: "./tools/vagrant/add_machine_to_vbmc.sh #{site} #{machine_name} #{bmc_port}"}
173         end
174         m.trigger.after [:destroy] do |trigger|
175           trigger.name = 'Removing machine from IPMI network'
176           trigger.run = {inline: "./tools/vagrant/remove_machine_from_vbmc.sh #{site} #{machine_name} #{bmc_port}"}
177         end
178       end
179     end
180   end
181 end