Compare commits

...

3 Commits

Author SHA1 Message Date
5eb8acbe01
Implement force-stop argument
By default, the running-detection is good enough, and avoids a useless
Vagrant "destroy" call with a misleading informational message if
"--stop" is used.
However if the deployment was interupted and is in an inconsistent state,
the running-detection returns false results - in such cases, "--force-stop"
can be used to issue a "destroy" call without considering the detected
status.

Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
2023-05-20 18:52:21 +02:00
f110f92150
Default option handling
Merge default options from [box] and [suite] blocks into the
respective [box.*]/[suite.*] sections.

Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
2023-05-20 18:51:03 +02:00
c5e404c9c6
Repair configuration check
Use membership test instead.

Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
2023-05-20 18:32:05 +02:00

View File

@ -31,6 +31,7 @@ arggroup.add_argument('--stop', help='Stop running machines', action='store_true
arggroup.add_argument('--test', help='Start machines and run tests', action='store_true') arggroup.add_argument('--test', help='Start machines and run tests', action='store_true')
arggroup.add_argument('--status', help='Get Vagrant deployment status', action='store_true') arggroup.add_argument('--status', help='Get Vagrant deployment status', action='store_true')
arggroup.add_argument('--refresh', help='Re-sync files and re-run bootstrap scripts', action='store_true') arggroup.add_argument('--refresh', help='Re-sync files and re-run bootstrap scripts', action='store_true')
argparser.add_argument('--force-stop', help='Invoke Vagrant destruction without having detected any running VM\'s', action='store_true')
args = argparser.parse_args() args = argparser.parse_args()
configfile = args.config configfile = args.config
@ -42,24 +43,33 @@ def _abort(msg):
sys.exit(1) sys.exit(1)
def _config(): def _config():
configmap = {'box': {}, 'suites': {}} configmap = {'boxes': {}, 'suites': {}}
if not config.options('box'): if not config.options('box'):
_abort('No "box" section found in the configuration file') _abort('No "box" section found in the configuration file')
for option in config.options('box'): boxes = [section for section in config.sections() if section.startswith('box.')]
configmap['box'][option] = config.get('box', option)
suites = [section for section in config.sections() if section.startswith('suite.')] suites = [section for section in config.sections() if section.startswith('suite.')]
if not len(suites): if not len(suites):
_abort('No suites configured') _abort('No suites configured')
log.debug('Suites: {}'.format(str(suites))) log.debug('Suites: {}'.format(str(suites)))
for section in suites: multis = {'boxes': {'conf': boxes, 'prefix': 'box.'}, 'suites': {'conf': suites, 'prefix': 'suite.'}}
suite = section.replace('suite.', '') for multi, multiconf in multis.items():
configmap['suites'][suite] = {} for section in multiconf['conf']:
for option in config.options(section): collection = section.replace(multiconf['prefix'], '')
if option in ['masters', 'minions']: configmap[multi][collection] = {}
value = config.getint(section, option) for option in config.options(section):
else: if option in ['masters', 'minions']:
value = config.get(section, option) value = config.getint(section, option)
configmap['suites'][suite][option] = value else:
value = config.get(section, option)
configmap[multi][collection][option] = value
# a bit of an ugly alternative to the "DEFAULT" section
multis = {'boxes': {'singular': 'box'}, 'suites': {'singular': 'suite'}}
for multis, multiconf in multis.items():
multi = multiconf['singular']
if multi in config.sections():
for option in config.options(multi):
for collection in configmap[multis]:
configmap[multis][collection][option] = config.get(multi, option)
log.debug('Config map: {}'.format(str(configmap))) log.debug('Config map: {}'.format(str(configmap)))
return configmap return configmap
@ -112,18 +122,24 @@ def vagrant_isup(suite):
def main_interactive(): def main_interactive():
configmap = _config() configmap = _config()
box = configmap['box'] boxes = configmap['boxes']
box_name = box.get('name', None)
box_image = box.get('image', None)
box_file = box.get('file', '{}/Vagrantfile-Template'.format(os.path.abspath(os.path.dirname(__file__))))
if any([box_name, box_image, box_file]) is None:
_abort('Box configuration is incomplete')
box_bootstrap = box.get('bootstrap', None)
suites = configmap['suites'] suites = configmap['suites']
suite = args.suite suite = args.suite
if suite not in suites: if suite not in suites:
_abort('No suite named {}'.format(suite)) _abort('No suite named {}'.format(suite))
suiteconf = configmap['suites'][suite] suiteconf = configmap['suites'][suite]
box = suiteconf.get('box', None)
if box is None:
_abort('Specified suite does not reference a box')
boxconf = configmap['boxes'].get(box, None)
if boxconf is None:
_abort('Suite referencs an undefined box')
box_name = boxconf.get('name', None)
box_image = boxconf.get('image', None)
box_file = boxconf.get('file', '{}/Vagrantfile-Template'.format(os.path.abspath(os.path.dirname(__file__))))
if None in [box_name, box_image, box_file]:
_abort('Box configuration is incomplete')
box_bootstrap = boxconf.get('bootstrap', None)
minions = None minions = None
masters = None masters = None
if suiteconf.get('minions', 0) > 0: if suiteconf.get('minions', 0) > 0:
@ -135,8 +151,8 @@ def main_interactive():
log.info('Status report: {}'.format(v.status())) log.info('Status report: {}'.format(v.status()))
return True return True
status = vagrant_isup(suite) status = vagrant_isup(suite)
if status[0] is True and status[1] is None or args.stop or args.refresh: if status[0] is True and status[1] is None or args.force_stop or args.refresh:
if args.stop is True: if True in [args.stop, args.force_stop]:
log.info('Destroying machines ...') log.info('Destroying machines ...')
v.destroy() v.destroy()
if vagrant_isup(suite)[0] is False: if vagrant_isup(suite)[0] is False:
@ -159,7 +175,7 @@ def main_interactive():
log.exception(myerror) log.exception(myerror)
_abort('Unhandled error') _abort('Unhandled error')
if args.stop is False: if args.stop is False and args.force_stop is False:
log.info('Launching {} ...'.format(suite)) log.info('Launching {} ...'.format(suite))
v.up() v.up()
if vagrant_isup(suite)[0] is True: if vagrant_isup(suite)[0] is True: