Beispiel #1
0
 def _uuidOsspInstalled(self):
     dbstatement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     statement = """
         select count(*) as count
         from pg_available_extensions
         where name = 'uuid-ossp'
         and installed_version IS NOT NULL
     """
     return dbstatement.execute(
         statement=statement,
         args=None,
         ownConnection=True,
         transaction=False,
     )[0]['count'] != 0
Beispiel #2
0
    def _userExists(self, environment):
        dbstatement = database.Statement(
            dbenvkeys=self._dbenvkeys,
            environment=environment,
        )
        hasUser = dbstatement.execute(
            statement="""
                select count(*) as count
                from pg_user
                where usename = %(user)s
            """,
            args=dict(user=_ind_env(self, DEK.USER), ),
            ownConnection=True,
            transaction=False,
        )[0]['count'] != 0

        return hasUser
Beispiel #3
0
 def _checkDatabaseOwnership(self):
     statement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     result = statement.execute(
         statement="""
             select
                 nsp.nspname as object_schema,
                 cls.relname as object_name,
                 rol.rolname as owner,
                 case cls.relkind
                     when 'r' then 'TABLE'
                     when 'i' then 'INDEX'
                     when 'S' then 'SEQUENCE'
                     when 'v' then 'VIEW'
                     when 'c' then 'TYPE'
                 else
                     cls.relkind::text
                 end as object_type
             from
                 pg_class cls join
                 pg_roles rol on rol.oid = cls.relowner join
                 pg_namespace nsp on nsp.oid = cls.relnamespace
             where
                 nsp.nspname not in ('information_schema', 'pg_catalog') and
                 nsp.nspname not like 'pg_%%' and
                 cls.relname not like 'pg_%%' and
                 rol.rolname != %(user)s
             order by
                 nsp.nspname,
                 cls.relname
         """,
         args=dict(
             user=self.environment[oenginecons.EngineDBEnv.USER],
         ),
         ownConnection=True,
         transaction=False,
     )
     if len(result) > 0:
         raise RuntimeError(
             _(
                 'Cannot upgrade the Engine database schema due to wrong '
                 'ownership of some database entities.\n'
             )
         )
Beispiel #4
0
    def _performDatabase(
        self,
        environment,
        op,
    ):
        statements = [
            ("""
                    {op} role {user}
                    with
                        login
                        encrypted password %(password)s
                """).format(
                op=op,
                user=self.environment[self._dbenvkeys['user']],
            ),
            ("""
                    {op} database {database}
                    owner {to} {user}
                    {encoding}
                """).format(
                op=op,
                to='to' if op == 'alter' else '',
                database=self.environment[self._dbenvkeys['database']],
                user=self.environment[self._dbenvkeys['user']],
                encoding="""
                    template template0
                    encoding 'UTF8'
                    lc_collate 'en_US.UTF-8'
                    lc_ctype 'en_US.UTF-8'
                """ if op != 'alter' else '',
            ),
        ]

        dbstatement = database.Statement(
            dbenvkeys=self._dbenvkeys,
            environment=environment,
        )
        for statement in statements:
            dbstatement.execute(
                statement=statement,
                args=dict(
                    password=self.environment[self._dbenvkeys['password']], ),
                ownConnection=True,
                transaction=False,
            )
Beispiel #5
0
    def _validation(self):
        statement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )

        # TODO: in the future go for a new API to fetch this value
        result = statement.execute(
            statement="""
                select version, option_value
                from vdc_options
                where option_name = %(name)s
            """,
            args=dict(
                name='MinimalETLVersion',
            ),
            ownConnection=True,
        )
        if not result:
            raise RuntimeError(
                _('Cannot find MinimalETLVersion in vdc_options')
            )
        minimalVersion = result[0]['option_value']

        minMajor, minMinor, minPatchLevel = self._parseVersionString(
            minimalVersion
        )
        if not (
            (int(odwhcons.Const.VERSION_MAJOR) == int(minMajor)) and
            (int(odwhcons.Const.VERSION_MINOR) == int(minMinor)) and
            (float(odwhcons.Const.VERSION_PATCH_LEVEL) >= int(minPatchLevel))
        ):
            raise RuntimeError(
                _(
                    'Minimal supported DWH version on the engine side is '
                    '{minimal}, and is incompatible with installed DWH '
                    'package version {major}.{minor}.{patch_level}. Please '
                    'upgrade or downgrade engine or DWH as applicable.'
                ).format(
                    minimal=minimalVersion,
                    major=odwhcons.Const.VERSION_MAJOR,
                    minor=odwhcons.Const.VERSION_MINOR,
                    patch_level=odwhcons.Const.VERSION_PATCH_LEVEL,
                )
            )
