From 5ffa192b7994322e02e3c89bd35e8f3707560d65 Mon Sep 17 00:00:00 2001 From: "Deng, Qian" Date: Thu, 2 Nov 2017 14:23:45 +0800 Subject: [PATCH] db migration from 1.2.0 to 1.3.0 --- tools/migration/db_meta.py | 43 +++++++++++-- .../migration_harbor/versions/1_3_0.py | 63 +++++++++++++++++++ 2 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 tools/migration/migration_harbor/versions/1_3_0.py diff --git a/tools/migration/db_meta.py b/tools/migration/db_meta.py index b447e5a54..63f102511 100644 --- a/tools/migration/db_meta.py +++ b/tools/migration/db_meta.py @@ -6,8 +6,10 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy.dialects import mysql + Base = declarative_base() + class User(Base): __tablename__ = 'user' @@ -24,12 +26,14 @@ class User(Base): creation_time = sa.Column(mysql.TIMESTAMP) update_time = sa.Column(mysql.TIMESTAMP) + class Properties(Base): __tablename__ = 'properties' k = sa.Column(sa.String(64), primary_key = True) v = sa.Column(sa.String(128), nullable = False) + class ProjectMember(Base): __tablename__ = 'project_member' @@ -42,6 +46,7 @@ class ProjectMember(Base): sa.ForeignKeyConstraint(['role'], [u'role.role_id'], ), sa.ForeignKeyConstraint(['user_id'], [u'user.user_id'], ), + class UserProjectRole(Base): __tablename__ = 'user_project_role' @@ -50,6 +55,7 @@ class UserProjectRole(Base): pr_id = sa.Column(sa.Integer(), sa.ForeignKey('project_role.pr_id')) project_role = relationship("ProjectRole") + class ProjectRole(Base): __tablename__ = 'project_role' @@ -59,6 +65,7 @@ class ProjectRole(Base): sa.ForeignKeyConstraint(['role_id'], [u'role.role_id']) sa.ForeignKeyConstraint(['project_id'], [u'project.project_id']) + class Access(Base): __tablename__ = 'access' @@ -66,6 +73,7 @@ class Access(Base): access_code = sa.Column(sa.String(1)) comment = sa.Column(sa.String(30)) + class Role(Base): __tablename__ = 'role' @@ -74,6 +82,7 @@ class Role(Base): role_code = sa.Column(sa.String(20)) name = sa.Column(sa.String(20)) + class Project(Base): __tablename__ = 'project' @@ -83,9 +92,23 @@ class Project(Base): creation_time = sa.Column(mysql.TIMESTAMP) update_time = sa.Column(mysql.TIMESTAMP) deleted = sa.Column(sa.Integer, nullable=False, server_default=sa.text("'0'")) - public = sa.Column(sa.Integer, nullable=False, server_default=sa.text("'0'")) owner = relationship(u'User') + +class ProjectMetadata(Base): + __tablename__ = 'project_metadata' + + id = sa.Column(sa.Integer, primary_key=True) + project_id = sa.Column(sa.ForeignKey(u'project.project_id'), nullable=False) + name = sa.Column(sa.String(255), nullable=False) + value = sa.Column(sa.String(255)) + creation_time = sa.Column(mysql.TIMESTAMP, server_default=sa.text("CURRENT_TIMESTAMP")) + update_time = sa.Column(mysql.TIMESTAMP, server_default=sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) + deleted = sa.Column(mysql.TINYINT(1), nullable=False, server_default='0') + + __table_args__ = (sa.UniqueConstraint('project_id', 'name', name='unique_project_id_and_name'),) + + class ReplicationPolicy(Base): __tablename__ = "replication_policy" @@ -100,6 +123,7 @@ class ReplicationPolicy(Base): creation_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP")) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) + class ReplicationTarget(Base): __tablename__ = "replication_target" @@ -109,9 +133,11 @@ class ReplicationTarget(Base): username = sa.Column(sa.String(255)) password = sa.Column(sa.String(40)) target_type = sa.Column(mysql.TINYINT(1), nullable=False, server_default=sa.text("'0'")) + insecure = sa.Column(mysql.TINYINT(1), nullable=False, server_default='0') creation_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP")) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) + class ReplicationJob(Base): __tablename__ = "replication_job" @@ -123,9 +149,10 @@ class ReplicationJob(Base): tags = sa.Column(sa.String(16384)) creation_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP")) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) - + __table_args__ = (sa.Index('policy', "policy_id"),) + class Repository(Base): __tablename__ = "repository" @@ -139,6 +166,7 @@ class Repository(Base): creation_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP")) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) + class AccessLog(Base): __tablename__ = "access_log" @@ -152,9 +180,10 @@ class AccessLog(Base): operation = sa.Column(sa.String(20)) op_time = sa.Column(mysql.TIMESTAMP) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) - + __table_args__ = (sa.Index('project_id', "op_time"),) - + + class ImageScanJob(Base): __tablename__ = "img_scan_job" @@ -165,7 +194,8 @@ class ImageScanJob(Base): digest = sa.Column(sa.String(128)) creation_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP")) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) - + + class ImageScanOverview(Base): __tablename__ = "img_scan_overview" @@ -177,7 +207,8 @@ class ImageScanOverview(Base): details_key = sa.Column(sa.String(128)) creation_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP")) update_time = sa.Column(mysql.TIMESTAMP, server_default = sa.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")) - + + class ClairVulnTimestamp(Base): __tablename__ = "clair_vuln_timestamp" diff --git a/tools/migration/migration_harbor/versions/1_3_0.py b/tools/migration/migration_harbor/versions/1_3_0.py new file mode 100644 index 000000000..5983dec1c --- /dev/null +++ b/tools/migration/migration_harbor/versions/1_3_0.py @@ -0,0 +1,63 @@ +# Copyright (c) 2008-2016 VMware, Inc. 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. + +"""1.2.0 to 1.3.0 + +Revision ID: 1.2.0 +Revises: + +""" + +# revision identifiers, used by Alembic. +revision = '1.3.0' +down_revision = '1.2.0' +branch_labels = None +depends_on = None + +from alembic import op +from db_meta import * + +from sqlalchemy.dialects import mysql + +Session = sessionmaker() + +def upgrade(): + """ + update schema&data + """ + bind = op.get_bind() + session = Session(bind=bind) + + # create table project_metadata + ProjectMetadata.__table__.create(bind) + + # migrate public data form project to project meta + # The original type is int in project_meta data value type is string + project_publicity = session.execute('SELECT project_id, public from project').fetchall() + project_metadatas = [ProjectMetadata(project_id=project_id, name='public', value='true' if public else 'false') + for project_id, public in project_publicity] + session.add_all(project_metadatas) + + # drop public column from project + op.drop_column("project", "public") + + # add column insecure to replication target + op.add_column('replication_target', sa.Column('insecure', mysql.TINYINT(1), nullable=False, server_default='0')) + + session.commit() + +def downgrade(): + """ + Downgrade has been disabled. + """