server/serverctl.py
changeset 2476 1294a6bdf3bf
parent 2473 490f88fb99b6
child 2493 9806571ea790
equal deleted inserted replaced
2475:b6753521129d 2476:1294a6bdf3bf
    56     return get_connection(driver, dbhost, dbname, user, password=password,
    56     return get_connection(driver, dbhost, dbname, user, password=password,
    57                           port=source.get('db-port'))
    57                           port=source.get('db-port'))
    58 
    58 
    59 def system_source_cnx(source, dbms_system_base=False,
    59 def system_source_cnx(source, dbms_system_base=False,
    60                       special_privs='CREATE/DROP DATABASE', verbose=True):
    60                       special_privs='CREATE/DROP DATABASE', verbose=True):
    61     """shortcut to get a connextion to the application system database
    61     """shortcut to get a connextion to the instance system database
    62     defined in the given config. If <dbms_system_base> is True,
    62     defined in the given config. If <dbms_system_base> is True,
    63     connect to the dbms system database instead (for task such as
    63     connect to the dbms system database instead (for task such as
    64     create/drop the application database)
    64     create/drop the instance database)
    65     """
    65     """
    66     if dbms_system_base:
    66     if dbms_system_base:
    67         from logilab.common.adbh import get_adv_func_helper
    67         from logilab.common.adbh import get_adv_func_helper
    68         system_db = get_adv_func_helper(source['db-driver']).system_database()
    68         system_db = get_adv_func_helper(source['db-driver']).system_database()
    69         return source_cnx(source, system_db, special_privs=special_privs, verbose=verbose)
    69         return source_cnx(source, system_db, special_privs=special_privs, verbose=verbose)
   117 class RepositoryCreateHandler(CommandHandler):
   117 class RepositoryCreateHandler(CommandHandler):
   118     cmdname = 'create'
   118     cmdname = 'create'
   119     cfgname = 'repository'
   119     cfgname = 'repository'
   120 
   120 
   121     def bootstrap(self, cubes, inputlevel=0):
   121     def bootstrap(self, cubes, inputlevel=0):
   122         """create an application by copying files from the given cube and by
   122         """create an instance by copying files from the given cube and by
   123         asking information necessary to build required configuration files
   123         asking information necessary to build required configuration files
   124         """
   124         """
   125         config = self.config
   125         config = self.config
   126         print underline_title('Configuring the repository')
   126         print underline_title('Configuring the repository')
   127         config.input_config('email', inputlevel)
   127         config.input_config('email', inputlevel)
   180 class RepositoryDeleteHandler(CommandHandler):
   180 class RepositoryDeleteHandler(CommandHandler):
   181     cmdname = 'delete'
   181     cmdname = 'delete'
   182     cfgname = 'repository'
   182     cfgname = 'repository'
   183 
   183 
   184     def cleanup(self):
   184     def cleanup(self):
   185         """remove application's configuration and database"""
   185         """remove instance's configuration and database"""
   186         from logilab.common.adbh import get_adv_func_helper
   186         from logilab.common.adbh import get_adv_func_helper
   187         source = self.config.sources()['system']
   187         source = self.config.sources()['system']
   188         dbname = source['db-name']
   188         dbname = source['db-name']
   189         helper = get_adv_func_helper(source['db-driver'])
   189         helper = get_adv_func_helper(source['db-driver'])
   190         if confirm('Delete database %s ?' % dbname):
   190         if confirm('Delete database %s ?' % dbname):
   229             from cubicweb.server.repository import pyro_unregister
   229             from cubicweb.server.repository import pyro_unregister
   230             pyro_unregister(self.config)
   230             pyro_unregister(self.config)
   231 
   231 
   232 
   232 
   233 # repository specific commands ################################################
   233 # repository specific commands ################################################
   234 class CreateApplicationDBCommand(Command):
   234 class CreateInstanceDBCommand(Command):
   235     """Create the system database of an application (run after 'create').
   235     """Create the system database of an instance (run after 'create').
   236 
   236 
   237     You will be prompted for a login / password to use to connect to
   237     You will be prompted for a login / password to use to connect to
   238     the system database.  The given user should have almost all rights
   238     the system database.  The given user should have almost all rights
   239     on the database (ie a super user on the dbms allowed to create
   239     on the database (ie a super user on the dbms allowed to create
   240     database, users, languages...).
   240     database, users, languages...).
   241 
   241 
   242     <application>
   242     <instance>
   243       the identifier of the application to initialize.
   243       the identifier of the instance to initialize.
   244     """
   244     """
   245     name = 'db-create'
   245     name = 'db-create'
   246     arguments = '<application>'
   246     arguments = '<instance>'
   247 
   247 
   248     options = (
   248     options = (
   249         ("create-db",
   249         ("create-db",
   250          {'short': 'c', 'type': "yn", 'metavar': '<y or n>',
   250          {'short': 'c', 'type': "yn", 'metavar': '<y or n>',
   251           'default': True,
   251           'default': True,
   260     def run(self, args):
   260     def run(self, args):
   261         """run the command with its specific arguments"""
   261         """run the command with its specific arguments"""
   262         from logilab.common.adbh import get_adv_func_helper
   262         from logilab.common.adbh import get_adv_func_helper
   263         from indexer import get_indexer
   263         from indexer import get_indexer
   264         verbose = self.get('verbose')
   264         verbose = self.get('verbose')
   265         appid = pop_arg(args, msg="No application specified !")
   265         appid = pop_arg(args, msg="No instance specified !")
   266         config = ServerConfiguration.config_for(appid)
   266         config = ServerConfiguration.config_for(appid)
   267         create_db = self.config.create_db
   267         create_db = self.config.create_db
   268         source = config.sources()['system']
   268         source = config.sources()['system']
   269         driver = source['db-driver']
   269         driver = source['db-driver']
   270         helper = get_adv_func_helper(driver)
   270         helper = get_adv_func_helper(driver)
   306             # install plpythonu/plpgsql language if not installed by the cube
   306             # install plpythonu/plpgsql language if not installed by the cube
   307             for extlang in ('plpythonu', 'plpgsql'):
   307             for extlang in ('plpythonu', 'plpgsql'):
   308                 helper.create_language(cursor, extlang)
   308                 helper.create_language(cursor, extlang)
   309         cursor.close()
   309         cursor.close()
   310         cnx.commit()
   310         cnx.commit()
   311         print '-> database for application %s created and necessary extensions installed.' % appid
   311         print '-> database for instance %s created and necessary extensions installed.' % appid
   312         print
   312         print
   313         if confirm('Do you want to run db-init to initialize the "system database" ?'):
   313         if confirm('Do you want to run db-init to initialize the "system database" ?'):
   314             cmd_run('db-init', config.appid)
   314             cmd_run('db-init', config.appid)
   315         else:
   315         else:
   316             print ('-> nevermind, you can do it later with '
   316             print ('-> nevermind, you can do it later with '
   317                    '"cubicweb-ctl db-init %s".' % self.config.appid)
   317                    '"cubicweb-ctl db-init %s".' % self.config.appid)
   318 
   318 
   319 
   319 
   320 class InitApplicationCommand(Command):
   320 class InitInstanceCommand(Command):
   321     """Initialize the system database of an application (run after 'db-create').
   321     """Initialize the system database of an instance (run after 'db-create').
   322 
   322 
   323     You will be prompted for a login / password to use to connect to
   323     You will be prompted for a login / password to use to connect to
   324     the system database.  The given user should have the create tables,
   324     the system database.  The given user should have the create tables,
   325     and grant permissions.
   325     and grant permissions.
   326 
   326 
   327     <application>
   327     <instance>
   328       the identifier of the application to initialize.
   328       the identifier of the instance to initialize.
   329     """
   329     """
   330     name = 'db-init'
   330     name = 'db-init'
   331     arguments = '<application>'
   331     arguments = '<instance>'
   332 
   332 
   333     options = (
   333     options = (
   334         ("drop",
   334         ("drop",
   335          {'short': 'd', 'action': 'store_true',
   335          {'short': 'd', 'action': 'store_true',
   336           'default': False,
   336           'default': False,
   339         )
   339         )
   340 
   340 
   341     def run(self, args):
   341     def run(self, args):
   342         print '\n'+underline_title('Initializing the "system database"')
   342         print '\n'+underline_title('Initializing the "system database"')
   343         from cubicweb.server import init_repository
   343         from cubicweb.server import init_repository
   344         appid = pop_arg(args, msg="No application specified !")
   344         appid = pop_arg(args, msg="No instance specified !")
   345         config = ServerConfiguration.config_for(appid)
   345         config = ServerConfiguration.config_for(appid)
   346         init_repository(config, drop=self.config.drop)
   346         init_repository(config, drop=self.config.drop)
   347 
   347 
   348 
   348 
   349 class GrantUserOnApplicationCommand(Command):
   349 class GrantUserOnInstanceCommand(Command):
   350     """Grant a database user on a repository system database.
   350     """Grant a database user on a repository system database.
   351 
   351 
   352     <application>
   352     <instance>
   353       the identifier of the application
   353       the identifier of the instance
   354     <user>
   354     <user>
   355       the database's user requiring grant access
   355       the database's user requiring grant access
   356     """
   356     """
   357     name = 'db-grant-user'
   357     name = 'db-grant-user'
   358     arguments = '<application> <user>'
   358     arguments = '<instance> <user>'
   359 
   359 
   360     options = (
   360     options = (
   361         ("set-owner",
   361         ("set-owner",
   362          {'short': 'o', 'type' : "yn", 'metavar' : '<yes or no>',
   362          {'short': 'o', 'type' : "yn", 'metavar' : '<yes or no>',
   363           'default' : False,
   363           'default' : False,
   365          ),
   365          ),
   366         )
   366         )
   367     def run(self, args):
   367     def run(self, args):
   368         """run the command with its specific arguments"""
   368         """run the command with its specific arguments"""
   369         from cubicweb.server.sqlutils import sqlexec, sqlgrants
   369         from cubicweb.server.sqlutils import sqlexec, sqlgrants
   370         appid = pop_arg(args, 1, msg="No application specified !")
   370         appid = pop_arg(args, 1, msg="No instance specified !")
   371         user = pop_arg(args, msg="No user specified !")
   371         user = pop_arg(args, msg="No user specified !")
   372         config = ServerConfiguration.config_for(appid)
   372         config = ServerConfiguration.config_for(appid)
   373         source = config.sources()['system']
   373         source = config.sources()['system']
   374         set_owner = self.config.set_owner
   374         set_owner = self.config.set_owner
   375         cnx = system_source_cnx(source, special_privs='GRANT')
   375         cnx = system_source_cnx(source, special_privs='GRANT')
   383             import traceback
   383             import traceback
   384             traceback.print_exc()
   384             traceback.print_exc()
   385             print '-> an error occured:', ex
   385             print '-> an error occured:', ex
   386         else:
   386         else:
   387             cnx.commit()
   387             cnx.commit()
   388             print '-> rights granted to %s on application %s.' % (appid, user)
   388             print '-> rights granted to %s on instance %s.' % (appid, user)
   389 
   389 
   390 class ResetAdminPasswordCommand(Command):
   390 class ResetAdminPasswordCommand(Command):
   391     """Reset the administrator password.
   391     """Reset the administrator password.
   392 
   392 
   393     <application>
   393     <instance>
   394       the identifier of the application
   394       the identifier of the instance
   395     """
   395     """
   396     name = 'reset-admin-pwd'
   396     name = 'reset-admin-pwd'
   397     arguments = '<application>'
   397     arguments = '<instance>'
   398 
   398 
   399     def run(self, args):
   399     def run(self, args):
   400         """run the command with its specific arguments"""
   400         """run the command with its specific arguments"""
   401         from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
   401         from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
   402         from cubicweb.server.utils import crypt_password, manager_userpasswd
   402         from cubicweb.server.utils import crypt_password, manager_userpasswd
   403         appid = pop_arg(args, 1, msg="No application specified !")
   403         appid = pop_arg(args, 1, msg="No instance specified !")
   404         config = ServerConfiguration.config_for(appid)
   404         config = ServerConfiguration.config_for(appid)
   405         sourcescfg = config.read_sources_file()
   405         sourcescfg = config.read_sources_file()
   406         try:
   406         try:
   407             adminlogin = sourcescfg['admin']['login']
   407             adminlogin = sourcescfg['admin']['login']
   408         except KeyError:
   408         except KeyError:
   431             cnx.commit()
   431             cnx.commit()
   432             print '-> password reset, sources file regenerated.'
   432             print '-> password reset, sources file regenerated.'
   433 
   433 
   434 
   434 
   435 class StartRepositoryCommand(Command):
   435 class StartRepositoryCommand(Command):
   436     """Start an CubicWeb RQL server for a given application.
   436     """Start an CubicWeb RQL server for a given instance.
   437 
   437 
   438     The server will be accessible through pyro
   438     The server will be accessible through pyro
   439 
   439 
   440     <application>
   440     <instance>
   441       the identifier of the application to initialize.
   441       the identifier of the instance to initialize.
   442     """
   442     """
   443     name = 'start-repository'
   443     name = 'start-repository'
   444     arguments = '<application>'
   444     arguments = '<instance>'
   445 
   445 
   446     options = (
   446     options = (
   447         ("debug",
   447         ("debug",
   448          {'short': 'D', 'action' : 'store_true',
   448          {'short': 'D', 'action' : 'store_true',
   449           'help': 'start server in debug mode.'}),
   449           'help': 'start server in debug mode.'}),
   450         )
   450         )
   451 
   451 
   452     def run(self, args):
   452     def run(self, args):
   453         from cubicweb.server.server import RepositoryServer
   453         from cubicweb.server.server import RepositoryServer
   454         appid = pop_arg(args, msg="No application specified !")
   454         appid = pop_arg(args, msg="No instance specified !")
   455         config = ServerConfiguration.config_for(appid)
   455         config = ServerConfiguration.config_for(appid)
   456         debug = self.config.debug
   456         debug = self.config.debug
   457         # create the server
   457         # create the server
   458         server = RepositoryServer(config, debug)
   458         server = RepositoryServer(config, debug)
   459         # go ! (don't daemonize in debug mode)
   459         # go ! (don't daemonize in debug mode)
   512     if not dbversions:
   512     if not dbversions:
   513         print "bad or missing version information in the database, don't upgrade file system"
   513         print "bad or missing version information in the database, don't upgrade file system"
   514         return
   514         return
   515     # version of installed software
   515     # version of installed software
   516     eversion = dbversions['cubicweb']
   516     eversion = dbversions['cubicweb']
   517     status = application_status(config, eversion, dbversions)
   517     status = instance_status(config, eversion, dbversions)
   518     # * database version > installed software
   518     # * database version > installed software
   519     if status == 'needsoftupgrade':
   519     if status == 'needsoftupgrade':
   520         print "database is using some earlier version than installed software!"
   520         print "database is using some earlier version than installed software!"
   521         print "please upgrade your software and then upgrade the instance"
   521         print "please upgrade your software and then upgrade the instance"
   522         print "using command 'cubicweb-ctl upgrade %s'" % config.appid
   522         print "using command 'cubicweb-ctl upgrade %s'" % config.appid
   530         return
   530         return
   531     # * database version = installed software, database version = instance fs version
   531     # * database version = installed software, database version = instance fs version
   532     #   ok!
   532     #   ok!
   533 
   533 
   534 
   534 
   535 def application_status(config, cubicwebapplversion, vcconf):
   535 def instance_status(config, cubicwebapplversion, vcconf):
   536     cubicwebversion = config.cubicweb_version()
   536     cubicwebversion = config.cubicweb_version()
   537     if cubicwebapplversion > cubicwebversion:
   537     if cubicwebapplversion > cubicwebversion:
   538         return 'needsoftupgrade'
   538         return 'needsoftupgrade'
   539     if cubicwebapplversion < cubicwebversion:
   539     if cubicwebapplversion < cubicwebversion:
   540         return 'needapplupgrade'
   540         return 'needapplupgrade'
   557             return 'needapplupgrade'
   557             return 'needapplupgrade'
   558     return None
   558     return None
   559 
   559 
   560 
   560 
   561 class DBDumpCommand(Command):
   561 class DBDumpCommand(Command):
   562     """Backup the system database of an application.
   562     """Backup the system database of an instance.
   563 
   563 
   564     <application>
   564     <instance>
   565       the identifier of the application to backup
   565       the identifier of the instance to backup
   566       format [[user@]host:]appname
   566       format [[user@]host:]appname
   567     """
   567     """
   568     name = 'db-dump'
   568     name = 'db-dump'
   569     arguments = '<application>'
   569     arguments = '<instance>'
   570 
   570 
   571     options = (
   571     options = (
   572         ("output",
   572         ("output",
   573          {'short': 'o', 'type' : "string", 'metavar' : '<file>',
   573          {'short': 'o', 'type' : "string", 'metavar' : '<file>',
   574           'default' : None,
   574           'default' : None,
   580           'help': 'Use sudo on the remote host.'}
   580           'help': 'Use sudo on the remote host.'}
   581          ),
   581          ),
   582         )
   582         )
   583 
   583 
   584     def run(self, args):
   584     def run(self, args):
   585         appid = pop_arg(args, 1, msg="No application specified !")
   585         appid = pop_arg(args, 1, msg="No instance specified !")
   586         if ':' in appid:
   586         if ':' in appid:
   587             host, appid = appid.split(':')
   587             host, appid = appid.split(':')
   588             _remote_dump(host, appid, self.config.output, self.config.sudo)
   588             _remote_dump(host, appid, self.config.output, self.config.sudo)
   589         else:
   589         else:
   590             _local_dump(appid, self.config.output)
   590             _local_dump(appid, self.config.output)
   591 
   591 
   592 
   592 
   593 class DBRestoreCommand(Command):
   593 class DBRestoreCommand(Command):
   594     """Restore the system database of an application.
   594     """Restore the system database of an instance.
   595 
   595 
   596     <application>
   596     <instance>
   597       the identifier of the application to restore
   597       the identifier of the instance to restore
   598     """
   598     """
   599     name = 'db-restore'
   599     name = 'db-restore'
   600     arguments = '<application> <backupfile>'
   600     arguments = '<instance> <backupfile>'
   601 
   601 
   602     options = (
   602     options = (
   603         ("no-drop",
   603         ("no-drop",
   604          {'short': 'n', 'action' : 'store_true',
   604          {'short': 'n', 'action' : 'store_true',
   605           'default' : False,
   605           'default' : False,
   607           'should not be dropped.'}
   607           'should not be dropped.'}
   608          ),
   608          ),
   609         )
   609         )
   610 
   610 
   611     def run(self, args):
   611     def run(self, args):
   612         appid = pop_arg(args, 1, msg="No application specified !")
   612         appid = pop_arg(args, 1, msg="No instance specified !")
   613         backupfile = pop_arg(args, msg="No backup file specified !")
   613         backupfile = pop_arg(args, msg="No backup file specified !")
   614         _local_restore(appid, backupfile, not self.config.no_drop)
   614         _local_restore(appid, backupfile, not self.config.no_drop)
   615 
   615 
   616 
   616 
   617 class DBCopyCommand(Command):
   617 class DBCopyCommand(Command):
   618     """Copy the system database of an application (backup and restore).
   618     """Copy the system database of an instance (backup and restore).
   619 
   619 
   620     <src-application>
   620     <src-instance>
   621       the identifier of the application to backup
   621       the identifier of the instance to backup
   622       format [[user@]host:]appname
   622       format [[user@]host:]appname
   623 
   623 
   624     <dest-application>
   624     <dest-instance>
   625       the identifier of the application to restore
   625       the identifier of the instance to restore
   626     """
   626     """
   627     name = 'db-copy'
   627     name = 'db-copy'
   628     arguments = '<src-application> <dest-application>'
   628     arguments = '<src-instance> <dest-instance>'
   629 
   629 
   630     options = (
   630     options = (
   631         ("no-drop",
   631         ("no-drop",
   632          {'short': 'n', 'action' : 'store_true',
   632          {'short': 'n', 'action' : 'store_true',
   633           'default' : False,
   633           'default' : False,
   646          ),
   646          ),
   647         )
   647         )
   648 
   648 
   649     def run(self, args):
   649     def run(self, args):
   650         import tempfile
   650         import tempfile
   651         srcappid = pop_arg(args, 1, msg="No source application specified !")
   651         srcappid = pop_arg(args, 1, msg="No source instance specified !")
   652         destappid = pop_arg(args, msg="No destination application specified !")
   652         destappid = pop_arg(args, msg="No destination instance specified !")
   653         _, output = tempfile.mkstemp()
   653         _, output = tempfile.mkstemp()
   654         if ':' in srcappid:
   654         if ':' in srcappid:
   655             host, srcappid = srcappid.split(':')
   655             host, srcappid = srcappid.split(':')
   656             _remote_dump(host, srcappid, output, self.config.sudo)
   656             _remote_dump(host, srcappid, output, self.config.sudo)
   657         else:
   657         else:
   662         else:
   662         else:
   663             os.remove(output)
   663             os.remove(output)
   664 
   664 
   665 
   665 
   666 class CheckRepositoryCommand(Command):
   666 class CheckRepositoryCommand(Command):
   667     """Check integrity of the system database of an application.
   667     """Check integrity of the system database of an instance.
   668 
   668 
   669     <application>
   669     <instance>
   670       the identifier of the application to check
   670       the identifier of the instance to check
   671     """
   671     """
   672     name = 'db-check'
   672     name = 'db-check'
   673     arguments = '<application>'
   673     arguments = '<instance>'
   674 
   674 
   675     options = (
   675     options = (
   676         ("checks",
   676         ("checks",
   677          {'short': 'c', 'type' : "csv", 'metavar' : '<check list>',
   677          {'short': 'c', 'type' : "csv", 'metavar' : '<check list>',
   678           'default' : ('entities', 'relations', 'metadata', 'schema', 'text_index'),
   678           'default' : ('entities', 'relations', 'metadata', 'schema', 'text_index'),
   700 
   700 
   701         )
   701         )
   702 
   702 
   703     def run(self, args):
   703     def run(self, args):
   704         from cubicweb.server.checkintegrity import check
   704         from cubicweb.server.checkintegrity import check
   705         appid = pop_arg(args, 1, msg="No application specified !")
   705         appid = pop_arg(args, 1, msg="No instance specified !")
   706         config = ServerConfiguration.config_for(appid)
   706         config = ServerConfiguration.config_for(appid)
   707         config.repairing = self.config.force
   707         config.repairing = self.config.force
   708         repo, cnx = repo_cnx(config)
   708         repo, cnx = repo_cnx(config)
   709         check(repo, cnx,
   709         check(repo, cnx,
   710               self.config.checks, self.config.reindex, self.config.autofix)
   710               self.config.checks, self.config.reindex, self.config.autofix)
   711 
   711 
   712 
   712 
   713 class RebuildFTICommand(Command):
   713 class RebuildFTICommand(Command):
   714     """Rebuild the full-text index of the system database of an application.
   714     """Rebuild the full-text index of the system database of an instance.
   715 
   715 
   716     <application>
   716     <instance>
   717       the identifier of the application to rebuild
   717       the identifier of the instance to rebuild
   718     """
   718     """
   719     name = 'db-rebuild-fti'
   719     name = 'db-rebuild-fti'
   720     arguments = '<application>'
   720     arguments = '<instance>'
   721 
   721 
   722     options = ()
   722     options = ()
   723 
   723 
   724     def run(self, args):
   724     def run(self, args):
   725         from cubicweb.server.checkintegrity import reindex_entities
   725         from cubicweb.server.checkintegrity import reindex_entities
   726         appid = pop_arg(args, 1, msg="No application specified !")
   726         appid = pop_arg(args, 1, msg="No instance specified !")
   727         config = ServerConfiguration.config_for(appid)
   727         config = ServerConfiguration.config_for(appid)
   728         repo, cnx = repo_cnx(config)
   728         repo, cnx = repo_cnx(config)
   729         session = repo._get_session(cnx.sessionid, setpool=True)
   729         session = repo._get_session(cnx.sessionid, setpool=True)
   730         reindex_entities(repo.schema, session)
   730         reindex_entities(repo.schema, session)
   731         cnx.commit()
   731         cnx.commit()
   732 
   732 
   733 
   733 
   734 class SynchronizeApplicationSchemaCommand(Command):
   734 class SynchronizeInstanceSchemaCommand(Command):
   735     """Synchronize persistent schema with cube schema.
   735     """Synchronize persistent schema with cube schema.
   736 
   736 
   737     Will synchronize common stuff between the cube schema and the
   737     Will synchronize common stuff between the cube schema and the
   738     actual persistent schema, but will not add/remove any entity or relation.
   738     actual persistent schema, but will not add/remove any entity or relation.
   739 
   739 
   740     <application>
   740     <instance>
   741       the identifier of the application to synchronize.
   741       the identifier of the instance to synchronize.
   742     """
   742     """
   743     name = 'schema-sync'
   743     name = 'schema-sync'
   744     arguments = '<application>'
   744     arguments = '<instance>'
   745 
   745 
   746     def run(self, args):
   746     def run(self, args):
   747         appid = pop_arg(args, msg="No application specified !")
   747         appid = pop_arg(args, msg="No instance specified !")
   748         config = ServerConfiguration.config_for(appid)
   748         config = ServerConfiguration.config_for(appid)
   749         mih = config.migration_handler()
   749         mih = config.migration_handler()
   750         mih.cmd_synchronize_schema()
   750         mih.cmd_synchronize_schema()
   751 
   751 
   752 
   752 
   753 register_commands( (CreateApplicationDBCommand,
   753 register_commands( (CreateInstanceDBCommand,
   754                     InitApplicationCommand,
   754                     InitInstanceCommand,
   755                     GrantUserOnApplicationCommand,
   755                     GrantUserOnInstanceCommand,
   756                     ResetAdminPasswordCommand,
   756                     ResetAdminPasswordCommand,
   757                     StartRepositoryCommand,
   757                     StartRepositoryCommand,
   758                     DBDumpCommand,
   758                     DBDumpCommand,
   759                     DBRestoreCommand,
   759                     DBRestoreCommand,
   760                     DBCopyCommand,
   760                     DBCopyCommand,
   761                     CheckRepositoryCommand,
   761                     CheckRepositoryCommand,
   762                     RebuildFTICommand,
   762                     RebuildFTICommand,
   763                     SynchronizeApplicationSchemaCommand,
   763                     SynchronizeInstanceSchemaCommand,
   764                     ) )
   764                     ) )