Beispiel #6
0
    def _get_dwh_host(self):
        self._statement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )

        self._dwhHost = dwh_history_timekeeping.getValueFromTimekeeping(
            statement=self._statement,
            name=dwh_history_timekeeping.DB_KEY_HOSTNAME
        )

        self.logger.debug(
            _(
                'DWH host is {dwhHost}.'
            ).format(
                dwhHost=self._dwhHost,
            )
        )
Beispiel #7
0
 def _closeupDWHConfig(self):
     self._statement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     self._dwh_host = dwh_history_timekeeping.getValueFromTimekeeping(
         statement=self._statement,
         name=dwh_history_timekeeping.DB_KEY_HOSTNAME
     )
     if not self._dwh_host:
         self.dialog.note(
             _(
                 'The engine requires access to the Data Warehouse '
                 'database.\nData Warehouse was not set up. Please set it '
                 'up on some other machine and configure access to it on '
                 'the engine.'
             )
         )
Beispiel #8
0
 def _get_invalid_providers(self):
     dbstatement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     statement = (
         'SELECT id,name,auth_url '
         'FROM providers WHERE '
         'auth_url !~ \'{valid_url}\''.format(
             valid_url=self._VALID_AUTH_URL,
             ownConnection=True,
         )
     )
     return dbstatement.execute(
         statement=statement,
         ownConnection=True,
         transaction=False,
     )
    def _check_provider_exists(self):
        statement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )
        results = statement.execute(
            statement="""
                select id from GetProviderByName(
                    v_name:=%(provider_name)s
                )
            """,
            args=dict(provider_name=self.PROVIDER_NAME, ),
            ownConnection=True,
        )
        if not results:
            return None

        return results[0]['id']
Beispiel #10
0
 def _misc_stop_remote_dwh(self):
     self._statement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     self._dwh_host = dwh_history_timekeeping.getValueFromTimekeeping(
         statement=self._statement,
         name=dwh_history_timekeeping.DB_KEY_HOSTNAME
     )
     if dwh_history_timekeeping.dwhIsUp(self._statement):
         self.logger.info(
             _(
                 'Stopping DWH service on host {hostname}...'
             ).format(
                 hostname=self._dwh_host,
             )
         )
         try:
             self._update_DisconnectDwh('1')
             retries = self.RETRIES
             while dwh_history_timekeeping.dwhIsUp(
                 self._statement
             ) and retries > 0:
                 retries -= 1
                 self.logger.debug(
                     'Waiting for remote dwh to die, %s retries left' %
                     retries
                 )
                 time.sleep(self.DELAY)
         finally:
             self._update_DisconnectDwh('0')
         if dwh_history_timekeeping.dwhIsUp(self._statement):
             self.logger.error(
                 _(
                     'dwhd is currently running.\n'
                     'Its hostname is {hostname}.\n'
                     'Please stop it before running Setup.'
                 ).format(
                     hostname=self._dwh_host,
                 )
             )
             raise RuntimeError(_('dwhd is currently running'))
         self.logger.info(_('Stopped DWH'))
         self._remote_dwh_stopped = True
Beispiel #11
0
    def _validateAsyncTasks(self):
        self.logger.info(
            _('Cleaning async tasks and compensations')
        )

        (
            runningTasks,
            runningCommands,
            compensations,
        ) = self._checkRunningTasks()

        dbstatement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )
        with self._engineInMaintenance(
            dbstatement=dbstatement,
            parent=self,
        ):
            if runningTasks or runningCommands or compensations:
                self._askUserToWaitForTasks(
                    runningTasks,
                    runningCommands,
                    compensations,
                )
                try:
                    self._waitForTasksToClear()
                except KeyboardInterrupt:
                    self.logger.error(
                        _(
                            'Upgrade cannot be completed; asynchronious tasks '
                            'or commands or compensations are still running. '
                            'Please make sure that there are no running tasks '
                            'before you continue.'
                        )
                    )
                    raise RuntimeError(
                        _('Upgrade cannot be completed due to running tasks.')
                    )
            self.logger.info(
                _('Unlocking existing entities')
            )
            self._unlockAll()
