Merge "Improve the container status"

This commit is contained in:
Jenkins 2017-01-22 07:35:16 +00:00 committed by Gerrit Code Review
commit b0bd22e8a2
6 changed files with 98 additions and 12 deletions

View File

@ -34,7 +34,8 @@ _basic_keys = (
'addresses',
'image_pull_policy',
'host',
'restart_policy'
'restart_policy',
'status_detail'
)

View File

@ -11,10 +11,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime
import six
from docker import errors
from oslo_log import log as logging
from oslo_utils import timeutils
from zun.common import exception
from zun.common.i18n import _
@ -131,30 +133,75 @@ class DockerDriver(driver.ContainerDriver):
self._populate_container(container, response)
return container
def format_status_detail(self, status_time):
try:
st = datetime.datetime.strptime((status_time[:-4]),
'%Y-%m-%dT%H:%M:%S.%f')
except ValueError as e:
LOG.exception(_LE("Error on parse {} : {}").format(status_time, e))
return
delta = timeutils.utcnow() - st
time_dict = {}
time_dict['days'] = delta.days
time_dict['hours'] = delta.seconds//3600
time_dict['minutes'] = (delta.seconds % 3600)//60
time_dict['seconds'] = delta.seconds
if time_dict['days']:
return '{} days'.format(time_dict['days'])
if time_dict['hours']:
return '{} hours'.format(time_dict['hours'])
if time_dict['minutes']:
return '{} mins'.format(time_dict['minutes'])
if time_dict['seconds']:
return '{} seconds'.format(time_dict['seconds'])
return
def _populate_container(self, container, response):
status = response.get('State')
if status:
status_detail = ''
if status.get('Error') is True:
container.status = fields.ContainerStatus.ERROR
status_detail = self.format_status_detail(
status.get('FinishedAt'))
container.status_detail = "Exited({}) {} ago " \
"(error)".format(status.get('ExitCode'), status_detail)
elif status.get('Paused'):
container.status = fields.ContainerStatus.PAUSED
status_detail = self.format_status_detail(
status.get('StartedAt'))
container.status_detail = "Up {} (paused)".format(
status_detail)
elif status.get('Running'):
container.status = fields.ContainerStatus.RUNNING
status_detail = self.format_status_detail(
status.get('StartedAt'))
container.status_detail = "Up {}".format(
status_detail)
else:
container.status = fields.ContainerStatus.STOPPED
status_detail = self.format_status_detail(
status.get('FinishedAt'))
container.status_detail = "Exited({}) {} ago ".format(
status.get('ExitCode'), status_detail)
if status_detail is None:
container.status_detail = None
config = response.get('Config')
if config:
# populate hostname
container.hostname = config.get('Hostname')
# populate ports
ports = []
exposed_ports = config.get('ExposedPorts')
if exposed_ports:
for key in exposed_ports:
port = key.split('/')[0]
ports.append(int(port))
container.ports = ports
self._populate_hostname_and_ports(container, config)
def _populate_hostname_and_ports(self, container, config):
# populate hostname
container.hostname = config.get('Hostname')
# populate ports
ports = []
exposed_ports = config.get('ExposedPorts')
if exposed_ports:
for key in exposed_ports:
port = key.split('/')[0]
ports.append(int(port))
container.ports = ports
@check_container_id
def reboot(self, container, timeout):

View File

@ -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_status_detail
Revision ID: ad43a2179cf2
Revises: bbcfa910a8a5
Create Date: 2017-01-17 03:14:50.739446
"""
# revision identifiers, used by Alembic.
revision = 'ad43a2179cf2'
down_revision = 'bbcfa910a8a5'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('container', sa.Column('status_detail',
sa.String(length=50), nullable=True))

View File

@ -147,6 +147,7 @@ class Container(Base):
image_pull_policy = Column(Text, nullable=True)
host = Column(String(255))
restart_policy = Column(JSONEncodedDict)
status_detail = Column(String(50))
class Image(Base):

View File

@ -28,7 +28,8 @@ class Container(base.ZunPersistentObject, base.ZunObject):
# Version 1.6: Add addresses column
# Version 1.7: Add host column
# Version 1.8: Add restart_policy
VERSION = '1.8'
# Version 1.9: Add status_detail column
VERSION = '1.9'
fields = {
'id': fields.IntegerField(),
@ -54,6 +55,7 @@ class Container(base.ZunPersistentObject, base.ZunObject):
'image_pull_policy': fields.StringField(nullable=True),
'host': fields.StringField(nullable=True),
'restart_policy': fields.DictOfStringsField(nullable=True),
'status_detail': fields.StringField(nullable=True)
}
@staticmethod

View File

@ -59,6 +59,7 @@ def get_test_container(**kw):
'host': kw.get('host', 'localhost'),
'restart_policy': kw.get('restart_policy',
{'Name': 'no', 'MaximumRetryCount': '0'}),
'status_detail': kw.get('status_detail', 'up from 5 hours'),
}