# Resources for writing plugins

> How to explore the Cloud Management Platform (CMP) models interactively, learn Django's ORM, and step through a plugin as it runs

---

Site [llms.txt](/llms.txt)

---

## Interact with the data model

Cloud Management Platform (CMP) has an interactive shell, allowing you to try a query before putting it in a plugin. Open an SSH session to the CMP appliance, switch to the root user, then start the shell_plus management command. It opens an interactive Python shell with all of the models already imported. From there you can work with them directly:

```python
# Reboot the server with hostname "devtest0032"
server = Server.objects.get(hostname="devtest0032")
server.reboot()

# Re-assign all of David's servers to Lisa
lisa = UserProfile.objects.get(user__username='lisa')
Server.objects.filter(owner__user__username='david').update(owner=lisa)

# Get OS build attributes whose template name matches "ubuntu_16_sqaqe03_green".
# This filter is case insensitive, so it can return several results when
# template names differ only by capitalization.
rh = ResourceHandler.objects.get(id=11)
rh.os_build_attributes.filter(template_name__iexact='ubuntu_16_sqaqe03_green')
```

<div class="alert alert-danger" role="alert">


The internal API can be destructive, both to CMP and to the servers it manages. Do plugin development on a non-production instance that manages only development servers.
</div>


## Learn Django's ORM

CMP's models are exposed through Django's object-relational mapper, so understanding the ORM is the key to querying CMP effectively. See [Use Django ORM](/docs/cmp/use/orchestration/plugins/django-orm/) for a CMP-specific introduction.

- [Making queries](https://docs.djangoproject.com/en/stable/topics/db/queries/) in the Django documentation
- [Django ORM and QuerySets](https://tutorial.djangogirls.org/en/django_orm/) in the Django Girls tutorial

## Learn Python

- [The Python Tutorial](https://docs.python.org/3/tutorial/)
- [The Python Standard Library reference](https://docs.python.org/3/library/index.html)

## Step through a plugin with the debugger

The plugin debugger helps you understand how a plugin works and why it fails. It gives a broader view of program flow than scattering logging statements through your code.

When a job enters debug mode, the job engine changes the job's state to **Paused**, and the job's details page shows the execution state: the value of every variable, and the current line highlighted. From there an administrator can step to the next line, run to the end of the current method, resume normal execution, or cancel the job.

### Enable debug mode

There are two ways:

- **From the interface**: Open the plugin's details page as an administrator and use the toggle in the upper right to turn the debugger on. Debugging starts before the plugin's first line runs.
- **From code**: Import the `settrace` decorator and apply it to the method you want to debug. This is the option to use when you want to start debugging at the beginning of a specific method rather than the whole plugin.

```python
# Put this line at the top of your plug-in, with your other imports
from jobs.tracer import settrace


@settrace
def method_you_want_to_trace():
    ...
```

<div class="alert alert-info" role="alert">


Methods that generate options for parameters cannot be traced, because they do not run in the context of a job.
</div>


## Related

- [Use Django ORM](/docs/cmp/use/orchestration/plugins/django-orm/)
- [Structure of a plugin](/docs/cmp/use/orchestration/plugins/structure/)
- [Development tips for plugins](/docs/cmp/use/orchestration/plugins/development-tips/)
- [Models](/docs/cmp/developer-resources/guide/models/): reference for the CMP models in the developer guide
