Introduction

In this post I will cover how to create an Arista Vagrant box for use with the vagrant-libvirt provider. This post assumes a working installation of Vagrant with the vagrant-libvirt plugin already installed. You can follow this post to get the vagrant-libvirt plugin installed.

Note

I originally covered this topic in November 2017. I have learned alot of lessons since then so this is a revamp of that previous post.

For reference the following software will be used in this post.

  • EOS - vEOS-lab-4.20.1F-combined.vmdk
  • Vagrant - Vagrant 2.0.1
  • vagrant-libvirt - 0.0.43

Download

Arista does not provide a Vagrant Libvirt box like they do for the Virtualbox provider, so we will need to download the vmdk from the Arista software download page. An account is required to download the software but, it's free to register and no support contract is required.

Once you have logged in download the vEOS-lab-4.20.1F-combined.vmdk image from the vEOS-lab section. This image combines the boot image and has the necessary drivers installed to work in virtual environments.

Install

Create and change into directory for veos files. I like to keep my custom vagrant boxes under ~/vagrant/boxes/.


mkdir -p ~/vagrant/boxes/arista/
cd ~/vagrant/boxes/arista/
            

Copy the veos files downloaded earlier to the ~/vagrant/boxes/arista/ directory.


cp ~/Downloads/vEOS-lab-4.20.1F-combined.vmdk .
          

The good folks who maintain the vagrant-libvirt plugin have a script can be used to convert qcow2 images to a vagrant box. Download the libvirt convertsion script.


curl -O https://raw.githubusercontent.com/vagrant-libvirt/vagrant-libvirt/master/tools/create_box.sh
          

Convert the vmdk disk to the qcow2 format for use with KVM.


qemu-img convert -f vmdk -O qcow2 vEOS-lab-4.20.1F-combined.vmdk vEOS-lab-4.20.1F-combined.qcow2
          

Launch the Arista veos VM in order to apply a bootstrap config to it that allows Vagrant to login and manage the box.


virt-install \
    --connect=qemu:///system \
    --name=veos \
    --os-type=linux \
    --arch=x86_64 \
    --cpu host \
    --vcpus=2 \
    --hvm \
    --ram=2048 \
    --disk path=vEOS-lab-4.20.1F-combined.qcow2,bus=ide,format=qcow2 \
    --network=network:vagrant-libvirt,model=virtio \
    --graphics none \
    --import
            

Conenct to the console to apply the bootstrap configuration.


virsh console veos

# output
Connected to domain veos
Escape character is ^]
Switching rootfs

Welcome to Arista Networks EOS 4.20.1F
New seat seat0.
[  OK  ] ConnMgr: Starting TimeAgent: [  OK  ]
Cannot find initial response [FAILED]
Starting ProcMgr: [  OK  ]
Starting EOS initialization stage 1: [   47.644196] NMI watchdog: failed to be enabled on some cpus
[  OK  ]
Starting NorCal initialization: [  OK  ]
Starting EOS initialization stage 2: [  OK  ]
Starting Power On Self Test (POST): [  OK  ]
Completing EOS initialization (press ESC to skip): [  OK  ]
Model and Serial Number: unknown
System RAM: 1893320 kB
Flash Memory size:  3.8G

localhost login: 
          

Login with the username admin (no password) and apply bootstrap configuration.


!
conf t
!
aaa authorization exec default local
!
no aaa root
!
username vagrant privilege 15 shell /bin/bash secret sha512 $6$3kgdKcJLJ3j/0N51$a0YshIzKL3xtdwP6XXXRlY9B8yHFK/tLdg0I95YUIaW7oHqLsgK9TxMg8/0bL6VDkImuWT.g7WRKTxi8nNPtA1
username vagrant sshkey ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
!
interface Management1
   ip address dhcp
!
no ip routing
!
management api http-commands
   no shutdown
!
end
wr mem
!
        

This configuration allows Vagrant to assign an IP address to the management interface via DHCP and to also ssh to the guest using ssh keys.

