mirror of https://github.com/containers/podman.git
podman logs passthrough driver support --cgroups=split
When run with --cgroups=split mode (e.g. quadlet) we do not use the a separate cgroup for the container and just run in the unit cgroup. When we filter logs we thus must match the unit name. Added a small test to the quadlet test to make sure it will work. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
parent
d7e96536ee
commit
79a05ca2b4
|
@ -38,14 +38,14 @@ func (c *Container) ReadLog(ctx context.Context, options *logs.LogOptions, logCh
|
||||||
switch c.LogDriver() {
|
switch c.LogDriver() {
|
||||||
case define.PassthroughLogging:
|
case define.PassthroughLogging:
|
||||||
// if running under systemd fallback to a more native journald reading
|
// if running under systemd fallback to a more native journald reading
|
||||||
if _, ok := c.config.Labels[systemdDefine.EnvVariable]; ok {
|
if unitName, ok := c.config.Labels[systemdDefine.EnvVariable]; ok {
|
||||||
return c.readFromJournal(ctx, options, logChannel, colorID, true)
|
return c.readFromJournal(ctx, options, logChannel, colorID, unitName)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("this container is using the 'passthrough' log driver, cannot read logs: %w", define.ErrNoLogs)
|
return fmt.Errorf("this container is using the 'passthrough' log driver, cannot read logs: %w", define.ErrNoLogs)
|
||||||
case define.NoLogging:
|
case define.NoLogging:
|
||||||
return fmt.Errorf("this container is using the 'none' log driver, cannot read logs: %w", define.ErrNoLogs)
|
return fmt.Errorf("this container is using the 'none' log driver, cannot read logs: %w", define.ErrNoLogs)
|
||||||
case define.JournaldLogging:
|
case define.JournaldLogging:
|
||||||
return c.readFromJournal(ctx, options, logChannel, colorID, false)
|
return c.readFromJournal(ctx, options, logChannel, colorID, "")
|
||||||
case define.JSONLogging:
|
case define.JSONLogging:
|
||||||
// TODO provide a separate implementation of this when Conmon
|
// TODO provide a separate implementation of this when Conmon
|
||||||
// has support.
|
// has support.
|
||||||
|
|
|
@ -32,7 +32,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOptions,
|
func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOptions,
|
||||||
logChannel chan *logs.LogLine, colorID int64, isPassthrough bool) error {
|
logChannel chan *logs.LogLine, colorID int64, passthroughUnit string) error {
|
||||||
// We need the container's events in the same journal to guarantee
|
// We need the container's events in the same journal to guarantee
|
||||||
// consistency, see #10323.
|
// consistency, see #10323.
|
||||||
if options.Follow && c.runtime.config.Engine.EventsLogger != "journald" {
|
if options.Follow && c.runtime.config.Engine.EventsLogger != "journald" {
|
||||||
|
@ -69,7 +69,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
|
||||||
return fmt.Errorf("adding filter disjunction to journald logger: %w", err)
|
return fmt.Errorf("adding filter disjunction to journald logger: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPassthrough {
|
if passthroughUnit != "" {
|
||||||
// Match based on systemd unit which is the container is cgroup
|
// Match based on systemd unit which is the container is cgroup
|
||||||
// so we get the exact logs for a single container even in the
|
// so we get the exact logs for a single container even in the
|
||||||
// play kube case where a single unit starts more than one container.
|
// play kube case where a single unit starts more than one container.
|
||||||
|
@ -77,9 +77,16 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
|
||||||
if rootless.IsRootless() {
|
if rootless.IsRootless() {
|
||||||
unitTypeName = "_SYSTEMD_USER_UNIT"
|
unitTypeName = "_SYSTEMD_USER_UNIT"
|
||||||
}
|
}
|
||||||
// FIXME: It looks like it is hardcoded to libpod-ID.scope but I am not
|
// By default we will have our own systemd cgroup with the name libpod-<ID>.scope.
|
||||||
// sure were we set this with all the different cgroup modes???
|
value := "libpod-" + c.ID() + ".scope"
|
||||||
match = sdjournal.Match{Field: unitTypeName, Value: "libpod-" + c.ID() + ".scope"}
|
if c.config.CgroupsMode == cgroupSplit {
|
||||||
|
// If cgroup split the container runs in the unit cgroup so we use this for logs,
|
||||||
|
// the good thing is we filter the podman events already out below.
|
||||||
|
// Thus we are left with the real container log and possibly podman output (e.g. logrus).
|
||||||
|
value = passthroughUnit
|
||||||
|
}
|
||||||
|
|
||||||
|
match = sdjournal.Match{Field: unitTypeName, Value: value}
|
||||||
if err := journal.AddMatch(match.String()); err != nil {
|
if err := journal.AddMatch(match.String()); err != nil {
|
||||||
return fmt.Errorf("adding filter to journald logger: %v: %w", match, err)
|
return fmt.Errorf("adding filter to journald logger: %v: %w", match, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,6 @@ import (
|
||||||
"github.com/containers/podman/v4/libpod/logs"
|
"github.com/containers/podman/v4/libpod/logs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Container) readFromJournal(_ context.Context, _ *logs.LogOptions, _ chan *logs.LogLine, _ int64, _ bool) error {
|
func (c *Container) readFromJournal(_ context.Context, _ *logs.LogOptions, _ chan *logs.LogLine, _ int64, _ string) error {
|
||||||
return fmt.Errorf("journald logging only enabled with systemd on linux: %w", define.ErrOSNotSupported)
|
return fmt.Errorf("journald logging only enabled with systemd on linux: %w", define.ErrOSNotSupported)
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ function remove_secret() {
|
||||||
cat > $quadlet_file <<EOF
|
cat > $quadlet_file <<EOF
|
||||||
[Container]
|
[Container]
|
||||||
Image=$IMAGE
|
Image=$IMAGE
|
||||||
Exec=sh -c "echo STARTED CONTAINER; echo "READY=1" | socat -u STDIN unix-sendto:\$NOTIFY_SOCKET; top"
|
Exec=sh -c "echo STARTED CONTAINER; echo "READY=1" | socat -u STDIN unix-sendto:\$NOTIFY_SOCKET; sleep inf"
|
||||||
Notify=yes
|
Notify=yes
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -152,6 +152,10 @@ EOF
|
||||||
run journalctl "--since=$STARTED_TIME" --unit="$QUADLET_SERVICE_NAME"
|
run journalctl "--since=$STARTED_TIME" --unit="$QUADLET_SERVICE_NAME"
|
||||||
is "$output" '.*STARTED CONTAINER.*'
|
is "$output" '.*STARTED CONTAINER.*'
|
||||||
|
|
||||||
|
# check that we can read the logs from the container with podman logs
|
||||||
|
run_podman logs $QUADLET_CONTAINER_NAME
|
||||||
|
assert "$output" == "STARTED CONTAINER" "podman logs works on quadlet container"
|
||||||
|
|
||||||
run_podman container inspect --format "{{.State.Status}}" $QUADLET_CONTAINER_NAME
|
run_podman container inspect --format "{{.State.Status}}" $QUADLET_CONTAINER_NAME
|
||||||
is "$output" "running" "container should be started by systemd and hence be running"
|
is "$output" "running" "container should be started by systemd and hence be running"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue