~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to nova/db/sqlalchemy/migration.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-24 13:12:53 UTC
  • mfrom: (1.1.55)
  • Revision ID: package-import@ubuntu.com-20120524131253-ommql08fg1en06ut
Tags: 2012.2~f1-0ubuntu1
* New upstream release.
* Prepare for quantal:
  - Dropped debian/patches/upstream/0006-Use-project_id-in-ec2.cloud._format_image.patch
  - Dropped debian/patches/upstream/0005-Populate-image-properties-with-project_id-again.patch
  - Dropped debian/patches/upstream/0004-Fixed-bug-962840-added-a-test-case.patch
  - Dropped debian/patches/upstream/0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch
  - Dropped debian/patches/upstream/0002-Stop-libvirt-test-from-deleting-instances-dir.patch
  - Dropped debian/patches/upstream/0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch 
  - Dropped debian/patches/0001-fix-useexisting-deprecation-warnings.patch
* debian/control: Add python-keystone as a dependency. (LP: #907197)
* debian/patches/kombu_tests_timeout.patch: Refreshed.
* debian/nova.conf, debian/nova-common.postinst: Convert to new ini
  file configuration
* debian/patches/nova-manage_flagfile_location.patch: Refreshed

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#    License for the specific language governing permissions and limitations
17
17
#    under the License.
18
18
 
 
19
import distutils.version as dist_version
19
20
import os
20
 
import sys
21
21
 
 
22
from nova.db import migration
 
23
from nova.db.sqlalchemy.session import get_engine
22
24
from nova import exception
23
25
from nova import flags
24
 
 
 
26
from nova import log as logging
 
27
 
 
28
 
 
29
import migrate
 
30
from migrate.versioning import util as migrate_util
25
31
import sqlalchemy
 
32
 
 
33
 
 
34
LOG = logging.getLogger(__name__)
 
35
 
 
36
 
 
37
@migrate_util.decorator
 
38
def patched_with_engine(f, *a, **kw):
 
39
    url = a[0]
 
40
    engine = migrate_util.construct_engine(url, **kw)
 
41
 
 
42
    try:
 
43
        kw['engine'] = engine
 
44
        return f(*a, **kw)
 
45
    finally:
 
46
        if isinstance(engine, migrate_util.Engine) and engine is not url:
 
47
            migrate_util.log.debug('Disposing SQLAlchemy engine %s', engine)
 
48
            engine.dispose()
 
49
 
 
50
 
 
51
# TODO(jkoelker) When migrate 0.7.3 is released and nova depends
 
52
#                on that version or higher, this can be removed
 
53
MIN_PKG_VERSION = dist_version.StrictVersion('0.7.3')
 
54
if (not hasattr(migrate, '__version__') or
 
55
    dist_version.StrictVersion(migrate.__version__) < MIN_PKG_VERSION):
 
56
    migrate_util.with_engine = patched_with_engine
 
57
 
 
58
 
 
59
# NOTE(jkoelker) Delay importing migrate until we are patched
 
60
from migrate import exceptions as versioning_exceptions
26
61
from migrate.versioning import api as versioning_api
27
 
 
28
 
try:
29
 
    from migrate.versioning import exceptions as versioning_exceptions
30
 
except ImportError:
31
 
    try:
32
 
        # python-migration changed location of exceptions after 1.6.3
33
 
        # See LP Bug #717467
34
 
        from migrate import exceptions as versioning_exceptions
35
 
    except ImportError:
36
 
        sys.exit(_("python-migrate is not installed. Exiting."))
 
62
from migrate.versioning.repository import Repository
37
63
 
38
64
FLAGS = flags.FLAGS
39
65
 
 
66
_REPOSITORY = None
 
67
 
40
68
 
41
69
def db_sync(version=None):
42
70
    if version is not None:
43
71
        try:
44
72
            version = int(version)
45
73
        except ValueError:
46
 
            raise exception.Error(_("version should be an integer"))
 
74
            raise exception.NovaException(_("version should be an integer"))
47
75
 
48
76
    current_version = db_version()
49
 
    repo_path = _find_migrate_repo()
 
77
    repository = _find_migrate_repo()
50
78
    if version is None or version > current_version:
51
 
        return versioning_api.upgrade(FLAGS.sql_connection, repo_path, version)
 
79
        return versioning_api.upgrade(get_engine(), repository, version)
52
80
    else:
53
 
        return versioning_api.downgrade(FLAGS.sql_connection, repo_path,
 
81
        return versioning_api.downgrade(get_engine(), repository,
54
82
                                        version)
55
83
 
56
84
 
57
85
def db_version():
58
 
    repo_path = _find_migrate_repo()
 
86
    repository = _find_migrate_repo()
59
87
    try:
60
 
        return versioning_api.db_version(FLAGS.sql_connection, repo_path)
 
88
        return versioning_api.db_version(get_engine(), repository)
61
89
    except versioning_exceptions.DatabaseNotControlledError:
62
 
        # If we aren't version controlled we may already have the database
63
 
        # in the state from before we started version control, check for that
64
 
        # and set up version_control appropriately
65
90
        meta = sqlalchemy.MetaData()
66
 
        engine = sqlalchemy.create_engine(FLAGS.sql_connection, echo=False)
 
91
        engine = get_engine()
67
92
        meta.reflect(bind=engine)
68
 
        try:
69
 
            for table in ('auth_tokens', 'zones', 'export_devices',
70
 
                          'fixed_ips', 'floating_ips', 'instances',
71
 
                          'key_pairs', 'networks', 'projects', 'quotas',
72
 
                          'security_group_instance_association',
73
 
                          'security_group_rules', 'security_groups',
74
 
                          'services', 'migrations',
75
 
                          'users', 'user_project_association',
76
 
                          'user_project_role_association',
77
 
                          'user_role_association',
78
 
                          'virtual_storage_arrays',
79
 
                          'volumes', 'volume_metadata',
80
 
                          'volume_types', 'volume_type_extra_specs'):
81
 
                assert table in meta.tables
82
 
            return db_version_control(1)
83
 
        except AssertionError:
84
 
            return db_version_control(0)
 
93
        tables = meta.tables
 
94
        if len(tables) == 0:
 
95
            db_version_control(migration.INIT_VERSION)
 
96
            return versioning_api.db_version(get_engine(), repository)
 
97
        else:
 
98
            # Some pre-Essex DB's may not be version controlled.
 
99
            # Require them to upgrade using Essex first.
 
100
            raise exception.Error(_("Upgrade DB using Essex release first."))
85
101
 
86
102
 
87
103
def db_version_control(version=None):
88
 
    repo_path = _find_migrate_repo()
89
 
    versioning_api.version_control(FLAGS.sql_connection, repo_path, version)
 
104
    repository = _find_migrate_repo()
 
105
    versioning_api.version_control(get_engine(), repository, version)
90
106
    return version
91
107
 
92
108
 
93
109
def _find_migrate_repo():
94
110
    """Get the path for the migrate repository."""
 
111
    global _REPOSITORY
95
112
    path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
96
113
                        'migrate_repo')
97
114
    assert os.path.exists(path)
98
 
    return path
 
115
    if _REPOSITORY is None:
 
116
        _REPOSITORY = Repository(path)
 
117
    return _REPOSITORY