Changeset - 307c876a6e89
[Not reviewed]
default
0 3 0
Mads Kiilerich (mads) - 6 years ago 2020-06-25 01:51:18
mads@kiilerich.com
db: introduce db-create --reuse option

Support use of an existing database so the Kallithea database user doesn't have
to be granted permissions to create databases.

The existing database must of course have been created "correctly", for example
using the right charset and collation on MariaDB/MySQL. Creating the database
manually also provides a way to avoid the hardcoded defaults.
3 files changed with 25 insertions and 6 deletions:
0 comments (0 inline, 0 general)
docs/setup.rst
Show inline comments
 
@@ -84,6 +84,15 @@ repositories Kallithea will add all of t
 
location to its database.  (Note: make sure you specify the correct
 
path to the root).
 

	
 
.. note:: It is also possible to use an existing database. For example,
 
          when using PostgreSQL without granting general createdb privileges to
 
          the PostgreSQL kallithea user, set ``sqlalchemy.url =
 
          postgresql://kallithea:password@localhost/kallithea`` and create the
 
          database like::
 

	
 
              sudo -u postgres createdb 'kallithea' --owner 'kallithea'
 
              kallithea-cli db-create -c my.ini --reuse
 

	
 
Prepare front-end files
 
^^^^^^^^^^^^^^^^^^^^^^^
 

	
kallithea/bin/kallithea_cli_db.py
Show inline comments
 
@@ -20,6 +20,8 @@ from kallithea.model.meta import Session
 

	
 

	
 
@cli_base.register_command(config_file=True)
 
@click.option('--reuse/--no-reuse', default=False,
 
        help='Reuse and clean existing database instead of dropping and creating (default: no reuse)')
 
@click.option('--user', help='Username of administrator account.')
 
@click.option('--password', help='Password for administrator account.')
 
@click.option('--email', help='Email address of administrator account.')
 
@@ -28,7 +30,7 @@ from kallithea.model.meta import Session
 
@click.option('--force-no', is_flag=True, help='Answer no to every question.')
 
@click.option('--public-access/--no-public-access', default=True,
 
        help='Enable/disable public access on this installation (default: enable)')
 
def db_create(user, password, email, repos, force_yes, force_no, public_access):
 
def db_create(user, password, email, repos, force_yes, force_no, public_access, reuse):
 
    """Initialize the database.
 

	
 
    Create all required tables in the database specified in the configuration
 
@@ -57,7 +59,7 @@ def db_create(user, password, email, rep
 
    )
 
    dbmanage = DbManage(dbconf=dbconf, root=kallithea.CONFIG['here'],
 
                        tests=False, cli_args=cli_args)
 
    dbmanage.create_tables()
 
    dbmanage.create_tables(reuse_database=reuse)
 
    repo_root_path = dbmanage.prompt_repo_root_path(None)
 
    dbmanage.create_settings(repo_root_path)
 
    dbmanage.create_default_user()
kallithea/lib/db_manage.py
Show inline comments
 
@@ -72,20 +72,28 @@ class DbManage(object):
 
            init_model(engine)
 
            self.sa = Session()
 

	
 
    def create_tables(self):
 
    def create_tables(self, reuse_database=False):
 
        """
 
        Create database (optional) and tables.
 
        The database will be dropped (if it exists) and a new one created.
 
        If reuse_database is false, the database will be dropped (if it exists)
 
        and a new one created. If true, the existing database will be reused
 
        and cleaned for content.
 
        """
 
        url = sqlalchemy.engine.url.make_url(self.dburi)
 
        database = url.database
 
        log.info("The existing database %r will be destroyed and created." % database)
 
        if reuse_database:
 
            log.info("The content of the database %r will be destroyed and new tables created." % database)
 
        else:
 
            log.info("The existing database %r will be destroyed and a new one created." % database)
 

	
 
        if not self.tests:
 
            if not self._ask_ok('Are you sure to destroy old database? [y/n]'):
 
                print('Nothing done.')
 
                sys.exit(0)
 

	
 
        if True:
 
        if reuse_database:
 
            Base.metadata.drop_all()
 
        else:
 
            if url.drivername == 'mysql':
 
                url.database = None  # don't connect to the database (it might not exist)
 
                engine = sqlalchemy.create_engine(url)
0 comments (0 inline, 0 general)