Beispiel #12
0
 def _checkCompatibilityVersion(self):
     statement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     supported = set([
         x.strip() for x in self.environment[
             osetupcons.CoreEnv.UPGRADE_SUPPORTED_VERSIONS].split(',')
         if x.strip()
     ])
     vms = statement.execute(
         statement="""
             select
                 vm_name,
                 custom_compatibility_version
             from
                 vms
             where
                 custom_compatibility_version is not null
                 and
                 custom_compatibility_version <> '';
         """,
         ownConnection=True,
         transaction=False,
     )
     if vms:
         names = [
             vm['vm_name'] for vm in vms
             if vm['custom_compatibility_version'] not in supported
         ]
         if names:
             raise RuntimeError(
                 _('Cannot upgrade the Engine due to low '
                   'custom_compatibility_version for virtual machines: '
                   '{r}. Please edit this virtual machines, in edit VM '
                   'dialog go to System->Advanced Parameters -> Custom '
                   'Compatibility Version and either reset to empty '
                   '(cluster default) or set a value supported by the '
                   'new installation: {s}.').format(
                       r=names,
                       s=', '.join(sorted(supported)),
                   ))
Beispiel #13
0
    def _validation_late(self):
        domain = None
        try:
            domain = vdcoption.VdcOption(statement=database.Statement(
                dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
                environment=self.environment,
            ), ).getVdcOption(
                'DomainName',
                ownConnection=True,
            )
        except RuntimeError:
            pass

        if domain:
            raise RuntimeError(
                _('Setup found legacy kerberos/ldap directory '
                  'integration in use (added by engine-manage-domains). '
                  'This provider is no longer supported, please '
                  'migrate to ovirt-engine-extension-aaa-ldap '
                  'provider or contact support for assistance.'))
Beispiel #14
0
    def _checkSupportedVersionsPresent(self):
        # TODO: figure out a better way to do this for the future
        statement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )
        dcVersions = statement.execute(
            statement="""
                SELECT compatibility_version FROM storage_pool;
            """,
            ownConnection=True,
            transaction=False,
        )
        clusterVersions = statement.execute(
            statement="""
                SELECT compatibility_version FROM vds_groups;;
            """,
            ownConnection=True,
            transaction=False,
        )

        versions = set([
            x['compatibility_version']
            for x in dcVersions + clusterVersions
        ])
        supported = set([
            x.strip()
            for x in self.environment[
                osetupcons.CoreEnv.UPGRADE_SUPPORTED_VERSIONS
            ].split(',')
            if x.strip()
        ])

        if versions - supported:
            raise RuntimeError(
                _(
                    'Trying to upgrade from unsupported versions: {versions}'
                ).format(
                    versions=' '.join(versions - supported)
                )
            )
    def connect_to_engine_db(self):
        statement = None
        dbovirtutils = database.OvirtUtils(
            plugin=self,
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
        )
        config = configfile.ConfigFile([
            oenginecons.FileLocations.OVIRT_ENGINE_SERVICE_CONFIG_DEFAULTS,
            oenginecons.FileLocations.OVIRT_ENGINE_SERVICE_CONFIG
        ])
        if config.get('ENGINE_DB_PASSWORD'):
            try:
                dbenv = {}
                for e, k in (
                    (oenginecons.EngineDBEnv.HOST, 'ENGINE_DB_HOST'),
                    (oenginecons.EngineDBEnv.PORT, 'ENGINE_DB_PORT'),
                    (oenginecons.EngineDBEnv.USER, 'ENGINE_DB_USER'),
                    (oenginecons.EngineDBEnv.PASSWORD, 'ENGINE_DB_PASSWORD'),
                    (oenginecons.EngineDBEnv.DATABASE, 'ENGINE_DB_DATABASE'),
                ):
                    dbenv[e] = config.get(k)
                for e, k in ((oenginecons.EngineDBEnv.SECURED,
                              'ENGINE_DB_SECURED'),
                             (oenginecons.EngineDBEnv.SECURED_HOST_VALIDATION,
                              'ENGINE_DB_SECURED_VALIDATION')):
                    dbenv[e] = config.getboolean(k)

                dbovirtutils.tryDatabaseConnect(dbenv)
                self.environment.update(dbenv)
                self.environment[oenginecons.EngineDBEnv.
                                 NEW_DATABASE] = dbovirtutils.isNewDatabase()
                statement = database.Statement(
                    dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
                    environment=self.environment,
                )
            except RuntimeError as e:
                self.logger.debug(
                    'Existing credential use failed',
                    exc_info=True,
                )
        return statement
Beispiel #16
0
    def _validation_late(self):
        domain = None
        try:
            domain = vdcoption.VdcOption(statement=database.Statement(
                dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
                environment=self.environment,
            ), ).getVdcOption(
                'DomainName',
                ownConnection=True,
            )
        except RuntimeError:
            pass

        if domain:
            self.logger.warning(
                _('Setup found legacy kerberos/ldap directory '
                  'integration in use (added by engine-manage-domains). '
                  'This provider is obsoleted and will be removed in '
                  'future. Please migrate to '
                  'ovirt-engine-extension-aaa-ldap provider or contact '
                  'support for assistance.'))
