def generate_self_signed_certificate(): """ Generate self signed certificate for AKRR Rest API """ log.info("Generating self-signed certificate for REST-API") cmd = """ openssl req \ -new \ -newkey rsa:4096 \ -days 3650 \ -nodes \ -x509 \ -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=localhost" \ -keyout {akrr_cfg_dir}/server.key \ -out {akrr_cfg_dir}/server.cert cp {akrr_cfg_dir}/server.key {akrr_cfg_dir}/server.pem cat {akrr_cfg_dir}/server.cert >> {akrr_cfg_dir}/server.pem """.format(akrr_cfg_dir=os.path.join(_akrr_home, 'etc')) if not akrr.dry_run: output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) log.debug(output.decode("utf-8")) log.info(" new self-signed certificate have been generated") else: log.dry_run("run command: " + cmd)
def _remove_user(): """remove user from dbs""" dbs = get_akrr_db(su=True), get_ak_db(su=True), get_xd_db(su=True) users = cfg.akrr_db_user, cfg.ak_db_user, cfg.xd_db_user for user, (db, cur) in zip(users, dbs): # see if user exists cur.execute("SELECT * FROM mysql.user WHERE user = %s", (user,)) records = cur.fetchall() for rec in records: log.info("Removing %s@%s from %s ", rec["User"], rec["Host"], str(db)) msg = "DRY RUN:\n" if dry_run else "" msg = msg + "SQL(%s): " % (str(db),) msg = msg + "DROP USER %s@%s" % (rec["User"], rec["Host"]) if dry_run: log.info(msg) else: log.dry_run(msg) if dry_run: continue # remove user cur.execute("DROP USER %s@%s", (rec["User"], rec["Host"])) db.commit() if len(records) == 0: log.info("There is no user with name %s on %s ", user, str(db)) for db, cur in dbs: cur.close() db.close()
def _make_dirs(path): """Recursively create directories if not in dry run mode""" if not dry_run: log.debug("Creating directory: {}".format(path)) os.makedirs(path) else: log.dry_run("_make_dirs({})".format(path))
def check_appsig(rsh, resource): log.info("Testing app.signature calculator on headnode\n") out = akrr.util.ssh.ssh_command( rsh, "%s/execs/bin/appsigcheck.sh `which md5sum`" % (resource['appkernel_dir'], )) if out.count("===ExeBinSignature===") > 0 and out.count("MD5:") > 0: log.info("App.signature calculator is working on headnode\n") else: if akrr.dry_run: log.dry_run("App.signature calculator is not working\n") return log.error( "App.signature calculator is not working\n" + "See full error report below\n%s", out) exit(1)
def cursor_execute(cur, query, args=None, dry_run=False): """Execute database affecting command if not in dry run mode""" if not dry_run: cur.execute(query, args) else: from akrr.util import log if args is not None: if isinstance(args, dict): args = dict((key, cur.connection.literal(item)) for key, item in args.items()) else: args = tuple(map(cur.connection.literal, args)) query = query % args log.dry_run("SQL: " + query)
def drop_db(db, cur, db_name, dry_run=False): """remove dbname database from db,cur connection""" from akrr.util import log cur.execute("SHOW databases") databases = cur.fetchall() if db_name in {v["Database"] for v in databases}: log.info("Removing %s database from %s ", db_name, str(db)) msg = "SQL(%s): " % (str(db), ) msg = msg + "DROP DATABASE IF EXISTS %s" % (db_name, ) if dry_run: log.dry_run(msg) if dry_run: return # remove user cur.execute("DROP DATABASE IF EXISTS %s" % (db_name, )) db.commit() else: log.info("Database %s is not present on %s ", db_name, str(db))
def make_dirs(path, verbose=True): """ Recursively create directories if not in dry run mode """ import akrr from akrr import akrrerror import os from akrr.util import log if not akrr.dry_run: if os.path.isdir(path): if verbose: log.debug2("Directory %s already exists.", path) elif not os.path.exists(path): if verbose: log.debug2("Creating directory: {}".format(path)) os.makedirs(path, mode=0o755) else: raise akrrerror.AkrrError( "Can not create directory %s, because it exists and is not directory" % path) else: log.dry_run("make_dirs(%s)", path)
def cursor_execute(cur, query, args=None, dry_run=None): """Execute database affecting command if not in dry run mode""" if dry_run is None: import akrr dry_run = akrr.dry_run sql_command = query.split() sql_command = sql_command[0].lower() if len(sql_command) > 0 else "UNKNOWN" sql_non_modified_command = sql_command in ('select', 'show') if log.verbose or dry_run: if args is not None: if isinstance(args, dict): args_filled = dict((key, cur.connection.literal(item)) for key, item in args.items()) else: args_filled = tuple(map(cur.connection.literal, args)) query_filled = query % args_filled else: query_filled = query if dry_run: log.dry_run("SQL: " + query_filled) else: log.debug("SQL: " + query_filled) if sql_non_modified_command or not dry_run: cur.execute(query, args)
def _stop_akrr(): akrr_daemon_pids = _get_akrr_pids() if akrr_daemon_pids is None: log.info("AKRR daemon is not running.") return log.info("AKRR daemon is running, trying to stop it.") try: if os.path.exists(os.path.join(cfg.which_akrr)): cmd = "{} {} daemon stop".format(sys.executable, cfg.which_akrr) if not dry_run: subprocess.check_output( cmd, shell=True, timeout=60) else: log.dry_run("should execute: " + cmd) except subprocess.CalledProcessError: pass akrr_daemon_pids = _get_akrr_pids() if akrr_daemon_pids is None: return try: for pid in akrr_daemon_pids: cmd = "kill -9 {}".format(pid) if not dry_run: subprocess.check_output( cmd, shell=True, timeout=60) else: log.dry_run("should execute: " + cmd) except subprocess.CalledProcessError: pass akrr_daemon_pids = _get_akrr_pids() if akrr_daemon_pids is None: return if dry_run: log.dry_run("at this point AKRR daemon should be stopped") return raise Exception("was not able to stop AKRR daemon")
def install_cron_scripts(self): """ Install cron scripts. """ log.info("Installing cron entries") if akrr.dry_run: return if self.cron_email: mail = "MAILTO = " + self.cron_email else: mail = None restart = '50 23 * * * bash -l -c "' + _akrr_bin_dir + '/akrr daemon restart -cron"' check_and_restart = '33 * * * * bash -l "' + _akrr_bin_dir + '/akrr daemon checknrestart -cron"' archive = '43 1 * * * bash -l -c "' + _akrr_bin_dir + '/akrr archive -cron"' try: crontab_content = subprocess.check_output("crontab -l", shell=True) crontab_content = crontab_content.decode("utf-8").splitlines(True) except Exception: log.info("Crontab does not have user's crontab yet") crontab_content = [] mail_updated = False mail_there = False restart_there = False check_and_restart_there = False archive_there = False for i in range(len(crontab_content)): tmpstr = crontab_content[i] if len(tmpstr.strip()) > 1 and tmpstr.strip()[0] != "#": m = re.match(r'^MAILTO\s*=\s*(.*)', tmpstr.strip()) if m: cron_email = m.group(1) cron_email = cron_email.replace('"', '') mail_there = True if self.cron_email != cron_email: if mail: crontab_content[i] = mail else: crontab_content[i] = "#" + crontab_content[i] mail_updated = True if tmpstr.count("akrr") and tmpstr.count( "daemon") and tmpstr.count("restart") > 0: restart_there = True if tmpstr.count("akrr") and tmpstr.count( "daemon") and tmpstr.count("checknrestart") > 0: check_and_restart_there = True if tmpstr.count("akrr") and tmpstr.count( "daemon") and tmpstr.count("archive") > 0: archive_there = True if mail_updated: log.info("Cron's MAILTO was updated") if ((self.cron_email is not None and mail_there) or ( self.cron_email is None and mail_there is False)) and restart_there and check_and_restart_there \ and mail_updated is False: log.warning( "All AKRR crond entries found. No modifications necessary.") return if self.cron_email is not None and mail_there is False: crontab_content.insert(0, mail + "\n") if restart_there is False: crontab_content.append(restart + "\n") if check_and_restart_there is False: crontab_content.append(check_and_restart + "\n") if archive_there is False: crontab_content.append(archive + "\n") tmp_cronfile_fd, tmp_cronfile = mkstemp(prefix="crontmp", dir=os.path.expanduser('~'), text=True) if not akrr.dry_run: with open(tmp_cronfile_fd, 'wt') as f: for tmp_str in crontab_content: f.write(tmp_str) subprocess.call("crontab " + tmp_cronfile, shell=True) os.remove(tmp_cronfile) log.info("Crontab updated.") else: log.dry_run("For removing old AKRR should update crontab to:\n" + "".join(crontab_content))
def generate_settings_file(self) -> dict: """ Generate configuration (akrr.conf) file Return dictionary with configuration """ log.info("Generating configuration file ...") with open(os.path.join(_akrr_mod_dir, 'templates', 'akrr.conf'), 'r') as f: akrr_inp_template = f.read() if not self.update: restapi_rw_password = self.get_random_password() restapi_ro_password = self.get_random_password() else: restapi_rw_password = self.update.old_cfg['restapi_rw_password'] restapi_ro_password = self.update.old_cfg['restapi_ro_password'] cfg = { 'akrr_db_host': '"%s"' % self.akrr_db_host, 'akrr_db_port': '%s' % str(self.akrr_db_port), 'akrr_db_user_name': '"%s"' % self.akrr_db_user_name, 'akrr_db_user_password': '******' % self.akrr_db_user_password, 'akrr_db_name': '"%s"' % self.akrr_db_name, 'ak_db_name': '"%s"' % self.ak_db_name, 'xd_db_name': '"%s"' % self.xd_db_name, 'restapi_host': "localhost", 'restapi_port': 8091, 'restapi_apiroot': '/api/v1', 'restapi_certfile': 'server.pem', 'restapi_token_expiration_time': 3600, 'restapi_rw_username': '******', 'restapi_rw_password': restapi_rw_password, 'restapi_ro_username': '******', 'restapi_ro_password': restapi_ro_password, 'data_dir': "../log/data", 'completed_tasks_dir': "../log/comptasks", 'max_task_handlers': 4, 'task_pickling_protocol': 0, 'scheduled_tasks_loop_sleep_time': 1.0, 'max_fatal_errors_for_task': 10, 'active_task_default_attempt_repeat': 'datetime.timedelta(minutes=30)', 'max_wall_time_for_task_handlers': 'datetime.timedelta(minutes=30)', 'repeat_after_forcible_termination': 'active_task_default_attempt_repeat', 'max_fails_to_submit_to_the_queue': 48, 'repeat_after_fails_to_submit_to_the_queue': 'datetime.timedelta(hours=1)', 'max_time_in_queue': 'datetime.timedelta(days=10)', 'export_db_repeat_attempt_in': 'datetime.timedelta(hours=1)', 'export_db_max_repeat_attempts': 48, 'default_task_params': "{'test_run': False}", 'akrr_version': akrrversion } if self.akrr_db_host == self.ak_db_host and self.akrr_db_port == self.ak_db_port and \ self.akrr_db_user_name == self.ak_db_user_name and \ self.akrr_db_user_password == self.ak_db_user_password: cfg.update({ 'ak_db_host': 'akrr_db_host', 'ak_db_port': 'akrr_db_port', 'ak_db_user_name': 'akrr_db_user', 'ak_db_user_password': '******' }) else: cfg.update({ 'ak_db_host': '"%s"' % self.ak_db_host, 'ak_db_port': '%s' % str(self.ak_db_port), 'ak_db_user_name': '"%s"' % self.ak_db_user_name, 'ak_db_user_password': '******' % self.ak_db_user_password }) if self.xd_db_host == self.akrr_db_host and self.xd_db_port == self.akrr_db_port and \ self.xd_db_user_name == self.akrr_db_user_name and \ self.xd_db_user_password == self.akrr_db_user_password: cfg.update({ 'xd_db_host': 'akrr_db_host', 'xd_db_port': 'akrr_db_port', 'xd_db_user_name': 'akrr_db_user', 'xd_db_user_password': '******', }) elif self.xd_db_host == self.ak_db_host and self.xd_db_port == self.ak_db_port and \ self.xd_db_user_name == self.ak_db_user_name and \ self.xd_db_user_password == self.ak_db_user_password: cfg.update({ 'xd_db_host': 'ak_db_host', 'xd_db_port': 'ak_db_port', 'xd_db_user_name': 'ak_db_user', 'xd_db_user_password': '******', }) else: cfg.update({ 'xd_db_host': '"%s"' % self.xd_db_host, 'xd_db_port': '%s' % str(self.xd_db_port), 'xd_db_user_name': '"%s"' % self.xd_db_user_name, 'xd_db_user_password': '******' % self.xd_db_user_password, }) if self.update: cfg['restapi_host'] = self.update.old_cfg['restapi_host'] cfg['restapi_port'] = self.update.old_cfg['restapi_port'] cfg['restapi_apiroot'] = self.update.old_cfg['restapi_apiroot'] cfg['restapi_certfile'] = self.update.old_cfg['restapi_certfile'] cfg['restapi_token_expiration_time'] = self.update.old_cfg[ 'restapi_token_expiration_time'] cfg['restapi_rw_username'] = self.update.old_cfg[ 'restapi_rw_username'] cfg['restapi_rw_password'] = self.update.old_cfg[ 'restapi_rw_password'] cfg['restapi_ro_username'] = self.update.old_cfg[ 'restapi_ro_username'] cfg['restapi_ro_password'] = self.update.old_cfg[ 'restapi_ro_password'] #cfg['data_dir'] = self.update.old_cfg['data_dir'] #cfg['completed_tasks_dir'] = self.update.old_cfg['completed_tasks_dir'] cfg['max_task_handlers'] = self.update.old_cfg['max_task_handlers'] cfg['task_pickling_protocol'] = self.update.old_cfg[ 'task_pickling_protocol'] cfg['scheduled_tasks_loop_sleep_time'] = self.update.old_cfg[ 'scheduled_tasks_loop_sleep_time'] cfg['max_fatal_errors_for_task'] = self.update.old_cfg[ 'max_fatal_errors_for_task'] cfg['active_task_default_attempt_repeat'] = repr( self.update.old_cfg['active_task_default_attempt_repeat']) cfg['max_wall_time_for_task_handlers'] = repr( self.update.old_cfg['max_wall_time_for_task_handlers']) cfg['repeat_after_forcible_termination'] = repr( self.update.old_cfg['repeat_after_forcible_termination']) cfg['max_fails_to_submit_to_the_queue'] = self.update.old_cfg[ 'max_fails_to_submit_to_the_queue'] cfg['repeat_after_fails_to_submit_to_the_queue'] = repr( self.update. old_cfg['repeat_after_fails_to_submit_to_the_queue']) cfg['max_time_in_queue'] = repr( self.update.old_cfg['max_time_in_queue']) cfg['export_db_repeat_attempt_in'] = repr( self.update.old_cfg['export_db_repeat_attempt_in']) cfg['export_db_max_repeat_attempts'] = self.update.old_cfg[ 'export_db_max_repeat_attempts'] cfg['default_task_params'] = repr( self.update.old_cfg['default_task_params']) if cfg['repeat_after_forcible_termination'] == cfg[ 'active_task_default_attempt_repeat']: cfg['repeat_after_forcible_termination'] = 'active_task_default_attempt_repeat' akrr_inp = akrr_inp_template.format(**cfg) if not akrr.dry_run: with open(_akrr_cfg, 'w') as f: f.write(akrr_inp) log.info("Configuration is written to: {0}".format(_akrr_cfg)) else: log.dry_run( "New config should be written to: {}".format(_akrr_cfg)) log.debug2(akrr_inp) # reset data_dir completed_tasks_dir as absolute path for further use during setup/update if not os.path.isabs(cfg['data_dir']): cfg['data_dir'] = os.path.abspath( os.path.join(os.path.dirname(_akrr_cfg), cfg['data_dir'])) if not os.path.isabs(cfg['completed_tasks_dir']): cfg['completed_tasks_dir'] = os.path.abspath( os.path.join(os.path.dirname(_akrr_cfg), cfg['completed_tasks_dir'])) return cfg
def generate_settings_file(self): """ Generate configuration (akrr.conf) file """ log.info("Generating configuration file ...") with open(os.path.join(akrr_mod_dir, 'templates', 'akrr.conf'), 'r') as f: akrr_inp_template = f.read() restapi_rw_password = self.get_random_password() restapi_ro_password = self.get_random_password() var = { 'akrr_db_host': '"%s"' % self.akrr_db_host, 'akrr_db_port': '%s' % str(self.akrr_db_port), 'akrr_db_user_name': '"%s"' % self.akrr_db_user_name, 'akrr_db_user_password': '******' % self.akrr_db_user_password, 'akrr_db_name': '"%s"' % self.akrr_db_name, 'ak_db_name': '"%s"' % self.ak_db_name, 'xd_db_name': '"%s"' % self.xd_db_name, 'restapi_rw_password': restapi_rw_password, 'restapi_ro_password': restapi_ro_password } if self.akrr_db_host == self.ak_db_host and self.akrr_db_port == self.ak_db_port and \ self.akrr_db_user_name == self.ak_db_user_name and \ self.akrr_db_user_password == self.ak_db_user_password: var.update({ 'ak_db_host': 'akrr_db_host', 'ak_db_port': 'akrr_db_port', 'ak_db_user_name': 'akrr_db_user', 'ak_db_user_password': '******' }) else: var.update({ 'ak_db_host': '"%s"' % self.ak_db_host, 'ak_db_port': '%s' % str(self.ak_db_port), 'ak_db_user_name': '"%s"' % self.ak_db_user_name, 'ak_db_user_password': '******' % self.ak_db_user_password }) if self.xd_db_host == self.akrr_db_host and self.xd_db_port == self.akrr_db_port and \ self.xd_db_user_name == self.akrr_db_user_name and \ self.xd_db_user_password == self.akrr_db_user_password: var.update({ 'xd_db_host': 'akrr_db_host', 'xd_db_port': 'akrr_db_port', 'xd_db_user_name': 'akrr_db_user', 'xd_db_user_password': '******', }) elif self.xd_db_host == self.ak_db_host and self.xd_db_port == self.ak_db_port and \ self.xd_db_user_name == self.ak_db_user_name and \ self.xd_db_user_password == self.ak_db_user_password: var.update({ 'xd_db_host': 'ak_db_host', 'xd_db_port': 'ak_db_port', 'xd_db_user_name': 'ak_db_user', 'xd_db_user_password': '******', }) else: var.update({ 'xd_db_host': '"%s"' % self.xd_db_host, 'xd_db_port': '%s' % str(self.xd_db_port), 'xd_db_user_name': '"%s"' % self.xd_db_user_name, 'xd_db_user_password': '******' % self.xd_db_user_password, }) akrr_inp = akrr_inp_template.format(**var) if not dry_run: with open(akrr_cfg, 'w') as f: f.write(akrr_inp) log.info("Configuration is written to: {0}".format(akrr_cfg)) else: log.dry_run("New config should be written to: {}".format(akrr_cfg)) log.debug2(akrr_inp)