Development environment
The process of developing a ZenPack can be made much faster and easier by starting with a good development environment. A good development environment should do the following.
- Isolate your changes from other users changes or a production systems.
- Allow you to quickly see the result of changes for faster iteration.
- Allow you to easily troubleshoot when changes do not have the desired effect.
The following recommendations are a good starting point for anyone wanting to develop ZenPacks for Collection Zone or Resource Manager deployments.
Installing
You must have Collection Zone or Resource Manager installed to develop ZenPacks. Zenoss recommends using a dedicated Resource Manager instance for development. Start by following the normal installation instructions available at docs.zenoss.com with the following notes.
- System requirements for development can be lower. See below.
- Use a single-host installation.
- Any supported operating system can be used. This guide assumes Linux.
- Verify that Zenoss has been deployed and its web interface is working.
System requirements
A development system will usually have system requirements lower than those of a production system. This is because it likely will not be storing as much data, supporting as many web users, or even performing continual monitoring. Your development system should have at least the following resources.
- 4 CPU cores
- 20 GB memory
- 75 GB storage
Configuring the system
To improve productivity, make the following changes to your development system. Each change will be detailed in subsequent sections.
- Add a
zenoss
user to the host that matches the same user in containers. - Create a
/z
directory on the host to share with containers. - Configure serviced to automatically share
/z
with all containers.
First make sure that you have Zenoss.resmgr
service deployed and running, and that you are able to login to its web
interface. All commands in the following sections should be run as root
or through sudo
unless otherwise noted.
Add a zenoss user
To make development easier we're going to be sharing files between the
host and docker containers running on the host. We can create
a zenoss
user on the host that matches the UID (user ID) and GID
(group ID) of the zenoss user in the containers to avoid having to worry
about permissions problems with those shared files.
groupadd --gid=1206 zenoss
adduser --uid=1337 --gid=1206 zenoss
The zenoss
user should be able to use sudo
and
docker
commands, which you enable by adding the user to
the wheel
and docker
groups, respectively.
usermod -a -G wheel zenoss
usermod -a -G docker zenoss
Also, add the user to the serviced
group as well, in order
to interact with Control Center containers.
usermod -a -G serviced zenoss
Helper aliases and functions
Many commands must be run inside Zope containers. To reduce toil,
add the following lines to the .bashrc
file of the zenoss
user:
## ZenPack development helpers.
alias zope='serviced service attach zope su zenoss -l'
alias zenhub='serviced service attach zenhub su zenoss -l'
z () { serviced service attach zope su zenoss -l -c "cd /z;$*"; }
zenbatchload () { z zenbatchload $*; }
zendisc () { z zendisc $*; }
zendmd () { z zendmd $*; }
zenmib () { z zenmib $*; }
zenmodeler () { z zenmodeler $*; }
zenpack () { z zenpack $*; }
zenpacklib () { z zenpacklib $*; }
zenpython () { z zenpython $*; }
The preceding declarations enable the following shortcuts:
zope
- Start a shell in a Zope container as thezenoss
user.zenhub
- Start a shell in thezenhub
container as thezenoss
user.z
- Run any command as thezenoss
user in a Zope container.zendisc
- Discover new deviceszendmd
- Open thezendmd
consolezenmib
- Import SNMP MIB fileszenmodeler
- Remodel existing deviceszenpack
- Install and remove ZenPackszenpacklib
- Runzenpacklib
commands
Authenticating as zenoss
You will likely want to login to the system as the zenoss
user after
getting the system configured. That way you won’t have to switch (su
) to
the user to make sure files you create have the right permissions.
Either set a password for the user or add your public
key to the user’s authorized_keys
file to support this.
Optionally set the zenoss
user’s password:
passwd zenoss
Optionally add your SSH public key to
the zenoss
user’s authorized_keys
file to login without a password:
mkdir -p /home/zenoss/.ssh
chmod 700 /home/zenoss/.ssh
cat >> /home/zenoss/.ssh/authorized_keys
... paste your public key, enter, ctrl-D ...
chmod 600 /home/zenoss/.ssh/authorized_keys
chown -R zenoss:zenoss /home/zenoss/.ssh
Create a /z directory
Now we can create a directory to share that the zenoss user on the host
and in the container will be able to use. The specific path of this
directory isn’t particularly important, but I like using /z
because
it’s as short as possible.
mkdir -p /z
chown -R zenoss:zenoss /z
Mount /z into all containers
Now we can configure serviced to automatically share (bind mount) the
host’s /z
directory into every container it starts. This will let us use
the same files on the host and in containers using the exact same path.
Edit /etc/default/serviced
. Find the existing SERVICED_OPTS
line. It
will likely be commented out (with a #) and look like the following.
## Arbitrary serviced daemon args
## SERVICED_OPTS=
Uncomment it, and add the bind mount configuration as follows.
/etc/default/serviced
## Arbitrary serviced daemon args
SERVICED_OPTS="--mount *,/z,/z"
You must then restart serviced.
systemctl restart serviced
Test /z sharing
Now you can verify that both the host and containers can read and write files in /z
.
On the host:
su - zenoss # becomes zenoss user on host
touch /z/host
serviced service attach zenhub # attach to a container
su - zenoss # becomes zenoss user in container
rm /z/host
touch /z/container
exit # back to container root user
exit # back to host zenoss user
rm /z/container
exit # back to host root user
Configuring Zenoss services
There are some optional tweaks you can make to Zenoss service definitions to make development faster and easier. We’ll go through the following here.
- Reducing Zope to a single instance so breakpoints can be used.
- Setting unnecessary services to not automatically launch.
Reducing Zope to a single instance
Out of the box, Zope is configured to run a
minimum of two instances. This is problematic when you insert a
breakpoint (pdb.set_trace()
) in code run by Zope because you can’t be
sure the breakpoint will occur in the instance of Zope you happen to be
running in the foreground.
Run the following command to edit the Zope service definition. This will
open vi
with Zope’s JSON service definition.
serviced service edit Zope
Search this file for “Instances” with the quotes. You should see a
section that looks something like the following.
Change Instances
, Min
, and Default
to 1. Then save and quit.
"Instances": 6,
"InstanceLimits": {
"Min": 2,
"Max": 0,
"Default": 6
},
Run the following command to restart Zope and effect the change.
serviced service restart Zope
Setting services to manual launch
The default Zenoss service templates are configured to launch almost all services they contain automatically. When developing ZenPacks it’s usually unnecessary to have all of the collector process such as zenping running. These services are consuming memory, CPU, and may need to be restarted frequently as you’re making code changes. To avoid all of that you can configure some services to not launch automatically when you start the service.
Run the following command to edit zenping’s service definition to make it not automatically launch.
serviced service edit zenping
Search this file for “Launch” with the quotes. You should see a section
that looks like the following. Change auto
to manual
. Then save and quit.
"Launch": "auto",
This won’t stop zenping if it was already running, but it will prevent it from starting up next time you start Zenoss.resmgr.
Here’s the base list of services you should consider setting to the manual launch mode.
- zencommand
- zenjmx
- zenmodeler
- zenperfsnmp
- zenping
- zenprocess
- zenpython
- zenstatus
- zensyslog
- zentrap
Here are some additional services that could be set to manual.
- zenjserver
- zenpropertymonitor
- zenucsevents
- zenvsphere
You may have more or less services on your system depending on what
ZenPacks are installed. The rule of thumb should be that any services
under the Collection
tree can be set to manual except for zenhub
,
zenhubworker
, MetricShipper
, collectorredis
, and zminion
.