Xavier (Open ERP) has proposed merging
lp:~openerp-dev/openobject-server/trunk-dump_and_restore_improvements-xmo into
lp:openobject-server.
Requested reviews:
OpenERP Core Team (openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-dump_and_restore_improvements-xmo/+merge/90654
Improvements to exp_dump and exp_restore:
* Use a contextmanager to handle setting and unsetting PGPASSWORD in the
environment around pg_dump and pg_restore, current version is less clear and
leaks the PGPASSWORD environment setting in case of dump or restore error (if
the dump or restore fails, an exception is raised without calling the cleanup
method). The contextmanager also allows for getting rid of a flag.
* converts exp_dump and exp_restore from netsvc.Logger to logging (although I'm
not quite sure if the logger names i used are correct).
--
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-dump_and_restore_improvements-xmo/+merge/90654
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openobject-server/trunk-dump_and_restore_improvements-xmo.
=== modified file 'openerp/service/web_services.py'
--- openerp/service/web_services.py 2012-01-18 16:03:05 +0000
+++ openerp/service/web_services.py 2012-01-30 08:14:24 +0000
@@ -20,6 +20,7 @@
##############################################################################
import base64
+import contextlib
import locale
import logging
import os
@@ -95,8 +96,6 @@
self.id = 0
self.id_protect = threading.Semaphore()
- self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
-
def dispatch(self, method, params):
if method in [ 'create', 'get_progress', 'drop', 'dump',
'restore', 'rename',
@@ -192,86 +191,85 @@
cr.close()
return True
- def _set_pg_psw_env_var(self):
- if os.name == 'nt' and not os.environ.get('PGPASSWORD', ''):
+ @contextlib.contextmanager
+ def _set_pg_password_in_environment(self):
+ """ On Win32, pg_dump (and pg_restore) require that
+ :envvar:`PGPASSWORD` be set
+
+ This context management method handles setting
+ :envvar:`PGPASSWORD` iif win32 and the envvar is not already
+ set, and removing it afterwards.
+ """
+ if os.name != 'nt' or os.environ.get('PGPASSWORD'):
+ yield
+ else:
os.environ['PGPASSWORD'] = tools.config['db_password']
- self._pg_psw_env_var_is_set = True
-
- def _unset_pg_psw_env_var(self):
- if os.name == 'nt' and self._pg_psw_env_var_is_set:
- os.environ['PGPASSWORD'] = ''
+ try:
+ yield
+ finally:
+ del os.environ['PGPASSWORD']
def exp_dump(self, db_name):
- logger = netsvc.Logger()
-
- self._set_pg_psw_env_var()
-
- cmd = ['pg_dump', '--format=c', '--no-owner']
- if tools.config['db_user']:
- cmd.append('--username=' + tools.config['db_user'])
- if tools.config['db_host']:
- cmd.append('--host=' + tools.config['db_host'])
- if tools.config['db_port']:
- cmd.append('--port=' + str(tools.config['db_port']))
- cmd.append(db_name)
-
- stdin, stdout = tools.exec_pg_command_pipe(*tuple(cmd))
- stdin.close()
- data = stdout.read()
- res = stdout.close()
- if res:
- logger.notifyChannel("web-services", netsvc.LOG_ERROR,
- 'DUMP DB: %s failed\n%s' % (db_name, data))
- raise Exception, "Couldn't dump database"
- logger.notifyChannel("web-services", netsvc.LOG_INFO,
- 'DUMP DB: %s' % (db_name))
-
- self._unset_pg_psw_env_var()
-
- return base64.encodestring(data)
+ logger = logging.getLogger('openerp.service.web_services.db.dump')
+
+ with self._set_pg_password_in_environment():
+ cmd = ['pg_dump', '--format=c', '--no-owner']
+ if tools.config['db_user']:
+ cmd.append('--username=' + tools.config['db_user'])
+ if tools.config['db_host']:
+ cmd.append('--host=' + tools.config['db_host'])
+ if tools.config['db_port']:
+ cmd.append('--port=' + str(tools.config['db_port']))
+ cmd.append(db_name)
+
+ stdin, stdout = tools.exec_pg_command_pipe(*tuple(cmd))
+ stdin.close()
+ data = stdout.read()
+ res = stdout.close()
+ if res:
+ logger.error('Failed to dump database %s:\n%s', db_name, data)
+ raise Exception, "Couldn't dump database"
+ logger.info('Dumped database %s', db_name)
+
+ return base64.encodestring(data)
def exp_restore(self, db_name, data):
- logger = netsvc.Logger()
-
- self._set_pg_psw_env_var()
-
- if self.exp_db_exist(db_name):
- logger.notifyChannel("web-services", netsvc.LOG_WARNING,
- 'RESTORE DB: %s already exists' % (db_name,))
- raise Exception, "Database already exists"
-
- self._create_empty_database(db_name)
-
- cmd = ['pg_restore', '--no-owner']
- if tools.config['db_user']:
- cmd.append('--username=' + tools.config['db_user'])
- if tools.config['db_host']:
- cmd.append('--host=' + tools.config['db_host'])
- if tools.config['db_port']:
- cmd.append('--port=' + str(tools.config['db_port']))
- cmd.append('--dbname=' + db_name)
- args2 = tuple(cmd)
-
- buf=base64.decodestring(data)
- if os.name == "nt":
- tmpfile = (os.environ['TMP'] or 'C:\\') + os.tmpnam()
- file(tmpfile, 'wb').write(buf)
- args2=list(args2)
- args2.append(' ' + tmpfile)
- args2=tuple(args2)
- stdin, stdout = tools.exec_pg_command_pipe(*args2)
- if not os.name == "nt":
- stdin.write(base64.decodestring(data))
- stdin.close()
- res = stdout.close()
- if res:
- raise Exception, "Couldn't restore database"
- logger.notifyChannel("web-services", netsvc.LOG_INFO,
- 'RESTORE DB: %s' % (db_name))
-
- self._unset_pg_psw_env_var()
-
- return True
+ logger = logging.getLogger('openerp.service.web_services.db.restore')
+
+ with self._set_pg_password_in_environment():
+ if self.exp_db_exist(db_name):
+ logger.warn('Database %s already exists, aborting', db_name)
+ raise Exception, "Database already exists"
+
+ self._create_empty_database(db_name)
+
+ cmd = ['pg_restore', '--no-owner']
+ if tools.config['db_user']:
+ cmd.append('--username=' + tools.config['db_user'])
+ if tools.config['db_host']:
+ cmd.append('--host=' + tools.config['db_host'])
+ if tools.config['db_port']:
+ cmd.append('--port=' + str(tools.config['db_port']))
+ cmd.append('--dbname=' + db_name)
+ args2 = tuple(cmd)
+
+ buf=base64.decodestring(data)
+ if os.name == "nt":
+ tmpfile = (os.environ['TMP'] or 'C:\\') + os.tmpnam()
+ file(tmpfile, 'wb').write(buf)
+ args2=list(args2)
+ args2.append(' ' + tmpfile)
+ args2=tuple(args2)
+ stdin, stdout = tools.exec_pg_command_pipe(*args2)
+ if not os.name == "nt":
+ stdin.write(base64.decodestring(data))
+ stdin.close()
+ res = stdout.close()
+ if res:
+ raise Exception, "Couldn't restore database"
+ logger.info("Restored database %s", db_name)
+
+ return True
def exp_rename(self, old_name, new_name):
openerp.modules.registry.RegistryManager.delete(old_name)
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp