In this tutorial we will develop a simple trigger plugin that checks if a given
web page is accessible and returns an
200 OK code.
To do this we will have to develop a pure backend plugin.
A basic plugin is just a directory with a manifest.yaml file. This plugin must be
accessible during development to the Serverboards Core, so look for your
plugins directory and create a
Serverboards auto reloads the plugin directory on every change, so you don’t need to restart Serverboards for it to realize there is a new plugin nor changes on it.
Every plugin at Serverboards requires a manifest.yaml file that defines what this plugin has.
It has some required fields:
id: tutorial.200ok name: Checks HTTP server returns 200 OK description: | This definition is for the full plugin. components: - id: 200daemon type: cmd command: 200ok.py - id: check type: trigger name: 200 OK Trigger description: | Checks every 5 seconds if the given server returns something different to 200 OK. command: 200daemon states: ok nok start: method: start_200ok params: - name: url #stop: # method: stop_200ok
Every plugin have one or several components. In the case of triggers we need an active command that will receive the start call, and the trigger definition itself.
Command components (type
cmd) are quite simple and just indicate some command to run
at the plugin directory. It may have an associates strategy, but here we will use
The Trigger component is a bit more complex.
It requires some common data with other components as user facing
information (name and description) and the command to execute
via a component id, which can be just a component id (
a full qualified component id (
Specific to triggers are the
states indicates in which states can be this trigger. It will trigger whenever
there is a state change.
start indicates the method to call at the command to start the watching. It may
have some params to know what to watch.
stop is an optional method name to call to stop the watcher.
How this methods works is explained better below.
An optional service component
For this plugin we will not need any special component as we will use built in
ones, specifically the ones with the
- name: Web Server type: service traits: url id: web_server icon: world fields: - label: URL name: url type: text validation: empty card: true
Command and test
We will use the Serverboards CLI through this tutorial. It can be used as
communication tool with the core, or with plugins. It eases the use of
the communication protocol (JSON-RPC), and have some goodies as line completion,
variables, and some error rescue support. It is distributed at
Find it and have it ready in a terminal.
We will also use the Python bindings, distributed at
plugins/bindings/python/serverboards.py. Copy it to your plugin directory.
The python bindings are based on decorators to allow any function to be exported
via JSON-RPC. It uses
stdout to communicate so its very important
not to use them for other purposes. If there is need for debug, use
Python bindings have a
serverboards.debug function that can be used.
We will first try a simple example:
#!/usr/bin/python import serverboards @serverboards.rpc_method def hello(name='world'): return "Hello %s!"%name serverboards.loop()
First we import the serverboards module. It provides many functions and an
object that we will use for advanced usage.
Next we define our function,
hello, that just returns a string with “Hello
world!” if no parameter is passed, or “Hello “ and the name if any is passed.
To try it, we will use the serverboards CLI.
200ok.py file has executable permissions.
./serverboards.py --command ../../serverboards/plugins/200ok/200ok.py - > dir [ "hello", "dir" ] > hello "Hello world!" > hello David "Hello David!" > hello name:David "Hello David!" > hello name:David,Moreno "Hello [u'David', u'Moreno']!"
Works as expected.
As you can see we can use positional parameters, and named parameters. In the parameters we can also use more complex structures as lists.
So next lets create the trigger method, modify your
200ok.py file to contain this:
#!/usr/bin/python import serverboards, requests, time @serverboards.rpc_method def start_200ok(id=None, url=None): serverboards.rpc.reply("some-id") last_ok=None while True: # will never exit try: r = requests.get(url) ok = r.ok except: ok = False if ok != last_ok: # state change if ok: # send ok serverboards.rpc.event("trigger", id=id, state="ok") else: # send nok serverboards.rpc.event("trigger", id=id, state="nok") last_ok=ok time.sleep(5) serverboards.loop()
So there it is. In this code we start with an unknown ok code at
then we will loop forever, and every 5 seconds (
time.sleep(5) at the end of
the loop) we will try to get the page.
It can fail with an exception (for example bad URL), or with some code. The
r.ok stores a boolean with the result.
Then we use this boolean to compare with the last ok code
last_ok (which started
with None, so it will always fail on the first run of the loop). If different it
will check if it should send a state of
This trigger does not perform stop at all. But the strategy is
we are sure nobody will call this trigger except for stopping it, and it will
kill it if the stop does not work (as per
This makes trigger development extremely simple, as we can have just one program that speaks very basic JSON-RPC and prints very basic JSON-RPC. It could be done even with bash.
We are now ready to test. Go to your Serverboards and check there is a new
trigger when you create a new rule. It will appear only on services that have
Fill out all the data, for example setting as actions set the tags of a service
UP -DOWN on status
-UP DOWN on status
If you activate the rule your plugin will be started, and if you deactivate it, it will be stopped.
We can evolve our trigger to be a
singleton that shares many watchers. To do
that we need several changes: First we need to change our
properly indicate that the daemon is a singleton now, and then change the code
to properly manage many watchers in one command.
If you are interested on the details, check the core triggers as they are developed using this strategy.