Fix usage of isotime

The commit I34b12b96de3ea21beaf935ed8a9f6bae2fe0d0bc and
Ib384ae8130dcc6cbd47a837d11ca171ce02ef29e introduced the
deprecated oslo_utils.timeutils.isotime() is deprecated
as of 1.6 so we need to stop using it.

The deprecation message says to use datetime.datetime.isoformat()
instead, but the format of the string generated by isoformat isn't
the same as the format of the string generated by isotime. The string
is used in tokens and other public APIs and we can't change it
without potentially breaking clients.

So the workaround is to copy the current implementation from
oslo_utils.timeutils.isotime() to gceapi.api.utils.isotime().

For more informations:
https://docs.openstack.org/oslo.utils/latest/reference/timeutils.html

Change-Id: I8c42273695af0fc6108ce9942c7c85f6e2dccc67
Partial-Bug: #1461251
This commit is contained in:
chenghuiyu 2017-09-11 10:04:17 +08:00
parent e6e1642aa0
commit 303960fb2e
5 changed files with 42 additions and 13 deletions

View File

@ -19,8 +19,8 @@ and sufficient to handle supported GCE API requests
"""
from oslo_config import cfg
from oslo_utils import timeutils
from gceapi.api import utils
from gceapi import db
from gceapi import exception
@ -166,7 +166,7 @@ class API(object):
"creationTimestamp" not in db_item):
# TODO(ft): Google doesn't return microseconds but returns
# server time zone: 2013-12-06T03:34:31.340-08:00
utcnow = timeutils.isotime(None, True)
utcnow = utils.isotime(None, True)
db_item["creationTimestamp"] = utcnow
item["creationTimestamp"] = utcnow
db.add_item(context, self._get_type(), db_item)

View File

@ -14,10 +14,9 @@
import uuid
from oslo_utils import timeutils
from gceapi.api import base_api
from gceapi.api import scopes
from gceapi.api import utils
from gceapi import exception
from gceapi.i18n import _
@ -95,7 +94,7 @@ class API(base_api.API):
operation.update(operation_progress)
if operation["progress"] == 100:
operation["status"] = "DONE"
operation["end_time"] = timeutils.isotime(None, True)
operation["end_time"] = utils.isotime(None, True)
self._update_db_item(context, operation)
return operation
@ -105,7 +104,7 @@ class API(base_api.API):
operation = {
"id": operation_id,
"name": "operation-" + operation_id,
"insert_time": timeutils.isotime(context.timestamp, True),
"insert_time": utils.isotime(context.timestamp, True),
"user": context.user_name,
"type": op_type,
"target_type": target_type,
@ -124,7 +123,7 @@ class API(base_api.API):
if method_key is None or "error_code" in operation:
operation["progress"] = 100
operation["status"] = "DONE"
operation["end_time"] = timeutils.isotime(None, True)
operation["end_time"] = utils.isotime(None, True)
else:
operation["progress"] = 0
operation["status"] = "RUNNING"
@ -144,7 +143,7 @@ class API(base_api.API):
operation.update(operation_result)
if operation["progress"] == 100 or "error_code" in operation:
operation["status"] = "DONE"
operation["end_time"] = timeutils.isotime(None, True)
operation["end_time"] = utils.isotime(None, True)
self._update_db_item(context, operation)
def _error_from_exception(self, ex):

View File

@ -14,9 +14,8 @@
import threading
from oslo_utils import timeutils
from gceapi.api import operation_api
from gceapi.api import utils
from gceapi.i18n import _
@ -44,7 +43,7 @@ def save_operation(context, action_result):
def start_operation(context, get_progress_method=None, item_id=None):
if context.operation is None or context.operation_start_time is not None:
return
context.operation_start_time = timeutils.isotime(None, True)
context.operation_start_time = utils.isotime(None, True)
context.operation_get_progress_method = get_progress_method
context.operation_item_id = item_id

View File

@ -14,6 +14,8 @@
"""Utilities and helper functions."""
from oslo_utils import timeutils
def _parse_slash(string):
res = ''
@ -158,3 +160,32 @@ def get_list_kind(type_name):
def get_aggregated_kind(type_name):
return "compute#%sAggregatedList" % type_name
_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f'
_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
def isotime(at=None, subsecond=False):
"""Stringify time in ISO 8601 format."""
# Python provides a similar instance method for datetime.datetime objects
# called isoformat(). The format of the strings generated by isoformat()
# have a couple of problems:
# 1) The strings generated by isotime are used in tokens and other public
# APIs that we can't change without a deprecation period. The strings
# generated by isoformat are not the same format, so we can't just
# change to it.
# 2) The strings generated by isoformat do not include the microseconds if
# the value happens to be 0. This will likely show up as random failures
# as parsers may be written to always expect microseconds, and it will
# parse correctly most of the time.
if not at:
at = timeutils.utcnow()
st = at.strftime(_ISO8601_TIME_FORMAT
if not subsecond
else _ISO8601_TIME_FORMAT_SUBSECOND)
tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
st += ('Z' if tz == 'UTC' else tz)
return st

View File

@ -21,9 +21,9 @@ from keystoneclient.auth import identity as keystone_identity
from keystoneclient import client as keystone_client
from neutronclient.v2_0 import client as neutronclient
from novaclient import client as novaclient
from oslo_utils import timeutils
import gceapi.api
from gceapi.api import utils
from gceapi.tests.unit.api import fake_cinder_client
from gceapi.tests.unit.api import fake_db
from gceapi.tests.unit.api import fake_glance_client
@ -114,7 +114,7 @@ class GCEControllerTest(test.TestCase):
lambda: uuid.UUID("735d48a5-284e-4fb4-a10c-a465ac0b8888"))
# NOTE(ft): we cannot stub datetime.utcnow,
# so we stub conversion from datetime to string
self.stubs.Set(timeutils, "isotime",
self.stubs.Set(utils, "isotime",
lambda x, y: "2013-12-27T08:46:34.684354Z")
def request_gce(self, url, method="GET", body=None):