Beispiel #17
0
    def getPostgresLocaleAndEncodingInitEnv(self, ):
        clivals = []
        if not self.supported():
            raise RuntimeError(
                _('Unsupported distribution for automatic '
                  'upgrading postgresql'))

        with AlternateUser(
                user=self.environment[oengcommcons.SystemEnv.USER_POSTGRES], ):
            usockenv = {
                self._dbenvkeys[DEK.HOST]: '',  # usock
                self._dbenvkeys[DEK.PORT]: '',
                self._dbenvkeys[DEK.SECURED]: False,
                self._dbenvkeys[DEK.HOST_VALIDATION]: False,
                self._dbenvkeys[DEK.USER]: 'postgres',
                self._dbenvkeys[DEK.PASSWORD]: '',
                self._dbenvkeys[DEK.DATABASE]: 'postgres',
            }
            self._waitForDatabase(environment=usockenv, )
            dbstatement = database.Statement(
                dbenvkeys=self._dbenvkeys,
                environment=usockenv,
            )
            entities_and_cli_options = {
                'server_encoding': '--encoding={val}',
                'lc_collate': '--lc-collate={val}',
                'lc_ctype': '--lc-ctype={val}',
            }
            for entity, cli_option in entities_and_cli_options.items():
                val = dbstatement.execute(
                    statement="SHOW {entity}".format(entity=entity),
                    ownConnection=True,
                    transaction=False,
                )[0][entity]
                clivals.append(cli_option.format(val=val))

        return {
            'PGSETUP_INITDB_OPTIONS': ' '.join(clivals),
        }
Beispiel #18
0
    def getConfigFiles(self, ):
        if not self.supported():
            raise RuntimeError(
                _('Unsupported distribution for automatic '
                  'upgrading postgresql'))

        conf_f = {}

        with AlternateUser(
                user=self.environment[oengcommcons.SystemEnv.USER_POSTGRES], ):
            usockenv = {
                self._dbenvkeys[DEK.HOST]: '',  # usock
                self._dbenvkeys[DEK.PORT]: '',
                self._dbenvkeys[DEK.SECURED]: False,
                self._dbenvkeys[DEK.HOST_VALIDATION]: False,
                self._dbenvkeys[DEK.USER]: 'postgres',
                self._dbenvkeys[DEK.PASSWORD]: '',
                self._dbenvkeys[DEK.DATABASE]: 'template1',
            }
            self._waitForDatabase(environment=usockenv, )

            dbstatement = database.Statement(
                dbenvkeys=self._dbenvkeys,
                environment=usockenv,
            )
            for f in [
                    'config_file', 'hba_file', 'ident_file', 'data_directory'
            ]:
                ret = dbstatement.execute(
                    statement="SHOW {f}".format(f=f),
                    ownConnection=True,
                    transaction=False,
                )
                conf_f[f] = ret[0][f]

        return conf_f
Beispiel #19
0
    def _validation_late(self):
        adminPassword = None
        try:
            adminPassword = vdcoption.VdcOption(
                statement=database.Statement(
                    dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
                    environment=self.environment,
                ),
            ).getVdcOption(
                'AdminPassword',
                ownConnection=True,
            )
        except RuntimeError:
            pass

        # we have legacy user
        if adminPassword is not None:
            self.environment[
                oenginecons.ConfigEnv.ADMIN_USER_AUTHZ_NAME
            ] = 'internal'
            self.environment[
                oenginecons.ConfigEnv.ADMIN_USER
            ] = 'admin@internal'
            self.environment[
                oenginecons.ConfigEnv.ADMIN_USER_ID
            ] = 'fdfc627c-d875-11e0-90f0-83df133b58cc'
            if self.environment[
                oenginecons.ConfigEnv.ADMIN_PASSWORD
            ] is None:
                if not adminPassword:
                    self.environment[
                        oenginecons.ConfigEnv.ADMIN_PASSWORD
                    ] = ''
                elif os.path.exists(
                    oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_STORE
                ):
                    def _getRSA():
                        rc, stdout, stderr = self.execute(
                            args=(
                                self.command.get('openssl'),
                                'pkcs12',
                                '-in', (
                                    oenginecons.FileLocations.
                                    OVIRT_ENGINE_PKI_ENGINE_STORE
                                ),
                                '-passin', 'pass:%s' % self.environment[
                                    oenginecons.PKIEnv.STORE_PASS
                                ],
                                '-nocerts',
                                '-nodes',
                            ),
                        )
                        return RSA.load_key_string(
                            str('\n'.join(stdout))
                        )

                    self.environment[
                        oenginecons.ConfigEnv.ADMIN_PASSWORD
                    ] = _getRSA().private_decrypt(
                        data=base64.b64decode(adminPassword),
                        padding=RSA.pkcs1_padding,
                    )
                else:
                    self.environment[
                        oenginecons.ConfigEnv.ADMIN_PASSWORD
                    ] = self._generatePassword()
                    self.logger.warning(
                        _(
                            "Cannot decrypt admin's password during upgrade. "
                            "Admin's password was set to a random password: "******"{password}. Please replace password as soon as "
                            "possible."
                        ).format(
                            password=self.environment[
                                oenginecons.ConfigEnv.ADMIN_PASSWORD
                            ],
                        )
                    )
