diff --git a/mongodb_consistent_backup/Backup/Mongodump/MongodumpThread.py b/mongodb_consistent_backup/Backup/Mongodump/MongodumpThread.py index 18190949..d97cc698 100644 --- a/mongodb_consistent_backup/Backup/Mongodump/MongodumpThread.py +++ b/mongodb_consistent_backup/Backup/Mongodump/MongodumpThread.py @@ -30,9 +30,12 @@ def __init__(self, state, uri, timer, user, password, authdb, base_dir, binary, self.dump_gzip = dump_gzip self.verbose = verbose - self.timer_name = "%s-%s" % (self.__class__.__name__, self.uri.replset) - self.exit_code = 1 - self._command = None + self.timer_name = "%s-%s" % (self.__class__.__name__, self.uri.replset) + self.exit_code = 1 + self._command = None + self.do_stdin_passwd = False + self.stdin_passwd_sent = False + self.backup_dir = os.path.join(self.base_dir, self.uri.replset) self.dump_dir = os.path.join(self.backup_dir, "dump") self.oplog_file = os.path.join(self.dump_dir, "oplog.bson") @@ -61,6 +64,18 @@ def parse_mongodump_line(self, line): except: return None + def is_password_prompt(self, line): + if self.do_stdin_passwd and ("Enter Password:" in line or "reading password from standard input" in line): + return True + return False + + def handle_password_prompt(self): + if self.do_stdin_passwd and not self.stdin_passwd_sent: + logging.debug("Received password prompt from mongodump, writing password to stdin") + self._process.stdin.write(self.password + "\n") + self._process.stdin.flush() + self.stdin_passwd_sent = True + def wait(self): try: while self._process.stderr: @@ -69,7 +84,11 @@ def wait(self): for fd in poll[0]: read = self._process.stderr.readline() line = self.parse_mongodump_line(read) - if line: + if not line: + continue + elif self.is_password_prompt(read): + self.handle_password_prompt() + else: logging.info(line) if self._process.poll() != None: break @@ -92,7 +111,12 @@ def mongodump_cmd(self): logging.debug("Using database %s for authentication" % self.authdb) mongodump_flags.extend(["--authenticationDatabase", self.authdb]) if self.user and self.password: - mongodump_flags.extend(["-u", self.user, "-p", self.password]) + # >= 3.0.2 supports password input via stdin to mask from ps + if tuple("3.0.2".split(".")) <= tuple(self.version.split(".")): + mongodump_flags.extend(["-u", self.user, "-p", '""']) + self.do_stdin_passwd = True + else: + mongodump_flags.extend(["-u", self.user, "-p", self.password]) mongodump_cmd.extend(mongodump_flags) return mongodump_cmd @@ -109,7 +133,7 @@ def run(self): rmtree(self.dump_dir) os.makedirs(self.dump_dir) logging.debug("Running mongodump cmd: %s" % mongodump_cmd) - self._process = Popen(mongodump_cmd, stderr=PIPE) + self._process = Popen(mongodump_cmd, stdin=PIPE, stderr=PIPE) self.wait() self.exit_code = self._process.returncode if self.exit_code > 0: diff --git a/scripts/build.sh b/scripts/build.sh index ba45695e..2793a8e9 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -100,7 +100,7 @@ if [ -d ${srcdir} ]; then if [ ! -d ${pexdir} ]; then mkdir -p ${pexdir} else - find ${pexdir} -type f -name "${mod_name}-*.whl" -print -delete + find ${pexdir} -type f -name "${mod_name}-*.whl" -delete fi [ ! -d ${bindir} ] && mkdir -p ${bindir} ${venvdir}/bin/python2.7 ${venvdir}/bin/pex -o ${output_file} -m ${mod_name} -r ${require_file} --pex-root=${pexdir} ${builddir}