def testObfuscatedCommand(self): cmd = ['echo', util.Obfuscated('password', '*******')] self.failUnlessEqual(['echo', 'password'], util.Obfuscated.get_real(cmd)) self.failUnlessEqual(['echo', '*******'], util.Obfuscated.get_fake(cmd))
def testCommandEncodingObfuscated(self): b = FakeSlaveBuilder(False, self.basedir) s = runprocess.RunProcess(b, [ bsutil.Obfuscated(u'abcd', u'ABCD') ], self.basedir) self.assertIsInstance(s.command[0], str) self.assertIsInstance(s.fake_command[0], str)
def obfus(w): if (isinstance(w, tuple) and len(w) == 3 and w[0] == 'obfuscated'): return util.Obfuscated(w[1], w[2]) return w
def __init__(self, builder, command, workdir, environ=None, sendStdout=True, sendStderr=True, sendRC=True, timeout=None, maxTime=None, initialStdin=None, keepStdout=False, keepStderr=False, logEnviron=True, logfiles={}, usePTY="slave-config", useProcGroup=True, user=None): """ @param keepStdout: if True, we keep a copy of all the stdout text that we've seen. This copy is available in self.stdout, which can be read after the command has finished. @param keepStderr: same, for stderr @param usePTY: "slave-config" -> use the SlaveBuilder's usePTY; otherwise, true to use a PTY, false to not use a PTY. @param useProcGroup: (default True) use a process group for non-PTY process invocations """ self.builder = builder if isinstance(command, list): command = [ util.Obfuscated(w[1], w[2]) if (isinstance(w, tuple) and len(w) == 3 and w[0] == 'obfuscated') else w for w in command ] # We need to take unicode commands and arguments and encode them using # the appropriate encoding for the slave. This is mostly platform # specific, but can be overridden in the slave's buildbot.tac file. # # Encoding the command line here ensures that the called executables # receive arguments as bytestrings encoded with an appropriate # platform-specific encoding. It also plays nicely with twisted's # spawnProcess which checks that arguments are regular strings or # unicode strings that can be encoded as ascii (which generates a # warning). def to_str(cmd): if isinstance(cmd, (tuple, list)): for i, a in enumerate(cmd): if isinstance(a, unicode): cmd[i] = a.encode(self.builder.unicode_encoding) elif isinstance(cmd, unicode): cmd = cmd.encode(self.builder.unicode_encoding) return cmd self.command = to_str(util.Obfuscated.get_real(command)) self.fake_command = to_str(util.Obfuscated.get_fake(command)) self.sendStdout = sendStdout self.sendStderr = sendStderr self.sendRC = sendRC self.logfiles = logfiles self.workdir = workdir self.process = None if not os.path.exists(workdir): os.makedirs(workdir) if environ: for key, v in environ.iteritems(): if isinstance(v, list): # Need to do os.pathsep translation. We could either do that # by replacing all incoming ':'s with os.pathsep, or by # accepting lists. I like lists better. # If it's not a string, treat it as a sequence to be # turned in to a string. environ[key] = os.pathsep.join(environ[key]) if environ.has_key('PYTHONPATH'): environ['PYTHONPATH'] += os.pathsep + "${PYTHONPATH}" # do substitution on variable values matching pattern: ${name} p = re.compile('\${([0-9a-zA-Z_]*)}') def subst(match): return os.environ.get(match.group(1), "") newenv = {} for key in os.environ.keys(): # setting a key to None will delete it from the slave environment if key not in environ or environ[key] is not None: newenv[key] = os.environ[key] for key, v in environ.iteritems(): if v is not None: if not isinstance(v, basestring): raise RuntimeError("'env' values must be strings or " "lists; key '%s' is incorrect" % (key, )) newenv[key] = p.sub(subst, v) self.environ = newenv else: # not environ self.environ = os.environ.copy() self.initialStdin = initialStdin self.logEnviron = logEnviron self.timeout = timeout self.ioTimeoutTimer = None self.maxTime = maxTime self.maxTimeoutTimer = None self.killTimer = None self.keepStdout = keepStdout self.keepStderr = keepStderr self.buffered = deque() self.buflen = 0 self.sendBuffersTimer = None if usePTY == "slave-config": self.usePTY = self.builder.usePTY else: self.usePTY = usePTY # usePTY=True is a convenience for cleaning up all children and # grandchildren of a hung command. Fall back to usePTY=False on systems # and in situations where ptys cause problems. PTYs are posix-only, # and for .closeStdin to matter, we must use a pipe, not a PTY if runtime.platformType != "posix" or initialStdin is not None: if self.usePTY and usePTY != "slave-config": self.sendStatus( {'header': "WARNING: disabling usePTY for this command"}) self.usePTY = False # use an explicit process group on POSIX, noting that usePTY always implies # a process group. if runtime.platformType != 'posix': useProcGroup = False elif self.usePTY: useProcGroup = True self.useProcGroup = useProcGroup self.logFileWatchers = [] for name, filevalue in self.logfiles.items(): filename = filevalue follow = False # check for a dictionary of options # filename is required, others are optional if type(filevalue) == dict: filename = filevalue['filename'] follow = filevalue.get('follow', False) w = LogFileWatcher(self, name, os.path.join(self.workdir, filename), follow=follow) self.logFileWatchers.append(w) if user is not None and runtime.platformType != 'posix': raise RuntimeError("Cannot use 'user' parameter on this platform") self.user = user
def testSimple(self): c = util.Obfuscated('real', '****') self.failUnlessEqual(str(c), '****') self.failUnlessEqual(repr(c), "'****'")