Beispiel #20
0
    def _local_domains_in_use(self):
        res = False
        dbovirtutils = database.OvirtUtils(
            plugin=self,
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
        )
        dbovirtutils.tryDatabaseConnect()
        dbstatement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )
        self._my_domains = []
        rows = dbstatement.execute(
            statement="""
                select
                    s.id,
                    s.status,
                    s.storage,
                    storage_name,
                    connection,
                    storage_domain_type
                from
                    storage_domains s,
                    storage_server_connections c
                where
                    s.storage = c.id and
                    s.storage_type=%(storage_type)s
            """,
            args=dict(storage_type=domains.StorageType.NFS, ),
            ownConnection=True,
        )
        for row in rows:
            host, path = row['connection'].split(':', 1)
            if host == self._current_fqdn:
                self._my_domains.append(row)

        if self._my_domains:
            self.logger.info(_('Engine machine hosting Storage Domains'))

        vms_with_iso = []
        for dom in self._my_domains:
            rows = dbstatement.execute(
                statement="""
                    select
                        distinct vm_name
                    from
                        storage_domains s,
                        vms,
                        cluster c,
                        storage_pool sp,
                        storage_domains sd
                    where
                        sd.storage_pool_id = sp.id and
                        sp.id = c.storage_pool_id and
                        c.cluster_id = vms.cluster_id and
                        sd.id = %(sd_id)s and
                        vms.current_cd != '' and
                        vms.status > 0
                """,
                args=dict(sd_id=dom['id'], ),
                ownConnection=True,
            )
            vms_with_iso.extend([r['vm_name'] for r in rows])
        if vms_with_iso:
            res = True
            self.dialog.note(text=_(
                'The following Virtual Machines have attached ISO images '
                'from one or more of the below Storage Domains:\n'
                '\n'
                '{vms_with_iso}\n'
                '\n'
                'Needed action: They should be shut down, and/or '
                'have the ISO images disconnected (e.g. by ejecting them).'
                '\n\n').format(vms_with_iso='\n'.join(sorted(
                    set(vms_with_iso))), ), )

        vms_with_disks = []
        for dom in self._my_domains:
            rows = dbstatement.execute(
                statement="""
                    select
                        distinct vm_name
                    from
                        all_disks_for_vms adfv,
                        vms
                    where
                        storage_id = %(sd_id)s and
                        adfv.vm_id = vms.vm_guid and
                        vms.status > 0
                """,
                args=dict(sd_id=dom['id'], ),
                ownConnection=True,
            )
            vms_with_disks.extend([r['vm_name'] for r in rows])
        if vms_with_disks:
            res = True
            self.dialog.note(text=_(
                'The following Virtual Machines have attached disk '
                'images from one or more of the below Storage Domains:\n'
                '\n'
                '{vms_with_disks}\n'
                '\n'
                'Needed action: They should be shut down.'
                '\n\n').format(vms_with_disks='\n'.join(
                    sorted(set(vms_with_disks))), ), )

        active_domains = [
            r for r in self._my_domains
            if r['status'] == domains.StorageDomainStatus.ACTIVE
        ]
        if active_domains:
            res = True
            self.dialog.note(text=_(
                'The following Storage Domains use the engine '
                'machine as an NFS server, and are active:\n'
                '\n'
                '{domains}\n'
                '\n'
                'Needed action: They should be moved to Maintenance.'
                '\n\n').format(domains='\n'.join(
                    sorted([d['storage_name'] for d in active_domains]))), )

        if not res and self._my_domains:
            # Lastly inform the user if we are going to rename
            # local storage domains (which are not in use)
            self.dialog.note(text=_(
                'The following Storage Domains use the engine '
                'machine as an NFS server:\n'
                '\n'
                '{domains}\n'
                '\n'
                'They will be modified to use the new name.\n'
                '\n').format(domains='\n'.join(
                    sorted([d['storage_name'] for d in self._my_domains]))), )

        return res
