9 CLI

_images/cli1.jpg

9.1 Overview

The Clixon CLI provides an interactive command-line interface to a user. Each usage instantiates a new process which communicates via NETCONF with the backend daemon over an IPC socket.

The Clixon CLI uses CLIgen, an interactive interpreter of commands. Syntax is given as cli-specifications which specify callbacks defined in plugins.

For details on CLIgen syntax and behavior, please consult the CLIgen tutorial.

Clixon comes with a generated CLI, the autocli, where all configuration-related syntax is generated from YANG.

You can also create a completely manually-made CLI.

The CLI depends on the following:

  • Clixon-config: The Clixon config-file contains initial CLI configuration, such as where to find cli-specs, plugins and autocli configuration.

  • Cli-specs: CLI specification files written in CLIgen syntax.

  • Plugins: Dynamic loadable plugin files loaded at startup. Callbacks from cli-spec files are resolved and need to exist as symbols either in the Clixon libs or in the plugin file.

The following example from the main example. First, a cli-spec file containing two commands:

set("Set configuration symbol") @datamodel, cli_auto_set();
show("Show a particular state of the system") configuration("Show configuration"), cli_show_config("candidate", "text", "/");
example("Callback example") <var:int32>("any number"), mycallback("myarg");

In the CLI, these generate CLI commands such as:

set interfaces interface eth9
show config
example 23

The effect of typing the commands above is calling callbacks, either library functions in Clixon libs(cli_show_config()), or application-defined in a plugin(mycallback())

In this way, a designer writes cli command specifications which invokes C-callbacks. If there are no appropriate callbacks the designer must write a new callback function.

9.1.1 Example usage

The following example shows an auto-cli session from the main example how to add an interface in candidate, validate and commit it to running, then look at it as xml and cli and finally delete it:

clixon_cli -f /usr/local/etc/example.xml
user@host> set interfaces interface eth9 ?
  description               enabled                   ipv4
  ipv6                      link-up-down-trap-enable  type
user@host> set interfaces interface eth9 type ex:eth
user@host> validate
user@host> commit
user@host> show configuration xml
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
  <interface>
    <name>eth9</name>
    <type>ex:eth</type>
    <enabled>true</enabled>
  </interface>
</interfaces>
user@host> show configuration cli
set interfaces interface eth9
set interfaces interface eth9 type ex:eth
set interfaces interface eth9 enabled true
user@host> delete interfaces interface eth9

9.1.2 Command-line options

The clixon_cli client has the following command-line options:
-h

Help

-V

Show version and exit

-D <level>

Debug level

-f <file>

Clixon config file

-E <dir>

Extra configuration directory

-l <option>

Log on (s)yslog, std(e)rr, std(o)ut, (n)one or (f)ile. Stderr is default.

-C <format>

Dump configuration options on stdout after loading. Format is one of xml|json|text

-F <file>

Read commands from file (default stdin)

-1

Run once, do not enter interactive mode

-a <family>

Internal IPC backend socket family: UNIX|IPv4|IPv6

-u <path|addr>

Internal IPC socket domain path or IP addr (see -a)

-d <dir>

Specify cli plugin directory

-m <mode>

Specify plugin syntax mode

-q

Quiet mode, do not print greetings or prompt, terminate on ctrl-C

-p <dir>

Add Yang directory path (see CLICON_YANG_DIR)

-G

Print auo-cli CLI syntax generated from YANG

-L

Debug print dynamic CLI syntax including completions and expansions

-y <file>

Load yang spec file (override yang main modul)e

-c <file>

Specify cli spec file

-U <user>

Over-ride unix user with a pseudo user for NACM.

-o <option=value>

Give configuration option overriding config file (see clixon-config.yang)

Inline CLI commands

CLI commands can be given directly after the options. These are executed directly:

clixon_cli -f example.xml show config

One can also add extra application-dependent plugin options after which can be read with clicon_argv_get():

clixon_cli -f example.xml show config -- -x extra-option

9.2 Configure options

The following config options are related to clispec and plugin files (clixon config options), ie they are set in the XML Clixon config file:

CLICON_CLI_DIR

Directory containing frontend cli loadable plugins. Load all .so plugins in this directory as CLI object plugins.

CLICON_CLISPEC_DIR

