# (c) Copyright 2012-2014 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import datetime
import uuid

from sqlalchemy import Boolean, Column, DateTime
from sqlalchemy import ForeignKey, MetaData, String, Table

from cinder.openstack.common import log as logging

LOG = logging.getLogger(__name__)

CREATED_AT = datetime.datetime.now()


def upgrade(migrate_engine):
    """Add volume multi attachment table."""
    meta = MetaData()
    meta.bind = migrate_engine

    # add the shareable flag to the volumes table.
    volumes = Table('volumes', meta, autoload=True)
    shareable = Column('shareable', Boolean)
    volumes.create_column(shareable)
    volumes.update().values(shareable=False).execute()

    # The new volume_attachment table
    volume_attachment = Table(
        'volume_attachment', meta,
        Column('created_at', DateTime),
        Column('updated_at', DateTime),
        Column('deleted_at', DateTime),
        Column('deleted', Boolean),
        Column('id', String(length=36), primary_key=True, nullable=False),
        Column('volume_id', String(length=36), ForeignKey('volumes.id'),
               nullable=False),
        Column('attached_host', String(length=255)),
        Column('instance_uuid', String(length=36)),
        Column('mountpoint', String(length=255)),
        Column('attach_time', DateTime),
        Column('detach_time', DateTime),
        Column('attach_mode', String(length=36)),
        Column('attach_status', String(length=255)),
        mysql_engine='InnoDB'
    )

    try:
        volume_attachment.create()
    except Exception:
        LOG.error(_("Table volume_attachment not created!"))
        raise

    # now migrate existing volume attachment info into the
    # new volume_attachment table
    volumes_list = list(volumes.select().execute())
    for volume in volumes_list:
        if volume.attach_status == 'attached':
            attachment = volume_attachment.insert()
            values = {'id': str(uuid.uuid4()),
                      'created_at': CREATED_AT,
                      'volume_id': volume.id,
                      'attached_host': volume.host,
                      'instance_uuid': volume.instance_uuid,
                      'mountpoint': volume.mountpoint,
                      'attach_time': volume.attach_time,
                      'attach_mode': 'rw',
                      'deleted': 0,
                      'attach_status': volume.attach_status,
                      }
            attachment.execute(values)

    # we have no reason to keep the columns that now
    # exist in the volume_attachment table
    mountpoint = volumes.columns.mountpoint
    volumes.drop_column(mountpoint)
    instance_uuid = volumes.columns.instance_uuid
    volumes.drop_column(instance_uuid)
    attach_time = volumes.columns.attach_time
    volumes.drop_column(attach_time)
    attached_host = volumes.columns.attached_host
    volumes.drop_column(attached_host)


def downgrade(migrate_engine):
    """Remove volume_attachment table."""
    meta = MetaData()
    meta.bind = migrate_engine

    # Put the needed volumes table columns back
    volumes = Table('volumes', meta, autoload=True)
    shareable = volumes.columns.shareable
    volumes.drop_column(shareable)

    attached_host = Column('attached_host', String(length=255))
    volumes.create_column(attached_host)
    volumes.update().values(attached_host=None).execute()

    attach_time = Column('attach_time', String(length=255))
    volumes.create_column(attach_time)
    volumes.update().values(attach_time=None).execute()

    instance_uuid = Column('instance_uuid', String(length=36))
    volumes.create_column(instance_uuid)
    volumes.update().values(instance_uuid=None).execute()

    mountpoint = Column('mountpoint', String(length=255))
    volumes.create_column(mountpoint)
    volumes.update().values(mountpoint=None).execute()

    volume_attachment = Table('volume_attachment', meta, autoload=True)
    attachments = list(volume_attachment.select().execute())
    for attachment in attachments:
        # we are going to lose data here for
        # multiple attaches.  We'll migrate and the
        # last update wins.

        if not attachment.deleted_at:
            volume_id = attachment.volume_id
            volumes.update().\
                where(volumes.c.id == volume_id).\
                values(mountpoint=attachment.mountpoint,
                       attached_host=attachment.attached_host,
                       attach_time=attachment.attach_time,
                       instance_uuid=attachment.instance_uuid).\
                execute()
    try:
        volume_attachment.drop()

    except Exception:
        LOG.error(_("Dropping volume_attachment table failed."))
        raise

# (c) Copyright 2012-2014 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import datetime
import uuid

from sqlalchemy import Boolean, Column, DateTime
from sqlalchemy import ForeignKey, MetaData, String, Table

from cinder.openstack.common import log as logging

LOG = logging.getLogger(__name__)

CREATED_AT = datetime.datetime.now()


