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): ...@@ -125,14 +125,17 @@ class FormatConfig(Parameters, Options):
def __init__(self, logger): def __init__(self, logger):
self.logger = logger self.logger = logger
def wrong(self, fmt, *args): def abort(self, fmt, *args):
return self.error(fmt, *args, exc=UsageError)
def error(self, fmt, *args):
message = fmt % tuple(args) message = fmt % tuple(args)
self.logger.error(message) self.logger.error(message)
raise ValueError(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): def warn(self, fmt, *args):
self.logger.warning(fmt, *args) self.logger.warning(fmt, *args)
...@@ -311,7 +314,7 @@ class Interface(object): ...@@ -311,7 +314,7 @@ class Interface(object):
try: try:
addresses = netifaces.ifaddresses(self.ipv6_interface)[AF_INET6] addresses = netifaces.ifaddresses(self.ipv6_interface)[AF_INET6]
except KeyError: except KeyError:
self.conf.error( self.conf.abort(
"%s must have at least one IPv6 address assigned", "%s must have at least one IPv6 address assigned",
self.ipv6_interface self.ipv6_interface
) )
...@@ -338,7 +341,7 @@ class Interface(object): ...@@ -338,7 +341,7 @@ class Interface(object):
network = self.ipv6_network network = self.ipv6_network
prefixlen = network.prefixlen + 16 prefixlen = network.prefixlen + 16
if prefixlen > 128: 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 bits = 128 - network.prefixlen
addr = network[(1 << (bits - 2)) + (index << (128 - prefixlen))] addr = network[(1 << (bits - 2)) + (index << (128 - prefixlen))]
return ipaddress.IPv6Network((addr, prefixlen)) return ipaddress.IPv6Network((addr, prefixlen))
...@@ -359,7 +362,7 @@ class Interface(object): ...@@ -359,7 +362,7 @@ class Interface(object):
if iface != interface: if iface != interface:
ifaddresses = netifaces.ifaddresses(iface).get(af, ()) ifaddresses = netifaces.ifaddresses(iface).get(af, ())
if address in (q['addr'].split('%')[0] for q in ifaddresses): 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", "Cannot add address %s (%s) to %s because it already exists on %s",
ip, reason, interface, iface ip, reason, interface, iface
) )
...@@ -367,7 +370,7 @@ class Interface(object): ...@@ -367,7 +370,7 @@ class Interface(object):
for q in ifaddresses: for q in ifaddresses:
if address == q['addr'].split('%')[0]: if address == q['addr'].split('%')[0]:
if netmask not in q['netmask']: if netmask not in q['netmask']:
self.conf.error( self.conf.abort(
"Address %s (%s) is already on %s but with another netmask %s", "Address %s (%s) is already on %s but with another netmask %s",
ip, reason, interface, q['netmask'] ip, reason, interface, q['netmask']
) )
...@@ -385,13 +388,12 @@ class Interface(object): ...@@ -385,13 +388,12 @@ class Interface(object):
for state in ('tentative', 'dadfailed'): for state in ('tentative', 'dadfailed'):
if state in line: if state in line:
call(['ip', 'addr', 'del', address, 'dev', interface]) 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", "Address %s (%s) on %s was in state %s so was removed: %r",
ip, reason, interface, state, line ip, reason, interface, state, line
) )
return return
report = self.conf.warn if self.conf.dry_run else self.conf.error self.conf.abort(
report(
"Address %s (%s) is unexpectedly not present on %s", "Address %s (%s) is unexpectedly not present on %s",
ip, reason, interface ip, reason, interface
) )
...@@ -569,6 +571,7 @@ class WrappedSystem(object): ...@@ -569,6 +571,7 @@ class WrappedSystem(object):
self.call = call self.call = call
self.os = os self.os = os
self.pwd = pwd self.pwd = pwd
self.abort = conf.abort
def __enter__(self): def __enter__(self):
global call, os, pwd global call, os, pwd
...@@ -587,8 +590,12 @@ class WrappedSystem(object): ...@@ -587,8 +590,12 @@ class WrappedSystem(object):
getpwnam=type('fake_getpwnam', (), {'pw_uid': 12345, 'pw_gid': 54321}), getpwnam=type('fake_getpwnam', (), {'pw_uid': 12345, 'pw_gid': 54321}),
) )
if conf.dry_run: if conf.dry_run:
conf.abort = conf.dryError
def dry_call(args, raise_on_error=True): def dry_call(args, raise_on_error=True):
conf.logger.debug(' '.join(args)) 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, '' return 0, ''
call = dry_call call = dry_call
else: else:
...@@ -602,5 +609,5 @@ class WrappedSystem(object): ...@@ -602,5 +609,5 @@ class WrappedSystem(object):
call = self.call call = self.call
os = self.os os = self.os
pwd = self.pwd pwd = self.pwd
self.conf.abort = self.abort
return False 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