1# -*- mode: ruby -*- 2# vi: set ft=ruby : 3 4require 'open3' 5def checkboxtype(distro) 6 localboxes, stderr, status = Open3.capture3("vagrant box list") 7 if localboxes.include? "spdk/"+distro 8 return "spdk/"+distro 9 else 10 case distro 11 when "centos7" 12 return "centos/7" 13 when "centos8" 14 return "centos/8" 15 when "ubuntu1604" 16 return "peru/ubuntu-16.04-server-amd64" 17 when "ubuntu1804" 18 return "peru/ubuntu-18.04-server-amd64" 19 when "fedora30" 20 return "generic/fedora30" 21 when "fedora31" 22 return "generic/fedora31" 23 when "fedora32" 24 return "generic/fedora32" 25 when "arch" 26 return "generic/arch" 27 when "freebsd11" 28 return "generic/freebsd11" 29 when "freebsd12" 30 return "generic/freebsd12" 31 when "clearlinux" 32 return "AntonioMeireles/ClearLinux" 33 else 34 "Invalid argument #{distro}" 35 abort("Invalid argument!") 36 end 37 end 38end 39 40Vagrant.configure(2) do |config| 41 42 # Pick the right distro and bootstrap, default is fedora30 43 distro = ( ENV['SPDK_VAGRANT_DISTRO'] || "fedora30") 44 provider = (ENV['SPDK_VAGRANT_PROVIDER'] || "virtualbox") 45 46 # Get all variables for creating vm 47 vmcpu=(ENV['SPDK_VAGRANT_VMCPU'] || 2) 48 vmram=(ENV['SPDK_VAGRANT_VMRAM'] || 4096) 49 spdk_dir=(ENV['SPDK_DIR'] || "none") 50 vmemulator=(ENV['SPDK_QEMU_EMULATOR'] || "") 51 emulated_nvme_types=(ENV['NVME_DISKS_TYPE'] || "nvme").split(',') 52 nvme_namespaces=(ENV['NVME_DISKS_NAMESPACES'] || "").split(',') 53 nvme_file=(ENV['NVME_FILE'] || "").split(',') 54 nvme_cmbs=(ENV['NVME_CMB'] || "").split(',') 55 vagrantfile_dir=(ENV['VAGRANTFILE_DIR'] || "none") 56 57 # generic/freebsd boxes do not work properly with vagrant-proxyconf and 58 # have issues installing rsync and sshfs for syncing files. NFS is 59 # pre-installed, so use it. 60 # generic/fedora boxes on the other hand have problems running NFS 61 # service so use sshfs+rsync combo instead. 62 plugins_sync_backend = {type: :sshfs} 63 files_sync_backend = {type: "rsync", rsync__auto: false} 64 if (distro.include? "freebsd") || (distro.include? "clearlinux") 65 plugins_sync_backend = {type: :nfs, nfs_udp: false} 66 files_sync_backend = {type: :nfs, nfs_udp: false, mount_options: ['ro']} 67 end 68 config.vm.box = checkboxtype(distro) 69 config.vm.box_check_update = false 70 config.vm.synced_folder '.', '/vagrant', disabled: true 71 72 # Copy in the .gitconfig if it exists 73 if File.file?(File.expand_path("~/.gitconfig")) 74 config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig" 75 end 76 77 # Copy the tsocks configuration file for use when installing some spdk test pool dependencies 78 if File.file?("/etc/tsocks.conf") 79 $tsocks_copy = <<-SCRIPT 80 sudo -s 81 mv -f tsocks.conf /etc/tsocks.conf 82 chown root /etc/tsocks.conf 83 chmod 644 /etc/tsocks.conf 84 SCRIPT 85 config.vm.provision "file", source: "/etc/tsocks.conf", destination: "tsocks.conf" 86 config.vm.provision "shell", inline: $tsocks_copy 87 end 88 89 # vagrant-cachier caches apt/yum etc to speed subsequent 90 # vagrant up 91 # to enable, run 92 # vagrant plugin install vagrant-cachier 93 # 94 if Vagrant.has_plugin?("vagrant-cachier") 95 config.cache.scope = :box 96 config.cache.synced_folder_opts = plugins_sync_backend 97 end 98 99 # use http proxy if avaiable 100 if ENV['http_proxy'] 101 if Vagrant.has_plugin?("vagrant-proxyconf") 102 config.proxy.http = ENV['http_proxy'] 103 config.proxy.https = ENV['https_proxy'] 104 config.proxy.no_proxy = "localhost,127.0.0.1" 105 end 106 107 # Proxyconf does not seem to support FreeBSD boxes or at least it's 108 # docs do not mention that. Set up proxy configuration manually. 109 if distro.include?("freebsd") 110 $freebsd_proxy = <<-SCRIPT 111 sudo -s 112 echo "export http_proxy=#{ENV['http_proxy']}" >> /etc/profile 113 echo "export https_proxy=#{ENV['http_proxy']}" >> /etc/profile 114 echo "pkg_env: {http_proxy: #{ENV['http_proxy']}}" > /usr/local/etc/pkg.conf 115 chown root:wheel /usr/local/etc/pkg.conf 116 chmod 644 /usr/local/etc/pkg.conf 117 SCRIPT 118 config.vm.provision "shell", inline: $freebsd_proxy 119 end 120 end 121 122 # freebsd and clearlinux boxes in order to have spdk sources synced from 123 # host properly will use NFS with "ro" option enabled to prevent changes 124 # on host filesystem. 125 # To make sources usable in the guest VM we need to unmount them and use 126 # local copy. 127 if distro.include? "freebsd" 128 $freebsd_spdk_repo = <<-SCRIPT 129 sudo -s 130 cp -R /home/vagrant/spdk_repo/spdk /tmp/spdk 131 umount /home/vagrant/spdk_repo/spdk && rm -rf /home/vagrant/spdk_repo/spdk 132 mv /tmp/spdk /home/vagrant/spdk_repo/spdk 133 chown -R vagrant:vagrant /home/vagrant/spdk_repo/spdk 134 SCRIPT 135 config.vm.provision "shell", inline: $freebsd_spdk_repo 136 elsif distro.include? "clearlinux" 137 $clearlinux_spdk_repo = <<-SCRIPT 138 sudo -s 139 cp -R /home/vagrant/spdk_repo/spdk /tmp/spdk 140 umount /home/vagrant/spdk_repo/spdk && rm -rf /home/vagrant/spdk_repo/spdk 141 mv /tmp/spdk /home/vagrant/spdk_repo/spdk 142 chown -R clear:clear /home/vagrant/spdk_repo/spdk 143 SCRIPT 144 config.vm.provision "shell", inline: $clearlinux_spdk_repo 145 end 146 147 config.ssh.forward_agent = true 148 config.ssh.forward_x11 = true 149 if ENV['VAGRANT_PASSWORD_AUTH'] == "1" 150 config.ssh.username = "vagrant" 151 config.ssh.password = "vagrant" 152 end 153 154 config.vm.provider "virtualbox" do |vb| 155 vb.customize ["modifyvm", :id, "--ioapic", "on"] 156 vb.memory = "#{vmram}" 157 vb.cpus = "#{vmcpu}" 158 159 nvme_disk=(ENV['NVME_FILE'] || "nvme_disk.img") 160 unless File.exist? (nvme_disk) 161 vb.customize ["createhd", "--filename", nvme_disk, "--variant", "Fixed", "--size", "1024"] 162 vb.customize ["storagectl", :id, "--name", "nvme", "--add", "pcie", "--controller", "NVMe", "--portcount", "1", "--bootable", "off"] 163 vb.customize ["storageattach", :id, "--storagectl", "nvme", "--type", "hdd", "--medium", nvme_disk, "--port", "0"] 164 end 165 166 #support for the SSE4.x instruction is required in some versions of VB. 167 vb.customize ["setextradata", :id, "VBoxInternal/CPUM/SSE4.1", "1"] 168 vb.customize ["setextradata", :id, "VBoxInternal/CPUM/SSE4.2", "1"] 169 end 170 171 # This setup was Tested on Fedora 27 172 # libvirt configuration need modern Qemu(tested on 2.10) & vagrant-libvirt in version 0.0.39+ 173 # There are few limitation for SElinux - The file added outside libvirt must have proper SE ACL policy or setenforce 0 174 config.vm.provider "libvirt" do |libvirt, override| 175 libvirt.random_hostname = "1" 176 libvirt.disk_bus = "virtio" 177 178 # generic/freebsd boxes need to be explicitly run with SCSI bus, 179 # otherwise boot process fails on mounting the disk 180 if (distro.include?("freebsd")) 181 libvirt.disk_bus = "scsi" 182 end 183 184 # Run generic/arch boxes explicitly with IDE bus, 185 # otherwise boot process fails on mounting the disk 186 if (distro.include?("arch")) 187 libvirt.disk_bus = "ide" 188 end 189 190 if not vmemulator.empty? 191 libvirt.emulator_path = "#{vmemulator}" 192 libvirt.machine_type = "pc" 193 end 194 195 # we put nvme_disk inside default pool to eliminate libvirt/SELinux Permissions Problems 196 # and to be able to run vagrant from user $HOME directory 197 198 # Loop to create all emulated disks set 199 emulated_nvme_types.each_with_index { |disk, index| 200 if ENV['NVME_FILE'] 201 nvme_disk_id="#{disk}" + "-#{index}" 202 nvme_disk="#{nvme_file["#{index}".to_i]}" 203 else 204 nvme_disk="/var/lib/libvirt/images/nvme_disk.img" 205 end 206 207 unless File.exist? (nvme_disk) 208 puts "If run with libvirt provider please execute create_nvme_img.sh" 209 end 210 211 if disk == "nvme" 212 libvirt.qemuargs :value => "-drive" 213 libvirt.qemuargs :value => "format=raw,file=#{nvme_disk},if=none,id=#{nvme_disk_id}" 214 libvirt.qemuargs :value => "-device" 215 nvme_drive = "nvme,drive=#{nvme_disk_id},serial=1234#{index}" 216 if !nvme_namespaces["#{index}".to_i].nil? && nvme_namespaces["#{index}".to_i] != 1 217 nvme_drive << ",namespaces=#{nvme_namespaces["#{index}".to_i]}" 218 end 219 if !nvme_cmbs["#{index}".to_i].nil? && nvme_cmbs["#{index}".to_i] == "true" 220 # Fix the size of the buffer to 128M 221 nvme_drive << ",cmb_size_mb=128" 222 end 223 libvirt.qemuargs :value => nvme_drive 224 elsif disk == "ocssd" 225 libvirt.qemuargs :value => "-drive" 226 libvirt.qemuargs :value => "format=raw,file=#{nvme_disk},if=none,id=#{nvme_disk_id}" 227 libvirt.qemuargs :value => "-device" 228 # create ocssd drive with special parameters 229 # lba_index=4 it is LBA namespace format, 4 means that block size is 4K and have 64B metadata 230 # lnum_lun, lnum_pln, lpgs_per_blk, lsecs_per_pg, lblks_per_pln this are parameters describing the device geometry 231 # we need to multiply these parameters by ourselves to have backend file minimal size: 232 # in our case: 4K * 8 * 2 * 1536 * 2 * 45 = 8640 MB 233 libvirt.qemuargs :value => "nvme,drive=#{nvme_disk_id},serial=deadbeef,oacs=0,namespaces=1,lver=2,lba_index=4,mdts=10,lnum_lun=8,lnum_pln=2,lpgs_per_blk=1536,lsecs_per_pg=2,lblks_per_pln=45,metadata=#{nvme_disk}_ocssd_md,nsdatafile=#{nvme_disk}_ocssd_blknvme.ns,laer_thread_sleep=3000,stride=4" 234 end 235 } 236 237 libvirt.driver = "kvm" 238 libvirt.graphics_type = "vnc" 239 libvirt.memory = "#{vmram}" 240 libvirt.cpus = "#{vmcpu}" 241 libvirt.video_type = "cirrus" 242 243 if ENV['VAGRANT_HUGE_MEM'] == "1" 244 libvirt.memorybacking :hugepages 245 end 246 247 # Optional field if we want use other storage pools than default 248 # libvirt.storage_pool_name = "vm" 249 end 250 251 # rsync the spdk directory if provision hasn't happened yet 252 # Warning: rsync does not work with freebsd boxes, so this step is disabled 253 if ENV['COPY_SPDK_DIR'] == "1" && spdk_dir != "none" 254 config.vm.synced_folder "#{spdk_dir}", "/home/vagrant/spdk_repo/spdk", files_sync_backend 255 end 256 257 # rsync artifacts from build 258 if ENV['COPY_SPDK_ARTIFACTS'] == "1" 259 config.vm.synced_folder "#{vagrantfile_dir}/output", "/home/vagrant/spdk_repo/output", plugins_sync_backend 260 end 261 262 # provision the vm with all of the necessary spdk dependencies for running the autorun.sh tests 263 if ENV['DEPLOY_TEST_VM'] == "1" && spdk_dir != "none" 264 config.vm.provision "shell" do |setup| 265 setup.path = "#{spdk_dir}/test/common/config/vm_setup.sh" 266 setup.privileged = false 267 setup.args = ["-u", "-i"] 268 end 269 end 270 271 # Clear CFLAGS in clear linux 272 if distro == "clearlinux" 273 $clearcflags = <<-SCRIPT 274 echo "export CFLAGS=" >> /etc/profile.d/clearcflags.sh 275 echo "export CFFLAGS=" >> /etc/profile.d/clearcflags.sh 276 echo "export CXXFLAGS=" >> /etc/profile.d/clearcflags.sh 277 echo "export FFLAGS=" >> /etc/profile.d/clearcflags.sh 278 echo "export THEANO_FLAGS=" >> /etc/profile.d/clearcflags.sh 279 SCRIPT 280 config.vm.provision "shell", inline: $clearcflags, run: "always" 281 end 282 283 # Copy in the user's tools if they exists 284 if File.directory?(File.expand_path("~/vagrant_tools")) 285 config.vm.synced_folder "~/vagrant_tools", "/home/vagrant/tools", files_sync_backend 286 end 287end 288