diff --git a/.gitignore b/.gitignore index fb311598..b907f50b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vagrant/ +.virtualbox/ log/ user-data config.rb diff --git a/README.md b/README.md index 6e11408e..f4202741 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ IRC: #coreos on freenode.org Mailing list: [coreos-dev](https://groups.google.com/forum/#!forum/coreos-dev) +## Linux Hosts using VirtualBox +The virtio NIC driver can cause random reboots +due to a kernel paging request in the RX path. +The `linux-virutalbox` branch avoids this issue +by changing the NIC type to an Intel device. + ## Streamlined setup 1) Install dependencies diff --git a/Vagrantfile b/Vagrantfile index 0f815d56..a9318885 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -2,6 +2,7 @@ # # vi: set ft=ruby : require 'fileutils' +require_relative 'util.rb' Vagrant.require_version ">= 1.6.0" @@ -30,9 +31,16 @@ $share_home = false $vm_gui = false $vm_memory = 1024 $vm_cpus = 1 +$num_big_instances = 0 +$vm_big_memory = 8192 +$vm_big_cpus = 2 $vb_cpuexecutioncap = 100 $shared_folders = {} $forwarded_ports = {} +$update_channel = "alpha" +# Additional disks to configure on each node +$num_data_disks = 0 +$data_disk_size = 10 # GBytes # Attempt to apply the deprecated environment variable NUM_INSTANCES to # $num_instances while allowing config.rb to override it @@ -49,11 +57,17 @@ def vm_gui $vb_gui.nil? ? $vm_gui : $vb_gui end -def vm_memory +def vm_memory(instance) + if instance > $num_instances then + return $vm_big_memory + end $vb_memory.nil? ? $vm_memory : $vb_memory end -def vm_cpus +def vm_cpus(instance) + if instance > $num_instances then + return $vm_big_cpus + end $vb_cpus.nil? ? $vm_cpus : $vb_cpus end @@ -63,14 +77,12 @@ Vagrant.configure("2") do |config| # forward ssh agent to easily ssh into the different machines config.ssh.forward_agent = true - config.vm.box = "coreos-alpha" - config.vm.box_url = "https://alpha.release.core-os.net/amd64-usr/current/coreos_production_vagrant_virtualbox.json" + config.vm.box = "coreos-%s" % $update_channel + config.vm.box_url = "https://%s.release.core-os.net/amd64-usr/current/coreos_production_vagrant_virtualbox.json" % $update_channel - ["vmware_fusion", "vmware_workstation"].each do |vmware| - config.vm.provider vmware do |v, override| - override.vm.box_url = "https://alpha.release.core-os.net/amd64-usr/current/coreos_production_vagrant_vmware_fusion.json" - end - end + # Note: Having VirtualBox be the first config.vm.provider means + # it will be the default provider. For details on this see: + # https://www.vagrantup.com/docs/providers/basic_usage.html config.vm.provider :virtualbox do |v| # On VirtualBox, we don't have guest additions or a functional vboxsf @@ -81,12 +93,23 @@ Vagrant.configure("2") do |config| config.ignition.enabled = true end + ["vmware_fusion", "vmware_workstation"].each do |vmware| + config.vm.provider vmware do |v, override| + override.vm.box_url = "https://%s.release.core-os.net/amd64-usr/current/coreos_production_vagrant_vmware_fusion.json" % $update_channel + end + end + + config.vm.provider :parallels do |v, override| + override.vm.box_url = "http://%s.release.core-os.net/amd64-usr/current/coreos_production_vagrant_parallels.json" % $update_channel + end + # plugin conflict if Vagrant.has_plugin?("vagrant-vbguest") then config.vbguest.auto_update = false end - (1..$num_instances).each do |i| + total_instances=$num_instances+$num_big_instances + (1..total_instances).each do |i| config.vm.define vm_name = "%s-%02d" % [$instance_name_prefix, i] do |config| config.vm.hostname = vm_name @@ -120,20 +143,26 @@ Vagrant.configure("2") do |config| config.vm.network "forwarded_port", guest: guest, host: host, auto_correct: true end + config.vm.provider :virtualbox do |vb| + vb.gui = vm_gui + vb.memory = vm_memory i + vb.cpus = vm_cpus i + vb.customize ["modifyvm", :id, "--cpuexecutioncap", "#{$vb_cpuexecutioncap}"] + config.ignition.config_obj = vb + end + ["vmware_fusion", "vmware_workstation"].each do |vmware| config.vm.provider vmware do |v| v.gui = vm_gui - v.vmx['memsize'] = vm_memory - v.vmx['numvcpus'] = vm_cpus + v.vmx['memsize'] = vm_memory i + v.vmx['numvcpus'] = vm_cpus i end end - config.vm.provider :virtualbox do |vb| - vb.gui = vm_gui - vb.memory = vm_memory - vb.cpus = vm_cpus - vb.customize ["modifyvm", :id, "--cpuexecutioncap", "#{$vb_cpuexecutioncap}"] - config.ignition.config_obj = vb + config.vm.provider :parallels do |vb| + vb.memory = vm_memory i + vb.cpus = vm_cpus i + vb.name = vm_name end ip = "172.17.8.#{i+100}" @@ -167,6 +196,10 @@ Vagrant.configure("2") do |config| config.ignition.path = 'config.ign' end end + + if $num_data_disks > 0 + attach_volumes(config, $num_data_disks, $data_disk_size) + end end end end diff --git a/util.rb b/util.rb new file mode 100644 index 00000000..d4c682d4 --- /dev/null +++ b/util.rb @@ -0,0 +1,102 @@ + +def get_provider + # Look for "--provider foo" + provider_index = ARGV.index('--provider') + if (provider_index && ARGV[provider_index + 1]) + return ARGV[provider_index + 1] + end + + # Look for "--provider=foo" + for i in 1 ... ARGV.length + if ARGV[i].include?('--provider=') + return ARGV[i].sub('--provider=', '') + end + end + + # Note: The assumption of the default provider + # being VirtualBox is predecated on the order + # of the config.vm.provider calls in Vagrantfile + return ENV['VAGRANT_DEFAULT_PROVIDER'] || 'virtualbox' +end + +$provider = get_provider().to_sym + +class VagrantPlugins::ProviderVirtualBox::Action::SetName + alias_method :original_call, :call + def call(env) + machine = env[:machine] + driver = machine.provider.driver + uuid = driver.instance_eval { @uuid } + ui = env[:ui] + + controller_name="SATA Controller" + + vm_info = driver.execute("showvminfo", uuid) + controller_already_exists = vm_info.match("Storage Controller Name.*#{controller_name}") + + if controller_already_exists + ui.info "already has the #{controller_name} hdd controller, skipping creation/add" + else + ui.info "creating #{controller_name} hdd controller" + driver.execute( + 'storagectl', + uuid, + '--name', "#{controller_name}", + '--add', 'sata', + '--controller', 'IntelAHCI') + end + + original_call(env) + end +end + +# Add persistent storage volumes +def attach_volumes(node, num_volumes, volume_size) + + if $provider == :virtualbox + node.vm.provider :virtualbox do |v, override| + (1..num_volumes).each do |disk| + diskname = File.join(File.dirname(File.expand_path(__FILE__)), ".virtualbox", "#{node.vm.hostname}-#{disk}.vdi") + unless File.exist?(diskname) + v.customize ['createhd', '--filename', diskname, '--size', volume_size * 1024] + end + v.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', disk, '--device', 0, '--type', 'hdd', '--medium', diskname] + end + end + end + + if $provider == :vmware_fusion || $provider == "vmware_workstation" + ["vmware_fusion", "vmware_workstation"].each do |vmware| + node.vm.provider vmware do |v, override| + + vdiskmanager = '/Applications/VMware\ Fusion.app/Contents/Library/vmware-vdiskmanager' + if File.exist?(vdiskmanager) + dir = File.join(File.dirname(File.expand_path(__FILE__)), ".vmware") + unless File.directory?( dir ) + Dir.mkdir dir + end + + (1..num_volumes).each do |disk| + diskname = File.join(dir, "#{node.vm.hostname}-#{disk}.vmdk") + unless File.exist?(diskname) + `#{vdiskmanager} -c -s #{volume_size}GB -a lsilogic -t 1 #{diskname}` + end + + v.vmx["scsi0:#{disk}.filename"] = diskname + v.vmx["scsi0:#{disk}.present"] = 'TRUE' + v.vmx["scsi0:#{disk}.redo"] = '' + end + end + end + end + end + + if $provider == :parallels + node.vm.provider :parallels do |v, override| + (1..num_volumes).each do |disk| + v.customize ['set', :id, '--device-add', 'hdd', '--size', volume_size * 1024] + end + end + end + +end