Commit cedc1659 authored by Xavier Thompson's avatar Xavier Thompson

slapformat: WIP: Improve exception interception in dry-run mode

parent 8e3692b8
......@@ -125,14 +125,17 @@ class FormatConfig(Parameters, Options):
def __init__(self, logger):
self.logger = logger
def wrong(self, fmt, *args):
return self.error(fmt, *args, exc=UsageError)
def error(self, fmt, *args):
def abort(self, fmt, *args):
message = fmt % tuple(args)
self.logger.error(message)
raise ValueError(message)
def wrong(self, fmt, *args):
return self.abort(fmt, *args, exc=UsageError)
def dryError(self, fmt, *args):
self.logger.warning('[dry-error] ' + fmt, *args)
def warn(self, fmt, *args):
self.logger.warning(fmt, *args)
......@@ -311,7 +314,7 @@ class Interface(object):
try:
addresses = netifaces.ifaddresses(self.ipv6_interface)[AF_INET6]
except KeyError:
self.conf.error(
self.conf.abort(
"%s must have at least one IPv6 address assigned",
self.ipv6_interface
)
......@@ -338,7 +341,7 @@ class Interface(object):
network = self.ipv6_network
prefixlen = network.prefixlen + 16
if prefixlen > 128:
self.conf.error("IPv6 network %s is too small for IPv6 ranges", network)
self.conf.abort("IPv6 network %s is too small for IPv6 ranges", network)
bits = 128 - network.prefixlen
addr = network[(1 << (bits - 2)) + (index << (128 - prefixlen))]
return ipaddress.IPv6Network((addr, prefixlen))
......@@ -359,7 +362,7 @@ class Interface(object):
if iface != interface:
ifaddresses = netifaces.ifaddresses(iface).get(af, ())
if address in (q['addr'].split('%')[0] for q in ifaddresses):
self.conf.error(
self.conf.abort(
"Cannot add address %s (%s) to %s because it already exists on %s",
ip, reason, interface, iface
)
......@@ -367,7 +370,7 @@ class Interface(object):
for q in ifaddresses:
if address == q['addr'].split('%')[0]:
if netmask not in q['netmask']:
self.conf.error(
self.conf.abort(
"Address %s (%s) is already on %s but with another netmask %s",
ip, reason, interface, q['netmask']
)
......@@ -385,13 +388,12 @@ class Interface(object):
for state in ('tentative', 'dadfailed'):
if state in line:
call(['ip', 'addr', 'del', address, 'dev', interface])
self.conf.error(
self.conf.abort(
"Address %s (%s) on %s was in state %s so was removed: %r",
ip, reason, interface, state, line
)
return
report = self.conf.warn if self.conf.dry_run else self.conf.error
report(
self.conf.abort(
"Address %s (%s) is unexpectedly not present on %s",
ip, reason, interface
)
......@@ -569,6 +571,7 @@ class WrappedSystem(object):
self.call = call
self.os = os
self.pwd = pwd
self.abort = conf.abort
def __enter__(self):
global call, os, pwd
......@@ -587,8 +590,12 @@ class WrappedSystem(object):
getpwnam=type('fake_getpwnam', (), {'pw_uid': 12345, 'pw_gid': 54321}),
)
if conf.dry_run:
conf.abort = conf.dryError
def dry_call(args, raise_on_error=True):
conf.logger.debug(' '.join(args))
it = iter(args)
if all(w in it for w in ('ip', 'addr', 'show')): # subsequence test
return self.call(args, raise_on_error=False)
return 0, ''
call = dry_call
else:
......@@ -602,5 +609,5 @@ class WrappedSystem(object):
call = self.call
os = self.os
pwd = self.pwd
self.conf.abort = self.abort
return False
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment