Dump early Scullery works
Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
This commit is contained in:
parent
2c8e6bb96f
commit
3bec65fae2
1
opensuse-salt-formulas/README.md
Normal file
1
opensuse-salt-formulas/README.md
Normal file
@ -0,0 +1 @@
|
||||
These files eventually became [Scullery](https://git.com.de/Georg/scullery).
|
66
opensuse-salt-formulas/Vagrantfile
vendored
Normal file
66
opensuse-salt-formulas/Vagrantfile
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.provider "libvirt"
|
||||
config.vm.box = "tumbleweed-salt"
|
||||
config.vm.box_url = "https://download.opensuse.org/repositories/home:/crameleon:/appliances/openSUSE_Tumbleweed/Tumbleweed.x86_64-libvirt.box"
|
||||
config.vm.provision "shell", env: {"APPLY" => ENV['APPLY']}, inline: <<-SHELL
|
||||
if [ ! -d /srv/formulas ]
|
||||
then
|
||||
mkdir /srv/formulas
|
||||
fi
|
||||
if [ ! -d /srv/pillar/samples ]
|
||||
then
|
||||
mkdir /srv/pillar/samples
|
||||
fi
|
||||
for formula in $(find /vagrant -mindepth 1 -maxdepth 1 -type d -name '*-formula' -printf '%P\\n')
|
||||
do
|
||||
echo "$formula"
|
||||
fname="${formula%%-*}"
|
||||
src_states="$formula/$fname"
|
||||
src_formula="/vagrant/$src_states"
|
||||
src_pillar="/vagrant/$formula/pillar.example"
|
||||
src_test_pillar="/vagrant/$formula/test/pillar/default.sls"
|
||||
if [ ! -d "$src_formula" ]
|
||||
then
|
||||
fname="${fname//_/-}"
|
||||
src_states="$formula/$fname"
|
||||
src_formula="/vagrant/$src_states"
|
||||
fi
|
||||
if [ ! -h "/srv/formulas/$fname" ]
|
||||
then
|
||||
ln -s "$src_formula" "/srv/formulas"
|
||||
fi
|
||||
dst_pillar="/srv/pillar/samples/$fname.sls"
|
||||
if [ -f "$src_test_pillar" ]
|
||||
then
|
||||
cp "$src_test_pillar" "$dst_pillar"
|
||||
elif [ -f "$src_pillar" ]
|
||||
then
|
||||
cp "$src_pillar" "$dst_pillar"
|
||||
fi
|
||||
done
|
||||
printf 'file_roots:\n base:\n - /srv/salt\n - /srv/formulas\n' > /etc/salt/minion.d/roots.conf
|
||||
tee /srv/pillar/top.sls >/dev/null <<EOF
|
||||
{{ saltenv }}:
|
||||
'*':
|
||||
- full
|
||||
EOF
|
||||
tee /srv/pillar/full.sls >/dev/null <<EOF
|
||||
include:
|
||||
- samples.*
|
||||
EOF
|
||||
echo "$APPLY"
|
||||
if [ -n "$APPLY" ]
|
||||
then
|
||||
salt-call --local state.apply "$APPLY"
|
||||
fi
|
||||
SHELL
|
||||
config.vm.define "masterless", primary: true do |vmconfig|
|
||||
vmconfig.vm.hostname = "saltomat"
|
||||
vmconfig.vm.provider :libvirt do |libvirt|
|
||||
libvirt.memory = 1024
|
||||
end
|
||||
end
|
||||
end
|
37
opensuse-salt-formulas/Vagrantfile-Master
Normal file
37
opensuse-salt-formulas/Vagrantfile-Master
Normal file
@ -0,0 +1,37 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.provider "libvirt"
|
||||
config.vm.box = "tumbleweed-salt"
|
||||
config.vm.box_url = "https://download.opensuse.org/repositories/home:/crameleon:/appliances/openSUSE_Tumbleweed/Tumbleweed.x86_64-libvirt.box"
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
# for some reason, Avahi DNS doesn't work until the network stack is restarted
|
||||
rcnetwork restart
|
||||
SHELL
|
||||
config.vm.define "master", primary: true do |master_config|
|
||||
master_config.vm.hostname = "salt-master"
|
||||
master_config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.memory = 768
|
||||
end
|
||||
master_config.vm.provision "shell", path: "bootstrap-salt-roots.sh"
|
||||
master_config.vm.provision "shell", 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
|
||||
systemctl enable --now salt-master
|
||||
SHELL
|
||||
end
|
||||
[
|
||||
"minion1",
|
||||
"minion2",
|
||||
].each do |vmname|
|
||||
config.vm.define "#{vmname}" do |minion_config|
|
||||
minion_config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
minion_config.vm.hostname = "salt-#{vmname}"
|
||||
minion_config.vm.provision "shell", inline: <<-SHELL
|
||||
sed -i 's/^#master:.*/master: salt-master/' /etc/salt/minion
|
||||
systemctl enable --now salt-minion
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
end
|
51
opensuse-salt-formulas/Vagrantfile-Template
Normal file
51
opensuse-salt-formulas/Vagrantfile-Template
Normal file
@ -0,0 +1,51 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
if ! ( ENV['SCULLERY_BOX_NAME'] && ENV['SCULLERY_BOX_IMAGE'] ) || ! ( ENV['SCULLERY_MASTERS'] || ENV['SCULLERY_MINIONS'] )
|
||||
print('Missing parameters')
|
||||
exit 1
|
||||
end
|
||||
|
||||
salt_bootstrap = "test/bootstrap-salt-roots.sh"
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.provider "libvirt"
|
||||
config.vm.box = ENV['SCULLERY_BOX_NAME']
|
||||
config.vm.box_url = ENV['SCULLERY_BOX_IMAGE']
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
# for some reason, Avahi DNS doesn't work until the network stack is restarted
|
||||
rcnetwork restart
|
||||
SHELL
|
||||
if ENV['SCULLERY_MASTERS']
|
||||
ENV['SCULLERY_MASTERS'].split(',').each do |vmname|
|
||||
config.vm.define "#{vmname}", primary: true do |master_config|
|
||||
master_config.vm.hostname = "#{vmname}"
|
||||
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
|
||||
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
|
||||
systemctl enable --now salt-master
|
||||
SHELL
|
||||
end
|
||||
end
|
||||
end
|
||||
if ENV['SCULLERY_MINIONS']
|
||||
ENV['SCULLERY_MINIONS'].split(',').each do |vmname|
|
||||
config.vm.define "#{vmname}" do |minion_config|
|
||||
minion_config.vm.hostname = "#{vmname}"
|
||||
if ENV['SCULLERY_MASTERS']
|
||||
minion_config.vm.synced_folder '.', '/vagrant', disabled: true
|
||||
minion_config.vm.provision "shell", inline: <<-SHELL
|
||||
sed -i 's/^#master:.*/master: scullery-master0/' /etc/salt/minion
|
||||
systemctl enable --now salt-minion
|
||||
SHELL
|
||||
else
|
||||
minion_config.vm.provision "shell", path: salt_bootstrap
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
166
opensuse-salt-formulas/scullery.py
Normal file
166
opensuse-salt-formulas/scullery.py
Normal file
@ -0,0 +1,166 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from configparser import ConfigParser
|
||||
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('--suite', help='Specify the suite to run', required=True)
|
||||
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('--status', help='Get Vagrant deployment status', action='store_true')
|
||||
|
||||
args = argparser.parse_args()
|
||||
config.read(args.config)
|
||||
|
||||
vmprefix = 'scullery'
|
||||
|
||||
def _abort(msg):
|
||||
log.error(msg)
|
||||
sys.exit(1)
|
||||
|
||||
def _config():
|
||||
configmap = {'box': {}, 'suites': {}}
|
||||
if not config.options('box'):
|
||||
_abort('No "box" section found in the configuration file')
|
||||
for option in config.options('box'):
|
||||
configmap['box'][option] = config.get('box', option)
|
||||
suites = [section for section in config.sections() if section.startswith('suite.')]
|
||||
if not len(suites):
|
||||
_abort('No suites configured')
|
||||
log.debug('Suites: {}'.format(str(suites)))
|
||||
for section in suites:
|
||||
suite = section.replace('suite.', '')
|
||||
configmap['suites'][suite] = {}
|
||||
for option in config.options(section):
|
||||
if option in ['masters', 'minions']:
|
||||
value = config.getint(section, option)
|
||||
else:
|
||||
value = config.get(section, option)
|
||||
configmap['suites'][suite][option] = value
|
||||
log.debug('Config map: {}'.format(str(configmap)))
|
||||
return configmap
|
||||
|
||||
def _vagrant(quiet=False):
|
||||
return vagrant.Vagrant(quiet_stdout=False, quiet_stderr=quiet)
|
||||
|
||||
def genvms(flavor, amount):
|
||||
vms = []
|
||||
for i in range(amount):
|
||||
vms.append('{}-{}{}'.format(vmprefix, flavor, i))
|
||||
return vms
|
||||
|
||||
def vagrant_env(box_name, box_image, minions=None, masters=None, vagrantfile=None):
|
||||
fh = open('.scullery_env', 'w')
|
||||
if vagrantfile is not None:
|
||||
env['VAGRANT_VAGRANTFILE'] = vagrantfile
|
||||
fh.write('VAGRANT_VAGRANTFILE={}\n'.format(vagrantfile))
|
||||
env['SCULLERY_BOX_NAME'] = box_name
|
||||
env['SCULLERY_BOX_IMAGE'] = box_image
|
||||
fh.write('SCULLERY_BOX_NAME={}\nSCULLERY_BOX_IMAGE={}\n'.format(box_name, box_image))
|
||||
if masters is not None:
|
||||
env_masters = ','.join(masters)
|
||||
env['SCULLERY_MASTERS'] = env_masters
|
||||
fh.write('SCULLERY_MASTERS={}\n'.format(env_masters))
|
||||
if minions is not None:
|
||||
env_minions = ','.join(minions)
|
||||
env['SCULLERY_MINIONS'] = env_minions
|
||||
fh.write('SCULLERY_MINIONS={}\n'.format(env_minions))
|
||||
#log.debug('Environment is: {}'.format(str(env)))
|
||||
fh.close()
|
||||
|
||||
v.env = env
|
||||
|
||||
def vagrant_isup(suite):
|
||||
ok = 0
|
||||
nok = 0
|
||||
statuses = v.status()
|
||||
total = len(statuses)
|
||||
for status in statuses:
|
||||
if status.state == 'running':
|
||||
ok += 1
|
||||
else:
|
||||
nok +=1
|
||||
if ok == total:
|
||||
return True, None
|
||||
elif nok == total:
|
||||
return False, True
|
||||
else:
|
||||
return False, False
|
||||
|
||||
def main_interactive():
|
||||
configmap = _config()
|
||||
box = configmap['box']
|
||||
suites = configmap['suites']
|
||||
suite = args.suite
|
||||
if suite not in suites:
|
||||
_abort('No suite named {}'.format(suite))
|
||||
suiteconf = configmap['suites'][suite]
|
||||
minions = None
|
||||
masters = None
|
||||
if suiteconf.get('minions', 0) > 0:
|
||||
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'])
|
||||
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 args.stop is True:
|
||||
log.info('Destroying machines ...')
|
||||
v.destroy()
|
||||
if vagrant_isup(suite)[0] is False:
|
||||
log.debug('OK')
|
||||
else:
|
||||
_abort('Destruction failed')
|
||||
else:
|
||||
log.info('Deployment is already running')
|
||||
elif status[0] is False:
|
||||
if status[1] is True:
|
||||
log.debug('Deployment is not running')
|
||||
elif status[1] is False:
|
||||
log.warning('Deployment is in an inconsistent state, destroying ...')
|
||||
try:
|
||||
v.destroy()
|
||||
except Exception as myerror:
|
||||
log.exception(myerror)
|
||||
_abort('Unhandled error')
|
||||
|
||||
if args.stop is False:
|
||||
log.info('Launching {} ...'.format(suite))
|
||||
v.up()
|
||||
if vagrant_isup(suite)[0] is True:
|
||||
log.debug('OK')
|
||||
else:
|
||||
_abort('Start failed')
|
||||
|
||||
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
|
||||
else:
|
||||
log_stderr = False
|
||||
v = _vagrant(log_stderr)
|
||||
|
||||
main_interactive()
|
||||
else:
|
||||
v = _vagrant()
|
Loading…
Reference in New Issue
Block a user