Directory containing frontend cligen spec files. Load all .cli files in this directory as CLI specification files.

CLICON_CLISPEC_FILE

Specific frontend cligen spec file as alternative or complement to CLICON_CLISPEC_DIR. Also available as -c in clixon_cli.

9.2.1 Terminal I/O

Clixon CLI have the following configuration options related to terminal I/O:

CLICON_CLI_LINESCROLLING

Set to 0 if you want CLI to wrap to next line. Set to 1 if you want CLI to scroll sideways when approaching right margin (default).

CLICON_CLI_LINES_DEFAULT Set to number of CLI terminal rows for pagination/scrolling. 0 means unlimited. The number is set statically UNLESS:

  • there is no terminal, such as file input, in which case nr lines is 0

  • there is a terminal sufficiently powerful to read the number of lines from ioctl calls.

In other words, this setting is used ONLY on raw terminals such as serial consoles.

CLICON_CLI_TAB_MODE

Set CLI tab mode. See detailed info in YANG source

9.2.2 History

Clixon CLI supports persistent command history. There are two CLI history related configuration options:

CLICON_CLI_HIST_FILE

The file containing the history, default value is: ~/.clixon_cli_history

CLICON_CLI_HIST_SIZE

Max number of history line, default value is 300.

The design is similar to bash history but is simpler in some respects:
  • The CLI loads/saves its complete history to a file on entry and exit, respectively

  • The size (number of lines) of the file is the same as the history in memory

  • Only the latest session dumping its history will survive (bash merges multiple session history).

Further, tilde-expansion is supported and if history files are not found or lack appropriate access will not cause an exit but are logged at debug level

9.2.3 Help strings

Help strings are specified using the following example syntax: ("help string"). help strings are shown at queries, eg “?”:

user@host> show <?>
   all       Show all
   routing   Show routing
   files     Show files

For long or multi-line help strings the following configure options exists:

CLICON_CLI_HELPSTRING_TRUNCATE

Set to 0 to wrap long help strings to the next line. (default) Set to 1 to truncate long help strings at the right margin

CLICON_CLI_HELPSTRING_LINES

Set to 0 to have no limit on the number of help string lines per command Set to <n> to limit the the number of help string lines

Long and multi-line help strings may especially be needed in the auto-cli, see autocli.

9.2.4 Modes

The CLI can have different modes which is controlled by a config option and some internal clispec variables. The config options are:

CLICON_CLI_MODE

Startup CLI mode. This should match a CLICON_MODE variable setting in one of the clispec files. Default is “base”.

CLICON_CLI_VARONLY

Do not include keys in cvec in cli vars callbacks

Inside the clispec files CLICON_MODE is used to specify to which modes the syntax in a specific file defines. For example, if you have major modes configure and operation you can have a file with commands for only that mode, or files with commands in both, (or in all).

First, lets add a single command in the configure mode:

CLICON_MODE="configure";
show configure;

Then add syntax to both modes:

CLICON_MODE="operation:configure";
show("Show") files("Show files");

Finally, add a command to all modes:

CLICON_MODE="*";
show("Show") all("Show all");

Note that CLI command trees are merged so that show commands in other files are shown together. Thus, for example, using the clispecs above the two modes are the three commands in total for the configure mode:

> clixon_cli -m configure
user@host> show <TAB>
  all     routing      files

but only two commands in the operation mode:

> clixon_cli -m operation
user@host> show <TAB>
  all      files

9.2.5 Cli-spec variables

A CLI specification file (note not clixon config file) typically starts with the following variables:

CLICON_MODE

