Commit 974e63e7 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2380] supported canceling creation of zone due to intermediate failure.

parent 8693df3c
......@@ -32,6 +32,12 @@ class BadArgument(Exception):
'''
pass
class LoadFailure(Exception):
'''An exception indicating failure in loading operation.
'''
pass
def set_cmd_options(parser):
'''Helper function to set command-line options.
......@@ -66,7 +72,31 @@ class LoadZoneRunner:
raise BadArgument("Invalid zone name '" + args[0] + "': " +
str(ex))
def __cancel_create(self):
'''sqlite3-only hack: delete the zone just created on load failure.
This should eventually be done via generic datasrc API, but right now
we don't have that interface. Leaving the zone in this situation
is too bad, so we handle it with a workaround.
'''
if self._datasrc_type is not 'sqlite3':
return
import sqlite3 # we need the module only here
import json
# If we are here, the following should basically succeed; since
# this is considered a temporary workaround we don't bother to catch
# and recover rare failure cases.
dbfile = json.loads(self._datasrc_config)['database_file']
with sqlite3.connect(dbfile) as conn:
cur = conn.cursor()
cur.execute("DELETE FROM zones WHERE name = ?",
[self._zone_name.to_text()])
def _do_load(self):
created = False
try:
datasrc_client = DataSourceClient(self._datasrc_type,
self._datasrc_config)
......@@ -79,15 +109,23 @@ class LoadZoneRunner:
loader.load()
return
except Exception as ex:
logger.error(LOADZONE_LOAD_ERROR, self._zone_name,
self._zone_class, ex)
raise ex
# release any remaining lock held in the client/loader
loader, datasrc_client = None, None
if created:
self.__cancel_create()
logger.error(LOADZONE_CANCEL_CREATE_ZONE, self._zone_name,
self._zone_class)
raise LoadFailure(str(ex))
def run(self):
try:
self._parse_args()
self._do_load()
except BadArgument as ex:
logger.error(LOADZONE_ARGUMENT_ERROR, ex)
except LoadFailure as ex:
logger.error(LOADZONE_LOAD_ERROR, self._zone_name,
self._zone_class, ex)
return 0
if '__main__' == __name__:
......
......@@ -21,3 +21,5 @@
% LOADZONE_ZONE_CREATED Zone %1/%2 does not exist in the data source, newly created
% LOADZONE_LOAD_ERROR Failed to load zone %1/%2: %3
% LOADZONE_CANCEL_CREATE_ZONE Creation of new zone %1/%2 was canceled
......@@ -127,7 +127,7 @@ class TestLoadZoneRunner(unittest.TestCase):
self.__common_load_setup()
self.__runner._datasrc_config = "invalid config"
self.__check_zone_soa(ORIG_SOA_TXT)
self.assertRaises(isc.datasrc.Error, self.__runner._do_load)
self.assertRaises(LoadFailure, self.__runner._do_load)
self.__check_zone_soa(ORIG_SOA_TXT) # no change to the zone
def test_load_fail_badzone(self):
......@@ -136,7 +136,7 @@ class TestLoadZoneRunner(unittest.TestCase):
self.__runner._zone_file = \
LOCAL_TESTDATA_PATH + '/broken-example.org.zone'
self.__check_zone_soa(ORIG_SOA_TXT)
self.assertRaises(isc.datasrc.MasterFileError, self.__runner._do_load)
self.assertRaises(LoadFailure, self.__runner._do_load)
self.__check_zone_soa(ORIG_SOA_TXT)
def test_load_fail_noloader(self):
......@@ -145,9 +145,19 @@ class TestLoadZoneRunner(unittest.TestCase):
self.__runner._datasrc_type = 'memory'
self.__runner._datasrc_config = '{"type": "memory"}'
self.__check_zone_soa(ORIG_SOA_TXT)
self.assertRaises(isc.datasrc.NotImplemented, self.__runner._do_load)
self.assertRaises(LoadFailure, self.__runner._do_load)
self.__check_zone_soa(ORIG_SOA_TXT)
def test_load_fail_create_cancel(self):
'''Load attempt fails and new creation of zone is canceled'''
self.__common_load_setup()
self.__runner._zone_name = Name('example.com')
self.__runner._zone_file = 'no-such-file'
self.__check_zone_soa(None, zone_name=Name('example.com'))
self.assertRaises(LoadFailure, self.__runner._do_load)
# _do_load() should have once created the zone but then canceled it.
self.__check_zone_soa(None, zone_name=Name('example.com'))
if __name__== "__main__":
isc.log.resetUnitTestRootLogger()
unittest.main()
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