Kaydet (Commit) 4a2db828 authored tarafından Viacheslav Boiko's avatar Viacheslav Boiko

Support the 'since' option in the 'containers/<id>/logs' endpoint

Signed-off-by: 's avatarViacheslav Boiko <v.e.boyko@gmail.com>
üst 7884ab9f
import six import six
import warnings import warnings
from datetime import datetime
from .. import errors from .. import errors
from .. import utils from .. import utils
...@@ -163,7 +164,7 @@ class ContainerApiMixin(object): ...@@ -163,7 +164,7 @@ class ContainerApiMixin(object):
@utils.check_resource @utils.check_resource
def logs(self, container, stdout=True, stderr=True, stream=False, def logs(self, container, stdout=True, stderr=True, stream=False,
timestamps=False, tail='all'): timestamps=False, tail='all', since=None):
if utils.compare_version('1.11', self._version) >= 0: if utils.compare_version('1.11', self._version) >= 0:
params = {'stderr': stderr and 1 or 0, params = {'stderr': stderr and 1 or 0,
'stdout': stdout and 1 or 0, 'stdout': stdout and 1 or 0,
...@@ -174,6 +175,17 @@ class ContainerApiMixin(object): ...@@ -174,6 +175,17 @@ class ContainerApiMixin(object):
if tail != 'all' and (not isinstance(tail, int) or tail <= 0): if tail != 'all' and (not isinstance(tail, int) or tail <= 0):
tail = 'all' tail = 'all'
params['tail'] = tail params['tail'] = tail
if since is not None:
if utils.compare_version('1.19', self._version) < 0:
raise errors.InvalidVersion(
'since is not supported in API < 1.19'
)
else:
if isinstance(since, datetime):
params['since'] = utils.datetime_to_timestamp(since)
elif (isinstance(since, int) and since > 0):
params['since'] = since
url = self._url("/containers/{0}/logs", container) url = self._url("/containers/{0}/logs", container)
res = self._get(url, params=params, stream=stream) res = self._get(url, params=params, stream=stream)
return self._get_result(container, stream, res) return self._get_result(container, stream, res)
......
from .utils import ( from .utils import (
compare_version, convert_port_bindings, convert_volume_binds, compare_version, convert_port_bindings, convert_volume_binds,
mkbuildcontext, tar, exclude_paths, parse_repository_tag, parse_host, mkbuildcontext, tar, exclude_paths, parse_repository_tag, parse_host,
kwargs_from_env, convert_filters, create_host_config, kwargs_from_env, convert_filters, datetime_to_timestamp, create_host_config,
create_container_config, parse_bytes, ping_registry, parse_env_file, create_container_config, parse_bytes, ping_registry, parse_env_file,
version_lt, version_gte version_lt, version_gte
) # flake8: noqa ) # flake8: noqa
......
...@@ -325,6 +325,7 @@ Sets up an exec instance in a running container. ...@@ -325,6 +325,7 @@ Sets up an exec instance in a running container.
* cmd (str or list): Command to be executed * cmd (str or list): Command to be executed
* stdout (bool): Attach to stdout of the exec command if true. Default: True * stdout (bool): Attach to stdout of the exec command if true. Default: True
* stderr (bool): Attach to stderr of the exec command if true. Default: True * stderr (bool): Attach to stderr of the exec command if true. Default: True
* since (UTC datetime or int): Output logs from this timestamp. Default: `None` (all logs are given)
* tty (bool): Allocate a pseudo-TTY. Default: False * tty (bool): Allocate a pseudo-TTY. Default: False
* user (str): User to execute command as. Default: root * user (str): User to execute command as. Default: root
......
...@@ -1439,6 +1439,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): ...@@ -1439,6 +1439,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase):
) )
def test_log_tail(self): def test_log_tail(self):
with mock.patch('docker.Client.inspect_container', with mock.patch('docker.Client.inspect_container',
fake_inspect_container): fake_inspect_container):
self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False, self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False,
...@@ -1453,6 +1454,39 @@ class DockerClientTest(Cleanup, base.BaseTestCase): ...@@ -1453,6 +1454,39 @@ class DockerClientTest(Cleanup, base.BaseTestCase):
stream=False stream=False
) )
def test_log_since(self):
ts = 809222400
with mock.patch('docker.Client.inspect_container',
fake_inspect_container):
self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False,
since=ts)
fake_request.assert_called_with(
'GET',
url_prefix + 'containers/3cc2351ab11b/logs',
params={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1,
'tail': 'all', 'since': ts},
timeout=DEFAULT_TIMEOUT_SECONDS,
stream=False
)
def test_log_since_with_datetime(self):
ts = 809222400
time = datetime.datetime.utcfromtimestamp(ts)
with mock.patch('docker.Client.inspect_container',
fake_inspect_container):
self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False,
since=time)
fake_request.assert_called_with(
'GET',
url_prefix + 'containers/3cc2351ab11b/logs',
params={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1,
'tail': 'all', 'since': ts},
timeout=DEFAULT_TIMEOUT_SECONDS,
stream=False
)
def test_log_tty(self): def test_log_tty(self):
m = mock.Mock() m = mock.Mock()
with mock.patch('docker.Client.inspect_container', with mock.patch('docker.Client.inspect_container',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment