frr/tests/lib/cli/common_cli.c
Renato Westphal fbdc1c0a84 lib: add support for confirmed commits
Confirmed commits allow the user to request an automatic rollback to
the previous configuration if the commit operation is not confirmed
within a number of minutes. This is particularly useful when the user
is accessing the CLI through the network (e.g. using SSH) and any
configuration change might cause an unexpected loss of connectivity
between the user and the managed device (e.g. misconfiguration of a
routing protocol). By using a confirmed commit, the user can rest
assured the connectivity will be restored after the given timeout
expires, avoiding the need to access the router physically to fix
the problem.

When "commit confirmed TIMEOUT" is used, a new "commit" command is
expected to confirm the previous commit before the given timeout
expires. If "commit confirmed TIMEOUT" is used while there's already
a confirmed-commit in progress, the confirmed-commit timeout is
reset to the new value.

In the current implementation, if other users perform commits while
there's a confirmed-commit in progress, all commits are rolled back
when the confirmed-commit timeout expires. It's recommended to use
the "configure exclusive" configuration mode to prevent unexpected
outcomes when using confirmed commits.

When an user exits from the configuration mode while there's a
confirmed-commit in progress, the commit is automatically rolled
back and the user is notified about it. In the future we might
want to prompt the user if he or she really wants to exit from the
configuration mode when there's a pending confirmed commit.

Needless to say, confirmed commit only work for configuration
commands converted to the new northbound model. vtysh support will
be implemented at a later time.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-12-07 11:11:33 -02:00

100 lines
2.3 KiB
C

/*
* generic CLI test helper functions
*
* Copyright (C) 2015 by David Lamparter,
* for Open Source Routing / NetDEF, Inc.
*
* Quagga is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* Quagga is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "thread.h"
#include "vty.h"
#include "command.h"
#include "memory.h"
#include "memory_vty.h"
#include "log.h"
#include "common_cli.h"
struct thread_master *master;
int dump_args(struct vty *vty, const char *descr, int argc,
struct cmd_token *argv[])
{
int i;
vty_out(vty, "%s with %d args.\n", descr, argc);
for (i = 0; i < argc; i++) {
vty_out(vty, "[%02d] %s@%s: %s\n", i, argv[i]->text,
argv[i]->varname, argv[i]->arg);
}
return CMD_SUCCESS;
}
static void vty_do_exit(int isexit)
{
printf("\nend.\n");
cmd_terminate();
vty_terminate();
nb_terminate();
yang_terminate();
thread_master_free(master);
closezlog();
log_memstats(stderr, "testcli");
if (!isexit)
exit(0);
}
/* main routine. */
int main(int argc, char **argv)
{
struct thread thread;
/* Set umask before anything for security */
umask(0027);
/* master init. */
master = thread_master_create(NULL);
openzlog("common-cli", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID,
LOG_DAEMON);
zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
zlog_set_level(ZLOG_DEST_STDOUT, ZLOG_DISABLED);
zlog_set_level(ZLOG_DEST_MONITOR, LOG_DEBUG);
/* Library inits. */
cmd_init(1);
cmd_hostname_set("test");
vty_init(master);
memory_init();
yang_init();
nb_init(master, NULL, 0);
test_init(argc, argv);
vty_stdio(vty_do_exit);
/* Fetch next active thread. */
while (thread_fetch(master, &thread))
thread_call(&thread);
/* Not reached. */
exit(0);
}