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

Reply via email to