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