#!/usr/bin/python # -*- coding: utf-8 -*- DOCUMENTATION = ''' --- module: glance_manage short_description: Initialize OpenStack Image (glance) database description: Create the tables for the database backend used by glance options: action: description: - action to perform. Currently only dbsync is supported. required: true conf: description: - path to glance-registry config file. required: false default: /etc/glance/glance-registry.conf requirements: [ glance ] author: Lorin Hochstein ''' EXAMPLES = ''' glance_manage: action=dbsync ''' from distutils.version import LooseVersion import os import subprocess import sys try: import glance import sqlalchemy except ImportError: print("failed=True msg='glance is not installed'") sys.exit(1) from glance.version import version_info # this is necessary between the havana and juno releases due to bug 885529 # https://bugs.launchpad.net/glance/+bug/885529 try: from glance.openstack.common import gettextutils gettextutils.install('glance') except ImportError: # gettextutils has been removed in version 2015.1, ignoring the error pass import glance.db.sqlalchemy.api try: glance_version = version_info.version_string() except AttributeError: glance_version = version_info.version if LooseVersion(glance_version) >= LooseVersion('2014.2'): from oslo.config.cfg import CONF from oslo.db.sqlalchemy import migration from migrate.versioning import api as versioning_api from glance.db import migration as db_migration from glance.db.sqlalchemy import api as db_api elif glance_version.startswith('2014.1'): from oslo.config.cfg import CONF from glance.openstack.common.db.sqlalchemy import migration from migrate.versioning import api as versioning_api else: from glance.db.sqlalchemy import migration from glance.common.exception import DatabaseMigrationError from migrate.versioning import api as versioning_api CONF = migration.CONF def is_under_version_control(conf): """ Return true if the database is under version control""" CONF(project='glance', default_config_files=[conf]) try: migration.db_version() except DatabaseMigrationError: return False # db_version() will fail with TypeError on icehouse. Icehouse uses db # migration so we're good. finally: return True def will_db_change(conf): """ Check if the database version will change after the sync """ # Load the config file options if not is_under_version_control(conf): return True if LooseVersion(glance_version) >= LooseVersion('2014.2'): engine = db_api.get_engine() repo_path = db_migration.MIGRATE_REPO_PATH current_version = migration.db_version(db_api.get_engine(), repo_path, db_migration.INIT_VERSION) elif glance_version.startswith('2014.1'): repo_path = os.path.join(os.path.dirname(glance.__file__), 'db', 'sqlalchemy', 'migrate_repo') engine = sqlalchemy.create_engine(CONF.database.connection) current_version = migration.db_version(engine, repo_path, 0) else: repo_path = migration.get_migrate_repo_path() current_version = migration.db_version() repo_version = versioning_api.repository.Repository(repo_path).latest return current_version != repo_version def put_under_version_control(): """ Create the initial sqlalchemy migrate database tables. """ args = ['glance-manage', 'version_control', '0'] call = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = call.communicate() return (call.returncode, out, err) def do_dbsync(): """ Do a database migration """ args = ['glance-manage', 'db_sync'] call = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = call.communicate() return (call.returncode, out, err) def main(): module = AnsibleModule( argument_spec=dict( action=dict(required=True), conf=dict(required=False, default="/etc/glance/glance-registry.conf") ), supports_check_mode=True ) action = module.params['action'] if action not in ['dbsync', 'db_sync']: module.fail_json(msg="Only supported action is 'dbsync'") conf = module.params['conf'] changed = will_db_change(conf) if module.check_mode: module.exit_json(changed=changed) if not is_under_version_control(conf): (res, stdout, stderr) = put_under_version_control() if res != 0: msg = "failed to put glance db under version control" module.fail_json(msg=msg, stdout=stdout, stderr=stderr) (res, stdout, stderr) = do_dbsync() if res != 0: msg = "failed to synchronize glance db with repository" module.fail_json(msg=msg, stdout=stdout, stderr=stderr) module.exit_json(changed=changed) #<> main()