mirror of
https://github.com/containers/podman.git
synced 2025-06-25 03:52:15 +08:00
Implemented Until Query Parameter for Containers/logs
compat containers/logs was missing actual usage of until query param. fixes #10859 Signed-off-by: cdoern <cdoern@redhat.com>
This commit is contained in:
@ -56,7 +56,7 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
|
||||
for _, nll := range tailLog {
|
||||
nll.CID = c.ID()
|
||||
nll.CName = c.Name()
|
||||
if nll.Since(options.Since) {
|
||||
if nll.Since(options.Since) && nll.Until(options.Until) {
|
||||
logChannel <- nll
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
|
||||
}
|
||||
nll.CID = c.ID()
|
||||
nll.CName = c.Name()
|
||||
if nll.Since(options.Since) {
|
||||
if nll.Since(options.Since) && nll.Until(options.Until) {
|
||||
logChannel <- nll
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
|
||||
}
|
||||
}()
|
||||
|
||||
beforeTimeStamp := true
|
||||
afterTimeStamp := false // needed for options.Since
|
||||
tailQueue := []*logs.LogLine{} // needed for options.Tail
|
||||
doTail := options.Tail > 0
|
||||
@ -156,6 +157,13 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
|
||||
}
|
||||
afterTimeStamp = true
|
||||
}
|
||||
if beforeTimeStamp {
|
||||
entryTime := time.Unix(0, int64(entry.RealtimeTimestamp)*int64(time.Microsecond))
|
||||
if entryTime.Before(options.Until) || !options.Until.IsZero() {
|
||||
continue
|
||||
}
|
||||
beforeTimeStamp = false
|
||||
}
|
||||
|
||||
// If we're reading an event and the container exited/died,
|
||||
// then we're done and can return.
|
||||
|
@ -34,6 +34,7 @@ type LogOptions struct {
|
||||
Details bool
|
||||
Follow bool
|
||||
Since time.Time
|
||||
Until time.Time
|
||||
Tail int64
|
||||
Timestamps bool
|
||||
Multi bool
|
||||
@ -184,7 +185,12 @@ func (l *LogLine) String(options *LogOptions) string {
|
||||
|
||||
// Since returns a bool as to whether a log line occurred after a given time
|
||||
func (l *LogLine) Since(since time.Time) bool {
|
||||
return l.Time.After(since)
|
||||
return l.Time.After(since) || since.IsZero()
|
||||
}
|
||||
|
||||
// Until returns a bool as to whether a log line occurred before a given time
|
||||
func (l *LogLine) Until(until time.Time) bool {
|
||||
return l.Time.Before(until) || until.IsZero()
|
||||
}
|
||||
|
||||
// NewLogLine creates a logLine struct from a container log string
|
||||
|
@ -72,18 +72,20 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var until time.Time
|
||||
if _, found := r.URL.Query()["until"]; found {
|
||||
// FIXME: until != since but the logs backend does not yet support until.
|
||||
since, err = util.ParseInputTime(query.Until)
|
||||
if query.Until != "0" {
|
||||
until, err = util.ParseInputTime(query.Until)
|
||||
if err != nil {
|
||||
utils.BadRequest(w, "until", query.Until, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options := &logs.LogOptions{
|
||||
Details: true,
|
||||
Follow: query.Follow,
|
||||
Since: since,
|
||||
Until: until,
|
||||
Tail: tail,
|
||||
Timestamps: query.Timestamps,
|
||||
}
|
||||
@ -119,7 +121,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
for line := range logChannel {
|
||||
if _, found := r.URL.Query()["until"]; found {
|
||||
if line.Time.After(until) {
|
||||
if line.Time.After(until) && !until.IsZero() {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import random
|
||||
import unittest
|
||||
import json
|
||||
|
||||
import requests
|
||||
from dateutil.parser import parse
|
||||
@ -97,6 +98,18 @@ class ContainerTestCase(APITestCase):
|
||||
def test_logs(self):
|
||||
r = requests.get(self.uri(self.resolve_container("/containers/{}/logs?stdout=true")))
|
||||
self.assertEqual(r.status_code, 200, r.text)
|
||||
r = requests.post(
|
||||
self.podman_url + "/v1.40/containers/create?name=topcontainer",
|
||||
json={"Cmd": ["top", "ls"], "Image": "alpine:latest"},
|
||||
)
|
||||
self.assertEqual(r.status_code, 201, r.text)
|
||||
payload = r.json()
|
||||
container_id = payload["Id"]
|
||||
self.assertIsNotNone(container_id)
|
||||
r = requests.get(self.podman_url + f"/v1.40/containers/{payload['Id']}/logs?follow=false&stdout=true&until=0")
|
||||
self.assertEqual(r.status_code, 200, r.text)
|
||||
r = requests.get(self.podman_url + f"/v1.40/containers/{payload['Id']}/logs?follow=false&stdout=true&until=1")
|
||||
self.assertEqual(r.status_code, 200, r.text)
|
||||
|
||||
def test_commit(self):
|
||||
r = requests.post(self.uri(self.resolve_container("/commit?container={}")))
|
||||
|
Reference in New Issue
Block a user