Debugging inventory code

Inventory code deals with finding inventory sources, reading or executing the discovered files, parsing the inventory data into inventory objects, and loading variable data for the inventory. To debug how Ansible will deal with an inventory, a breakpoint must be added inside inventory/__init__.py or one of the other files within the inventory/ subdirectory. This directory will be located on the local filesystem wherever Ansible has been installed. On a Linux system, this is typically stored in the /usr/lib/python2.7/site-packages/ansible/inventory/ path. This path may be inside a Python virtual environment if Ansible has been installed that way. To discover where Ansible is installed, simply type which ansible from the command line. This command will show you where the Ansible executable is installed, and may indicate a Python virtual environment. For this book, Ansible has been installed using the operating system Python distribute, with the Ansible binaries located in /usr/bin/.

To discover the path to the Ansible Python code, simply type python -c "import ansible; print(ansible)". On my system, this shows <module 'ansible' from '/usr/lib/python2.7/site-packages/ansible/__init__.pyc'>, from which we can deduce that the inventory subdirectory is located at /usr/lib/python2.7/site-packages/ansible/inventory.

The inventory directory has been restructured in recent releases of Ansible, and in version 2.7, we need to look in inventory/manager.py. Here, there is a class definition for the Inventory class. This is the inventory object that will be used throughout a playbook run, and it is created when ansible-playbook parses the options provided to it for an inventory source. The __init__ method of the Inventory class does all the inventory discovery, parsing, and variable loading. To troubleshoot an issue in those three areas, a breakpoint should be added within the __init__() method. A good place to start would be after all of the class variables are given an initial value, and just before any data is processed.

In version 2.7.5.0 of Ansible, this would be line 143 of inventory/manager.py, where the parse_sources function is called.

We can skip down to the parse_sources function definition on line 195 to insert our breakpoint. To insert a breakpoint, we must first import the pdb module and then call the set_trace() function, as follows:

To start debugging, save the source file and then execute ansible-playbook as normal. When the breakpoint is reached, the execution will stop and a pdb prompt will be displayed:

From here, we can issue any number of debugger commands, such as the help command, as follows:

The where and list commands can help us determine where we are in the stack, and where we are in the code:

The where command shows us that we're in inventory/manager.py in the parse_sources() method. The next frame up is the same file, the __init__() function. Before that is a different file, the playbook.py file, and the function in that file is run(). This line calls to ansible.inventory.InventoryManager to create the inventory object. Before that is the original file, ansible-playbook, calling cli.run().

The list command shows the source code around our current point of execution, five lines before, and five lines after.

From here, we can guide pdb through the function line by line with the next command. And, if we choose to, we can trace into other function calls with the step command. We can also print variable data to inspect values, as shown in the following screenshot:

We can see that the self._sources variable has a full path of our mastery-hosts inventory file, which is the string we gave ansible-playbook for our inventory data. We can continue to walk through or jump around, or just use the continue command to run until the next breakpoint or the completion of the code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.147.190