Beispiel #21
0
 def _checkDatabaseOwnership(self):
     statement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     result = statement.execute(
         statement="""
             select
                 nsp.nspname as object_schema,
                 cls.relname as object_name,
                 rol.rolname as owner,
                 case cls.relkind
                     when 'r' then 'TABLE'
                     when 'i' then 'INDEX'
                     when 'S' then 'SEQUENCE'
                     when 'v' then 'VIEW'
                     when 'c' then 'TYPE'
                 else
                     cls.relkind::text
                 end as object_type
             from
                 pg_class cls join
                 pg_roles rol on rol.oid = cls.relowner join
                 pg_namespace nsp on nsp.oid = cls.relnamespace
             where
                 nsp.nspname not in ('information_schema', 'pg_catalog') and
                 nsp.nspname not like 'pg_%%' and
                 rol.rolname != %(user)s
             order by
                 nsp.nspname,
                 cls.relname
         """,
         args=dict(
             user=self.environment[oenginecons.EngineDBEnv.USER],
         ),
         ownConnection=True,
         transaction=False,
     )
     if len(result) > 0:
         raise RuntimeError(
             _(
                 'Cannot upgrade the Engine database schema due to wrong '
                 'ownership of some database entities.\n'
                 'Please execute: {command}\n'
                 'Using the password of the "postgres" user.'
             ).format(
                 command=(
                     '{cmd} '
                     '-s {server} '
                     '-p {port} '
                     '-d {db} '
                     '-f postgres '
                     '-t {user}'
                 ).format(
                     cmd=(
                         oenginecons.FileLocations.
                         OVIRT_ENGINE_DB_CHANGE_OWNER
                     ),
                     server=self.environment[oenginecons.EngineDBEnv.HOST],
                     port=self.environment[oenginecons.EngineDBEnv.PORT],
                     db=self.environment[oenginecons.EngineDBEnv.DATABASE],
                     user=self.environment[oenginecons.EngineDBEnv.USER],
                 ),
             )
         )
Beispiel #22
0
    def _checkSupportedVersionsPresent(self):
        # TODO: figure out a better way to do this for the future
        statement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )
        dcVersions = statement.execute(
            statement="""
                SELECT name, compatibility_version FROM storage_pool;
            """,
            ownConnection=True,
            transaction=False,
        )
        clusterTable = statement.execute(
            statement="""
                SELECT table_name FROM information_schema.tables
                WHERE table_name IN ('vds_groups', 'cluster');
            """,
            ownConnection=True,
            transaction=False,
        )
        sql = _(
            'SELECT name, compatibility_version FROM {table};'
        ).format(
            table=clusterTable[0]['table_name']
        )
        clusterVersions = statement.execute(
            statement=sql,
            ownConnection=True,
            transaction=False,
        )

        versions = set([
            x['compatibility_version']
            for x in dcVersions + clusterVersions
        ])
        supported = set([
            x.strip()
            for x in self.environment[
                osetupcons.CoreEnv.UPGRADE_SUPPORTED_VERSIONS
            ].split(',')
            if x.strip()
        ])

        if versions - supported:
            for (queryres, errmsg) in (
                (
                    dcVersions,
                    _(
                        'The following Data Centers have a too old '
                        'compatibility level, please upgrade them:'
                    )
                ),
                (
                    clusterVersions,
                    _(
                        'The following Clusters have a too old '
                        'compatibility level, please upgrade them:'
                    )
                ),
            ):
                objs = [
                    x['name']
                    for x in queryres
                    if x['compatibility_version'] not in supported
                ]
                if objs:
                    self.logger.error(errmsg)
                    self.dialog.note('\n'.join(objs))

            raise RuntimeError(
                _(
                    'Trying to upgrade from unsupported versions: {versions}'
                ).format(
                    versions=' '.join(versions - supported)
                )
            )
