def proc_sympa_remove(request): """Execute the request for removing a sympa mailing list. @type request: ?? @param request: A dict-like object containing all the parameters for sympa list removal. """ try: state = pickle.loads(str(request["state_data"])) except: logger.exception("Corrupt request state for sympa request %s: %s", request["request_id"], request["state_data"]) return True try: listname = state["listname"] host = state["run_host"] except KeyError: logger.error("No listname/runhost specified for request %s", request["request_id"]) return True cmd = [cereconf.SYMPA_SCRIPT, host, 'rmlist', listname] return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
def delete_user(uname, old_host, old_home, operator, mail_server): account = get_account(name=uname) generation = account.get_trait(const.trait_account_generation) if generation: generation = generation['numval'] + 1 else: generation = 1 args = [ SUDO_CMD, cereconf.RMUSER_SCRIPT, '--username', account.account_name, '--deleted-by', operator, '--homedir', old_home, '--generation', str(generation) ] if DEBUG: args.append('--debug') cmd = SSH_CEREBELLUM + [" ".join(args), ] if Utils.spawn_and_log_output(cmd, connect_to=[old_host]) == EXIT_SUCCESS: account.populate_trait(const.trait_account_generation, numval=generation) account.write_db() return True return False
def archive_cyrus_data(uname, mail_server, generation): args = [ SUDO_CMD, cereconf.ARCHIVE_MAIL_SCRIPT, '--server', mail_server, '--user', uname, '--gen', str(generation) ] if DEBUG: args.append('--debug') cmd = SSH_CEREBELLUM + [" ".join(args), ] return ( Utils.spawn_and_log_output(cmd, connect_to=[mail_server]) == EXIT_SUCCESS)
def move_user(uname, uid, gid, old_host, old_disk, new_host, new_disk, operator): args = [SUDO_CMD, cereconf.MVUSER_SCRIPT, '--user', uname, '--uid', str(uid), '--gid', str(gid), '--old-disk', old_disk, '--new-disk', new_disk, '--operator', operator] if DEBUG: args.append('--debug') cmd = SSH_CEREBELLUM + [" ".join(args), ] return (Utils.spawn_and_log_output(cmd, connect_to=[old_host, new_host]) == EXIT_SUCCESS)
def proc_sympa_create(request): """Execute the request for creating a sympa mailing list. :type request: db_row :param request: A dict-like object describing the sympa list creation request. """ try: listname = get_address(request["entity_id"]) except Errors.NotFoundError: logger.info("Sympa list address id:%s is deleted! No need to create", request["entity_id"]) return True try: state = json.loads(request["state_data"]) except ValueError: state = None # Remove this when there's no chance of pickled data if state is None: try: state = pickle.loads(request["state_data"]) except Exception: pass if state is None: logger.error("Cannot parse request state for sympa list=%s: %s", listname, request["state_data"]) return True try: host = state["runhost"] profile = state["profile"] description = state["description"] admins = state["admins"] admins = ",".join(admins) except KeyError: logger.error("No host/profile/description specified for sympa list %s", listname) return True # 2008-08-01 IVR FIXME: Safe quote everything fished out from state. cmd = [ cereconf.SYMPA_SCRIPT, host, 'newlist', listname, admins, profile, description ] return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
def proc_sympa_create(request): """Execute the request for creating a sympa mailing list. :type request: db_row :param request: A dict-like object describing the sympa list creation request. """ try: listname = get_address(request["entity_id"]) except Errors.NotFoundError: logger.info("Sympa list address id:%s is deleted! No need to create", request["entity_id"]) return True try: state = json.loads(request["state_data"]) except ValueError: state = None # Remove this when there's no chance of pickled data if state is None: try: state = pickle.loads(request["state_data"]) except Exception: pass if state is None: logger.error("Cannot parse request state for sympa list=%s: %s", listname, request["state_data"]) return True try: host = state["runhost"] profile = state["profile"] description = state["description"] admins = state["admins"] admins = ",".join(admins) except KeyError: logger.error("No host/profile/description specified for sympa list %s", listname) return True # 2008-08-01 IVR FIXME: Safe quote everything fished out from state. cmd = [cereconf.SYMPA_SCRIPT, host, 'newlist', listname, admins, profile, description] return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
def proc_sympa_create(request): """Execute the request for creating a sympa mailing list. @type request: ?? @param request: An object describing the sympa list creation request. """ try: listname = get_address(request["entity_id"]) except Errors.NotFoundError: logger.warn("Sympa list address id:%s is deleted! No need to create", request["entity_id"]) return True try: state = pickle.loads(str(request["state_data"])) except: logger.exception("Corrupt request state for sympa list=%s: %s", listname, request["state_data"]) return True try: host = state["runhost"] profile = state["profile"] description = state["description"] admins = state["admins"] admins = ",".join(admins) except KeyError: logger.error("No host/profile/description specified for sympa list %s", listname) return True # 2008-08-01 IVR FIXME: Safe quote everything fished out from state. cmd = [cereconf.SYMPA_SCRIPT, host, 'newlist', listname, admins, profile, description] return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
def proc_sympa_remove(request): """Execute the request for removing a sympa mailing list. :type request: db_row :param request: A dict-like object containing all the parameters for sympa list removal. """ try: state = json.loads(request["state_data"]) except ValueError: state = None # Remove this when there's no chance of pickled data if state is None: try: state = pickle.loads(request["state_data"]) except Exception: pass if state is None: logger.error("Cannot parse request state for sympa request %s: %s", request["request_id"], request["state_data"]) return True try: listname = state["listname"] host = state["run_host"] except KeyError: logger.error("No listname/runhost specified for request %s", request["request_id"]) return True cmd = [cereconf.SYMPA_SCRIPT, host, 'rmlist', listname] return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
def email_move_child(host, r): local_db = Utils.Factory.get('Database')() local_co = Utils.Factory.get('Constants')(local_db) r_id = r['request_id'] if not is_valid_request(r_id, local_db=local_db, local_co=local_co): return if dependency_pending(r['state_data'], local_db=local_db, local_co=local_co): logger.debug("Request '%d' still has deps: '%s'.", r_id, r['state_data']) return try: acc = get_account(r['entity_id'], local_db=local_db) except Errors.NotFoundError: logger.error("email_move: user %d not found", r['entity_id']) return old_server = get_email_server(r['entity_id'], local_db=local_db) new_server = Email.EmailServer(local_db) new_server.find(r['destination_id']) if old_server.entity_id == new_server.entity_id: logger.error("Trying to move %s from " % acc.account_name + "and to the same server! Deleting request") br = BofhdRequests(local_db, local_co) br.delete_request(request_id=r_id) local_db.commit() return if not email_delivery_stopped(acc.account_name): logger.debug("E-mail delivery not stopped for %s", acc.account_name) return logger.debug("User being moved: '%s'.", acc.account_name) reqlock = RequestLockHandler() if not reqlock.grab(r_id): return # Disable quota while copying so the move doesn't fail cyrus_set_quota(acc.entity_id, 0, host=new_server, local_db=local_db) # Call the script cmd = [SSH_CMD, "cerebrum@%s" % host, cereconf.IMAPSYNC_SCRIPT, '--user1', acc.account_name, '--host1', old_server.name, '--user2', acc.account_name, '--host2', new_server.name, '--authusing', cereconf.CYRUS_ADMIN, '--passfile1', '/etc/cyrus.pw', '--useheader', 'Message-ID', '--regexmess', 's/\\0/ /g', '--ssl', '--subscribe', '--nofoldersizes'] proc = subprocess.Popen(cmd, capturestderr=True, bufsize=10240, close_fds=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) pid = proc.pid logger.debug("Called cmd(%d): '%s'", pid, cmd) proc.stdin.close() # Stolen from Utils.py:spawn_and_log_output() descriptor = {proc.stdout: logger.debug, proc.stderr: logger.info} while descriptor: # select() is called for _every_ line, since we can't inspect # the buffering in Python's file object. This works OK since # select() will return "readable" for an unread EOF, and # Python won't read the EOF until the buffers are exhausted. ready, x, x = select(descriptor.keys(), [], []) for fd in ready: line = fd.readline() if line == '': fd.close() del descriptor[fd] else: descriptor[fd]("[%d] %s" % (pid, line.rstrip())) status = proc.wait() if status == EXIT_SUCCESS: logger.debug("[%d] Completed successfully", pid) elif os.WIFSIGNALED(status): # The process was killed by a signal. sig = os.WTERMSIG(status) logger.warning('[%d] Command "%r" was killed by signal %d', pid, cmd, sig) return else: # The process exited with an exit status sig = os.WSTOPSIG(status) logger.warning("[%d] Return value was %d from command %r", pid, sig, cmd) return # Need move SIEVE filters as well cmd = [cereconf.MANAGESIEVE_SCRIPT, '-v', '-a', cereconf.CYRUS_ADMIN, '-p', pwfile, acc.account_name, old_server.name, new_server.name] if Utils.spawn_and_log_output( cmd, connect_to=[old_server.name, new_server.name]) != 0: logger.warning('%s: managesieve_sync failed!', acc.account_name) return logger.info('%s: managesieve_sync completed successfully', acc.account_name) # The move was successful, update the user's server # Now set the correct quota. hq = get_email_hardquota(acc.entity_id, local_db=local_db) cyrus_set_quota(acc.entity_id, hq, host=new_server, local_db=local_db) et = Email.EmailTarget(local_db) et.find_by_target_entity(acc.entity_id) et.email_server_id = new_server.entity_id et.write_db() # We need to delete this request before adding the # delete to avoid triggering the conflicting request # test. br = BofhdRequests(local_db, local_co) br.delete_request(request_id=r_id) local_db.commit() br.add_request(r['requestee_id'], r['run_at'], local_co.bofh_email_delete, r['entity_id'], old_server.entity_id) local_db.commit() logger.info("%s: move_email success.", acc.account_name) reqlock.release()