A colon-separated list of CLIgen modes. The CLI spec in the file are added to all modes specified in the list. You can also use wildcards * and ‘?`.

CLICON_PROMPT

A string describing the CLI prompt using a very simple format with: %H (host) , %U (user) , %T (tty), %W (last element of working path), %w (full working path).

CLICON_PLUGIN

The name of the object file containing callbacks in this file.

CLICON_PIPETREE

Name of a pipe output tree as described in

9.3 CLI callbacks

CLI callback functions are “library” functions that an application may call from a clispec. A user is expected to create new application-specific callbacks.

As an example, consider the following clispec:

example("Callback example") <var:int32>("any number"), mycallback("myarg");

containing a keyword (example) and a variable (var) and mycallback is a cli callback with argument: (myarg).

In C, the callback has the following signature:

int mycallback(clixon_handle h, cvec *cvv, cvec *argv);

Suppose a user enters the following command in the CLI:

user@host> example 23

The callback is called with the following parameters:

cvv:
   0: example 23
   1: 23
argv:
   0: "myarg"

which means that cvv contains dynamic values set by the user, and argv contains static values set by the clispec designer.

9.4 Show commands

Clixon includes show commands for showing datastore and state content.An application may use these functions as basis for more specialized show functions. Some show functions are:

  • cli_show_config() - Multi-purpose show function for manual CLI show commands

  • cli_show_auto() - Used in conjunction with the autocli with expansion trees

  • cli_show_auto_mode() - Used in conjunction with the autocli with edit-modes

  • cli_pagination() - Show paginated data of a large list

The CLI show functions are utility functions in the sense that they are not part of the core functionality and a user or product may want to specialize them.

Note

CLI library functions are subject to change in new releases

9.4.1 cli_show_config

The cli_show_config is a basic function to display datastore and state data. A typical use in a cli spec is as follows:

show("Show configuration"), cli_show_config("candidate", "text");

Using this command in the CLI could provicde the following output:

cli> show
<table xmlns="urn:example:clixon">
   <parameter>
      <name>a</name>
      <value>x</value>
   </parameter>
</table>

The callback has the following parameters, only the first is mandatory:

  • dbname : Name of datastore to show, such as “running”, “candidate” or “startup”

  • format : Show format, one of text, xml, json, cli, or netconf (see datastore formats)

  • xpath : Static xpath (only present in this API function)

  • namespace : Default namespace for xpath (only present in this API function)

  • pretty : If true, make output pretty-printed

  • state : If true, include non-config data in output

  • default : Optional default retrieval mode: one of report-all, trim, explicit, report-all-tagged. See also extended values below

  • prepend : Optional prefix to prepend before cli syntax output, only valid for CLI format.

  • fromroot : If false show from xpath node, if true show from root

9.4.2 cli_show_auto

The cli_show_auto() callback is used together with the autocli to show sub-parts of a configured tree using expansion. A typical definition is as follows:

show("Show expand") @datamodelshow, cli_show_auto("candidate", "xml");

That is, it must always be used together with a tree-reference as described in Section autocli.

An example CLI usage is:

cli> show table parameter a
<parameter>
   <name>a</name>
   <value>x</value>
</parameter>

The arguments are similar to cli_show_config with the difference that the xpath is implicitly defined by the current position of the tree reference:

* `dbname` : Name of datastore to show, such as "running", "candidate" or "startup"
* `format` : Show format, one of `text`, `xml`, `json`, `cli`, or `netconf` (see :ref:`datastore formats <clixon_datastore>`)
* `pretty` : If `true`, make output pretty-printed
* `state`  : If `true`, include non-config data in output
* `default` : Optional default retrieval mode: one of `report-all`, `trim`, `explicit`, `report-all-tagged`. See also extended values below
* `prepend`  : Opional prefix to print before cli syntax output, only valid for CLI format.

9.4.3 cli_show_auto_mode

The cli_show_auto_mode() callback also used together with the autocli but instead of exapansion uses the edit-modes (see Section edit modes). A typical definition is:

show, cli_show_auto_mode("candidate");

An example usage using edit-modes is:

 cli> edit table
 cli> show
<parameter>
   <name>a</name>
   <value>x</value>
</parameter>

Same parameters as cli_show_auto

9.4.4 Common show parameters

with-default parameter

All show commands have an optional with-default retrieval mode: one of report-all, trim, explicit, report-all-tagged. There are also extra propriatary modes of default serving as examples:

  • NULL, default with-default value, usually report-all

  • report-all-tagged-default, which gets the config as report-all-tagged but strips the tags/attributes (same as report-all).

  • report-all-tagged-strip, which also gets the config as report-all-tagged but strips the nodes associated with the default tags (same as trim).

pretty parameter

All show commands have a pretty-print parameter. If true the putput is pretty-printed. Indentation level is controlled by the PRETTYPRINT_INDENT compile-time option

9.5 Output pipes

Output pipes resemble UNIX shell pipes and are useful to filter or modify CLI output. Example:

cli> print all | grep parameter
  <parameter>5</parameter>
  <parameter>x</parameter>
cli> show config | showas json
  {
    "table": {
      "parameter": [
          ...
cli>

Output pipe functions are declared using a special variant of a CLI tree with a name starting with a vertical bar. Example:

CLICON_MODE="|mypipe";
\| {
   grep <arg:rest>, pipe_grep_fn("-e", "arg");
   showas json, pipe_json_fn();
}

where pipe_grep_fn and pipe_json_fn are special callbacks that use stdio to modify output.

Such a pipe tree can be referenced with either an explicit reference, or an implicit rule.

Only a single level of pipes is possibly in this release. For example, a|b|c is not possible.

Note

Only one level of pipes is supported

9.5.1 Explicit reference

An explicit reference is for single commands. For example, adding a pipe to the print commands:

print, print_cb("all");{
   @|mypipe, print_cb("all");
   all @|mypipe, print_cb("all");
   detail;
}

where a pipe tree is added as a tree reference, appending pipe functions to the regular print_cb callback. Note that the following commands are possible in this example:

print
print | count
print all | count
print detail

9.5.2 Implicit rule

An implicit rule adds pipes to all commands in a cli mode. An example of an implicit rule is as follows:

CLICON_PIPETREE="|mypipe";
print, print_cb("all");{
   all, print_cb("all");
   detail, print_cb("detail);
}

where the pipe tree is added implicitly to all commands in that file, and possibly on other files with the same mode.

Pipe trees also work for sub-trees, ie a subtree referenced by the top-level tree may also use output pipes.

9.5.3 Combinations

It is possible to combine an implicit (default) rule with an explict rule as follows:

CLICON_MODE="|commonpipe";
print, print_cb("all");{
   @|mypipe, print_cb("all");
   all @|mypipe, print_cb("all");
   detail;
}

In this example, print and print all use the ¡mypipe menu, while print detail uses the |common menu

9.5.4 Inheriting

Sub-trees inherit pipe commands from the top-level according to the following rules:
  1. Top-level implicit rules are inherited to all sub-trees, unless

  2. Explicit rules are present at the tree-reference

  3. No pipe commands are allowed in a pipe-command (only single level allowed)

Rules 1 and 2 are illustrated as follows:

CLICON_MODE="|commonpipe";
aaa {
   @datamodel, cli_show();
   @|mypipe, cli_show();
}
bbb {
   @datamodel, cli_show();
}

Pipe commands in the datamodel tree are |mypipe if preceeded by aaa, but |commonpipe if preceeded by bbb

9.5.5 Pipe functions

Clixon contains several example pipe functions primarily for testing, users of Clixon should review these and consider implementing their own.

9.6 Autocli

The Clixon CLI contains parts that are generated from a YANG specification. This autocli is generated from YANG into CLI specifications, parsed and merged into the top-level Clixon CLI.

The autocli is configured using three basic mechanisms:

  1. Config file : Modify behavior of the generated tree

  2. Tree expansion: How the generated cli is merged into the overall CLI

  3. YANG Extensions: Modify CLI behavior via YANG

Each mechanism is described in sub-sections below, but first an overview of autocli usage.

9.6.1 Overview

Consider a (simplified) YANG specification, such as:

module example {
  container table {
    list parameter{
      key name;
      leaf name{
        type string;
      }
    }
  }
}

An example of a generated syntax is as follows (again simplified):

table; {
   parameter <name:string>;
}

The auto-cli syntax is loaded using a sub-tree operator such as @datamodel into the Clixon CLI as follows:

CLICON_PROMPT="%U@%H %W> ";
set @datamodel, cli_auto_set();
merge @datamodel, cli_auto_merge();
delete @datamodel, cli_auto_del();
show config, cli_auto_show("datamodel", "candidate", "text", true, false);{
   @datamodel, cli_show_auto("candidate", "text");
}

For example, the set part is expanded using the CLIgen tree-operator to something like:

set table, cli_auto_set(); {
      parameter <name:string>, cli_auto_set();
}

An example run of the above example is as follows:

> clixon_cli
user@host /> set table ?
  <cr>
  parameter
user@host /> set table parameter 23
user@host /> show config
table {
   parameter {
      name 23;
   }
}
user@host />

where the generated autocli extends the Clixon CLI with YANG-derived configuration statements.

9.6.2 Config file

The clixon config file has a <autocli> sub-clause for global autocli configurations. A typical CLI configuration with default autocli settings is as follows:

<clixon-config xmlns="http://clicon.org/config">
  <CLICON_CONFIGFILE>/usr/local/etc/example.xml</CLICON_CONFIGFILE>
  ...
  <autocli>
    <module-default>true</module-default>
    <list-keyword-default>kw-nokey</list-keyword-default>
    <treeref-state-default>false</treeref-state-default>
    <edit-mode-default>list container</edit-mode-default>
    <completion-default>true</completion-default>
  </autocli>
</clixon-config>

The autocli configuration consists of a set of default options, followed by a set of rules. For more info see the clixon-autocli.yang specification.

Options

The following options set default values to the auto-cli, some of these may be further refined by successive rules.

module-default

How to generate the autocli from modules:

  • If true, all modules with a top-level datanode are generated, ie they get a top-level entry in the @basemodel tree. This is default

  • If false, you need to explicitly enable modules for autocli generation using module enable rules.

list-keyword-default

How to generate the autocli from YANG lists. There are several variants defined. To understand the different variants, consider a simple YANG LIST defintion as follows:

list a {
   key x;
   leaf x;
   leaf y;
}

The different variants with the resulting autocli are as follows:

  • kw-none : No extra keywords, only variables: a <x> <y>

  • kw-nokey : Keywords on non-key variables: a <x> y <y>. This is default.

  • kw-all : Keywords on all variables: a x <x> y <y>

treeref-state-default

If generate autocli from YANG state data. The motivation for this option is that many specs have very large state parts. In particular, some openconfig YANG specifications have ca 10 times larger state than config parts.

  • If true, generate CLI from YANG state/non-config statements, not only from config data.

  • If false do not generate autocli commands from YANG state data. This is default.

edit-mode-default

Open automatic edit-modes for some YANG keywords and do not allow others. A CLI edit mode opens a carriage-return option and changes the context to be in that local context. For example:

user@host> interfaces interface e0<cr>
eth0>

Default is to generate edit-modes for all YANG containers and lists. For more info see edit modes

completion-default

Generate code for CLI completion of existing db symbols. That is, check existing configure database for completion options. This is normally always enabled.

grouping-treeref

Controls the behaviour when generating CLISPEC of YANG ‘uses’ statements into the corresponding ‘grouping’ definition. If ‘true’, use indirect tree reference @treeref’ to reference the grouping definition. This may reduces memory footprint of the CLI.

Rules

To complement options, a set of rules to further define the autocli can be defined. Common rule fields are:

name

Arbitrary name assigned for the rule, must be unique.

operation

Rule operation, There are currently two operations defined: module enable and command compress.

module-name

Name of the module associated with this rule. Wildchars ‘*’ and ‘?’ can be used (glob pattern). Revision and yang suffix are omitted. Example: openconfig-*

Module enable rules

Module enable rules are used in combination with module-default=false to enable CLI generation for a limited set of YANG modules.

For example, assume you want to enable modules example1, example2 and no others:

<autocli>
   <module-default>false</module-default>
   <rule>
      <name>include example</name>
      <operation>enable</operation>
      <module-name>example*</module-name>
  </rule>
</autocli>

If the option module-default is true, module enable rules have no effect since all modules are already enabled.

Compress rules

Compress rules are used to skip CLI commands, making the complete command name shorter.

For example, assume YANG definition:

container interfaces {
   list interface {
      ...
   }
}

Instead of typing interfaces interface e0 you would want to type only interface e0. The following rule matches all YANG containers with lists as its only child, and removes the keyword interfaces:

<rule>
   <name>compress</name>
   <operation>compress</operation>
   <yang-keyword>container</yang-keyword>
   <yang-keyword-child>list</yang-keyword-child>
</rule>

Note that this matches the openconfig compress rule: The surrounding ‘container’ entities are removed from ‘list’ nodes

A second openconfig compress rule is The ‘config’ and ‘state’ containers are “compressed” out of the schema. as examplified here (for ‘config’ only):

<rule>
   <name>openconfig compress</name>
   <operation>compress</operation>
   <yang-keyword>container</yang-keyword>
   <schema-nodeid>config</schema-nodeid>
   <module-name>openconfig*</module-name>
</rule>

Specific fields for compress are:

yang-keyword

If present identifes a YANG keyword which the rule applies to. Example: container

schema-nodeid

A single <id> identifying a YANG schema-node identifier as defined in RFC 7950 Sec 6.5. Example: config

yang-keyword-child

The YANG statement has a single child, and the yang type of the child is the value of this option. Example: : container

extension

The extension is set either in the node itself, or in the module the node belongs to. Extension prefix must be set. Example: oc-ext:openconfig-version

9.6.3 Tree expansion

In the example above, the tree-reference @datamodel is used to merge the YANG-generated cli-spec into the overall cli-spec. There are several variants of how the generated tree is expanded with slight differences in which symbols are shown, how completion works, etc.

They are all derivates of the basic @basemodel tree. The following tree variants are defined:

  • @basemodel - The most basic tree including everything

  • @datamodel - The most common tree for configuration with state

  • @datamodelshow - A tree made for showing configuration syntax

  • @datamodelmode - A tree for editing modes

  • @datamodelstate - A tree for showing state as well as configuration

Note to use @datamodelstate config option treeref-state-default must be set.

9.6.4 YANG Extensions

A third method to define the autocli is using YANG extensions, where a YANG specification is annotated with extension.

Clixon provides a dedicated YANG extension for the autocli for this purpose: clixon-lib:autocli.

The following example shows the main example usage of the “hide” extension of the “hidden” leaf:

import clixon-autocli{
   prefix autocli;
}
container table{
   list parameter{
      ...
      leaf hidden{
         type string;
         autocli:hide;
      }
   }
}

The CLI hidden command is not shown but the command still exists:

cli /> set table parameter a ?
value
<cr>
cli /> set table parameter a hidden 99
cli /> show configuration
table {
  parameter {
      name a;
      hidden 99;
  }
}

The following autocli extensions are defined:

hide

Do not show the command in eg auto-completion. This was primarily intended for operational commands such as start shell but is this context used for hiding commands generated from the associated YANG node.

skip

Skip the command altogether.

hide-show

Do not show the config in show configuration commands. However, retreiving a config via NETCONF or examining the datastore directly shows the hidden configure commands.

strict-expand

Only show exactly the expanded options of a variable. It shuld not be possible to add a new value that is not in the expanded list.o

alias

Replace the command with another value, only implemented for YANG leaves.

9.6.5 Edit modes

The autocli supports automatic edit modes where by entering a <cr>, you enter an edit mode. An edit mode is created for every YANG container or list.

For example, the example YANG previously given and the following cli-spec:

edit @datamodelmode, cli_auto_edit("basemodel");
up, cli_auto_up("basemodel");
top, cli_auto_top("basemodel");
set @datamodel, cli_auto_set();

Then an example session for illustration is as follows, where first a small config is created, then a list instance mode is entered(parameter a), a value changed, and a container mode (table):

user@host /> set table parameter a value 42
user@host /> set table parameter b value 77
user@host /> edit table parameter a
user@host parameter=a/>
user@host parameter=a/> show configuration
  name a;
  value 42;
user@host parameter=a/> set value 99
user@host parameter=a/> up
user@host table> show configuration
parameter {
    name a;
    value 99;
}
parameter {
    name b;
    value 77;
}
user@host table> top
user@host />

9.7 Advanced

This section describes some advanced options in the Clixon CLI not described elsewhere.

9.7.1 Backend socket

By default, the CLI uses a UNIX socket as an IPC to communicate with the backend. It is possible to use an IP socket but with a restricted functionality, see backend section.

Start session

The session creation is “lazy” in the sense that a NETCONF session is only established when needed. After the session has been established, it is maintained (cached) by the CLI client to keep track of candidate edits and locks, as described in 7.5 of RFC 6241.

If there is no backend running at the time of session establishment, a warning is printed:

cli /> show config
Mar 18 11:53:43: clicon_rpc_connect_unix: 541: Protocol error: /usr/local/var/example/example.sock: config daemon not running?: No such file or directory
Protocol error: /usr/local/var/example/example.sock: config daemon not running?: No such file or directory
cli />

If at a later time, the backend is started, the session is established normally

Close session

After a session is established and the backend exits, crashes or restarts, any state associated with the session will be lost, including:

  • explicit locks

  • edits in candidate-db

If the backend exits during an existing session, it will close with the same error message as above:

cli /> show config
Mar 18 11:53:43: clicon_rpc_connect_unix: 541: Protocol error: /usr/local/var/example/example.sock: config daemon not running?: No such file or directory
Protocol error: /usr/local/var/example/example.sock: config daemon not running?: No such file or directory
cli />

If the backend restarts, a new session is created with a warning:

cli /> show configuration
Mar 18 11:57:55: The backend was probably restarted and the client has reconnected to the backend. Any locks or candidate edits are lost.
cli />

Alternative

It is possible to change the default behavior by undefining the compile-option: #undef PROTO_RESTART_RECONNECT. If so, the CLI is exited when the existing session is closed in anyway:

cli /> show configuration
Mar 18 12:02:57: clicon_rpc_msg: 210: Protocol error: Unexpected close of CLICON_SOCK. Clixon backend daemon may have crashed.: Cannot send after transport endpoint shutdown
Protocol error: Unexpected close of CLICON_SOCK. Clixon backend daemon may have crashed.: Cannot send after transport endpoint shutdown
bash#

9.7.2 Sub-tree operator

Sub-trees are defined using the tree operator @. Every mode gets assigned a tree which can be referenced as @name. This tree can be either on the top-level or as a sub-tree. For example, create a specific sub-tree that is used as sub-trees in other modes:

CLICON_MODE="subtree";
subcommand{
  a, a();
  b, b();
}

then access that subtree from other modes:

CLICON_MODE="configure";
main @subtree;
other @subtree,c();

The configure mode will now use the same subtree in two different commands. Additionally, in the other command, the callbacks are overwritten by c. That is, if other a, or other b is called, callback function c is invoked.

9.7.3 Translators

CLIgen supports wrapper functions that can take the output of a callback and transform it to something else.

The CLI can perform variable translation. This is useful if you want to process the input, such as hashing, encrypting or in other way translate the input.

The following example is based on the main Clixon example and is included in the regression tests. In the following CLI specification, a “translate” command sets a modifed value to the “table/parameter=translate/value”:

translate <value:string translate:cli_incstr()>, cli_set("/clixon-example:table/parameter=translate/value");

If you run this example using the cli_incstr() function which increments the characters in the input, you get this result:

user@host> translate HAL
user@host> show configuration
table {
   parameter {
      name translate;
      value IBM;
   }
}

The example is very simple and based on strings, but can be used also for other types and more advanced functions.

9.7.4 Autocli tree labels

The autocli trees described in tree expansion are implemented using filtering of CLIgen labels. While @basemodel includes all labels, the other trees have removed some labels.

For most uses, the pre-defined trees above are enough, using explicit label filtering is more powerful.

The currently defined labels are:

  • act-list : Terminal entries of YANG LIST nodes.

  • act-container : Terminal entries of YANG CONTAINER nodes.

  • ac-leaf : Leaf/leaf-list nodes

  • act-prekey : Terminal entries of LIST leaf keys, except the last keys in multi-key cases.

  • act-lastkey : Terminal entries of LIST leaf keys, except the last keys in multi-key cases.

  • act-leafconst : Terminal entries of non-empty non-key YANG LEAF/LEAF_LISTs command nodes.

  • act-leafvar : Terminal entries of non-key YANG LEAF/LEAF_LISTs variable nodes.

  • ac-state : Nodes which have YANG config false as child

  • ac-config : Nodes nodes which do not have any state nodes as siblings

Labels with prefix act_ are terminal labels in the sense that they mark a terminal command, ie the node itself; while labels with ac_ represent the non-terminal, ie the whole sub-tree.

As an example, the @datamodel tree is basemodel with labels removed as follows:

@basemodel, @remove:act-prekey, @remove:act-list, @remove:act-leaf, @remove:ac-state;

which is an alternative way of specifying the datamodel tree.

9.7.5 Extensions to CLIgen

Clixon adds some features and structure to CLIgen which include:

  • A plugin framework for both textual CLI specifications(.cli) and object files (.so)

  • Object files contains compiled C functions referenced by callbacks in the CLI specification. For example, in the cli spec command: a,fn(), fn must exist in the object file as a C function.

  • The CLIgen treename syntax does not work.

  • A CLI specification file is enhanced with the CLIgen variables CLICON_MODE, CLICON_PROMPT, CLICON_PLUGIN and CLICON_PIPETREE.

  • Clixon generates a command syntax from the Yang specification that can be referenced as @datamodel. This is useful if you do not want to hand-craft CLI syntax for configuration syntax.

Example of @datamodel syntax:

set    @datamodel, cli_set();
merge  @datamodel, cli_merge();
create @datamodel, cli_create();
show   @datamodel, cli_show_auto("running", "xml");

The commands (eg cli_set) will be called with the first argument an api-path to the referenced object.

9.7.6 Running CLI scripts

The CLI can run scripts using either the -1 option for single commands:

clixon_cli -1 show version
4.8.0.PRE

Or using the -F <file> command-line option to redirect input from file

clixon_cli -F file

Or using “shebang”:

#!/usr/local/bin/clixon_cli -F
show version
quit
Two caveats regarding “shebang”:
  1. The clixon config file is /usr/local/etc/clixon.xml

  2. The mode is CLICON_CLI_MODE

You may mod this by using soft links or creating a new executable to use use in the “shebang” with other default values.

9.7.7 How to deal with large specs

CLIgen is designed to handle large specifications in runtime, but it may be difficult to handle large specifications from a design perspective.

Here are some techniques and hints on how to reduce the complexity of large CLI specs:

Sub-modes

The CLICON_MODE is used to specify in which modes the syntax in a specific file should be added. For example, if you have major modes configure and operation you can have a file with commands for only that mode, or files with commands in both, (or in all).

First, lets add a basic set in each:

CLICON_MODE="configure";
show configure;

and

CLICON_MODE="operation";
show configure;

Note that CLI command trees are merged so that show commands in other files are shown together. Thus, for example:

CLICON_MODE="operation:files";
show("Show") files("files");

will result in both commands in the operation mode:

> clixon_cli -m operation
user@host> show <TAB>
  configure      files

but

> clixon_cli -m configure
user@host> show <TAB>
  configure

Sub-trees

You can also use sub-trees and the the tree operator @. Every mode gets assigned a tree which can be referenced as @name. This tree can be either on the top-level or as a sub-tree. For example, create a specific sub-tree that is used as sub-trees in other modes:

CLICON_MODE="subtree";
subcommand{
  a, a();
  b, b();
}

then access that subtree from other modes:

CLICON_MODE="configure";
main @subtree;
other @subtree,c();

The configure mode will now use the same subtree in two different commands. Additionally, in the other command, the callbacks will be overwritten by c. That is, if other a, or other b is called, callback function c will be invoked.

C-preprocessor

You can also add the C preprocessor as a first step. You can then define macros, include files, etc. Here is an example of a Makefile using cpp:

C_CPP    = clispec_example1.cpp clispec_example2.cpp
C_CLI    = $(C_CPP:.cpp=.cli
CLIS     = $(C_CLI)
all:     $(CLIS)
%.cli : %.cpp
     $(CPP) -P -x assembler-with-cpp $(INCLUDES) -o $@ $<

9.7.8 Bits

The Yang bits built-in type as defined in RFC 7950 Sec 9.7 provides a set of bit names. In the CLI, the names should be given in a white-spaced delimited list, such as "fin syn rst".

The RFC defines a “canonical form” where the bits appear ordered by their position in YANG, but Clixon validation accepts them in any order.

Given them in XML and JSON follows thus, eg XML:

<flags>fin rst syn</flags>

Clixon CLI does not treat individual bits as “first-level objects”. Instead it only validates the whole string of bit names. Operations (add/remove) are made atomically on the whole string.

9.7.9 Api-path-fmt

The clixon CLI uses an internal meta-format called api_path_fmt which is used to generate api-paths, as described i Section XML.

An api-path-fmt extends an api-path with % flag characters (like printf) as follows:

  • %s: The value of a cligen-variable

  • %k: The key of a YANG list

Example, an explicit clispec expansion variable could be:

<name:string expand_dbvar("candidate","/interface=%s/%k")>

which could expand to /interface=eth0/mykey if “eth0” is given as the “name” variable and “mykey” is the YANG interface list key.