def quicksetup( ctx, non_interactive, profile, email, first_name, last_name, institution, db_engine, db_backend, db_host, db_port, db_name, db_username, db_password, su_db_name, su_db_username, su_db_password, repository ): """Setup a new profile in a fully automated fashion.""" # pylint: disable=too-many-arguments,too-many-locals from aiida.manage.external.postgres import Postgres, manual_setup_instructions dbinfo_su = { 'host': db_host, 'port': db_port, 'user': su_db_username, 'password': su_db_password, } postgres = Postgres(interactive=not non_interactive, quiet=False, dbinfo=dbinfo_su) if not postgres.is_connected: echo.echo_critical('failed to determine the PostgreSQL setup') try: create = True if not postgres.dbuser_exists(db_username): postgres.create_dbuser(db_username, db_password) else: db_name, create = postgres.check_db_name(db_name) if create: postgres.create_db(db_username, db_name) except Exception as exception: echo.echo_error( '\n'.join([ 'Oops! quicksetup was unable to create the AiiDA database for you.', 'For AiiDA to work, please either create the database yourself as follows:', manual_setup_instructions(dbuser=su_db_username, dbname=su_db_name), '', 'Alternatively, give your (operating system) user permission to create postgresql databases' + 'and run quicksetup again.', '' ]) ) raise exception # The contextual defaults or `verdi setup` are not being called when `invoking`, so we have to explicitly define # them here, even though the `verdi setup` command would populate those when called from the command line. setup_parameters = { 'non_interactive': non_interactive, 'profile': profile, 'email': email, 'first_name': first_name, 'last_name': last_name, 'institution': institution, 'db_engine': db_engine, 'db_backend': db_backend, 'db_name': db_name, # from now on we connect as the AiiDA DB user, which may be forbidden when going via sockets 'db_host': db_host or 'localhost', 'db_port': db_port, 'db_username': db_username, 'db_password': db_password, 'repository': repository, } ctx.invoke(setup, **setup_parameters)
def quicksetup( ctx, non_interactive, profile, email, first_name, last_name, institution, db_engine, db_backend, db_host, db_port, db_name, db_username, db_password, su_db_name, su_db_username, su_db_password, broker_protocol, broker_username, broker_password, broker_host, broker_port, broker_virtual_host, repository ): """Setup a new profile in a fully automated fashion.""" # pylint: disable=too-many-arguments,too-many-locals from aiida.manage.external.postgres import Postgres, manual_setup_instructions dbinfo_su = { 'host': db_host, 'port': db_port, 'user': su_db_username, 'password': su_db_password, } postgres = Postgres(interactive=not non_interactive, quiet=False, dbinfo=dbinfo_su) if not postgres.is_connected: echo.echo_critical('failed to determine the PostgreSQL setup') try: db_username, db_name = postgres.create_dbuser_db_safe(dbname=db_name, dbuser=db_username, dbpass=db_password) except Exception as exception: echo.echo_error( '\n'.join([ 'Oops! quicksetup was unable to create the AiiDA database for you.', 'See `verdi quicksetup -h` for how to specify non-standard parameters for the postgresql connection.\n' 'Alternatively, create the AiiDA database yourself: ', manual_setup_instructions(dbuser=su_db_username, dbname=su_db_name), '', 'and then use `verdi setup` instead', '' ]) ) raise exception # The contextual defaults or `verdi setup` are not being called when `invoking`, so we have to explicitly define # them here, even though the `verdi setup` command would populate those when called from the command line. setup_parameters = { 'non_interactive': non_interactive, 'profile': profile, 'email': email, 'first_name': first_name, 'last_name': last_name, 'institution': institution, 'db_engine': db_engine, 'db_backend': db_backend, 'db_name': db_name, # from now on we connect as the AiiDA DB user, which may be forbidden when going via sockets 'db_host': postgres.host_for_psycopg2, 'db_port': postgres.port_for_psycopg2, 'db_username': db_username, 'db_password': db_password, 'broker_protocol': broker_protocol, 'broker_username': broker_username, 'broker_password': broker_password, 'broker_host': broker_host, 'broker_port': broker_port, 'broker_virtual_host': broker_virtual_host, 'repository': repository, } ctx.invoke(setup, **setup_parameters)
def test_determine_setup_fail(self): """Check that setup fails, if bad port is provided. Note: In interactive mode, this would prompt for the connection details. """ postgres = Postgres(interactive=False, quiet=True, dbinfo={'port': '11111'}) self.assertFalse(postgres.is_connected)
def test_setup_fail_callback(self): """Make sure `determine_setup` works despite wrong initial values in case of correct callback""" def correct_setup(interactive, dbinfo): # pylint: disable=unused-argument return self.pg_test.dsn postgres = Postgres(interactive=False, quiet=True, dbinfo={'port': '11111'}, determine_setup=False) postgres.set_setup_fail_callback(correct_setup) setup_success = postgres.determine_setup() self.assertTrue(setup_success)
def create_aiida_db(self): """ Create the necessary database on the temporary postgres instance. """ if configuration.PROFILE is not None: raise TestManagerError('AiiDA dbenv can not be loaded while creating a tests db environment') if self.pg_cluster is None: self.create_db_cluster() self.postgres = Postgres(interactive=False, quiet=True, dbinfo=self.dbinfo) # note: not using postgres.create_dbuser_db_safe here since we don't want prompts self.postgres.create_dbuser(self.profile_info['database_username'], self.profile_info['database_password']) self.postgres.create_db(self.profile_info['database_username'], self.profile_info['database_name']) self.dbinfo = self.postgres.dbinfo self.profile_info['database_hostname'] = self.postgres.host_for_psycopg2 self.profile_info['database_port'] = self.postgres.port_for_psycopg2 self._has_test_db = True
def test_setup(self): """Test `verdi setup`.""" postgres = Postgres(interactive=False, quiet=True, dbinfo=self.pg_test.dsn) postgres.determine_setup() db_name = 'aiida_test_setup' db_user = '******' db_pass = '******' postgres.create_dbuser(db_user, db_pass) postgres.create_db(db_user, db_name) configuration.reset_profile() profile_name = 'testing' user_email = '*****@*****.**' user_first_name = 'John' user_last_name = 'Smith' user_institution = 'ECMA' # Keep the `--profile` option last as a regression test for #2897 and #2907. Some of the other options have # defaults, callbacks and or contextual defaults that might depend on it, but should not fail if they are parsed # before the profile option is parsed. options = [ '--non-interactive', '--email', user_email, '--first-name', user_first_name, '--last-name', user_last_name, '--institution', user_institution, '--db-name', db_name, '--db-username', db_user, '--db-password', db_pass, '--db-port', self.pg_test.dsn['port'], '--db-backend', self.backend, '--profile', profile_name ] result = self.cli_runner.invoke(cmd_setup.setup, options) self.assertClickResultNoException(result) self.assertClickSuccess(result) config = configuration.get_config() self.assertIn(profile_name, config.profile_names) profile = config.get_profile(profile_name) profile.default_user = user_email # Verify that the backend type of the created profile matches that of the profile for the current test session self.assertEqual(self.backend, profile.database_backend) user = orm.User.objects.get(email=user_email) self.assertEqual(user.first_name, user_first_name) self.assertEqual(user.last_name, user_last_name) self.assertEqual(user.institution, user_institution)
def create_db(profile): """Create PostgreSQL database, if missing.""" dbinfo_su = { 'host': profile.database_hostname, 'port': profile.database_port, 'user': os.getenv("AIIDADB_SUPER_USER"), 'password': os.getenv("AIIDADB_SUPER_PASS"), 'database': 'template1', } postgres = Postgres(interactive=False, quiet=False, dbinfo=dbinfo_su) #, determine_setup=False) if not postgres.is_connected: raise ConnectionError("Unable to connect as super user") try: if not postgres.dbuser_exists(dbuser=profile.database_username): postgres.create_dbuser(dbuser=profile.database_username, dbpass=profile.database_password) if not postgres.db_exists(dbname=profile.database_name): postgres.create_db(profile.database_username, profile.database_name) # Fill DB with vanilla content load_profile(profile.name) backend = get_manager()._load_backend(schema_check=False) # pylint: disable=protected-access try: backend.migrate() except Exception as exception: # pylint: disable=broad-except print( 'database migration failed, probably because connection details are incorrect:\n{}' .format(exception)) # Create the user if it does not yet exist created, user = orm.User.objects.get_or_create( email=profile.default_user, first_name='AiiDA', last_name='EXPLORER', institution='WEBSERVICE') if created: user.store() profile.default_user = user.email except: print(traceback.format_exc())
def create_aiida_db(self, pgtest=None): """ Create the necessary database on the temporary postgres instance. By utilizing pgtest it is possible to forward initialization arguments to PGTest(). :param pgtest: a dictionary containing input to PGTest() """ if configuration.PROFILE is not None: raise TestManagerError( 'AiiDA dbenv can not be loaded while creating a tests db environment' ) if self.pg_cluster is None: self.create_db_cluster(pgtest) self.postgres = Postgres(interactive=False, quiet=True, dbinfo=self.dbinfo) self.dbinfo = self.postgres.dbinfo.copy() self.postgres.create_dbuser(self.profile_info['database_username'], self.profile_info['database_password']) self.postgres.create_db(self.profile_info['database_username'], self.profile_info['database_name']) self._has_test_db = True
def _setup_postgres(self): return Postgres(interactive=False, quiet=True, dbinfo=self.pg_test.dsn)
def test_determine_setup_fail(self): postgres = Postgres(interactive=False, quiet=True, dbinfo={'port': '11111'}) self.assertFalse(postgres.is_connected)