We've had a convertor from the new style configuration command definitions in XML to the old style "templates" for a while in VyOS 1.2.0. As I predicted, a number of issues were only discovered and fixed as we have rewritten more old scripts, but by now they should be fully functional. However, until very recently, there was no equivalent of it for the operational mode commands. Now there is.
The new style
In case you've missed our earlier posts, here's a quick review. The configuration backend currently used by VyOS keeps command definitions in a very cumbesome format with a lot of nested directories where a directory represents a nesting level (e.g. "system options reboot-on-panic" is in "templates/system/options/reboot-on-panic"), a file with command properties must be present in every directory, and command definition files are allowed to have embedded shell scripts.
This makes command definitions very hard to read, and even harder to write. We cannot easily change that format until a new configuration backend is complete, but we can abstract it away, and that's what we did.
The new command definitions are in XML, and a RelaxNG schema is provided, so everyone can see its complete grammar and automatically check if their definitions are correctly written. Automated validation is already integrated in the build process.
Rewriting the command definitions goes along with rewriting the code they call. New style code goes to the vyos-1x package.
The new directory structure
Before we discuss the op mode definitions, let's talk about another important change we've made lately. If you've ever looked inside the VyOS filesystem, you noticed that the directory structure we inherited from Vyatta Core doesn't make much sense. Everything is in /opt/vyatta even though its contents are a) anything but optional b) actually managed by APT. Inside, it gets worse: executables almost arbitrarily distributed between bin/, bin/sudo-users, and sbin and so on.
Trying to restructure it all at once is a dangerous idea since the effect of the changes on the old code that often has hardcoded paths is hard to predict, so we decided to move the files to new locations as we rewrite them. The new directory structure is:
usr/libexec/vyos/
conf_mode/ # Configuration mode scripts
op_mode/ # Operational mode scripts
validators/ # Value validation scripts
completion/ # Completion scripts
helpers/ # Miscelanneous helper programs (nothing there yet)
New executables useful for the end users will go to /usr/bin and /usr/sbin, and new data will go to /usr/share/vyos, as per the filesystem hierarchy standard as well.
We've also introduced environment variables for referencing those directories. I suppose we've learnt the lesson of hardcoded paths too well by now, so let's avoid them in the future. Instead we can reference the directories by:
vyos_libexec_dir=/usr/libexec/vyos
vyos_op_scripts_dir=/usr/libexec/vyos/op_mode
vyos_validators_dir=/usr/libexec/vyos/validators
vyos_completion_dir=/usr/libexec/vyos/completion
vyos_conf_scripts_dir=/usr/libexec/vyos/conf_mode
vyos_sbin_dir=/usr/sbin
vyos_bin_dir=/usr/bin
How to write an operational command definition
For the proof of concept, I've migrated the operational mode commands for traffic dumps and bandwidth usage. Let's look at the CLI for traffic dumps. You can find its definitions in op-mode-definitions/traffic-dump.xml
- "list" tags — those are static lists of options, interface speed in ethernet is a perfect example, "<list>10 100 1000 2500 10000</list>"
- "script" tags — those are paths to scripts that produce a list of something, that's what we keep in the ${vyos_completion_dir}
- "path" tags — those are configuration paths, such as "interfaces ethernet". It only makes sense for tag nodes of course, even though technically you can use any non-leaf node there. It's a thin wrapper for /bin/cli-shell-api listNodes $path
And that's pretty much all that is to it. You can fine the RelaxNG schema and its compact syntax equivalent right there in the package.
Join the work
The vyatta-op package has lots of simple commands that are a perfect fit for new contributors, so it makes a good starting point if you want to join VyOS development. Create a task in our Phabricator, write your code, reference the task number in the commits, and make a pull request against vyos-1x. For more complicated commands, it's a good idea to discuss it first.
The "reboot"/"show reboot", "show hardware", and "show system" families are perfect candidates since most of the commands there call just one system command. Let's make the command definitions easily readable and editable!