Check IP address assigned via DHCP.


show ip int brie

# output
Interface              IP Address         Status     Protocol         MTU
Management1            192.168.121.173/24 up         up              1500
          

From your host terminal confirm you can SSH to the Arista VM with the vagrant ssh key. You will be placed in the /bin/bash shell, use the FastCli command to change to the Arista eos CLI.


# host terminal            
ssh vagrant@192.168.121.173 -i ~/.vagrant.d/insecure_private_key

# now in arista VM
[vagrant@localhost ~]$ FastCli

localhost#show version 
Arista vEOS
Hardware version:    
Serial number:       
System MAC address:  5254.004b.5f79

Software image version: 4.20.1F
Architecture:           i386
Internal build version: 4.20.1F-6820520.4201F
Internal build ID:      790a11e8-5aaf-4be7-a11a-e61795d05b91

Uptime:                 6 minutes
Total memory:           1893320 kB
Free memory:            867428 kB

localhost#
          

Once logged in apply the following additional config to activate a couple of event handlers.


!
conf t
!
event-handler ALTER-VAGRANT-SHELL
   trigger on-intf Management0 ip
   action bash sudo sed -i 's:^username vagrant privilege 15 shell /bin/bash :username vagrant privilege 15 :g' /mnt/flash/startup-config
   delay 60
!
event-handler COPY-STARTUP-TO-RUNNING
   trigger on-intf Management0 ip
   action bash FastCli -p 15 -c 'configure replace startup-config'
   delay 70
!
end
wr mem
!
        

The first handler ALTER-VAGRANT-SHELL removes the /bin/bash argument from the vagrant users login shell. Having the default prompt set to /bin/bash allows Vagrant to login and perform guest OS detection when the hosts boots up without spitting back any errors.

The second handler COPY-STARTUP-TO-RUNNING applies the change to the running config. That way when you login to the guest with the vagrant ssh command you are placed into the Arista eos CLI rather than a /bin/bash shell.

If you successfully connected and applied the additional event handler config power off the VM.


bash sudo poweroff

# output
Flushing AAA accounting queue: [  OK  ]
.
. <snip>
.
Storage is finalized.
[  763.709085] System halted.
          

To exit the console press and hold CTRL and SHIFT while pressing 6 then ]

Even though the eos software is shutdown the VM is still powered on, so poweroff the VM.


virsh destroy veos

# output
Domain veos destroyed
          

Create a file called metadata.json with the following contents.


{"provider":"libvirt","format":"qcow2","virtual_size":4}
            

Use the previously downloaded script create_box.sh to create a vagrant box.


bash create_box.sh vEOS-lab-4.20.1F-combined.qcow2

# output
{4}
==> Creating box, tarring and gzipping
./metadata.json
./Vagrantfile
./box.img
Total bytes written: 619786240 (592MiB, 35MiB/s)
==> box.box created
==> You can now add the box:
==>   'vagrant box add vEOS-lab-4.20.1F-combined.box --name box'
            

Create a metadata file called veos.json so that the box is added with the correct version number.


{
  "name": "arista/veos",
  "description": "Arista vEOS",
  "versions": [
    {
      "version": "4.20.1F",
      "providers": [
        {
          "name": "libvirt",
          "url": "file:///home/bradmin/vagrant/boxes/arista/vEOS-lab-4.20.1F-combined.box"
        }
      ]
    }
  ]
}
          

Add the box to Vagrant.


vagrant box add veos.json

# output
==> box: Loading metadata for box 'veos.json'
box: URL: file:///home/bradmin/vagrant/boxes/arista/veos.json
==> box: Adding box 'arista/veos' (v4.20.1F) for provider: libvirt
box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/arista/vEOS-lab-4.20.1F-combined.box
==> box: Successfully added box 'arista/veos' (v4.20.1F) for 'libvirt'!
            

Confirm the box was added successfully


vagrant box list

# output
arista/veos                   (libvirt, 4.20.1F)
CumulusCommunity/cumulus-vx   (libvirt, 3.5.3)
              

