summaryrefslogtreecommitdiffstats
path: root/src/spdk/scripts/vagrant/Vagrantfile
blob: ccf6d632e22fe8bc393eeccd8260447bc23777c8 (plain)
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'open3'
def checkboxtype(distro)
  localboxes, stderr, status = Open3.capture3("vagrant box list")
  if localboxes.include? "spdk/"+distro
    return "spdk/"+distro
  else
      case distro
      when "centos7"
        return "centos/7"
      when "centos8"
        return "centos/8"
      when "ubuntu1604"
        return "peru/ubuntu-16.04-server-amd64"
      when "ubuntu1804"
        return "peru/ubuntu-18.04-server-amd64"
      when "fedora30"
        return "generic/fedora30"
      when "fedora31"
        return "generic/fedora31"
      when "fedora32"
        return "generic/fedora32"
      when "arch"
        return "generic/arch"
      when "freebsd11"
        return "generic/freebsd11"
      when "freebsd12"
        return "generic/freebsd12"
      when "clearlinux"
        return "AntonioMeireles/ClearLinux"
      else
        "Invalid argument #{distro}"
        abort("Invalid argument!")
      end
  end
end

Vagrant.configure(2) do |config|

  # Pick the right distro and bootstrap, default is fedora30
  distro = ( ENV['SPDK_VAGRANT_DISTRO'] || "fedora30")
  provider = (ENV['SPDK_VAGRANT_PROVIDER'] || "virtualbox")

  # Get all variables for creating vm
  vmcpu=(ENV['SPDK_VAGRANT_VMCPU'] || 2)
  vmram=(ENV['SPDK_VAGRANT_VMRAM'] || 4096)
  spdk_dir=(ENV['SPDK_DIR'] || "none")
  vmemulator=(ENV['SPDK_QEMU_EMULATOR'] || "")
  emulated_nvme_types=(ENV['NVME_DISKS_TYPE'] || "nvme").split(',')
  nvme_namespaces=(ENV['NVME_DISKS_NAMESPACES'] || "").split(',')
  nvme_file=(ENV['NVME_FILE'] || "").split(',')
  nvme_cmbs=(ENV['NVME_CMB'] || "").split(',')
  vagrantfile_dir=(ENV['VAGRANTFILE_DIR'] || "none")

  # generic/freebsd boxes do not work properly with vagrant-proxyconf and
  # have issues installing rsync and sshfs for syncing files. NFS is
  # pre-installed, so use it.
  # generic/fedora boxes on the other hand have problems running NFS
  # service so use sshfs+rsync combo instead.
  plugins_sync_backend = {type: :sshfs}
  # Remove --copy-links from default rsync cmdline since we do want to sync
  # actual symlinks as well. Also, since copy is made between host and its
  # local VM we don't need to worry about saturating the local link so skip
  # the compression to speed up the whole transfer.
  files_sync_backend = {type: "rsync", rsync__auto: false, rsync__args: ["--archive", "--verbose", "--delete"]}
  if (distro.include? "freebsd") || (distro.include? "clearlinux")
    plugins_sync_backend = {type: :nfs, nfs_udp: false}
    files_sync_backend = {type: :nfs, nfs_udp: false,  mount_options: ['ro']}
  end
  config.vm.box = checkboxtype(distro)
  config.vm.box_check_update = false
  config.vm.synced_folder '.', '/vagrant', disabled: true

  # Copy in the .gitconfig if it exists
  if File.file?(File.expand_path("~/.gitconfig"))
    config.vm.provision  "file", source: "~/.gitconfig", destination: ".gitconfig"
  end

  # Copy the tsocks configuration file for use when installing some spdk test pool dependencies
  if File.file?("/etc/tsocks.conf")
    $tsocks_copy = <<-SCRIPT
    sudo -s
    mv -f tsocks.conf /etc/tsocks.conf
    chown root /etc/tsocks.conf
    chmod 644 /etc/tsocks.conf
    SCRIPT
    config.vm.provision  "file", source: "/etc/tsocks.conf", destination: "tsocks.conf"
    config.vm.provision "shell", inline: $tsocks_copy
  end

  # vagrant-cachier caches apt/yum etc to speed subsequent
  # vagrant up
  # to enable, run
  # vagrant plugin install vagrant-cachier
  #
  if Vagrant.has_plugin?("vagrant-cachier")
    config.cache.scope = :box
    config.cache.synced_folder_opts = plugins_sync_backend
  end

  # use http proxy if avaiable
  if ENV['http_proxy']
    if Vagrant.has_plugin?("vagrant-proxyconf")
      config.proxy.http     = ENV['http_proxy']
      config.proxy.https    = ENV['https_proxy']
      config.proxy.no_proxy = "localhost,127.0.0.1"
    end

    # Proxyconf does not seem to support FreeBSD boxes or at least it's
    # docs do not mention that. Set up proxy configuration manually.
    if distro.include?("freebsd")
      $freebsd_proxy = <<-SCRIPT
      sudo -s
      echo "export http_proxy=#{ENV['http_proxy']}" >> /etc/profile
      echo "export https_proxy=#{ENV['http_proxy']}" >> /etc/profile
      echo "pkg_env: {http_proxy: #{ENV['http_proxy']}}" > /usr/local/etc/pkg.conf
      chown root:wheel /usr/local/etc/pkg.conf
      chmod 644 /usr/local/etc/pkg.conf
      SCRIPT
      config.vm.provision "shell", inline: $freebsd_proxy
    end
  end

  # freebsd and clearlinux boxes in order to have spdk sources synced from
  # host properly will use NFS with "ro" option enabled to prevent changes
  # on host filesystem.
  # To make sources usable in the guest VM we need to unmount them and use
  # local copy.
  if distro.include? "freebsd"
    $freebsd_spdk_repo = <<-SCRIPT
    sudo -s
    cp -R /home/vagrant/spdk_repo/spdk /tmp/spdk
    umount /home/vagrant/spdk_repo/spdk && rm -rf /home/vagrant/spdk_repo/spdk
    mv /tmp/spdk /home/vagrant/spdk_repo/spdk
    chown -R vagrant:vagrant /home/vagrant/spdk_repo/spdk
    SCRIPT
    config.vm.provision "shell", inline: $freebsd_spdk_repo
  elsif distro.include? "clearlinux"
    $clearlinux_spdk_repo = <<-SCRIPT
    sudo -s
    cp -R /home/vagrant/spdk_repo/spdk /tmp/spdk
    umount /home/vagrant/spdk_repo/spdk && rm -rf /home/vagrant/spdk_repo/spdk
    mv /tmp/spdk /home/vagrant/spdk_repo/spdk
    chown -R clear:clear /home/vagrant/spdk_repo/spdk
    SCRIPT
    config.vm.provision "shell", inline: $clearlinux_spdk_repo
  end

  config.ssh.forward_agent = true
  config.ssh.forward_x11 = true
  if ENV['VAGRANT_PASSWORD_AUTH'] == "1"
    config.ssh.username = "vagrant"
    config.ssh.password = "vagrant"
  end

  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--ioapic", "on"]
    vb.memory = "#{vmram}"
    vb.cpus = "#{vmcpu}"

    nvme_disk=(ENV['NVME_FILE'] || "nvme_disk.img")
    unless File.exist? (nvme_disk)
      vb.customize ["createhd", "--filename", nvme_disk, "--variant", "Fixed", "--size", "1024"]
      vb.customize ["storagectl", :id, "--name", "nvme", "--add", "pcie", "--controller", "NVMe", "--portcount", "1", "--bootable", "off"]
      vb.customize ["storageattach", :id, "--storagectl", "nvme", "--type", "hdd", "--medium", nvme_disk, "--port", "0"]
    end

    #support for the SSE4.x instruction is required in some versions of VB.
    vb.customize ["setextradata", :id, "VBoxInternal/CPUM/SSE4.1", "1"]
    vb.customize ["setextradata", :id, "VBoxInternal/CPUM/SSE4.2", "1"]
  end

  # This setup was Tested on Fedora 27
  # libvirt configuration need modern Qemu(tested on 2.10) & vagrant-libvirt in version 0.0.39+
  # There are few limitation for SElinux - The file added outside libvirt must have proper SE ACL policy or setenforce 0
  config.vm.provider "libvirt" do |libvirt, override|
    libvirt.random_hostname = "1"
    libvirt.disk_bus = "virtio"

    # generic/freebsd boxes need to be explicitly run with SCSI bus,
    # otherwise boot process fails on mounting the disk
    if (distro.include?("freebsd"))
      libvirt.disk_bus = "scsi"
    end

    # Run generic/arch boxes explicitly with IDE bus,
    # otherwise boot process fails on mounting the disk
    if (distro.include?("arch"))
      libvirt.disk_bus = "ide"
    end

    if not vmemulator.empty?
      libvirt.emulator_path = "#{vmemulator}"
      libvirt.machine_type = "pc"
    end

    # we put nvme_disk inside default pool to eliminate libvirt/SELinux Permissions Problems
    # and to be able to run vagrant from user $HOME directory

    # Loop to create all emulated disks set
    emulated_nvme_types.each_with_index { |disk, index|
      if ENV['NVME_FILE']
        nvme_disk_id="#{disk}" + "-#{index}"
        nvme_disk="#{nvme_file["#{index}".to_i]}"
      else
        nvme_disk="/var/lib/libvirt/images/nvme_disk.img"
      end

      unless File.exist? (nvme_disk)
        puts "If run with libvirt provider please execute create_nvme_img.sh"
      end

      if disk == "nvme"
        libvirt.qemuargs :value => "-drive"
        libvirt.qemuargs :value => "format=raw,file=#{nvme_disk},if=none,id=#{nvme_disk_id}"
        libvirt.qemuargs :value => "-device"
        nvme_drive = "nvme,drive=#{nvme_disk_id},serial=1234#{index}"
        if !nvme_namespaces["#{index}".to_i].nil? && nvme_namespaces["#{index}".to_i] != 1
          nvme_drive << ",namespaces=#{nvme_namespaces["#{index}".to_i]}"
        end
        if !nvme_cmbs["#{index}".to_i].nil? && nvme_cmbs["#{index}".to_i] == "true"
          # Fix the size of the buffer to 128M
          nvme_drive << ",cmb_size_mb=128"
        end
        libvirt.qemuargs :value => nvme_drive
      elsif disk == "ocssd"
        libvirt.qemuargs :value => "-drive"
        libvirt.qemuargs :value => "format=raw,file=#{nvme_disk},if=none,id=#{nvme_disk_id}"
        libvirt.qemuargs :value => "-device"
        # create ocssd drive with special parameters
        # lba_index=4 it is LBA namespace format, 4 means that block size is 4K and have 64B metadata
        # lnum_lun, lnum_pln, lpgs_per_blk, lsecs_per_pg, lblks_per_pln this are parameters describing the device geometry
        # we need to multiply these parameters by ourselves to have backend file minimal size:
        # in our case: 4K * 8 * 2 * 1536 * 2 * 45 = 8640 MB
        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"
      end
    }

    libvirt.driver = "kvm"
    libvirt.graphics_type = "vnc"
    libvirt.memory = "#{vmram}"
    libvirt.cpus = "#{vmcpu}"
    libvirt.video_type = "cirrus"

    if ENV['VAGRANT_HUGE_MEM'] == "1"
      libvirt.memorybacking :hugepages
    end

    # Optional field if we want use other storage pools than default
    # libvirt.storage_pool_name = "vm"
  end

  # rsync the spdk directory if provision hasn't happened yet
  # Warning: rsync does not work with freebsd boxes, so this step is disabled
  if ENV['COPY_SPDK_DIR'] == "1" && spdk_dir != "none"
    config.vm.synced_folder "#{spdk_dir}", "/home/vagrant/spdk_repo/spdk", files_sync_backend
  end

  # rsync artifacts from build
  if ENV['COPY_SPDK_ARTIFACTS'] == "1"
    config.vm.synced_folder "#{vagrantfile_dir}/output", "/home/vagrant/spdk_repo/output", plugins_sync_backend
  end

  # provision the vm with all of the necessary spdk dependencies for running the autorun.sh tests
  if ENV['DEPLOY_TEST_VM'] == "1" && spdk_dir != "none"
    config.vm.provision "shell" do |setup|
      setup.path = "#{spdk_dir}/test/common/config/vm_setup.sh"
      setup.privileged = false
      setup.args = ["-u", "-i"]
    end
  end

  # Clear CFLAGS in clear linux
  if distro == "clearlinux"
    $clearcflags = <<-SCRIPT
    echo "export CFLAGS=" >> /etc/profile.d/clearcflags.sh
    echo "export CFFLAGS=" >> /etc/profile.d/clearcflags.sh
    echo "export CXXFLAGS=" >> /etc/profile.d/clearcflags.sh
    echo "export FFLAGS=" >> /etc/profile.d/clearcflags.sh
    echo "export THEANO_FLAGS=" >> /etc/profile.d/clearcflags.sh
    SCRIPT
    config.vm.provision "shell", inline: $clearcflags, run: "always"
  end

  # Copy in the user's tools if they exists
  if File.directory?(File.expand_path("~/vagrant_tools"))
    config.vm.synced_folder "~/vagrant_tools", "/home/vagrant/tools", files_sync_backend
  end
end