Beispiel #23
0
 def _checkSnapshotCompatibilityVersion(self):
     statement = database.Statement(
         dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
         environment=self.environment,
     )
     supported = set([
         x.strip()
         for x in self.environment[
             osetupcons.CoreEnv.UPGRADE_SUPPORTED_VERSIONS
         ].split(',')
         if x.strip()
     ])
     snapshots = statement.execute(
         statement="""
             select
                 vms.vm_name,
                 snapshots.description,
                 snapshots.vm_configuration
             from
                 vms,
                 snapshots
             where
                 snapshots.vm_id=vms.vm_guid
                 and
                 snapshot_type='REGULAR'
         """,
         ownConnection=True,
         transaction=False,
         logResult=False,
     )
     old_snapshots = []
     if snapshots:
         for snapshot in snapshots:
             vm_configuration = snapshot['vm_configuration']
             creation_date = 'UnknownDate'
             snapshot_cl = 'UnknownLevel'
             try:
                 doc = libxml2.parseDoc(vm_configuration)
                 ctx = doc.xpathNewContext()
                 ctx.xpathRegisterNs(
                     'ovf', 'http://schemas.dmtf.org/ovf/envelope/1/'
                 )
                 compat_level_nodes = ctx.xpathEval(
                     "/ovf:Envelope/Content/ClusterCompatibilityVersion"
                 )
                 if not compat_level_nodes:
                     # Didn't find them, probably because in <= 4.2 we
                     # had a wrong namespace. Try also that one.
                     ctx.xpathRegisterNs(
                         'ovf', 'http://schemas.dmtf.org/ovf/envelope/1'
                     )
                     compat_level_nodes = ctx.xpathEval(
                         "/ovf:Envelope/Content/ClusterCompatibilityVersion"
                     )
                 creation_date_nodes = ctx.xpathEval(
                     "/ovf:Envelope/Content/CreationDate"
                 )
                 if creation_date_nodes:
                     creation_date = creation_date_nodes[0].content
                 if compat_level_nodes:
                     snapshot_cl = compat_level_nodes[0].content
             except Exception:
                 creation_date = 'UnknownDate'
                 snapshot_cl = 'UnknownLevel'
             self.logger.debug(
                 'Found snapshot: %(vm)s:%(snap)s '
                 'created %(date)s version %(v)s',
                 {
                     'vm': snapshot['vm_name'],
                     'snap': snapshot['description'],
                     'date': creation_date,
                     'v': snapshot_cl,
                 },
             )
             if snapshot_cl not in supported:
                 old_snapshots.append(
                     '{vm}:{snap} level {v} (created {date})'.format(
                         vm=snapshot['vm_name'],
                         snap=snapshot['description'],
                         date=creation_date,
                         v=snapshot_cl,
                     )
                 )
         if old_snapshots:
             if not dialog.queryBoolean(
                 dialog=self.dialog,
                 name='OVESETUP_IGNORE_SNAPSHOTS_WITH_OLD_COMPAT_LEVEL',
                 note=_(
                     '\nThe following virtual machines have snapshots with '
                     'older compatibility levels, which are not supported '
                     'by the version you upgrade to, so you will not be '
                     'able to use them:\n\n'
                     '{old_snapshots}\n\n'
                     'Proceed? (@VALUES@) [@DEFAULT@]: '
                 ).format(
                     old_snapshots='\n'.join(old_snapshots),
                 ),
                 default=False,
                 prompt=True,
             ):
                 raise RuntimeError(_('Aborted by user'))
Beispiel #24
0
    def _setDatabaseResources(self, environment):
        dbstatement = database.Statement(
            dbenvkeys=self._dbenvkeys,
            environment=environment,
        )
        hasDatabase = dbstatement.execute(
            statement="""
                select count(*) as count
                from pg_database
                where datname = %(database)s
            """,
            args=dict(
                database=self.environment[
                    self._dbenvkeys['database']
                ],
            ),
            ownConnection=True,
            transaction=False,
        )[0]['count'] != 0
        hasUser = dbstatement.execute(
            statement="""
                select count(*) as count
                from pg_user
                where usename = %(user)s
            """,
            args=dict(
                user=self.environment[
                    self._dbenvkeys['user']
                ],
            ),
            ownConnection=True,
            transaction=False,
        )[0]['count'] != 0

        generate = hasDatabase or hasUser
        existing = False

        if hasDatabase and hasUser:
            dbovirtutils = database.OvirtUtils(
                plugin=self,
                dbenvkeys=self._dbenvkeys,
                environment=environment,
            )
            if dbovirtutils.isNewDatabase(
                database=self.environment[
                    self._dbenvkeys['database']
                ],
            ):
                self.logger.debug('Found empty database')
                generate = False
                existing = True
            else:
                generate = True

        if generate:
            self.logger.debug('Existing resources found, generating names')
            suffix = '_%s' % datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            self.environment[self._dbenvkeys['database']] += suffix
            self.environment[self._dbenvkeys['user']] += suffix
            self._renamedDBResources = True

        return existing
