From 72eac7c8f281de64054dfa07e3f31369c5a251f0 Mon Sep 17 00:00:00 2001 From: weikeyou Date: Fri, 17 Aug 2018 14:05:11 +0800 Subject: [PATCH] Add host to image table This patch solves two problems: 1. When use "zun image-show" to see its details, we donot know which host the image is on. 2. The unique constraint of image table in db is "repo" and "tag". If we pull ubuntu:test image on host1, an error will occur when we pull ubuntu:test on host2. Because the repo:tag that is the unique constrainthas has generated in db. This patch adds host to image table and changes the unique constraint to 'repo', 'tag', 'host'. Change-Id: Id698d15fcc76ea9935d1d6ce4594459dd2ad9319 --- zun/api/controllers/v1/images.py | 1 + .../a019998b09b5_add_host_to_image.py | 38 +++++++++++++++++++ zun/db/sqlalchemy/models.py | 1 + zun/objects/image.py | 6 ++- zun/tests/unit/db/utils.py | 1 + zun/tests/unit/objects/test_objects.py | 2 +- 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 zun/db/sqlalchemy/alembic/versions/a019998b09b5_add_host_to_image.py diff --git a/zun/api/controllers/v1/images.py b/zun/api/controllers/v1/images.py index 8eccd173e..583a381ed 100644 --- a/zun/api/controllers/v1/images.py +++ b/zun/api/controllers/v1/images.py @@ -144,6 +144,7 @@ class ImagesController(base.Controller): image_dict['project_id'] = context.project_id image_dict['user_id'] = context.user_id repo_tag = image_dict.get('repo') + image_dict['host'] = host.hostname image_dict['repo'], image_dict['tag'] = utils.parse_image_name( repo_tag) new_image = objects.Image(context, **image_dict) diff --git a/zun/db/sqlalchemy/alembic/versions/a019998b09b5_add_host_to_image.py b/zun/db/sqlalchemy/alembic/versions/a019998b09b5_add_host_to_image.py new file mode 100644 index 000000000..9e61f2962 --- /dev/null +++ b/zun/db/sqlalchemy/alembic/versions/a019998b09b5_add_host_to_image.py @@ -0,0 +1,38 @@ +# 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 host to image + +Revision ID: a019998b09b5 +Revises: a9c9fb54274a +Create Date: 2018-08-17 13:49:11.470002 + +""" + +# revision identifiers, used by Alembic. +revision = 'a019998b09b5' +down_revision = 'a9c9fb54274a' +branch_labels = None +depends_on = None + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column('image', + sa.Column('host', sa.String(length=255), nullable=True)) + op.drop_constraint(constraint_name='uniq_image0repotag', + table_name='image', type_='unique') + op.create_unique_constraint(constraint_name='uniq_image0repotaghost', + table_name='image', + columns=['repo', 'tag', 'host']) diff --git a/zun/db/sqlalchemy/models.py b/zun/db/sqlalchemy/models.py index f7d6ca99b..5fe6e834b 100644 --- a/zun/db/sqlalchemy/models.py +++ b/zun/db/sqlalchemy/models.py @@ -241,6 +241,7 @@ class Image(Base): repo = Column(String(255)) tag = Column(String(255)) size = Column(String(255)) + host = Column(String(255)) class ResourceProvider(Base): diff --git a/zun/objects/image.py b/zun/objects/image.py index 06ee3891a..b482f66b1 100644 --- a/zun/objects/image.py +++ b/zun/objects/image.py @@ -19,8 +19,9 @@ from zun.objects import base @base.ZunObjectRegistry.register class Image(base.ZunPersistentObject, base.ZunObject): # Version 1.0: Initial version - # Version = '1.1': Add delete image - VERSION = '1.1' + # Version 1.1: Add delete image + # Version 1.2: Add host to image + VERSION = '1.2' fields = { 'id': fields.IntegerField(), @@ -31,6 +32,7 @@ class Image(base.ZunPersistentObject, base.ZunObject): 'repo': fields.StringField(nullable=True), 'tag': fields.StringField(nullable=True), 'size': fields.StringField(nullable=True), + 'host': fields.StringField(nullable=True), } @staticmethod diff --git a/zun/tests/unit/db/utils.py b/zun/tests/unit/db/utils.py index 3faee6ad2..df209139b 100644 --- a/zun/tests/unit/db/utils.py +++ b/zun/tests/unit/db/utils.py @@ -177,6 +177,7 @@ def get_test_image(**kwargs): 'user_id': kwargs.get('user_id', 'fake_user'), 'created_at': kwargs.get('created_at'), 'updated_at': kwargs.get('updated_at'), + 'host': kwargs.get('host', 'host1'), } diff --git a/zun/tests/unit/objects/test_objects.py b/zun/tests/unit/objects/test_objects.py index 0ffb91032..3ccf0a417 100644 --- a/zun/tests/unit/objects/test_objects.py +++ b/zun/tests/unit/objects/test_objects.py @@ -346,7 +346,7 @@ class TestObject(test_base.TestCase, _TestObject): object_data = { 'Container': '1.36-ad2bacdaa51afd0047e96003f93ff181', 'VolumeMapping': '1.3-14e3f9fc64e7afd751727c6ad3f32a94', - 'Image': '1.1-330e6205c80b99b59717e1cfc6a79935', + 'Image': '1.2-80504fdd797e9dd86128a91680e876ad', 'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd', 'NUMANode': '1.0-cba878b70b2f8b52f1e031b41ac13b4e', 'NUMATopology': '1.0-b54086eda7e4b2e6145ecb6ee2c925ab',