We are finished with the install and ready to test our new Arista vagrant-libvirt box.

Testing

Now that we have the box installed lets create a Vagrantfile and confirm we can build VM's with Vagrant.

Create a test directory.

      
mkdir ~/arista-test
cd ~/arista-test
          

Add a Vagrantfile to the test directory with the following contents

      
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.vm.box = "arista/veos"
  config.vm.box_version = "4.20.1F"

  # Turn off shared folders
  config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true

  # Dont change default SSH key
  config.ssh.insert_key = false

  config.vm.provider :libvirt do |domain|
    domain.disk_bus = 'ide'
    domain.cpus = 2
    domain.memory = 2048
  end

end
            

Now vagrant up and confirm you can login.

      
vagrant up

# output
Bringing machine 'sw01' up with 'libvirt' provider...
==> default: Checking if box 'arista/veos' is up to date...
==> default: Creating image (snapshot of base box volume).
==> default: Creating domain with the following settings...
==> default:  -- Name:              arista-test_default
==> default:  -- Domain type:       kvm
==> default:  -- Cpus:              2
==> default:
==> default:  -- Feature:           acpi
==> default:  -- Feature:           apic
==> default:  -- Feature:           pae
==> default:  -- Memory:            2048M
==> default:  -- Management MAC:
==> default:  -- Loader:
==> default:  -- Base box:          arista/veos
==> default:  -- Storage pool:      default
==> default:  -- Image:             /var/lib/libvirt/images/arista-test_sw01.img (5G)
==> default:  -- Volume Cache:      default
==> default:  -- Kernel:
==> default:  -- Initrd:
==> default:  -- Graphics Type:     vnc
==> default:  -- Graphics Port:     -1
==> default:  -- Graphics IP:       127.0.0.1
==> default:  -- Graphics Password: Not defined
==> default:  -- Video Type:        cirrus
==> default:  -- Video VRAM:        9216
==> default:  -- Sound Type:
==> default:  -- Keymap:            en-us
==> default:  -- TPM Path:
==> default:  -- INPUT:             type=mouse, bus=ps2
==> default: Creating shared folders metadata...
==> default: Starting domain.
==> default: Waiting for domain to get an IP address...
==> default: Waiting for SSH to become available...
==> default: Configuring and enabling network interfaces...
    default: SSH address: 192.168.121.144:22
    default: SSH username: vagrant
    default: SSH auth method: private key
            

Note

Once the VM boots up it takes approximately 30 seconds for the event handler config to be applied.

Confirm you can login to the box.

      
# Host terminal
vagrant ssh

# Now in vagrant box terminal
localhost#show version
Arista vEOS
Hardware version:
Serial number:
System MAC address:  28b7.adae.a3cd

Software image version: 4.20.1F
Architecture:           i386
Internal build version: 4.20.1F-6820520.4201F
Internal build ID:      790a11e8-5aaf-4be7-a11a-e61795d05b91

Uptime:                 4 minutes
Total memory:           2017148 kB
Free memory:            1206280 kB

localhost#
            

Awesome, we can build and login to the box with Vagrant. Lastly, let clean up a bit.


# back in host shell    
vagrant destroy -f

# output
==> default: Removing domain...
          

Summary

Although that was a lot more involved than using the off the shelf virtualbox box provided by Arista. For me, the benefits of using the libvirt provider are worth the effort.

Links

https://www.arista.com/en/support/software-download
https://eos.arista.com/veos-running-eos-in-a-vm/
https://gist.github.com/lowescott/ca31c88a52284eb12ac2
http://blog.vuksan.com/2014/01/10/running-arista-veos-under-linux-kvm
https://the-bitmask.com/2017/07/19/arista-veos-l3slv-part2/
https://www.centos.org/docs/5/html/5.2/Virtualization/chap-Virtualization-Managing_guests_with_virsh.html






















Published: 2017-11-18
Updated: 2017-04-24 - Updated with lessons learned to make the process simpler.