mirror of
https://github.com/containers/podman.git
synced 2025-05-17 23:26:08 +08:00
properly implement pull-error event status
Commit 03f6589f3 added basic support for pull-error event from libimage but it contains several problems: 1. storing the error as error type prevents it from being unmarshalled, thus change it to a string 2. the error was never propagated from the libimage event to the podman event struct 3. the error message was not wired into the cli and API This commit fixes these problems. Fixes #21458 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
@ -1420,10 +1420,10 @@ func AutocompleteEventFilter(cmd *cobra.Command, args []string, toComplete strin
|
|||||||
events.Exited.String(), events.Export.String(), events.Import.String(), events.Init.String(), events.Kill.String(),
|
events.Exited.String(), events.Export.String(), events.Import.String(), events.Init.String(), events.Kill.String(),
|
||||||
events.LoadFromArchive.String(), events.Mount.String(), events.NetworkConnect.String(),
|
events.LoadFromArchive.String(), events.Mount.String(), events.NetworkConnect.String(),
|
||||||
events.NetworkDisconnect.String(), events.Pause.String(), events.Prune.String(), events.Pull.String(),
|
events.NetworkDisconnect.String(), events.Pause.String(), events.Prune.String(), events.Pull.String(),
|
||||||
events.Push.String(), events.Refresh.String(), events.Remove.String(), events.Rename.String(),
|
events.PullError.String(), events.Push.String(), events.Refresh.String(), events.Remove.String(),
|
||||||
events.Renumber.String(), events.Restart.String(), events.Restore.String(), events.Save.String(),
|
events.Rename.String(), events.Renumber.String(), events.Restart.String(), events.Restore.String(),
|
||||||
events.Start.String(), events.Stop.String(), events.Sync.String(), events.Tag.String(), events.Unmount.String(),
|
events.Save.String(), events.Start.String(), events.Stop.String(), events.Sync.String(), events.Tag.String(),
|
||||||
events.Unpause.String(), events.Untag.String(),
|
events.Unmount.String(), events.Unpause.String(), events.Untag.String(),
|
||||||
}, cobra.ShellCompDirectiveNoFileComp
|
}, cobra.ShellCompDirectiveNoFileComp
|
||||||
}
|
}
|
||||||
eventTypes := func(_ string) ([]string, cobra.ShellCompDirective) {
|
eventTypes := func(_ string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
@ -71,6 +71,8 @@ type Event struct {
|
|||||||
Type events.Type
|
Type events.Type
|
||||||
// Health status of the current container
|
// Health status of the current container
|
||||||
HealthStatus string `json:"health_status,omitempty"`
|
HealthStatus string `json:"health_status,omitempty"`
|
||||||
|
// Error code for certain events involving errors.
|
||||||
|
Error string `json:",omitempty"`
|
||||||
|
|
||||||
events.Details
|
events.Details
|
||||||
}
|
}
|
||||||
@ -88,6 +90,7 @@ func newEventFromLibpodEvent(e *events.Event) Event {
|
|||||||
HealthStatus: e.HealthStatus,
|
HealthStatus: e.HealthStatus,
|
||||||
Details: e.Details,
|
Details: e.Details,
|
||||||
TimeNano: e.Time.UnixNano(),
|
TimeNano: e.Time.UnixNano(),
|
||||||
|
Error: e.Error,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ The *image* event type reports the following statuses:
|
|||||||
* loadFromArchive,
|
* loadFromArchive,
|
||||||
* mount
|
* mount
|
||||||
* pull
|
* pull
|
||||||
|
* pull-error
|
||||||
* push
|
* push
|
||||||
* remove
|
* remove
|
||||||
* save
|
* save
|
||||||
@ -104,21 +105,22 @@ In the case where an ID is used, the ID may be in its full or shortened form. T
|
|||||||
|
|
||||||
Format the output to JSON Lines or using the given Go template.
|
Format the output to JSON Lines or using the given Go template.
|
||||||
|
|
||||||
| **Placeholder** | **Description** |
|
| **Placeholder** | **Description** |
|
||||||
|-------------------------|----------------------------------------------- ---|
|
| --------------------- | -------------------------------------------------------------------- |
|
||||||
| .Attributes ... | created_at, _by, labels, and more (map[]) |
|
| .Attributes ... | created_at, _by, labels, and more (map[]) |
|
||||||
| .ContainerExitCode | Exit code (int) |
|
| .ContainerExitCode | Exit code (int) |
|
||||||
| .ContainerInspectData | Payload of the container's inspect |
|
| .ContainerInspectData | Payload of the container's inspect |
|
||||||
| .HealthStatus | Health Status (string) |
|
| .Error | Error message in case the event status is an error (e.g. pull-error) |
|
||||||
| .ID | Container ID (full 64-bit SHA) |
|
| .HealthStatus | Health Status (string) |
|
||||||
| .Image | Name of image being run (string) |
|
| .ID | Container ID (full 64-bit SHA) |
|
||||||
| .Name | Container name (string) |
|
| .Image | Name of image being run (string) |
|
||||||
| .Network | Name of network being used (string) |
|
| .Name | Container name (string) |
|
||||||
| .PodID | ID of pod associated with container, if any |
|
| .Network | Name of network being used (string) |
|
||||||
| .Status | Event status (e.g., create, start, died, ...) |
|
| .PodID | ID of pod associated with container, if any |
|
||||||
| .Time | Event timestamp (string) |
|
| .Status | Event status (e.g., create, start, died, ...) |
|
||||||
| .TimeNano | Event timestamp with nanosecond precision (int64) |
|
| .Time | Event timestamp (string) |
|
||||||
| .Type | Event type (e.g., image, container, pod, ...) |
|
| .TimeNano | Event timestamp with nanosecond precision (int64) |
|
||||||
|
| .Type | Event type (e.g., image, container, pod, ...) |
|
||||||
|
|
||||||
#### **--help**
|
#### **--help**
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ type Event struct {
|
|||||||
// Health status of the current container
|
// Health status of the current container
|
||||||
HealthStatus string `json:"health_status,omitempty"`
|
HealthStatus string `json:"health_status,omitempty"`
|
||||||
// Error code for certain events involving errors.
|
// Error code for certain events involving errors.
|
||||||
Error error `json:"error,omitempty"`
|
Error string `json:"error,omitempty"`
|
||||||
|
|
||||||
Details
|
Details
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,9 @@ func (e *Event) ToHumanReadable(truncate bool) string {
|
|||||||
humanFormat = fmt.Sprintf("%s %s %s %s (container=%s, name=%s)", e.Time, e.Type, e.Status, id, id, e.Network)
|
humanFormat = fmt.Sprintf("%s %s %s %s (container=%s, name=%s)", e.Time, e.Type, e.Status, id, id, e.Network)
|
||||||
case Image:
|
case Image:
|
||||||
humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, id, e.Name)
|
humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, id, e.Name)
|
||||||
|
if e.Error != "" {
|
||||||
|
humanFormat += " " + e.Error
|
||||||
|
}
|
||||||
case System:
|
case System:
|
||||||
if e.Name != "" {
|
if e.Name != "" {
|
||||||
humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, e.Name)
|
humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, e.Name)
|
||||||
|
@ -43,8 +43,8 @@ func (e EventJournalD) Write(ee Event) error {
|
|||||||
case Image:
|
case Image:
|
||||||
m["PODMAN_NAME"] = ee.Name
|
m["PODMAN_NAME"] = ee.Name
|
||||||
m["PODMAN_ID"] = ee.ID
|
m["PODMAN_ID"] = ee.ID
|
||||||
if ee.Error != nil {
|
if ee.Error != "" {
|
||||||
m["ERROR"] = ee.Error.Error()
|
m["ERROR"] = ee.Error
|
||||||
}
|
}
|
||||||
case Container, Pod:
|
case Container, Pod:
|
||||||
m["PODMAN_IMAGE"] = ee.Image
|
m["PODMAN_IMAGE"] = ee.Image
|
||||||
@ -231,8 +231,8 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) {
|
|||||||
newEvent.Network = entry.Fields["PODMAN_NETWORK_NAME"]
|
newEvent.Network = entry.Fields["PODMAN_NETWORK_NAME"]
|
||||||
case Image:
|
case Image:
|
||||||
newEvent.ID = entry.Fields["PODMAN_ID"]
|
newEvent.ID = entry.Fields["PODMAN_ID"]
|
||||||
if _, ok := entry.Fields["ERROR"]; ok {
|
if val, ok := entry.Fields["ERROR"]; ok {
|
||||||
newEvent.Error = errors.New(entry.Fields["ERROR"])
|
newEvent.Error = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &newEvent, nil
|
return &newEvent, nil
|
||||||
|
@ -737,6 +737,9 @@ func (r *Runtime) libimageEvents() {
|
|||||||
Time: libimageEvent.Time,
|
Time: libimageEvent.Time,
|
||||||
Type: events.Image,
|
Type: events.Image,
|
||||||
}
|
}
|
||||||
|
if libimageEvent.Error != nil {
|
||||||
|
e.Error = libimageEvent.Error.Error()
|
||||||
|
}
|
||||||
if err := r.eventer.Write(e); err != nil {
|
if err := r.eventer.Write(e); err != nil {
|
||||||
logrus.Errorf("Unable to write image event: %q", err)
|
logrus.Errorf("Unable to write image event: %q", err)
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,13 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
|||||||
name := e.Actor.Attributes["name"]
|
name := e.Actor.Attributes["name"]
|
||||||
network := e.Actor.Attributes["network"]
|
network := e.Actor.Attributes["network"]
|
||||||
podID := e.Actor.Attributes["podId"]
|
podID := e.Actor.Attributes["podId"]
|
||||||
|
errorString := e.Actor.Attributes["error"]
|
||||||
details := e.Actor.Attributes
|
details := e.Actor.Attributes
|
||||||
delete(details, "image")
|
delete(details, "image")
|
||||||
delete(details, "name")
|
delete(details, "name")
|
||||||
delete(details, "network")
|
delete(details, "network")
|
||||||
delete(details, "podId")
|
delete(details, "podId")
|
||||||
|
delete(details, "error")
|
||||||
delete(details, "containerExitCode")
|
delete(details, "containerExitCode")
|
||||||
return &libpodEvents.Event{
|
return &libpodEvents.Event{
|
||||||
ContainerExitCode: &exitCode,
|
ContainerExitCode: &exitCode,
|
||||||
@ -49,6 +51,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
|
|||||||
Time: time.Unix(0, e.TimeNano),
|
Time: time.Unix(0, e.TimeNano),
|
||||||
Type: t,
|
Type: t,
|
||||||
HealthStatus: e.HealthStatus,
|
HealthStatus: e.HealthStatus,
|
||||||
|
Error: errorString,
|
||||||
Details: libpodEvents.Details{
|
Details: libpodEvents.Details{
|
||||||
PodID: podID,
|
PodID: podID,
|
||||||
Attributes: details,
|
Attributes: details,
|
||||||
@ -71,6 +74,9 @@ func ConvertToEntitiesEvent(e libpodEvents.Event) *types.Event {
|
|||||||
if e.Network != "" {
|
if e.Network != "" {
|
||||||
attributes["network"] = e.Network
|
attributes["network"] = e.Network
|
||||||
}
|
}
|
||||||
|
if e.Error != "" {
|
||||||
|
attributes["error"] = e.Error
|
||||||
|
}
|
||||||
message := dockerEvents.Message{
|
message := dockerEvents.Message{
|
||||||
// Compatibility with clients that still look for deprecated API elements
|
// Compatibility with clients that still look for deprecated API elements
|
||||||
Status: e.Status.String(),
|
Status: e.Status.String(),
|
||||||
|
@ -343,4 +343,14 @@ t GET libpod/images/no-alias-for-sure/resolve 200 \
|
|||||||
t GET libpod/images/noCAPITALcharAllowed/resolve 400 \
|
t GET libpod/images/noCAPITALcharAllowed/resolve 400 \
|
||||||
.cause="repository name must be lowercase"
|
.cause="repository name must be lowercase"
|
||||||
|
|
||||||
|
|
||||||
|
START=$(date +%s.%N)
|
||||||
|
# test pull-error API response
|
||||||
|
podman pull --retry 0 localhost:5000/idonotexist || true
|
||||||
|
t GET "libpod/events?stream=false&since=$START" 200 \
|
||||||
|
.status=pull-error \
|
||||||
|
.Action=pull-error \
|
||||||
|
.Actor.Attributes.name="localhost:5000/idonotexist" \
|
||||||
|
.Actor.Attributes.error~".*connection refused"
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
load helpers
|
load helpers
|
||||||
|
load helpers.network
|
||||||
|
|
||||||
# bats test_tags=distro-integration
|
# bats test_tags=distro-integration
|
||||||
@test "events with a filter by label" {
|
@test "events with a filter by label" {
|
||||||
@ -57,12 +58,15 @@ load helpers
|
|||||||
t0=$(date --iso-8601=seconds)
|
t0=$(date --iso-8601=seconds)
|
||||||
tag=registry.com/$(random_string 10 | tr A-Z a-z)
|
tag=registry.com/$(random_string 10 | tr A-Z a-z)
|
||||||
|
|
||||||
|
bogus_image="localhost:$(random_free_port)/bogus"
|
||||||
|
|
||||||
# Force using the file backend since the journal backend is eating events
|
# Force using the file backend since the journal backend is eating events
|
||||||
# (see containers/podman/pull/10219#issuecomment-842325032).
|
# (see containers/podman/pull/10219#issuecomment-842325032).
|
||||||
run_podman --events-backend=file push $IMAGE dir:$pushedDir
|
run_podman --events-backend=file push $IMAGE dir:$pushedDir
|
||||||
run_podman --events-backend=file save $IMAGE -o $tarball
|
run_podman --events-backend=file save $IMAGE -o $tarball
|
||||||
run_podman --events-backend=file load -i $tarball
|
run_podman --events-backend=file load -i $tarball
|
||||||
run_podman --events-backend=file pull docker-archive:$tarball
|
run_podman --events-backend=file pull docker-archive:$tarball
|
||||||
|
run_podman 125 --events-backend=file pull --retry 0 $bogus_image
|
||||||
run_podman --events-backend=file tag $IMAGE $tag
|
run_podman --events-backend=file tag $IMAGE $tag
|
||||||
run_podman --events-backend=file untag $IMAGE $tag
|
run_podman --events-backend=file untag $IMAGE $tag
|
||||||
run_podman --events-backend=file tag $IMAGE $tag
|
run_podman --events-backend=file tag $IMAGE $tag
|
||||||
@ -74,6 +78,7 @@ load helpers
|
|||||||
.*image save $imageID $tarball
|
.*image save $imageID $tarball
|
||||||
.*image loadfromarchive $imageID $tarball
|
.*image loadfromarchive $imageID $tarball
|
||||||
.*image pull $imageID docker-archive:$tarball
|
.*image pull $imageID docker-archive:$tarball
|
||||||
|
.*image pull-error $bogus_image .*pinging container registry localhost.*connection refused
|
||||||
.*image tag $imageID $tag
|
.*image tag $imageID $tag
|
||||||
.*image untag $imageID $tag:latest
|
.*image untag $imageID $tag:latest
|
||||||
.*image tag $imageID $tag
|
.*image tag $imageID $tag
|
||||||
@ -87,6 +92,7 @@ load helpers
|
|||||||
"save--$tarball"
|
"save--$tarball"
|
||||||
"loadfromarchive--$tarball"
|
"loadfromarchive--$tarball"
|
||||||
"pull--docker-archive:$tarball"
|
"pull--docker-archive:$tarball"
|
||||||
|
"pull-error--$bogus_image"
|
||||||
"tag--$tag"
|
"tag--$tag"
|
||||||
"untag--$tag:latest"
|
"untag--$tag:latest"
|
||||||
"tag--$tag"
|
"tag--$tag"
|
||||||
|
Reference in New Issue
Block a user