def sendMail(mailText): """sends mailText (which has to have all the headers) via sendmail. (which is configured in [general]sendmail). This will return True when sendmail has accepted the mail, False otherwise. """ mailText = formatMail(mailText) pipe = subprocess.Popen(config.get("sendmail"), shell=True, stdin=subprocess.PIPE) pipe.stdin.write(mailText) pipe.stdin.close() if pipe.wait(): utils.sendUIEvent( "Error", "Wanted to send mail starting with" " '%s', but sendmail returned an error message" " (check the [general]sendmail setting)." % utils.makeEllipsis(mailText, 300)) return False return True
def tryRemoteReload(rdId): """tries to reload the rdId on a running service This only works if there's [web]adminpasswd and[web]serverURL set, and both match what the actual server uses. """ pw = config.get("web", "adminpasswd") # don't bother if admin passwd has not been set or when running unit tests. if pw == "" or pw == "this_is_the_unittest_suite": return try: f = utils.urlopenRemote(makeAbsoluteURL("/seffe/%s" % rdId), urllib.urlencode({ "__nevow_form__": "adminOps", "submit": "Reload RD" }), creds=("gavoadmin", pw)) f.read() except IOError, ex: utils.sendUIEvent( "Warning", "Could not reload %s RD (%s). This means" " that the server may still use stale metadata. You may want" " to reload %s manually (or restart the server)." % (rdId, ex, rdId))
def _updatePrivileges(self, objectName, foundPrivs, shouldPrivs): """is a helper for set[Table|Schema]Privileges. Requests for granting privileges not known to the database are ignored, but a log entry is generated. """ for role in set(foundPrivs) - set(shouldPrivs): if role: self.query("REVOKE ALL PRIVILEGES ON %s FROM %s" % (objectName, role)) for role in set(shouldPrivs) - set(foundPrivs): if role: if self.roleExists(role): self.query("GRANT %s ON %s TO %s" % (shouldPrivs[role], objectName, role)) else: utils.sendUIEvent( "Warning", "Request to grant privileges to non-existing" " database user %s dropped" % role) for role in set(shouldPrivs) & set(foundPrivs): if role: if shouldPrivs[role] != foundPrivs[role]: self.query("REVOKE ALL PRIVILEGES ON %s FROM %s" % (objectName, role)) self.query("GRANT %s ON %s TO %s" % (shouldPrivs[role], objectName, role))
def _connect(self, key=None): """creates a new trustedquery connection and assigns it to key if not None. This is an implementation detail of psycopg2's connection pools. """ conn = getDBConnection(self.profileName) if self.autocommitted: try: conn.set_session(autocommit=True, readonly=True) except AttributeError: # fallback for old psycopg2 conn.set_isolation_level( psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) except ProgrammingError: utils.sendUIEvent( "Warning", "Uncommitted transaction escaped; please" " investigate and fix") conn.commit() if key is not None: self._used[key] = conn self._rused[id(conn)] = key else: self._pool.append(conn) return conn
def run(self): """runs callable under somewhat reliable circumstances. """ try: self.callable() except Exception: utils.sendUIEvent( "Error", "Failure in timed job %s. Trying to send maintainer a mail." % utils.safe_str(self)) self.reportCronFailure("".join( traceback.format_exception(*sys.exc_info())))
def serverRestarted(cls): utils.sendUIEvent( "Warning", "Suspecting a database restart." " Discarding old connection pools, asking to create new ones.") for pool in cls.knownPools: try: pool().stale = True except AttributeError: # already gone pass # we risk a race condition here; this is used rarely enough that this # shouldn't matter. cls.knownPools = []
def asString(root, xmlDecl=False): """returns the V.VOTABLE root as a string. """ res = StringIO() try: write(root, res, xmlDecl=xmlDecl) except Exception: # something bad happened while generating the VOTable. We probably # have unwound the element stack and left an error INFO, so probably # the document is all right. Let's return it, but try to report an # error anyway if there's the infrastructure to do that utils.sendUIEvent( "Error", "Exception during VOTable write (delivering" " the document anyway)") return res.getvalue()
def buildCodec(source, env): """returns a compiled function for source in env. Source is the result of one of the makeXXX functions in this module, env typically the result of a getGlobals() on the codec module. """ ns = {} ns.update(env) try: #open("codec.py", "w").write(source) exec source in ns except: utils.sendUIEvent( "Error", "Error when compling VOTable codec (source in dcInfo)") utils.sendUIEvent("Info", "The failing source code was:\n" + source) raise return ns["codec"]
def sendMailToAdmin(subject, message): """tries to send a mail to the configured administrator. This relies on a functional mail infrastructure on the local host. """ if not config.get("maintainerAddress"): utils.sendUIEvent( "Error", "Wanted to send mail with subject '%s', but no" " maintainerAddress is given" % subject) return osinter.sendMail("\n".join([ "To: " + config.get("maintainerAddress"), "Subject: " + subject, "From: DaCHS server <%s>" % config.get("maintainerAddress"), "Content-Type: text/plain", "", utils.safe_str(message) ]))
def _cleanupAfterDBError(ex, conn, pool, poolLock): """removes conn from pool after an error occurred. This is a helper for getConnFromPool below. """ if isinstance(ex, OperationalError) and ex.pgcode is None: # this is probably a db server restart. Invalidate all connections # immediately. with poolLock: if pool: pool[0].serverRestarted() # Make sure the connection is closed; something bad happened # in it, so we don't want to re-use it try: pool[0].putconn(conn, close=True) except InterfaceError: # Connection already closed pass except Exception, msg: utils.sendUIEvent("Error", "Disaster: %s while force-closing connection" % msg)