From 42235b9d6214e0d2e4e1af4d43a8c20fa7ed9bca Mon Sep 17 00:00:00 2001 From: Georg Pfuetzenreuter Date: Sat, 20 May 2023 17:51:32 +0200 Subject: [PATCH] Improve option handling - move bootstrap script to configuration option - repair typo - handle undefined but required options gracefully Signed-off-by: Georg Pfuetzenreuter --- Vagrantfile-Template | 18 +++++++++++----- scullery.py | 51 +++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 24 deletions(-) mode change 100644 => 100755 scullery.py diff --git a/Vagrantfile-Template b/Vagrantfile-Template index e7d2b16..b4c6add 100644 --- a/Vagrantfile-Template +++ b/Vagrantfile-Template @@ -6,7 +6,8 @@ if ! ( ENV['SCULLERY_BOX_NAME'] && ENV['SCULLERY_BOX_IMAGE'] ) || ! ( ENV['SCULL exit 1 end -salt_bootstrap = "test/bootstrap-salt-roots.sh" +salt_bootstrap = ENV['SCULLERY_BOOTSTRAP'] +salt_file_roots = 'file_roots:\n base:\n - /srv/salt\n - /srv/formulas\n' Vagrant.configure("2") do |config| config.vm.provider "libvirt" @@ -22,10 +23,12 @@ Vagrant.configure("2") do |config| master_config.vm.provider :libvirt do |libvirt| libvirt.memory = 768 end - master_config.vm.provision "shell", path: salt_bootstrap - master_config.vm.provision "shell", inline: <<-SHELL + if salt_bootstrap + master_config.vm.provision "shell", path: salt_bootstrap + end + master_config.vm.provision "shell", env: {'SALT_FILE_ROOTS': salt_file_roots}, inline: <<-SHELL printf 'auto_accept: True\n' > /etc/salt/master.d/notsecure.conf - printf 'file_roots:\n base:\n - /srv/salt\n - /srv/formulas\n' > /etc/salt/master.d/roots.conf + printf "$SALT_FILE_ROOTS" > /etc/salt/master.d/roots.conf systemctl enable --now salt-master SHELL end @@ -42,7 +45,12 @@ Vagrant.configure("2") do |config| systemctl enable --now salt-minion SHELL else - minion_config.vm.provision "shell", path: salt_bootstrap + minion_config.vm.provision "shell", env: {'SALT_FILE_ROOTS': salt_file_roots}, inline: <<-SHELL + printf "$SALT_FILE_ROOTS" > /etc/salt/minion.d/roots.conf + SHELL + if salt_bootstrap + minion_config.vm.provision "shell", path: salt_bootstrap + end end end end diff --git a/scullery.py b/scullery.py old mode 100644 new mode 100755 index 3af7d84..bd0b483 --- a/scullery.py +++ b/scullery.py @@ -18,19 +18,13 @@ import logging import os import sys -try: - import vagrant -except ImportError as myerror: - print('Could not load python-vagrant') - sys.exit(1) - argparser = ArgumentParser() config = ConfigParser() env = os.environ.copy() arggroup = argparser.add_mutually_exclusive_group() argparser.add_argument('--debug', help='Print extremely verbose output', action='store_const', dest='loglevel', const=logging.DEBUG, default=logging.INFO) -argparser.add_argument('--config', help='Specify the configuration file to use', default='{}/scullery.ini'.format(os.path.abspath(os.path.dirname(__file__)))) +argparser.add_argument('--config', help='Specify the configuration file to use', default='{}/scullery.ini'.format(os.getcwd())) argparser.add_argument('--env', help='Write environment file for direct use of Vagrant', action='store_true') argparser.add_argument('--suite', help='Specify the suite to run', required=True) arggroup.add_argument('--stop', help='Stop running machines', action='store_true') @@ -38,7 +32,7 @@ arggroup.add_argument('--test', help='Start machines and run tests', action='sto arggroup.add_argument('--status', help='Get Vagrant deployment status', action='store_true') args = argparser.parse_args() -config.read(args.config) +configfile = args.config vmprefix = 'scullery' @@ -81,7 +75,7 @@ def _setenv(envmap, dump=False): if dump: log.debug('Writing environment variable file') fh = open('.scullery_env', 'w') - for variable, vlaue in envmap.items(): + for variable, value in envmap.items(): if value is not None: if isinstance(value, list): value = ','.join(value) @@ -91,9 +85,9 @@ def _setenv(envmap, dump=False): if dump: fh.close() -def vagrant_env(box_name, box_image, minions=None, masters=None, vagrantfile=None): +def vagrant_env(box_name, box_image, minions=None, masters=None, vagrantfile=None, bootstrap=None): envmap = {'VAGRANT_VAGRANTFILE': vagrantfile, 'SCULLERY_BOX_NAME': box_name, 'SCULLERY_BOX_IMAGE': box_image, - 'SCULLERY_MASTERS': masters, 'SCULLERY_MINIONS': minions} + 'SCULLERY_MASTERS': masters, 'SCULLERY_MINIONS': minions, 'SCULLERY_BOOTSTRAP': bootstrap} log.debug('Environment variable map: {}'.format(str(envmap))) _setenv(envmap, args.env) v.env = env @@ -118,6 +112,12 @@ def vagrant_isup(suite): def main_interactive(): configmap = _config() box = configmap['box'] + 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'] suite = args.suite if suite not in suites: @@ -129,12 +129,12 @@ def main_interactive(): minions = genvms('minion', suiteconf['minions']) if suiteconf.get('masters', 0) > 0: masters = genvms('master', suiteconf['masters']) - vagrant_env(box['name'], box['image'], minions, masters, box['file']) + vagrant_env(box_name, box_image, minions, masters, box_file, box_bootstrap) if args.status: log.info('Status report: {}'.format(v.status())) return True status = vagrant_isup(suite) - if status[0] is True and status[1] is None: + if status[0] is True and status[1] is None or args.stop: if args.stop is True: log.info('Destroying machines ...') v.destroy() @@ -163,17 +163,30 @@ def main_interactive(): else: _abort('Start failed') +logging.basicConfig(format='%(asctime)s %(levelname)s - %(funcName)s: %(message)s', datefmt='%H:%M:%S') +log = logging.getLogger('scullery') + if __name__ == '__main__': - logging.basicConfig(format='%(asctime)s %(levelname)s - %(funcName)s: %(message)s', datefmt='%H:%M:%S') - log = logging.getLogger('scullery') log.setLevel(args.loglevel) log.debug(args) - if args.loglevel == logging.INFO: - log_stderr = True + if args.loglevel == logging.WARNING: + quiet_stderr = True else: - log_stderr = False - v = _vagrant(log_stderr) + quiet_stderr = False + log.debug('Vagrant stderr: {}'.format(str(quiet_stderr))) +try: + import vagrant +except ImportError as myerror: + _abort('Could not load python-vagrant') + +if os.path.isfile(configfile): + config.read(configfile) +else: + _abort('Unable to locate configuration file at {}'.format(configfile)) + +if __name__ == '__main__': + v = _vagrant(quiet_stderr) main_interactive() else: v = _vagrant()