mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 00:56:19 +00:00
tools: non hardcoded paths in frr-reload
allow command line parameters to specify different folder for the vtysh binary, config file location and temporary file. Keep the old hardcoded paths as default values for those options to preserve current functionality. Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
This commit is contained in:
parent
f7f051f230
commit
1a11d9cd1e
@ -114,7 +114,7 @@ class Config(object):
|
|||||||
self.lines = []
|
self.lines = []
|
||||||
self.contexts = OrderedDict()
|
self.contexts = OrderedDict()
|
||||||
|
|
||||||
def load_from_file(self, filename):
|
def load_from_file(self, filename, bindir, confdir):
|
||||||
"""
|
"""
|
||||||
Read configuration from specified file and slurp it into internal memory
|
Read configuration from specified file and slurp it into internal memory
|
||||||
The internal representation has been marked appropriately by passing it
|
The internal representation has been marked appropriately by passing it
|
||||||
@ -123,7 +123,7 @@ class Config(object):
|
|||||||
log.info('Loading Config object from file %s', filename)
|
log.info('Loading Config object from file %s', filename)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename],
|
file_output = subprocess.check_output([str(bindir + '/vtysh'), '-m', '-f', filename, '--config_dir', confdir],
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
ve = VtyshMarkException(e)
|
ve = VtyshMarkException(e)
|
||||||
@ -144,7 +144,7 @@ class Config(object):
|
|||||||
|
|
||||||
self.load_contexts()
|
self.load_contexts()
|
||||||
|
|
||||||
def load_from_show_running(self):
|
def load_from_show_running(self, bindir, confdir):
|
||||||
"""
|
"""
|
||||||
Read running configuration and slurp it into internal memory
|
Read running configuration and slurp it into internal memory
|
||||||
The internal representation has been marked appropriately by passing it
|
The internal representation has been marked appropriately by passing it
|
||||||
@ -154,7 +154,7 @@ class Config(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
config_text = subprocess.check_output(
|
config_text = subprocess.check_output(
|
||||||
"/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -",
|
bindir + "/vtysh --config_dir " + confdir + " -c 'show run' | /usr/bin/tail -n +4 | " + bindir + "/vtysh --config_dir " + confdir + " -m -f -",
|
||||||
shell=True, stderr=subprocess.STDOUT)
|
shell=True, stderr=subprocess.STDOUT)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
ve = VtyshMarkException(e)
|
ve = VtyshMarkException(e)
|
||||||
@ -528,13 +528,15 @@ end
|
|||||||
self.save_contexts(ctx_keys, current_context_lines)
|
self.save_contexts(ctx_keys, current_context_lines)
|
||||||
|
|
||||||
|
|
||||||
def line_to_vtysh_conft(ctx_keys, line, delete):
|
def line_to_vtysh_conft(ctx_keys, line, delete, bindir, confdir):
|
||||||
"""
|
"""
|
||||||
Return the vtysh command for the specified context line
|
Return the vtysh command for the specified context line
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cmd = []
|
cmd = []
|
||||||
cmd.append('vtysh')
|
cmd.append(str(bindir + '/vtysh'))
|
||||||
|
cmd.append('--config_dir')
|
||||||
|
cmd.append(confdir)
|
||||||
cmd.append('-c')
|
cmd.append('-c')
|
||||||
cmd.append('conf t')
|
cmd.append('conf t')
|
||||||
|
|
||||||
@ -1074,7 +1076,7 @@ def compare_context_objects(newconf, running):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def vtysh_config_available():
|
def vtysh_config_available(bindir, confdir):
|
||||||
"""
|
"""
|
||||||
Return False if no frr daemon is running or some other vtysh session is
|
Return False if no frr daemon is running or some other vtysh session is
|
||||||
in 'configuration terminal' mode which will prevent us from making any
|
in 'configuration terminal' mode which will prevent us from making any
|
||||||
@ -1082,7 +1084,7 @@ def vtysh_config_available():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmd = ['/usr/bin/vtysh', '-c', 'conf t']
|
cmd = [str(bindir + '/vtysh'), '--config_dir', confdir, '-c', 'conf t']
|
||||||
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
|
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).strip()
|
||||||
|
|
||||||
if 'VTY configuration is locked by other VTY' in output.decode('utf-8'):
|
if 'VTY configuration is locked by other VTY' in output.decode('utf-8'):
|
||||||
@ -1110,6 +1112,9 @@ if __name__ == '__main__':
|
|||||||
parser.add_argument('--stdout', action='store_true', help='Log to STDOUT', default=False)
|
parser.add_argument('--stdout', action='store_true', help='Log to STDOUT', default=False)
|
||||||
parser.add_argument('filename', help='Location of new frr config file')
|
parser.add_argument('filename', help='Location of new frr config file')
|
||||||
parser.add_argument('--overwrite', action='store_true', help='Overwrite frr.conf with running config output', default=False)
|
parser.add_argument('--overwrite', action='store_true', help='Overwrite frr.conf with running config output', default=False)
|
||||||
|
parser.add_argument('--bindir', help='path to the vtysh executable', default='/usr/bin')
|
||||||
|
parser.add_argument('--confdir', help='path to the daemon config files', default='/etc/frr')
|
||||||
|
parser.add_argument('--rundir', help='path for the temp config file', default='/var/run/frr')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
@ -1149,8 +1154,22 @@ if __name__ == '__main__':
|
|||||||
log.error(msg)
|
log.error(msg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Verify that confdir is correct
|
||||||
|
if not os.path.isdir(args.confdir):
|
||||||
|
msg = "Confdir %s is not a valid path" % args.confdir
|
||||||
|
print(msg)
|
||||||
|
log.error(msg)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Verify that bindir is correct
|
||||||
|
if not os.path.isdir(args.bindir) or not os.path.isfile(args.bindir + '/vtysh'):
|
||||||
|
msg = "Bindir %s is not a valid path to vtysh" % args.bindir
|
||||||
|
print(msg)
|
||||||
|
log.error(msg)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# Verify that 'service integrated-vtysh-config' is configured
|
# Verify that 'service integrated-vtysh-config' is configured
|
||||||
vtysh_filename = '/etc/frr/vtysh.conf'
|
vtysh_filename = args.confdir + '/vtysh.conf'
|
||||||
service_integrated_vtysh_config = True
|
service_integrated_vtysh_config = True
|
||||||
|
|
||||||
if os.path.isfile(vtysh_filename):
|
if os.path.isfile(vtysh_filename):
|
||||||
@ -1175,7 +1194,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# Create a Config object from the config generated by newconf
|
# Create a Config object from the config generated by newconf
|
||||||
newconf = Config()
|
newconf = Config()
|
||||||
newconf.load_from_file(args.filename)
|
newconf.load_from_file(args.filename, args.bindir, args.confdir)
|
||||||
reload_ok = True
|
reload_ok = True
|
||||||
|
|
||||||
if args.test:
|
if args.test:
|
||||||
@ -1184,9 +1203,9 @@ if __name__ == '__main__':
|
|||||||
running = Config()
|
running = Config()
|
||||||
|
|
||||||
if args.input:
|
if args.input:
|
||||||
running.load_from_file(args.input)
|
running.load_from_file(args.input, args.bindir, args.confdir)
|
||||||
else:
|
else:
|
||||||
running.load_from_show_running()
|
running.load_from_show_running(args.bindir, args.confdir)
|
||||||
|
|
||||||
(lines_to_add, lines_to_del) = compare_context_objects(newconf, running)
|
(lines_to_add, lines_to_del) = compare_context_objects(newconf, running)
|
||||||
lines_to_configure = []
|
lines_to_configure = []
|
||||||
@ -1220,7 +1239,7 @@ if __name__ == '__main__':
|
|||||||
elif args.reload:
|
elif args.reload:
|
||||||
|
|
||||||
# We will not be able to do anything, go ahead and exit(1)
|
# We will not be able to do anything, go ahead and exit(1)
|
||||||
if not vtysh_config_available():
|
if not vtysh_config_available(args.bindir, args.confdir):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
log.debug('New Frr Config\n%s', newconf.get_lines())
|
log.debug('New Frr Config\n%s', newconf.get_lines())
|
||||||
@ -1264,7 +1283,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
for x in range(2):
|
for x in range(2):
|
||||||
running = Config()
|
running = Config()
|
||||||
running.load_from_show_running()
|
running.load_from_show_running(args.bindir, args.confdir)
|
||||||
log.debug('Running Frr Config (Pass #%d)\n%s', x, running.get_lines())
|
log.debug('Running Frr Config (Pass #%d)\n%s', x, running.get_lines())
|
||||||
|
|
||||||
(lines_to_add, lines_to_del) = compare_context_objects(newconf, running)
|
(lines_to_add, lines_to_del) = compare_context_objects(newconf, running)
|
||||||
@ -1296,7 +1315,7 @@ if __name__ == '__main__':
|
|||||||
# 'no' commands are tricky, we can't just put them in a file and
|
# 'no' commands are tricky, we can't just put them in a file and
|
||||||
# vtysh -f that file. See the next comment for an explanation
|
# vtysh -f that file. See the next comment for an explanation
|
||||||
# of their quirks
|
# of their quirks
|
||||||
cmd = line_to_vtysh_conft(ctx_keys, line, True)
|
cmd = line_to_vtysh_conft(ctx_keys, line, True, args.bindir, args.confdir)
|
||||||
original_cmd = cmd
|
original_cmd = cmd
|
||||||
|
|
||||||
# Some commands in frr are picky about taking a "no" of the entire line.
|
# Some commands in frr are picky about taking a "no" of the entire line.
|
||||||
@ -1352,7 +1371,7 @@ if __name__ == '__main__':
|
|||||||
string.ascii_uppercase +
|
string.ascii_uppercase +
|
||||||
string.digits) for _ in range(6))
|
string.digits) for _ in range(6))
|
||||||
|
|
||||||
filename = "/var/run/frr/reload-%s.txt" % random_string
|
filename = args.rundir + "/reload-%s.txt" % random_string
|
||||||
log.info("%s content\n%s" % (filename, pformat(lines_to_configure)))
|
log.info("%s content\n%s" % (filename, pformat(lines_to_configure)))
|
||||||
|
|
||||||
with open(filename, 'w') as fh:
|
with open(filename, 'w') as fh:
|
||||||
@ -1360,15 +1379,15 @@ if __name__ == '__main__':
|
|||||||
fh.write(line + '\n')
|
fh.write(line + '\n')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(['/usr/bin/vtysh', '-f', filename], stderr=subprocess.STDOUT)
|
subprocess.check_output([str(args.bindir + '/vtysh'), '--config_dir', args.confdir, '-f', filename], stderr=subprocess.STDOUT)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
log.warning("frr-reload.py failed due to\n%s" % e.output)
|
log.warning("frr-reload.py failed due to\n%s" % e.output)
|
||||||
reload_ok = False
|
reload_ok = False
|
||||||
os.unlink(filename)
|
os.unlink(filename)
|
||||||
|
|
||||||
# Make these changes persistent
|
# Make these changes persistent
|
||||||
if args.overwrite or args.filename != '/etc/frr/frr.conf':
|
if args.overwrite or args.filename != str(args.confdir + '/frr.conf'):
|
||||||
subprocess.call(['/usr/bin/vtysh', '-c', 'write'])
|
subprocess.call([str(args.bindir + '/vtysh'), '--config_dir', args.confdir, '-c', 'write'])
|
||||||
|
|
||||||
if not reload_ok:
|
if not reload_ok:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
Loading…
Reference in New Issue
Block a user