def _importenv(envfn): srcfn = envfn[:-4] rootdir = path.dirname(path.dirname(envfn)) deploydir = path.join(rootdir, 'deploy') envdir = path.join(deploydir, path.basename(srcfn)) if path.isdir(envdir): sh.rmtree(envdir) sh.makedirs(envdir) sh.chmod(envdir, 0o0700) log.msg("%s.zip: unpack" % srcfn) sh.unpack_archive(srcfn + '.zip', extract_dir=envdir, format='zip')
def _prune(env): dstdir = env.settings.get('service.munin_node', 'target.dir', fallback=path.join('etc', 'munin')) pl = env.settings.getlist('service.munin_node', 'prune.plugins', fallback=[]) for x in pl: x = path.normpath(x) fl = path.glob(path.join(dstdir, 'plugins', x)) for fn in fl: env.log("prune %s" % fn) path.unlink(fn)
def _synchome(env, user, homedir): cfgdir = env.settings.get('os', 'users.config.dir') dirmode = env.settings.getint('os', 'users.dirmode') filemode = env.settings.getint('os', 'users.filemode') srcdir = path.join(cfgdir, user) dstdir = path.join(homedir, user) if env.assets.isdir(cfgdir, user): env.log("sync %s -> %s" % (srcdir, dstdir)) builddir.sync(env, srcdir, dstdir, user=user, group=user, dirmode=dirmode, filemode=filemode)
def _jailLocalConf(env, cfgdir, destdir): fn = 'jail.local' if env.assets.isfile(cfgdir, fn): src = env.assets.name(cfgdir, fn) dst = path.join(destdir, fn) env.log("copy %s" % dst) builddir.copy(env, src, dst)
def _configureListen(env, cfg): cfgFiles = ( 'listen.cfg', env.assets.name(env.name(), 'listen.cfg'), ) cfgfn = None for fn in cfgFiles: if env.assets.isfile(fn): cfgfn = fn break if cfgfn is not None: env.log("enable sadm.listen %s" % cfgfn) env.session.set('sadm.listen.enable', True) # sync listen.cfg if not cfg.has_section('sync'): cfg.add_section('sync') cfg.set( 'sync', 'sadm.listen.config', "%s %s filemode:640 user:sadm" % (cfgfn, path.join(path.sep, 'etc', 'opt', 'sadm', 'listen.cfg'))) # os.pkg if not env.settings.has_section('os.pkg'): env.settings.add_section('os.pkg') if env.dist() == 'debian': env.settings.setlist('os.pkg', 'debian.sadm.listen.install', ( 'at', 'uwsgi-plugin-python3', 'ssl-cert', ))
def deploy(path): with repodir(path): if fpath.isdir('.sadm'): for sn in _deployScripts: script = fpath.join('.', '.sadm', sn) if fpath.isfile(script): callCheck(['/bin/sh', script])
def _syncConf(env, cfgdir, destdir): for dn in ('action.d', 'fail2ban.d', 'filter.d'): if env.assets.isdir(cfgdir, dn): src = env.assets.name(cfgdir, dn) dst = path.join(destdir, dn) env.log("sync %s" % dst) builddir.sync(env, src, dst)
def _prune(env, dbdir, htmldir, sect, domain, host): pl = env.settings.getlist(sect, host) for patt in pl: patt = path.normpath(patt) if domain.upper() == 'ALL': domain = '*' if host.upper() == 'ALL': host = '*' fl = path.glob(path.join(dbdir, domain, "%s-%s-*.rrd" % (host, patt))) fl.extend(path.glob(path.join(htmldir, domain, host, "%s.html" % patt))) fl.extend( path.glob(path.join(htmldir, domain, host, "%s-*.png" % patt))) for fn in fl: env.log("prune %s" % fn) path.unlink(fn)
def _jailEnable(env, cfgdir, destdir): jenable = env.settings.getlist('network.fail2ban', 'jail.enable') if env.assets.isdir(cfgdir, 'jail.d'): for jn in jenable: src = env.assets.name(cfgdir, 'jail.d', jn + '.conf') dst = path.join(destdir, 'jail.d', jn + '.conf') env.log("enable %s" % dst) builddir.copy(env, src, dst)
def _configureDeploy(env, cfg): if env.assets.isfile('deploy.cfg'): env.log('sync deploy.cfg') if not cfg.has_section('sync'): cfg.add_section('sync') cfg.set( 'sync', 'sadm.deploy.config', "deploy.cfg %s filemode=644" % path.join(path.sep, 'etc', 'opt', 'sadm', 'deploy.cfg'))
def configure(env, unit, typ, name, tpldat): service = "%s-%s.%s" % (unit, name, typ) with libdir.fopen('utils', 'systemd', "%s.%s" % (unit, typ)) as fh: data = fh.read() dst = path.join('etc', 'systemd', 'system', service) with builddir.create(env, dst) as fh: fh.write(data.format(**tpldat)) fh.flush()
def deploy(env): destdir = env.settings.get('network.fail2ban', 'config.destdir') jdisable = env.settings.getlist('network.fail2ban', 'jail.disable') for jn in jdisable: fn = path.join(destdir, 'jail.d', jn + '.conf') if path.isfile(fn): env.log("remove %s" % fn) path.unlink(fn) env.log("restart") systemd.restart('fail2ban')
def _zip(env): env.log("%s.zip" % env.name()) rdir = builddir.fpath(env, '.', meta = True) fn = builddir.fpath(env, '.') make_archive(fn, 'zip', root_dir = rdir, base_dir = '.', verbose = 1) h = sha256() with open(fn + '.zip', 'rb') as fh: h.update(fh.read()) with open(fn + '.env', 'x') as fh: fh.write("%s %s\n" % (h.hexdigest(), path.join(_destdir, 'env', env.name() + '.zip')))
def uwsgi(): cmd = [ 'uwsgi', '--need-plugin', 'python3', '--set-ph', "sadm-home=%s" % sys.exec_prefix, '--touch-reload', path.join(path.sep, 'etc', 'opt', 'sadm', 'listen.cfg'), '--touch-reload', libdir.fpath('listen', 'wsgi', 'uwsgi.ini'), '--safe-pidfile', path.join(path.sep, 'tmp', 'sadm.listen.uwsgi.pid'), '--ini', libdir.fpath('listen', 'wsgi', 'uwsgi.ini'), ] try: callCheck(cmd) except CommandError as err: return err.rc return 0
def main(args, sumode): log.debug("deploy %s sumode=%s" % (args.env, sumode)) if sumode == 'not': config = cfg.new(cfgfile=cfgfile) dn = config.get('deploy', 'rundir', fallback=path.join('~', '.local', 'sadm', 'deploy')) sh.makedirs(dn, mode=0o750, exists_ok=True) with sh.lockd(dn): env = Env('deploy', args.env, config) try: _check(_sumode(env, 'pre')) _check(_usermode(env)) _check(_sumode(env, 'post')) except CmdError as err: return err.code else: return cmd.run(args.env, sumode) return 39
def _buildListen(env): cfgfiles = ( (libdir.fpath('listen', 'wsgi', 'uwsgi.ini'), path.join(path.sep, 'etc', 'opt', 'sadm', 'listen', 'uwsgi.ini')), (libdir.fpath('listen', 'wsgi', 'uwsgi.service'), path.join(path.sep, 'etc', 'systemd', 'system', 'sadm-listen.service')), (libdir.fpath('listen', 'wsgi', 'apache.conf'), path.join(path.sep, 'etc', 'opt', 'sadm', 'listen', 'apache.conf')), (libdir.fpath('listen', 'wsgi', 'nginx.conf'), path.join(path.sep, 'etc', 'opt', 'sadm', 'listen', 'nginx.conf')), (libdir.fpath('listen', 'wsgi', 'lighttpd.conf'), path.join(path.sep, 'etc', 'opt', 'sadm', 'listen', 'lighttpd.conf')), (libdir.fpath('listen', 'fail2ban', 'filter.d', 'sadm-listen.conf'), path.join(path.sep, 'etc', 'fail2ban', 'filter.d', 'sadm-listen.conf')), (libdir.fpath('listen', 'fail2ban', 'jail.d', 'sadm-listen.conf'), path.join(path.sep, 'etc', 'fail2ban', 'jail.d', 'sadm-listen.conf')), ) for srcfn, dstfn in cfgfiles: env.log("create %s" % dstfn) with open(srcfn, 'r') as src: with builddir.create(env, dstfn) as dst: dst.write(src.read())
# Copyright (c) Jeremías Casteglione <*****@*****.**> # See LICENSE file. from _sadm.utils import path, systemd __all__ = ['deploy'] _cfgfn = path.join(path.sep, 'etc', 'opt', 'sadm', 'listen.cfg') # run as root at first pass sumode = 'pre' def deploy(env): # TODO: read config and check if it is enabled if path.isfile(_cfgfn): env.info("%s found" % _cfgfn) if systemd.status('sadm-listen', 'is-enabled') != 0: env.log('sadm-listen enable') systemd.enable('sadm-listen') if systemd.status('sadm-listen') != 0: env.log('sadm-listen restart') systemd.restart('sadm-listen')
# Copyright (c) Jeremías Casteglione <*****@*****.**> # See LICENSE file. import bottle from _sadm import libdir, log, version from _sadm.devops.wapp import cfg, errors, handlers from _sadm.devops.wapp.plugin.auth import AuthPlugin from _sadm.devops.wapp.session import session from _sadm.utils import path __all__ = ['init'] _wappcfg = libdir.fpath('devops', 'wapp', 'wapp.conf') _cfgfn = path.join(path.sep, 'etc', 'opt', 'sadm', 'devops.cfg') wapp = bottle.Bottle() def init(cfgfn=_cfgfn): config = cfg.new(cfgfn) log.init(config.get('sadm', 'log', fallback='error')) log.debug(version.string('sadm-devops')) log.debug("read config %s" % cfgfn) log.debug("bottle config %s" % _wappcfg) wapp.config.load_config(_wappcfg) tpldir = libdir.fpath('devops', 'wapp', 'tpl') log.debug("templates dir %s" % tpldir)
def _getURL(req): # ~ for k, v in req.headers.items(): # ~ log.debug("%s: %s" % (k, v)) u = urlparse(req.url) scheme = u.scheme if not scheme: # pragma: no cover scheme = 'http' port = u.port if not port: port = '3666' url = "%s://127.0.0.1:%s" % (scheme, port) log.debug("URL: %s" % url) return url _pycmd = path.join(sys.exec_prefix, 'bin', 'python3') _selfpath = libdir.fpath('listen', 'exec.py') def _sched(taskfn): log.debug("exec prefix %s" % sys.exec_prefix) cmd = [_pycmd, _selfpath, taskfn] atcmd = "echo '%s' | at now" % ' '.join(cmd) log.debug("run: %s" % atcmd) callCheck(atcmd) # # task exec main (runs under a new process) #
# Copyright (c) Jeremías Casteglione <*****@*****.**> # See LICENSE file. import json from hashlib import sha256 from shutil import make_archive from _sadm.utils import path, builddir __all__ = ['pre_build', 'post_build'] _destdir = path.join(path.sep, 'opt', 'sadm') def pre_build(env): env.build.create() def post_build(env): env.build.close() _checksum(env) _meta(env) _zip(env) def _checksum(env): env.log("%s.tar" % env.name()) fn = builddir.fpath(env, env.name() + '.tar', meta = True) h = sha256() with open(fn, 'rb') as fh: h.update(fh.read()) env.session.set('sadm.env.checksum', h.hexdigest())
def parse(name, **data): fn = "%s.html" % path.join(*name.split('/')) return bottle.template(fn, tpl=Template(name, data))