forked from Submitty/Submitty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Vagrantfile
239 lines (198 loc) · 8.69 KB
/
Vagrantfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Usage:
# vagrant up
# or
# NO_SUBMISSIONS=1 vagrant up
# or
# EXTRA=rpi vagrant up
#
#
# If you want to override the default image used for the virtual machines, you can set the
# environment variable VAGRANT_BOX. See https://vagrantup.com/boxes/search for a list of
# distributed boxes. For example:
#
# VAGRANT_BOX=ubuntu/focal64 vagrant up
#
#
# If you want to install extra packages (such as rpi or matlab), you need to have the environment
# variable EXTRA set. The easiest way to do this is doing:
#
# EXTRA=rpi vagrant up
# or
# EXTRA=rpi,matlab vagrant up
#
# If you don't want any submissions to be automatically generated for the courses created
# by vagrant, you'll want to specify NO_SUBMISSIONS flag.
# Don't buffer output.
$stdout.sync = true
$stderr.sync = true
require 'json'
def gen_script(machine_name, worker: false)
no_submissions = !ENV.fetch('NO_SUBMISSIONS', '').empty?
extra = ENV.fetch('EXTRA', '')
setup_cmd = 'bash ${GIT_PATH}/.setup/'
if worker
setup_cmd += 'install_worker.sh'
else
setup_cmd += 'vagrant/setup_vagrant.sh'
if no_submissions
setup_cmd += ' --no_submissions'
end
end
unless extra.empty?
setup_cmd += " #{extra}"
end
setup_cmd += " 2>&1 | tee ${GIT_PATH}/.vagrant/logs/#{machine_name}.log"
script = <<SCRIPT
GIT_PATH=/usr/local/submitty/GIT_CHECKOUT/Submitty
DISTRO=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
VERSION=$(lsb_release -sr | tr '[:upper:]' '[:lower:]')
mkdir -p ${GIT_PATH}/.vagrant/logs
#{setup_cmd}
SCRIPT
return script
end
base_boxes = Hash[]
# Should all be base Ubuntu boxes that use the same version
base_boxes.default = "bento/ubuntu-22.04"
base_boxes[:arm_bento] = "bento/ubuntu-22.04-arm64"
base_boxes[:libvirt] = "generic/ubuntu2204"
base_boxes[:arm_mac_qemu] = "perk/ubuntu-2204-arm64"
def mount_folders(config, mount_options)
# ideally we would use submitty_daemon or something as the owner/group, but since that user doesn't exist
# till post-provision (and this is mounted before provisioning), we want the group to be 'vagrant'
# which is guaranteed to exist and that during install_system.sh we add submitty_daemon/submitty_php/etc to the
# vagrant group so that they can write to this shared folder, primarily just for the log files
owner = 'root'
group = 'vagrant'
config.vm.synced_folder '.', '/usr/local/submitty/GIT_CHECKOUT/Submitty', create: true, owner: owner, group: group, mount_options: mount_options, smb_host: '10.0.2.2', smb_username: `whoami`.chomp
optional_repos = %w(AnalysisTools AnalysisToolsTS Lichen RainbowGrades Tutorial CrashCourseCPPSyntax LichenTestData)
optional_repos.each {|repo|
repo_path = File.expand_path("../" + repo)
if File.directory?(repo_path)
config.vm.synced_folder repo_path, "/usr/local/submitty/GIT_CHECKOUT/" + repo, owner: owner, group: group, mount_options: mount_options, smb_host: '10.0.2.2', smb_username: `whoami`.chomp
end
}
end
def get_workers()
worker_file = File.join(__dir__, '.vagrant', 'workers.json')
if File.file?(worker_file)
return JSON.parse(File.read(worker_file), symbolize_names: true)
else
return Hash[]
end
end
Vagrant.configure(2) do |config|
if Vagrant.has_plugin?('vagrant-env')
config.env.enable
end
config.vm.box = ENV.fetch('VAGRANT_BOX', base_boxes.default)
arch = `uname -m`.chomp
arm = arch == 'arm64' || arch == 'aarch64'
apple_silicon = Vagrant::Util::Platform.darwin? && (arm || (`sysctl -n machdep.cpu.brand_string`.chomp.start_with? 'Apple M'))
custom_box = ENV.has_key?('VAGRANT_BOX')
mount_options = []
# The time in seconds that Vagrant will wait for the machine to boot and be accessible.
config.vm.boot_timeout = 600
# Specify the various machines that we might develop on. After defining a name, we
# can specify if the vm is our "primary" one (if we don't specify a VM, it'll use
# that one) as well as making sure all non-primary ones have "autostart: false" set
# so that when we do "vagrant up", it doesn't spin up those machines.
get_workers.map do |worker_name, data|
config.vm.define worker_name do |ubuntu|
ubuntu.vm.network 'private_network', ip: data[:ip_addr]
ubuntu.vm.network 'forwarded_port', guest: 22, host: data[:ssh_port], id: 'ssh'
ubuntu.vm.provision 'shell', inline: gen_script(worker_name, worker: true)
end
end
vm_name = 'ubuntu-22.04'
config.vm.define vm_name, primary: true do |ubuntu|
ubuntu.vm.network 'forwarded_port', guest: 1511, host: ENV.fetch('VM_PORT_SITE', 1511)
ubuntu.vm.network 'forwarded_port', guest: 8443, host: ENV.fetch('VM_PORT_WS', 8443)
ubuntu.vm.network 'forwarded_port', guest: 5432, host: ENV.fetch('VM_PORT_DB', 16442)
ubuntu.vm.network 'forwarded_port', guest: 7000, host: ENV.fetch('VM_PORT_SAML', 7000)
ubuntu.vm.network 'forwarded_port', guest: 22, host: ENV.fetch('VM_PORT_SSH', 2222), id: 'ssh'
ubuntu.vm.provision 'shell', inline: gen_script(vm_name)
end
config.vm.provider 'virtualbox' do |vb, override|
vb.memory = 2048
vb.cpus = 2
# When you put your computer (while running the VM) to sleep, then resume work some time later the VM will be out
# of sync timewise with the host for however long the host was asleep. Of course, the VM by default will
# detect this and if the drift is great enough, it'll resync things such that the time matches, otherwise
# the VM will just slowly adjust the timing so they'll eventually match. However, this can cause confusion when
# times are important for late day calculations and building so we set the maximum time the VM and host can drift
# to be 10 seconds at most which should make things work generally ideally
vb.customize ['guestproperty', 'set', :id, '/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold', 10000 ]
# VirtualBox sometimes has isseus with getting the DNS to work inside of itself for whatever reason.
# While it will sometimes randomly work, we can just set VirtualBox to use a DNS proxy from the host,
# which seems to be far more reliable in having the DNS work, rather than leaving it to VirtualBox.
# See https://serverfault.com/a/453260 for more info.
# vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
# Sometimes Vagrant will error on trying to SSH into the machine when it starts, due to a bug in how
# Ubuntu 20.04 and later setup the virtual serial port, where the machine takes minutes to start, plus
# occasionally restarting. Modifying the behavior of the uart fields, as well as disabling features like USB and
# audio (which we don't need) seems to greatly reduce boot times and make vagrant work consistently. See
# https://github.com/hashicorp/vagrant/issues/11777 for more info.
vb.customize ["modifyvm", :id, "--uart1", "0x3F8", "4"]
vb.customize ["modifyvm", :id, "--uartmode1", "file", File::NULL]
vb.customize ["modifyvm", :id, "--audio", "none"]
vb.customize ["modifyvm", :id, "--usb", "off"]
vb.customize ["modifyvm", :id, "--uart1", "off"]
vb.customize ["modifyvm", :id, "--uart2", "off"]
vb.customize ["modifyvm", :id, "--uart3", "off"]
vb.customize ["modifyvm", :id, "--uart4", "off"]
mount_folders(override, ["dmode=775", "fmode=664"])
if ARGV.include?('ssh')
override.ssh.timeout = 20
end
end
config.vm.provider "parallels" do |prl, override|
unless custom_box
if (arm || apple_silicon)
override.vm.box = base_boxes[:arm_bento]
end
end
prl.memory = 2048
prl.cpus = 2
mount_folders(override, ["share", "nosuid"])
end
config.vm.provider "vmware_desktop" do |vmware, override|
unless custom_box
if (arm || apple_silicon)
override.vm.box = base_boxes[:arm_bento]
end
end
vmware.vmx["memsize"] = "2048"
vmware.vmx["numvcpus"] = "2"
mount_folders(override, [])
end
config.vm.provider "libvirt" do |libvirt, override|
unless custom_box
override.vm.box = base_boxes[:libvirt]
end
libvirt.memory = 2048
libvirt.cpus = 2
libvirt.forward_ssh_port = true
mount_folders(override, [])
end
config.vm.provider "qemu" do |qe, override|
unless custom_box
if apple_silicon
override.vm.box = base_boxes[:arm_mac_qemu]
end
end
qe.memory = "2G"
qe.smp = 2
qe.ssh_port = ENV.fetch('VM_PORT_SSH', 2222)
mount_folders(override, [])
end
config.vm.provision :shell, :inline => " sudo timedatectl set-timezone America/New_York", run: "once"
if ARGV.include?('ssh')
config.ssh.username = 'root'
config.ssh.password = 'vagrant'
config.ssh.insert_key = 'true'
end
end