---
title: "Ansible KVM Router Lab Part 6"
date: 2021-10-17
draft: false
tags: ["linux", "kvm", "libvirt", "virsh", "ansible", "bash"]
authors: ["trent"]
post: 31
---
date: 2021-10-17

## Introduction
This is Part 6 of a multi-part series of blog posts for building a
[router lab](https://github.com/TrentSPalmer/router-lab){target="_blank"}
automatically using a series of bash scripts and ansible.

[Ansible KVM Router Lab Part 1](/posts/ansible-kvm-router-lab-part-1/){target="_blank"}
is an overview.

In [Ansible KVM Router Lab Part 2](/posts/ansible-kvm-router-lab-part-2/){target="_blank"},
I break down the script 
[build_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/build_vms.bash){target="_blank"}.

In [Ansible KVM Router Lab Part 3](/posts/ansible-kvm-router-lab-part-3/){target="_blank"},
I explain
[define_bridge_networks.bash](https://github.com/TrentSPalmer/router-lab/blob/master/define_bridge_networks.bash){target="_blank"}
and
[shutdown_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/shutdown_vms.bash){target="_blank"}
scripts which are used to construct the lab.

In [Ansible KVM Router Lab Part 4](/posts/ansible-kvm-router-lab-part-4/){target="_blank"},
I explain
[connect_vms_to_bridges.bash](https://github.com/TrentSPalmer/router-lab/blob/master/connect_vms_to_bridges.bash){target="_blank"},
[start_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/start_vms.bash){target="_blank"},
and [rebuild_known_hosts.bash](https://github.com/TrentSPalmer/router-lab/blob/master/rebuild_known_hosts.bash){target="_blank"}
scripts which are used to construct the lab.

In [Ansible KVM Router Lab Part 5](/posts/ansible-kvm-router-lab-part-5/){target="_blank"},
I explain the ansible playbook tasks used to finish building the lab.

In this post I explain how I use
[disconnect_vms_from_bridges.bash](https://github.com/TrentSPalmer/router-lab/blob/master/disconnect_vms_from_bridges.bash){target="_blank"},
[undefine_and_remove_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/undefine_and_remove_vms.bash){target="_blank"},
and
[remove_bridge_networks.bash](https://github.com/TrentSPalmer/router-lab/blob/master/remove_bridge_networks.bash){target="_blank"},
to destroy the lab.

## `shutdown_vms.bash`
I explain `shutdown_vms.bash` in
[Ansible KVM Router Lab Part 3](/posts/ansible-kvm-router-lab-part-3/#shutdown_vmsbash){target="_blank"}.

## `disconnect_vms_from_bridges.bash`

### `check_uid "${USER_UID}"`
[disconnect_vms_from_bridges.bash](https://github.com/TrentSPalmer/router-lab/blob/master/disconnect_vms_from_bridges.bash)
begins by making sure that it is run as a _non-privileged_ user. You can call
the script with `bash disconnect_vms_from_bridges.bash`.

### `function detach_vms()`
`detach_vms` loops over the MACHINES array, passing each name twice to `detach_vm`,
once for the upper bridge network, and again for the lower bridge network.

### `function detach_vm()`
`detach_vm` invokes `virsh dominfo` against the given virtual machine, and parses the output
to decide if the machine is running or not. If the given virtual machine is running,
`detach_vm` calls `detach_running_vm` against the given virtual machine and the given network.
If the given virtual machine is not running, `detach_vm` calls `detach_shut_off_vm` against the
given virtual machine and against the given network.

### `function detach_running_vm()`
`detach_running_vm` invokes `virsh domiflist` against the given virtual machine and greps that
for the given network to decide whether or not the given virtual machine is attached to the
given network. If the given virtual machine is attached to the given network, `detach_running_vm`
once again similarly invokes `virsh domiflist`, but this time parsing the mac of the attached interface.
`detach_running_vm` then invokes `virsh detach-interface` against parsed mac, and then recursively
calls itself for the purpose of verification.

### `function detach_shut_off_vm()`
`detach_shut_off_vm` is almost identical to `detach_running_vm`, but the options for the
invocation of `virsh detach-interface` are adjusted to be appropriate for a virtual machine
which is not running.

## `undefine_and_remove_vms.bash`

### `check_uid "${USER_UID}"`
[undefine_and_remove_vms.bash](https://github.com/TrentSPalmer/router-lab/blob/master/undefine_and_remove_vms.bash)
begins by making sure that it is run as a _non-privileged_ user. You can call
the script with `bash undefine_and_remove_vms.bash`.

### `function destroy_vms()`
`destroy_vms` simultaneously passes the entire MACHINES array to `destroy_vm`, which parses the output of
`virsh list --all` to find out if the virtual machine exists, and if it does invokes the command
`virsh undefine` with the `--remove-all-storage` option, against the virtual machine.

## `remove_bridge_networks.bash`

### `check_uid "${USER_UID}"`
[remove_bridge_networks.bash](https://github.com/TrentSPalmer/router-lab/blob/master/remove_bridge_networks.bash)
begins by making sure that it is run as a _non-privileged_ user. You can call
the script with `bash remove_bridge_networks.bash`.

### `function disable_autostart_bridge_networks()`
`disable_autostart_bridge_networks` passes each of the upper and lower bridge network names to `disable_autostart_bridge_network`,
which parses the output of `virsh net-info` to find out if the network has autostart enabled, and if it is,
invokes `virsh net-autostart` with the `--disable` option to disable autostart for the given network, and then recursively calls itself
for the purpose of verification.

### `function stop_bridge_networks()`
`stop_bridge_networks` passes each of the upper and lower bridge network names to `stop_bridge_network`,
which parses the output of `virsh net-info` in order to find out if the given network is running, and it if is,
invokes `virsh net-destroy` against the given network to stop it, and then recursively calls itself for the purpose of
verification.

### `function undefine_bridge_networks()`
`undefine_bridge_networks` passes each of the upper and lower bridge network names to `undefine_bridge_network`,
which parses the output of `virsh net-list --all` in order to find out if the given network is defined, and if it is,
invokes `virsh net-undefine` against the given network to undefine it, and then recursively calls itself for the purpose of
verification.
