Add availability_zone to service
Add a new attribute 'availability_zone' to the 'service' resource. This attribute indicates the availability zone of the zun-compute agent. Cloud administrators can customize the availability zone of each compute node by setting the following in the config file: [DEFAULT] default_availability_zone = my-zone If this is not set, the default availability zone is 'nova' (we use this value for consistency with neutron and cinder's defaults). In the future, we will add support for scheduling containers to a specified AZ and the 'availability_zone' attribute will be used by scheduler to check if the availability zone of the compute node equals to the one requested by API users. Change-Id: I4a4206b4eb0aa5149bbfc8ab72ae408a08317de4 Partial-Implements: blueprint zun-availability-zone
This commit is contained in:
parent
4ef02ca76c
commit
df66e4cf58
@ -21,9 +21,13 @@ from zun.api import servicegroup as svcgrp_api
|
||||
from zun.common import exception
|
||||
from zun.common import policy
|
||||
from zun.common import validation
|
||||
import zun.conf
|
||||
from zun import objects
|
||||
|
||||
|
||||
CONF = zun.conf.CONF
|
||||
|
||||
|
||||
class ZunServiceCollection(collection.Collection):
|
||||
|
||||
fields = {
|
||||
@ -41,11 +45,13 @@ class ZunServiceCollection(collection.Collection):
|
||||
collection = ZunServiceCollection()
|
||||
collection.services = []
|
||||
for p in rpc_hsvcs:
|
||||
hsvc = p.as_dict()
|
||||
service = p.as_dict()
|
||||
alive = servicegroup_api.service_is_up(p)
|
||||
state = 'up' if alive else 'down'
|
||||
hsvc['state'] = state
|
||||
collection.services.append(hsvc)
|
||||
service['state'] = state
|
||||
collection.services.append(service)
|
||||
if not service['availability_zone']:
|
||||
service['availability_zone'] = CONF.default_availability_zone
|
||||
next = collection.get_next(limit=None, url=None, **kwargs)
|
||||
if next is not None:
|
||||
collection.next = next
|
||||
|
@ -15,6 +15,7 @@
|
||||
from oslo_config import cfg
|
||||
|
||||
from zun.conf import api
|
||||
from zun.conf import availability_zone
|
||||
from zun.conf import cinder_client
|
||||
from zun.conf import compute
|
||||
from zun.conf import container_driver
|
||||
@ -61,3 +62,4 @@ pci.register_opts(CONF)
|
||||
volume.register_opts(CONF)
|
||||
cinder_client.register_opts(CONF)
|
||||
netconf.register_opts(CONF)
|
||||
availability_zone.register_opts(CONF)
|
||||
|
36
zun/conf/availability_zone.py
Normal file
36
zun/conf/availability_zone.py
Normal file
@ -0,0 +1,36 @@
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
availability_zone_opts = [
|
||||
cfg.StrOpt('default_availability_zone',
|
||||
default='nova',
|
||||
help="""
|
||||
Default availability zone for compute services.
|
||||
|
||||
This option determines the default availability zone for 'zun-compute'
|
||||
services.
|
||||
|
||||
Possible values:
|
||||
|
||||
* Any string representing an existing availability zone name.
|
||||
"""),
|
||||
]
|
||||
|
||||
|
||||
def register_opts(conf):
|
||||
conf.register_opts(availability_zone_opts)
|
||||
|
||||
|
||||
def list_opts():
|
||||
return {'DEFAULT': availability_zone_opts}
|
@ -0,0 +1,34 @@
|
||||
# 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 availability_zone to service
|
||||
|
||||
Revision ID: 3f49fa520409
|
||||
Revises: 50829990c965
|
||||
Create Date: 2018-02-10 22:33:22.890723
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '3f49fa520409'
|
||||
down_revision = '50829990c965'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('zun_service',
|
||||
sa.Column('availability_zone', sa.String(255),
|
||||
nullable=True))
|
@ -122,6 +122,7 @@ class ZunService(Base):
|
||||
last_seen_up = Column(DateTime, nullable=True)
|
||||
forced_down = Column(Boolean, default=False)
|
||||
report_count = Column(Integer, nullable=False, default=0)
|
||||
availability_zone = Column(String(255), nullable=True)
|
||||
|
||||
|
||||
class Container(Base):
|
||||
|
@ -21,7 +21,8 @@ class ZunService(base.ZunPersistentObject, base.ZunObject):
|
||||
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Add update method
|
||||
VERSION = '1.1'
|
||||
# Version 1.2: Add availability_zone field
|
||||
VERSION = '1.2'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
@ -32,6 +33,7 @@ class ZunService(base.ZunPersistentObject, base.ZunObject):
|
||||
'last_seen_up': fields.DateTimeField(nullable=True),
|
||||
'forced_down': fields.BooleanField(),
|
||||
'report_count': fields.IntegerField(),
|
||||
'availability_zone': fields.StringField(nullable=True),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -11,6 +11,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
|
||||
from zun.api import servicegroup
|
||||
from zun import objects
|
||||
@ -35,10 +36,10 @@ class TestZunServiceController(api_base.FunctionalTest):
|
||||
response = self.get_json('/services')
|
||||
self.assertEqual([], response['services'])
|
||||
|
||||
def _rpc_api_reply(self, count=1):
|
||||
def _rpc_api_reply(self, count=1, **kwarg):
|
||||
reclist = []
|
||||
for i in range(count):
|
||||
elem = api_utils.zservice_get_data()
|
||||
elem = api_utils.zservice_get_data(**kwarg)
|
||||
elem['id'] = i + 1
|
||||
rec = DbRec(elem)
|
||||
reclist.append(rec)
|
||||
@ -55,6 +56,8 @@ class TestZunServiceController(api_base.FunctionalTest):
|
||||
response = self.get_json('/services')
|
||||
self.assertEqual(1, len(response['services']))
|
||||
self.assertEqual(1, response['services'][0]['id'])
|
||||
self.assertEqual('fake-zone',
|
||||
response['services'][0]['availability_zone'])
|
||||
|
||||
@mock.patch('zun.common.policy.enforce')
|
||||
@mock.patch.object(objects.ZunService, 'list')
|
||||
@ -71,6 +74,21 @@ class TestZunServiceController(api_base.FunctionalTest):
|
||||
elem = response['services'][i]
|
||||
self.assertEqual(elem['id'], i + 1)
|
||||
|
||||
@mock.patch('zun.common.policy.enforce')
|
||||
@mock.patch.object(objects.ZunService, 'list')
|
||||
@mock.patch.object(servicegroup.ServiceGroup, 'service_is_up')
|
||||
def test_default_availability_zone(self, svc_up, mock_list, mock_policy):
|
||||
cfg.CONF.set_override("default_availability_zone", "default-zone")
|
||||
mock_policy.return_value = True
|
||||
mock_list.return_value = self._rpc_api_reply(availability_zone=None)
|
||||
svc_up.return_value = "up"
|
||||
|
||||
response = self.get_json('/services')
|
||||
self.assertEqual(1, len(response['services']))
|
||||
self.assertEqual(1, response['services'][0]['id'])
|
||||
self.assertEqual('default-zone',
|
||||
response['services'][0]['availability_zone'])
|
||||
|
||||
@mock.patch('zun.common.policy.enforce')
|
||||
@mock.patch.object(objects.ZunService, 'get_by_host_and_binary')
|
||||
@mock.patch.object(objects.ZunService, 'update')
|
||||
|
@ -31,4 +31,5 @@ def zservice_get_data(**kwargs):
|
||||
'last_seen_up': kwargs.get('last_seen_up', faketime),
|
||||
'created_at': kwargs.get('created_at', faketime),
|
||||
'updated_at': kwargs.get('updated_at', faketime),
|
||||
'availability_zone': kwargs.get('availability_zone', 'fake-zone'),
|
||||
}
|
||||
|
@ -198,6 +198,7 @@ def get_test_zun_service(**kwargs):
|
||||
'report_count': kwargs.get('report_count', 13),
|
||||
'created_at': kwargs.get('created_at'),
|
||||
'updated_at': kwargs.get('updated_at'),
|
||||
'availability_zone': kwargs.get('availability_zone', 'fake-zone'),
|
||||
}
|
||||
|
||||
|
||||
|
@ -352,7 +352,7 @@ object_data = {
|
||||
'NUMATopology': '1.0-b54086eda7e4b2e6145ecb6ee2c925ab',
|
||||
'ResourceClass': '1.1-d661c7675b3cd5b8c3618b68ba64324e',
|
||||
'ResourceProvider': '1.0-92b427359d5a4cf9ec6c72cbe630ee24',
|
||||
'ZunService': '1.1-b1549134bfd5271daec417ca8cabc77e',
|
||||
'ZunService': '1.2-deff2a74a9ce23baa231ae12f39a6189',
|
||||
'Capsule': '1.5-cbdaffa78fa68c26cf4a61d8f75dd32d',
|
||||
'PciDevice': '1.1-6e3f0851ad1cf12583e6af4df1883979',
|
||||
'ComputeNode': '1.9-e8536102d3b28cb3378e9e26f508cd72',
|
||||
|
Loading…
Reference in New Issue
Block a user