Esempio n. 1
0
def updateMySQLBackend(backendConfigFile=u'/etc/opsi/backends/mysql.conf',
                       additionalBackendConfiguration={}):
    """
	Applies migrations to the MySQL backend.

	:param backendConfigFile: Path to the file where the backend \
configuration is read from.
	:type backendConfigFile: str
	:param additionalBackendConfiguration: Additional / different \
settings for the backend that will extend / override the configuration \
read from `backendConfigFile`.
	:type additionalBackendConfiguration: dict
	"""

    config = getBackendConfiguration(backendConfigFile)
    config.update(additionalBackendConfiguration)
    LOGGER.info(u"Current mysql backend config: %s" % config)

    LOGGER.notice(u"Connection to database '%s' on '%s' as user '%s'" %
                  (config['database'], config['address'], config['username']))
    mysql = MySQL(**config)

    schemaVersion = readSchemaVersion(mysql)
    LOGGER.debug("Found database schema version {0}", schemaVersion)

    if schemaVersion is None:
        LOGGER.notice("Missing information about database schema. Creating...")
        createSchemaVersionTable(mysql)
        with updateSchemaVersion(mysql, version=0):
            _processOpsi40migrations(mysql)

        schemaVersion = readSchemaVersion(mysql)

    # The migrations that follow are each a function that will take the
    # established database connection as first parameter.
    # Do not change the order of the migrations once released, because
    # this may lead to hard-to-debug inconsistent version numbers.
    migrations = [
        _dropTableBootconfiguration,
        _addIndexOnProductPropertyValues,
        _addWorkbenchAttributesToHosts,
        _adjustLengthOfGroupId,
        _increaseInventoryNumberLength,
    ]

    for newSchemaVersion, migration in enumerate(migrations, start=1):
        if schemaVersion < newSchemaVersion:
            with updateSchemaVersion(mysql, version=newSchemaVersion):
                migration(mysql)

    LOGGER.debug("Expected database schema version: {0}",
                 DATABASE_SCHEMA_VERSION)
    if not readSchemaVersion(mysql) == DATABASE_SCHEMA_VERSION:
        raise BackendUpdateError("Not all migrations have been run!")

    with MySQLBackend(**config) as mysqlBackend:
        # We do this to make sure all tables that are currently
        # non-existing will be created. That creation will give them
        # the currently wanted schema.
        mysqlBackend.backend_createBase()
def testUpdatingSchemaVersion(mysqlBackendConfig, mySQLBackendConfigFile):
    with cleanDatabase(MySQL(**mysqlBackendConfig)) as db:
        createSchemaVersionTable(db)

        version = readSchemaVersion(db)
        assert version is None

        with updateSchemaVersion(db, version=2):
            pass  # NOOP

        version = readSchemaVersion(db)
        assert version == 2
def testReadingSchemaVersionFailsOnUnfinishedUpdate(mysqlBackendConfig,
                                                    mySQLBackendConfigFile):
    with cleanDatabase(MySQL(**mysqlBackendConfig)) as db:
        createSchemaVersionTable(db)

        try:
            with updateSchemaVersion(db, version=1):
                raise RuntimeError("For testing.")
        except RuntimeError:
            pass

        with pytest.raises(DatabaseMigrationUnfinishedError):
            readSchemaVersion(db)
def testReadingSchemaVersionOnlyReturnsNewestValue(mysqlBackendConfig,
                                                   mySQLBackendConfigFile):
    with cleanDatabase(MySQL(**mysqlBackendConfig)) as db:
        createSchemaVersionTable(db)

        with updateSchemaVersion(db, version=1):
            pass

        with updateSchemaVersion(db, version=15):
            pass

        for number in range(1, 4):
            with updateSchemaVersion(db, version=number * 2):
                pass

        with updateSchemaVersion(db, version=3):
            pass

        assert readSchemaVersion(db) == 15
def testReadingSchemaVersionFromEmptyTable(mysqlBackendConfig,
                                           mySQLBackendConfigFile):
    with cleanDatabase(MySQL(**mysqlBackendConfig)) as db:
        createSchemaVersionTable(db)

        assert readSchemaVersion(db) is None