Device Readiness Checks
Virtualization providers often report that a lab device has started long before it can be configured. For example, containerlab declares success as soon as the containers are running, even when they contain virtual machines that need minutes to boot, and some devices accept SSH sessions before they detect their data-plane interfaces.
netlab initial (and netlab config –reload) thus starts with a sequence of device readiness checks. This document describes how those checks are selected, executed, and configured, and how you can add readiness checks for a new device.
When Are the Readiness Checks Executed?
The readiness checks are executed:
As the first step of the configuration deployment process in netlab initial (and thus netlab up) unless the (internal)
--skip-readyflag is set.Before reloading saved device configurations with netlab config –reload.
As the only action of the netlab initial –ready command. You can use that command in CLI hooks or when testing the readiness checks of a new device.
The readiness checks are executed only on nodes that will be configured (the nodes specified with the --limit parameter, excluding unprovisioned nodes).
The readiness checks are implemented in the netsim/cli/initial/ready package.
Selecting the Readiness Checks
The readiness checks executed on a node are specified in the netlab_ready group variable, a list of readiness steps. As with other group variables, you can set it for a device (group_vars.netlab_ready), for a device/provider combination (provider.group_vars.netlab_ready), or on an individual node.
These readiness steps are recognized by netlab:
Step |
Description |
Handler |
|---|---|---|
health |
Wait for the virtualization provider to report healthy nodes |
internal (Python) |
ssh |
internal or Ansible playbook |
|
command |
internal (Python) |
|
ansible |
Ansible playbook |
Notes:
netlab performs no readiness checks on devices that do not have the netlab_ready variable. That’s perfectly fine for devices started with Vagrant (Vagrant waits for the SSH server) or for Linux containers that are configured with
docker exec.The order of the steps in the netlab_ready list is irrelevant. The readiness checks are always executed in this order: health, ssh, command, and finally the Ansible playbook (that includes the ansible step).
Every step is executed in parallel on all nodes that need it. The next step starts after all the nodes have completed the previous step.
A failed readiness check aborts the lab configuration process.
Some devices set netlab_ready to
[ ansible ]without having an Ansible readiness task list. That’s a trick to skip the SSH readiness check that would otherwise be inherited from another device or a provider-specific setting.
Example: Cisco Nexus OS uses the command readiness check on all virtualization providers. It also has to wait for the SSH server when running in a vrnetlab container:
group_vars:
netlab_ready: [ command ]
netlab_check_retries: 50
netlab_check_delay: 10
clab:
group_vars:
netlab_ready: [ ssh, command ]
features:
initial:
healthcheck: true
Internal and Ansible Handlers
The defaults.netlab.initial.ready dictionary specifies which readiness steps are executed with internal (Python) code:
netlab:
initial:
ready:
ssh: internal
health: internal
command: internal
The readiness steps that are not handled internally (including the ansible step) are executed with the device-ready.ansible playbook, with Ansible tags set to ready_step for every step that has to be executed.
The device-ready.ansible playbook implements only the ssh and ansible steps. Changing the health or command handler to anything but internal thus disables those checks.
The playbook selects the target hosts with the netlab_ready_step Ansible inventory groups. The ansible output module (netsim/outputs/ansible.py) creates those groups from the netlab_ready values of individual nodes.
Wait Times
All readiness checks use these group variables (that can also be set on individual nodes) to control the wait time:
Variable |
Default |
Meaning |
|---|---|---|
netlab_check_retries |
20 |
Number of retries |
netlab_check_delay |
5 |
Delay between retries/timeout of a single attempt (seconds) |
The internal handlers compute the maximum wait time as netlab_check_retries × netlab_check_delay (100 seconds with the default values) and keep retrying the check until it succeeds or the wait time expires. The Ansible task lists should use the same variables in their retries and delay parameters.
Provider Health Check
The health step calls the health_check method of all virtualization providers used by the nodes in the waitlist. The method receives the list of nodes that need the health check and the lab topology. The default implementation (in netsim/providers/__init__.py) does nothing.
Only the containerlab provider implements the health check:
The provider init hook (
health_ready_setupinnetsim/providers/clab/labops.py) adds the health step to the clab.group_vars.netlab_ready list of every device with the clab.features.initial.healthcheck feature (copying the device group_vars.netlab_ready value into the provider-specific group variables first).The health_check method executes containerlab inspect every second until all specified containers report the healthy state or until the defaults.providers.clab.healthy_timeout (default: 600 seconds) expires.
The health check is disabled when defaults.providers.clab.healthy_timeout is set to zero.
To use the health check on a new containerlab device (usually a vrnetlab container), set the clab.features.initial.healthcheck device feature to True:
clab:
features:
initial:
healthcheck: true
Tip
A healthy vrnetlab container does not imply a working SSH server. You’ll probably have to add the ssh step to the clab.group_vars.netlab_ready list.
SSH Server Check
The ssh step waits until netlab can log into the device using SSH and execute a CLI command. The internal implementation is in netsim/cli/initial/ready/ssh.py:
netlab uses netmiko to connect to the device and execute the command when the netmiko library is installed and the device has the netmiko.device_type feature (see Deploying Device Configurations with Netmiko for details). All netmiko timeouts are set to netlab_check_delay.
Otherwise, netlab executes the
sshcommand (prefixed withsshpasswhen the ansible_ssh_pass variable is set) with a netlab_check_delay timeout.Both methods connect to the node management IPv4 address (or IPv6 address if the node has no IPv4 management address) using the ansible_user username. The SSH check fails if the node has no management IP address.
The check is retried (once per second) until it succeeds or the maximum wait time expires.
The maximum wait time is increased to defaults.providers.provider.ssh_timeout if that value is set and larger than the computed wait time.
These group variables control the SSH server check:
Variable |
Meaning |
|---|---|
ansible_user |
SSH username |
ansible_ssh_pass |
SSH password (requires |
netlab_check_command |
CLI command to execute (default: |
netlab_ssh_args |
Extra arguments for the |
The Ansible implementation of the SSH check (netsim/ansible/tasks/readiness-check/ssh.yml) is used when defaults.netlab.initial.ready.ssh is set to ansible. It executes the same ssh command with a 10-second timeout, retrying it netlab_check_retries times with a netlab_check_delay delay.
Command Check
The command step waits until a CLI command executed on the device returns the expected output (for example, until the device detects its first data-plane interface). The internal implementation is in netsim/cli/initial/ready/command.py; it uses the netlab connect code to execute the command, so it works with SSH and docker exec connections (selected with the netlab_console_connection or ansible_connection group variable).
The command check is configured with the command.ready device feature, a dictionary with these keys:
Key |
Meaning |
|---|---|
execute |
The command to execute on the device |
expect |
A string that must appear in the command output |
when |
Optional Python expression. The command check is skipped when the expression evaluates to False |
The when expression and the execute and expect strings (evaluated as Python f-strings) can use all node attributes and the phy_interfaces variable, the list of node interfaces without the virtual_interface attribute.
Example: Cisco Nexus OS command readiness check (netsim/devices/nxos.yml) waits for the first physical interface to appear in the show interface brief printout:
features:
command:
ready:
when: phy_interfaces
execute: show interface brief
expect: '{phy_interfaces[0].ifname.replace("Ethernet","Eth")}'
The command is executed every netlab_check_delay seconds (at least once per second) until its output contains the expect string or until the maximum wait time expires. If the command execution fails (for example, the SSH session cannot be established), the check is retried, but only for a quarter of the maximum wait time; in that case netlab reports the last error it encountered.
Warning
A device with the command step in its netlab_ready list must have the command.ready feature; netlab reports an internal error otherwise.
Ansible Readiness Task List
The ansible step executes a device-specific Ansible task list. Use it when the device needs a readiness check that cannot be implemented with the generic mechanisms described above, for example:
Waiting for a Linux service (
cumulus_nvue.yml)Waiting for a HTTPS (
fortios-clab.yml) or gNMI (sros.yml) serverExecuting a device-specific command over a NETCONF or REST API connection (
junos.yml,netscaler.yml)
The device-ready.ansible playbook executes the tasks/wait-for-ready.yml task list on all hosts in the netlab_ready_ansible inventory group. That task list finds the device readiness task list using the paths.ready.dirs directory search path and the paths.ready.files filename patterns (more details):
ready:
dirs:
- "topology:readiness-check"
- "readiness-check"
- "~/.netlab/readiness-check"
- "/etc/netlab/readiness-check"
- "package:ansible/tasks/readiness-check"
files:
- "{{netlab_device_type}}-{{node_provider}}.yml"
- "{{netlab_device_type}}.yml"
- "{{ansible_network_os}}-{{node_provider}}.yml"
- "{{ansible_network_os}}.yml"
The system readiness task lists are thus stored in the netsim/ansible/tasks/readiness-check directory, and the task list name is based on the netlab_device_type variable (or ansible_network_os when netlab_device_type is not set), optionally combined with the node provider (example: vyos-clab.yml). The task list is skipped if no matching file is found.
Warning
The Ansible readiness task list is executed only on nodes that have the ansible step in their netlab_ready list.
The readiness task list is executed with gather_facts set to false. The playbook sets the netlab_device_type, netlab_interfaces, and node_provider variables before executing the task list. Use netlab_check_retries and netlab_check_delay variables (with device-specific defaults) to control the wait time, for example:
- name: Check {{ inventory_hostname }} nscli readiness
ansible.builtin.raw: nscli -U '127.0.0.1:{{ ansible_user }}:{{ ansible_ssh_pass }}' 'show ns hostName'
changed_when: False
register: command_out
until: command_out.rc == 0 and "Done" in command_out.stdout
retries: "{{ netlab_check_retries | default(60) }}"
delay: "{{ netlab_check_delay | default(5) }}"
Adding Readiness Checks to a New Device
Use these guidelines to select the readiness checks for a new device:
Devices started by Vagrant usually don’t need the ssh step (Vagrant waits for the SSH server).
vrnetlab containers usually need the health check (set clab.features.initial.healthcheck) and the ssh step (in clab.group_vars.netlab_ready).
Use the command step for devices that accept SSH sessions before they’re ready to be configured (for example, before they detect data-plane interfaces). Prefer it over an Ansible task list; it’s faster and does not depend on Ansible collections.
Use the ansible step only when you cannot implement the readiness check with the internal handlers.
Set netlab_check_retries and netlab_check_delay if the device needs more than 100 seconds to become ready.
Troubleshooting
Use netlab initial –ready to execute just the readiness checks.
Use
--debug sshto display the SSH commands, wait times, and SSH errors (every five seconds).Use
--debug readyto display the command check wait times, the command outputs, and the expected results.Use
-vto display the readiness check progress even when the devices become ready in less than five seconds.