def upgrade(migrate_engine):
    """Add volume multi attachment table."""
    meta = MetaData()
    meta.bind = migrate_engine

    # add the shareable flag to the volumes table.
    volumes = Table('volumes', meta, autoload=True)
    shareable = Column('shareable', Boolean)
    volumes.create_column(shareable)
    volumes.update().values(shareable=False).execute()

    # The new volume_attachment table
    volume_attachment = Table(
        'volume_attachment', meta,
        Column('created_at', DateTime),
        Column('updated_at', DateTime),
        Column('deleted_at', DateTime),
        Column('deleted', Boolean),
        Column('id', String(length=36), primary_key=True, nullable=False),
        Column('volume_id', String(length=36), ForeignKey('volumes.id'),
               nullable=False),
        Column('attached_host', String(length=255)),
        Column('instance_uuid', String(length=36)),
        Column('mountpoint', String(length=255)),
        Column('attach_time', DateTime),
        Column('detach_time', DateTime),
        Column('attach_mode', String(length=36)),
        Column('attach_status', String(length=255)),
        mysql_engine='InnoDB'
    )

    try:
        volume_attachment.create()
    except Exception:
        LOG.error(_("Table volume_attachment not created!"))
        raise

    # now migrate existing volume attachment info into the
    # new volume_attachment table
    volumes_list = list(volumes.select().execute())
    for volume in volumes_list:
        if volume.attach_status == 'attached':
            attachment = volume_attachment.insert()
            values = {'id': str(uuid.uuid4()),
                      'created_at': CREATED_AT,
                      'volume_id': volume.id,
                      'attached_host': volume.host,
                      'instance_uuid': volume.instance_uuid,
                      'mountpoint': volume.mountpoint,
                      'attach_time': volume.attach_time,
                      'attach_mode': 'rw',
                      'deleted': 0,
                      'attach_status': volume.attach_status,
                      }
            attachment.execute(values)

    # we have no reason to keep the columns that now
    # exist in the volume_attachment table
    mountpoint = volumes.columns.mountpoint
    volumes.drop_column(mountpoint)
    instance_uuid = volumes.columns.instance_uuid
    volumes.drop_column(instance_uuid)
    attach_time = volumes.columns.attach_time
    volumes.drop_column(attach_time)
    attached_host = volumes.columns.attached_host
    volumes.drop_column(attached_host)


def downgrade(migrate_engine):
    """Remove volume_attachment table."""
    meta = MetaData()
    meta.bind = migrate_engine

    # Put the needed volumes table columns back
    volumes = Table('volumes', meta, autoload=True)
    shareable = volumes.columns.shareable
    volumes.drop_column(shareable)

    attached_host = Column('attached_host', String(length=255))
    volumes.create_column(attached_host)
    volumes.update().values(attached_host=None).execute()

    attach_time = Column('attach_time', String(length=255))
    volumes.create_column(attach_time)
    volumes.update().values(attach_time=None).execute()

    instance_uuid = Column('instance_uuid', String(length=36))
    volumes.create_column(instance_uuid)
    volumes.update().values(instance_uuid=None).execute()

    mountpoint = Column('mountpoint', String(length=255))
    volumes.create_column(mountpoint)
    volumes.update().values(mountpoint=None).execute()

    volume_attachment = Table('volume_attachment', meta, autoload=True)
    attachments = list(volume_attachment.select().execute())
    for attachment in attachments:
        # we are going to lose data here for
        # multiple attaches.  We'll migrate and the
        # last update wins.

        if not attachment.deleted_at:
            volume_id = attachment.volume_id
            volumes.update().\
                where(volumes.c.id == volume_id).\
                values(mountpoint=attachment.mountpoint,
                       attached_host=attachment.attached_host,
                       attach_time=attachment.attach_time,
                       instance_uuid=attachment.instance_uuid).\
                execute()
    try:
        volume_attachment.drop()

    except Exception:
        LOG.error(_("Dropping volume_attachment table failed."))
        raise

# (c) Copyright 2012-2014 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # #    Licensed under the Apache License, Version 2.0 (the "License"); you may #    not use this file except in compliance with the License. You may obtain #    a copy of the License at # #         http://www.apache.org/licenses/LICENSE-2.0 # #    Unless required by applicable law or agreed to in writing, software #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the #    License for the specific language governing permissions and limitations #    under the License. Add volume multi attachment table. # add the shareable flag to the volumes table. # The new volume_attachment table # now migrate existing volume attachment info into the # new volume_attachment table # we have no reason to keep the columns that now # exist in the volume_attachment table Remove volume_attachment table. # Put the needed volumes table columns back # we are going to lose data here for # multiple attaches.  We'll migrate and the # last update wins.