[FIX] db dump: report errors due to missing password + pass PGPASSWORD even on Unix
Even on Unix systems the PGPASSWORD env var is necessary when Postgres is configured to deny unix socket connections or to require a password anyway. This avoids asking admins to manually create a ~/.pgpass file in order to use the dump/restore tools. Also did some cleanup to ensure the PGPASSWORD var is removed from the environment as soon as the operation is done. lp bug: https://launchpad.net/bugs/790164 fixed lp bug: https://launchpad.net/bugs/919100 fixed bzr revid: odo@openerp.com-20120131110849-tji6ipjovxc9oi4v
This commit is contained in:
parent
a6c106365a
commit
f11e1de5eb
|
@ -192,86 +192,94 @@ class db(netsvc.ExportService):
|
||||||
cr.close()
|
cr.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _set_pg_psw_env_var(self):
|
def _set_pg_psw_env_var(self):
|
||||||
if os.name == 'nt' and not os.environ.get('PGPASSWORD', ''):
|
# see http://www.postgresql.org/docs/8.4/static/libpq-pgpass.html
|
||||||
|
# FIXME: This is not thread-safe, and should never be enabled for
|
||||||
|
# SaaS (giving SaaS users the super-admin password is not a good idea
|
||||||
|
# anyway)
|
||||||
|
if tools.config['db_password'] and not os.environ.get('PGPASSWORD', ''):
|
||||||
os.environ['PGPASSWORD'] = tools.config['db_password']
|
os.environ['PGPASSWORD'] = tools.config['db_password']
|
||||||
self._pg_psw_env_var_is_set = True
|
self._pg_psw_env_var_is_set = True
|
||||||
|
|
||||||
def _unset_pg_psw_env_var(self):
|
def _unset_pg_psw_env_var(self):
|
||||||
if os.name == 'nt' and self._pg_psw_env_var_is_set:
|
if self._pg_psw_env_var_is_set:
|
||||||
os.environ['PGPASSWORD'] = ''
|
os.environ['PGPASSWORD'] = ''
|
||||||
|
|
||||||
def exp_dump(self, db_name):
|
def exp_dump(self, db_name):
|
||||||
logger = netsvc.Logger()
|
logger = netsvc.Logger()
|
||||||
|
try:
|
||||||
self._set_pg_psw_env_var()
|
self._set_pg_psw_env_var()
|
||||||
|
cmd = ['pg_dump', '--format=c', '--no-owner']
|
||||||
cmd = ['pg_dump', '--format=c', '--no-owner']
|
if tools.config['db_user']:
|
||||||
if tools.config['db_user']:
|
cmd.append('--username=' + tools.config['db_user'])
|
||||||
cmd.append('--username=' + tools.config['db_user'])
|
if tools.config['db_host']:
|
||||||
if tools.config['db_host']:
|
cmd.append('--host=' + tools.config['db_host'])
|
||||||
cmd.append('--host=' + tools.config['db_host'])
|
if tools.config['db_port']:
|
||||||
if tools.config['db_port']:
|
cmd.append('--port=' + str(tools.config['db_port']))
|
||||||
cmd.append('--port=' + str(tools.config['db_port']))
|
cmd.append(db_name)
|
||||||
cmd.append(db_name)
|
|
||||||
|
stdin, stdout = tools.exec_pg_command_pipe(*tuple(cmd))
|
||||||
stdin, stdout = tools.exec_pg_command_pipe(*tuple(cmd))
|
stdin.close()
|
||||||
stdin.close()
|
data = stdout.read()
|
||||||
data = stdout.read()
|
res = stdout.close()
|
||||||
res = stdout.close()
|
|
||||||
if res:
|
if not data or res:
|
||||||
logger.notifyChannel("web-services", netsvc.LOG_ERROR,
|
logger.notifyChannel("web-services", netsvc.LOG_ERROR,
|
||||||
'DUMP DB: %s failed\n%s' % (db_name, data))
|
'DUMP DB: %s failed! Please verify the configuration of the database password on the server. '\
|
||||||
raise Exception, "Couldn't dump database"
|
'It should be provided as a -w <PASSWD> command-line option, or as `db_password` in the '\
|
||||||
logger.notifyChannel("web-services", netsvc.LOG_INFO,
|
'server configuration file.\n %s' % (db_name, data))
|
||||||
'DUMP DB: %s' % (db_name))
|
raise Exception, "Couldn't dump database"
|
||||||
|
logger.notifyChannel("web-services", netsvc.LOG_INFO,
|
||||||
self._unset_pg_psw_env_var()
|
'DUMP DB successful: %s' % (db_name))
|
||||||
|
|
||||||
return base64.encodestring(data)
|
return base64.encodestring(data)
|
||||||
|
finally:
|
||||||
|
self._unset_pg_psw_env_var()
|
||||||
|
|
||||||
def exp_restore(self, db_name, data):
|
def exp_restore(self, db_name, data):
|
||||||
logger = netsvc.Logger()
|
logger = netsvc.Logger()
|
||||||
|
|
||||||
self._set_pg_psw_env_var()
|
try:
|
||||||
|
self._set_pg_psw_env_var()
|
||||||
|
|
||||||
if self.exp_db_exist(db_name):
|
if self.exp_db_exist(db_name):
|
||||||
logger.notifyChannel("web-services", netsvc.LOG_WARNING,
|
logger.notifyChannel("web-services", netsvc.LOG_WARNING,
|
||||||
'RESTORE DB: %s already exists' % (db_name,))
|
'RESTORE DB: %s already exists' % (db_name,))
|
||||||
raise Exception, "Database already exists"
|
raise Exception, "Database already exists"
|
||||||
|
|
||||||
self._create_empty_database(db_name)
|
self._create_empty_database(db_name)
|
||||||
|
|
||||||
cmd = ['pg_restore', '--no-owner']
|
cmd = ['pg_restore', '--no-owner']
|
||||||
if tools.config['db_user']:
|
if tools.config['db_user']:
|
||||||
cmd.append('--username=' + tools.config['db_user'])
|
cmd.append('--username=' + tools.config['db_user'])
|
||||||
if tools.config['db_host']:
|
if tools.config['db_host']:
|
||||||
cmd.append('--host=' + tools.config['db_host'])
|
cmd.append('--host=' + tools.config['db_host'])
|
||||||
if tools.config['db_port']:
|
if tools.config['db_port']:
|
||||||
cmd.append('--port=' + str(tools.config['db_port']))
|
cmd.append('--port=' + str(tools.config['db_port']))
|
||||||
cmd.append('--dbname=' + db_name)
|
cmd.append('--dbname=' + db_name)
|
||||||
args2 = tuple(cmd)
|
args2 = tuple(cmd)
|
||||||
|
|
||||||
buf=base64.decodestring(data)
|
buf=base64.decodestring(data)
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
tmpfile = (os.environ['TMP'] or 'C:\\') + os.tmpnam()
|
tmpfile = (os.environ['TMP'] or 'C:\\') + os.tmpnam()
|
||||||
file(tmpfile, 'wb').write(buf)
|
file(tmpfile, 'wb').write(buf)
|
||||||
args2=list(args2)
|
args2=list(args2)
|
||||||
args2.append(' ' + tmpfile)
|
args2.append(' ' + tmpfile)
|
||||||
args2=tuple(args2)
|
args2=tuple(args2)
|
||||||
stdin, stdout = tools.exec_pg_command_pipe(*args2)
|
stdin, stdout = tools.exec_pg_command_pipe(*args2)
|
||||||
if not os.name == "nt":
|
if not os.name == "nt":
|
||||||
stdin.write(base64.decodestring(data))
|
stdin.write(base64.decodestring(data))
|
||||||
stdin.close()
|
stdin.close()
|
||||||
res = stdout.close()
|
res = stdout.close()
|
||||||
if res:
|
if res:
|
||||||
raise Exception, "Couldn't restore database"
|
raise Exception, "Couldn't restore database"
|
||||||
logger.notifyChannel("web-services", netsvc.LOG_INFO,
|
logger.notifyChannel("web-services", netsvc.LOG_INFO,
|
||||||
'RESTORE DB: %s' % (db_name))
|
'RESTORE DB: %s' % (db_name))
|
||||||
|
|
||||||
self._unset_pg_psw_env_var()
|
return True
|
||||||
|
finally:
|
||||||
return True
|
self._unset_pg_psw_env_var()
|
||||||
|
|
||||||
def exp_rename(self, old_name, new_name):
|
def exp_rename(self, old_name, new_name):
|
||||||
openerp.modules.registry.RegistryManager.delete(old_name)
|
openerp.modules.registry.RegistryManager.delete(old_name)
|
||||||
|
|
Loading…
Reference in New Issue