An open API service indexing awesome lists of open source software.

https://github.com/mweisel/cisco-nxos9kv-vagrant-libvirt

A procedure for creating a Cisco Nexus 9000v Vagrant box for the libvirt provider.
https://github.com/mweisel/cisco-nxos9kv-vagrant-libvirt

cisco-nexus cisco-nx-os libvirt-provider vagrant-box

Last synced: about 1 month ago
JSON representation

A procedure for creating a Cisco Nexus 9000v Vagrant box for the libvirt provider.

Awesome Lists containing this project

README

        

Vagrant

# Cisco Nexus 9000v Vagrant box

A procedure for creating a Cisco Nexus 9000v Vagrant box for the [libvirt](https://libvirt.org) provider.

## Prerequisites

* [Git](https://git-scm.com)
* [Python](https://www.python.org) >= 3.8
* [Ansible](https://docs.ansible.com/ansible/latest/index.html) >= 2.11.0
* [libvirt](https://libvirt.org) with client tools
* [QEMU](https://www.qemu.org)
* [Expect](https://en.wikipedia.org/wiki/Expect)
* [Telnet](https://en.wikipedia.org/wiki/Telnet)
* [Vagrant](https://www.vagrantup.com) >= 2.2.10, != 2.2.16
* [vagrant-libvirt](https://github.com/vagrant-libvirt/vagrant-libvirt)

## Steps

0\. Verify the prerequisite tools are installed.


$ which git python ansible libvirtd virsh qemu-system-x86_64 expect telnet vagrant
$ vagrant plugin list
vagrant-libvirt (0.9.0, global)

1\. Install the `ovmf` package.

> Ubuntu 18.04


$ sudo apt install ovmf

> Arch Linux


$ sudo pacman -S edk2-ovmf

2\. Log in and download the _Cisco Nexus 9000/3000 Virtual Switch for KVM_ disk image file from your [Cisco](https://www.cisco.com/c/en/us/support/switches/nexus-9000v-switch/model.html#~tab-downloads) account. Save the file to your `Downloads` directory.

3\. Copy (and rename) the disk image file to the `/var/lib/libvirt/images` directory. Use one of the following examples corresponding to the file version you downloaded:

> 7.0(3)I7(10)


$ sudo cp $HOME/Downloads/nxosv-final.7.0.3.I7.10.qcow2 /var/lib/libvirt/images/cisco-nxosv.qcow2

> 9300v 9.3(7)


$ sudo cp $HOME/Downloads/nexus9300v.9.3.7.qcow2 /var/lib/libvirt/images/cisco-nxosv.qcow2

> 9500v64 10.1(2)


$ sudo cp $HOME/Downloads/nexus9500v64.10.1.2.qcow2 /var/lib/libvirt/images/cisco-nxosv.qcow2

> 9300v64 10.2(3)(F) lite


$ sudo cp $HOME/Downloads/nexus9300v64-lite.10.2.3.F.qcow2 /var/lib/libvirt/images/cisco-nxosv.qcow2

4\. Modify the file ownership and permissions. Note the owner may differ between Linux distributions.

> Ubuntu 18.04


$ sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/cisco-nxosv.qcow2
$ sudo chmod u+x /var/lib/libvirt/images/cisco-nxosv.qcow2

> Arch Linux


$ sudo chown libvirt-qemu:libvirt-qemu /var/lib/libvirt/images/cisco-nxosv.qcow2
$ sudo chmod u+x /var/lib/libvirt/images/cisco-nxosv.qcow2

5\. Create the `boxes` directory.


$ mkdir -p $HOME/boxes

6\. Start the `vagrant-libvirt` network (if not already started).


$ virsh -c qemu:///system net-list
$ virsh -c qemu:///system net-start vagrant-libvirt

7\. Clone this GitHub repo and `cd` into the directory.


$ git clone https://github.com/mweisel/cisco-nxos9kv-vagrant-libvirt
$ cd cisco-nxos9kv-vagrant-libvirt

8\. Get the path to your OVMF (x64) firmware image and runtime variables template.

> Ubuntu 18.04


$ dpkg -L ovmf | grep -E 'OVMF_(CODE|VARS)\.fd'

> Arch Linux


$ pacman -Ql edk2-ovmf | grep -E 'x64/OVMF_(CODE|VARS)\.fd'

9\. Modify the OVMF paths.

> Ubuntu 18.04


$ vim files/cisco-nxosv.xml


<domain type='kvm'>
<name>cisco-nxosv</name>
<memory unit='KiB'>10485760</memory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<loader readonly='yes' secure='no' type='rom'>/usr/share/OVMF/OVMF_CODE.fd</loader>
<nvram template='/usr/share/OVMF/OVMF_VARS.fd'/>
<boot dev='hd'/>
</os>
...


$ vim files/create_box.sh


...

config.vm.provider :libvirt do |domain|
domain.cpus = 2
domain.features = ['acpi']
domain.loader = '/usr/share/OVMF/OVMF_CODE.fd'
domain.memory = 8192
domain.disk_bus = 'sata'
domain.disk_device = 'sda'
domain.disk_driver :cache => 'none'
domain.nic_model_type = 'e1000'
domain.graphics_type = 'none'
end
...


> Arch Linux


$ vim files/cisco-nxosv.xml


<domain type='kvm'>
<name>cisco-nxosv</name>
<memory unit='KiB'>10485760</memory>
<vcpu placement='static'>2</vcpu>
<os>
<type arch='x86_64'>hvm</type>
<loader readonly='yes' secure='no' type='rom'>/usr/share/edk2-ovmf/x64/OVMF_CODE.fd</loader>
<nvram template='/usr/share/edk2-ovmf/x64/OVMF_VARS.fd'/>
<boot dev='hd'/>
</os>
...


$ vim files/create_box.sh


...

config.vm.provider :libvirt do |domain|
domain.cpus = 2
domain.features = ['acpi']
domain.loader = '/usr/share/edk2-ovmf/x64/OVMF_CODE.fd'
domain.memory = 8192
domain.disk_bus = 'sata'
domain.disk_device = 'sda'
domain.disk_driver :cache => 'none'
domain.nic_model_type = 'e1000'
domain.graphics_type = 'none'
end
...

10\. Modify/Verify the variable values in the `boot_image.exp` script file. Use the following table and examples for guidance:

| Disk image | nxos | is_64bit | is_lite |
| :--- | :--- | :--- | :--- |
| nxosv-final.7.0.3.I7.10.qcow2 | 7.0.3.I7.10 | 0 | 0 |
| nexus9300v.9.3.7.qcow2 | 9.3.7 | 0 | 0 |
| nexus9500v64.10.1.2.qcow2 | 10.1.2 | 1 | 0 |
| nexus9300v64-lite.10.2.3.F.qcow2 | 10.2.3.F | 1 | 1 |



$ vim files/boot_image.exp

> 7.0(3)I7(10)


set timeout 360
set prompt "(>|#) $"
set nxos "7.0.3.I7.10"
set is_64bit 0
set is_lite 0
log_file -noappend "~/nxosv-console.explog"

...

> 9300v 9.3(7)


set timeout 360
set prompt "(>|#) $"
set nxos "9.3.7"
set is_64bit 0
set is_lite 0
log_file -noappend "~/nxosv-console.explog"

...

> 9500v64 10.1(2)


set timeout 360
set prompt "(>|#) $"
set nxos "10.1.2"
set is_64bit 1
set is_lite 0
log_file -noappend "~/nxosv-console.explog"

...

> 9300v64 10.2(3)(F) lite


set timeout 360
set prompt "(>|#) $"
set nxos "10.2.3.F"
set is_64bit 1
set is_lite 1
log_file -noappend "~/nxosv-console.explog"

...

11\. Run the Ansible playbook.


$ ansible-playbook main.yml

12\. Copy (and rename) the Vagrant box artifact to the `boxes` directory.

> 7.0(3)I7(10)


$ cp cisco-nxosv.box $HOME/boxes/cisco-nexus9000v-7.0.3.I7.10.box

> 9300v 9.3(7)


$ cp cisco-nxosv.box $HOME/boxes/cisco-nexus9300v-9.3.7.box

> 9500v64 10.1(2)


$ cp cisco-nxosv.box $HOME/boxes/cisco-nexus9500v-10.1.2.box

> 9300v64 10.2(3)(F) lite


$ cp cisco-nxosv.box $HOME/boxes/cisco-nexus9300v-10.2.3.F-lite.box

13\. Copy the box metadata file to the `boxes` directory.

> 7.0(3)I7(10)


$ cp ./files/cisco-nexus9000v.json $HOME/boxes/

> 9300v 9.3(7)


$ cp ./files/cisco-nexus9300v.json $HOME/boxes/

> 9500v64 10.1(2)


$ cp ./files/cisco-nexus9500v.json $HOME/boxes/

> 9300v64 10.2(3)(F) lite


$ cp ./files/cisco-nexus9300v-lite.json $HOME/boxes/

14\. Change the current working directory to `boxes`.


$ cd $HOME/boxes

15\. Substitute the `HOME` placeholder string in the box metadata file.

> 7.0(3)I7(10)


$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9000v.json
"url": "file://HOME/boxes/cisco-nexus9000v-VER.box"

$ sed -i "s|HOME|${HOME}|" cisco-nexus9000v.json

$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9000v.json
"url": "file:///home/marc/boxes/cisco-nexus9000v-VER.box"

> 9300v 9.3(7)


$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9300v.json
"url": "file://HOME/boxes/cisco-nexus9300v-VER.box"

$ sed -i "s|HOME|${HOME}|" cisco-nexus9300v.json

$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9300v.json
"url": "file:///home/marc/boxes/cisco-nexus9300v-VER.box"

> 9500v64 10.1(2)


$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9500v.json
"url": "file://HOME/boxes/cisco-nexus9500v-VER.box"

$ sed -i "s|HOME|${HOME}|" cisco-nexus9500v.json

$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9500v.json
"url": "file:///home/marc/boxes/cisco-nexus9500v-VER.box"

> 9300v64 10.2(3)(F) lite


$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9300v-lite.json
"url": "file://HOME/boxes/cisco-nexus9300v-VER-lite.box"

$ sed -i "s|HOME|${HOME}|" cisco-nexus9300v-lite.json

$ awk '/url/{gsub(/^ */,"");print}' cisco-nexus9300v-lite.json
"url": "file:///home/marc/boxes/cisco-nexus9300v-VER-lite.box"

16\. Also, substitute the `VER` placeholder string with the Cisco NX-OS version.

> 7.0(3)I7(10)


$ awk '/VER/{gsub(/^ */,"");print}' cisco-nexus9000v.json
"version": "VER",
"url": "file:///home/marc/boxes/cisco-nexus9000v-VER.box"

$ sed -i 's/VER/7.0.3.I7.10/g' cisco-nexus9000v.json

$ awk '/\<version\>|url/{gsub(/^ */,"");print}' cisco-nexus9000v.json
"version": "7.0.3.I7.10",
"url": "file:///home/marc/boxes/cisco-nexus9000v-7.0.3.I7.10.box"

> 9300v 9.3(7)


$ awk '/VER/{gsub(/^ */,"");print}' cisco-nexus9300v.json
"version": "VER",
"url": "file:///home/marc/boxes/cisco-nexus9300v-VER.box"

$ sed -i 's/VER/9.3.7/g' cisco-nexus9300v.json

$ awk '/\<version\>|url/{gsub(/^ */,"");print}' cisco-nexus9300v.json
"version": "9.3.7",
"url": "file:///home/marc/boxes/cisco-nexus9300v-9.3.7.box"

> 9500v64 10.1(2)


$ awk '/VER/{gsub(/^ */,"");print}' cisco-nexus9500v.json
"version": "VER",
"url": "file:///home/marc/boxes/cisco-nexus9500v-VER.box"

$ sed -i 's/VER/10.1.2/g' cisco-nexus9500v.json

$ awk '/\<version\>|url/{gsub(/^ */,"");print}' cisco-nexus9500v.json
"version": "10.1.2",
"url": "file:///home/marc/boxes/cisco-nexus9500v-10.1.2.box"

> 9300v64 10.2(3)(F) lite


$ awk '/VER/{gsub(/^ */,"");print}' cisco-nexus9300v-lite.json
"version": "VER",
"url": "file:///home/marc/boxes/cisco-nexus9300v-VER-lite.box"

$ sed -i 's/VER/10.2.3.F/g' cisco-nexus9300v-lite.json

$ awk '/\<version\>|url/{gsub(/^ */,"");print}' cisco-nexus9300v-lite.json
"version": "10.2.3.F",
"url": "file:///home/marc/boxes/cisco-nexus9300v-10.2.3.F-lite.box"

17\. Add the Vagrant box to the local inventory.

> 7.0(3)I7(10)


$ vagrant box add --box-version 7.0.3.I7.10 cisco-nexus9000v.json

> 9300v 9.3(7)


$ vagrant box add --box-version 9.3.7 cisco-nexus9300v.json

> 9500v64 10.1(2)


$ vagrant box add --box-version 10.1.2 cisco-nexus9500v.json

> 9300v64 10.2(3)(F) lite


$ vagrant box add --box-version 10.2.3.F cisco-nexus9300v-lite.json

## Debug

View the telnet session output for the `expect` task:


$ tail -f ~/nxosv-console.explog

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details