Beispiel #25
0
    def _setup(self):
        dbovirtutils = database.OvirtUtils(
            plugin=self,
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
        )
        dbovirtutils.detectCommands()

        config = configfile.ConfigFile([
            oenginecons.FileLocations.OVIRT_ENGINE_SERVICE_CONFIG_DEFAULTS,
            oenginecons.FileLocations.OVIRT_ENGINE_SERVICE_CONFIG
        ])
        if config.get('ENGINE_DB_PASSWORD'):
            try:
                dbenv = {}
                for e, k in (
                    (oenginecons.EngineDBEnv.HOST, 'ENGINE_DB_HOST'),
                    (oenginecons.EngineDBEnv.PORT, 'ENGINE_DB_PORT'),
                    (oenginecons.EngineDBEnv.USER, 'ENGINE_DB_USER'),
                    (oenginecons.EngineDBEnv.PASSWORD, 'ENGINE_DB_PASSWORD'),
                    (oenginecons.EngineDBEnv.DATABASE, 'ENGINE_DB_DATABASE'),
                ):
                    dbenv[e] = config.get(k)
                for e, k in ((oenginecons.EngineDBEnv.SECURED,
                              'ENGINE_DB_SECURED'),
                             (oenginecons.EngineDBEnv.SECURED_HOST_VALIDATION,
                              'ENGINE_DB_SECURED_VALIDATION')):
                    dbenv[e] = config.getboolean(k)

                dbovirtutils.tryDatabaseConnect(dbenv)
                self.environment.update(dbenv)
                self.environment[oenginecons.EngineDBEnv.
                                 NEW_DATABASE] = dbovirtutils.isNewDatabase()

                self.environment[
                    oenginecons.EngineDBEnv.
                    NEED_DBMSUPGRADE] = dbovirtutils.checkDBMSUpgrade()

            except RuntimeError:
                self.logger.debug(
                    'Existing credential use failed',
                    exc_info=True,
                )
                msg = _('Cannot connect to Engine database using existing '
                        'credentials: {user}@{host}:{port}').format(
                            host=dbenv[oenginecons.EngineDBEnv.HOST],
                            port=dbenv[oenginecons.EngineDBEnv.PORT],
                            database=dbenv[oenginecons.EngineDBEnv.DATABASE],
                            user=dbenv[oenginecons.EngineDBEnv.USER],
                        )
                if self.environment[osetupcons.CoreEnv.
                                    ACTION] == osetupcons.Const.ACTION_REMOVE:
                    self.logger.warning(msg)
                else:
                    raise RuntimeError(msg)
            if not self.environment[oenginecons.EngineDBEnv.NEW_DATABASE]:
                statement = database.Statement(
                    dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
                    environment=self.environment,
                )
                try:
                    justRestored = vdcoption.VdcOption(
                        statement=statement, ).getVdcOption(
                            'DbJustRestored',
                            ownConnection=True,
                        )
                    self.environment[oenginecons.EngineDBEnv.JUST_RESTORED] = (
                        justRestored == '1')
                except RuntimeError:
                    pass
                if self.environment[oenginecons.EngineDBEnv.JUST_RESTORED]:
                    self.logger.info(
                        _('The engine DB has been restored from a backup'))
Beispiel #26
0
    def _validate(self):
        ShowHEError = True
        statement = database.Statement(
            dbenvkeys=oenginecons.Const.ENGINE_DB_ENV_KEYS,
            environment=self.environment,
        )

        try:
            HostedEngineVmName = vdcoption.VdcOption(
                statement=statement, ).getVdcOption(
                    'HostedEngineVmName',
                    ownConnection=True,
                )
        except RuntimeError:
            HostedEngineVmName = 'HostedEngine'

        VdsId = statement.execute(
            statement="""
                SELECT vm_guid, run_on_vds
                FROM vms
                WHERE vm_name = %(HostedEngineVmName)s;
            """,
            args=dict(HostedEngineVmName=HostedEngineVmName, ),
            ownConnection=True,
            transaction=False,
        )

        try:
            if not VdsId[0]['vm_guid']:
                ShowHEError = False
            elif VdsId[0]['run_on_vds']:
                HAGlobalMaintenance = statement.execute(
                    statement="""
                        SELECT vds_id, ha_global_maintenance
                        FROM vds_statistics
                        WHERE vds_id = %(VdsId)s;
                    """,
                    args=dict(VdsId=VdsId[0]['run_on_vds'], ),
                    ownConnection=True,
                    transaction=False,
                )

                try:
                    if HAGlobalMaintenance[0]['ha_global_maintenance']:
                        self.logger.info(
                            _('Hosted Engine HA is in Global Maintenance mode.'
                              ))
                        ShowHEError = False
                except IndexError:
                    pass
        except IndexError:
            ShowHEError = False

        if ShowHEError:
            self.logger.error(
                _('It seems that you are running your engine inside of '
                  'the hosted-engine VM and are not in "Global '
                  'Maintenance" mode.\n'
                  'In that case you should put the system into the "Global '
                  'Maintenance" mode before running engine-setup, or the '
                  'hosted-engine HA agent might kill the machine, which '
                  'might corrupt your data.\n'))
            raise RuntimeError(
                _('Hosted Engine setup detected, '
                  'but Global Maintenance is not set.'))