Merge pull request #5770 from baude/v2events

podmanv2 events
This commit is contained in:
OpenShift Merge Robot 2020-04-15 18:37:18 +02:00 committed by GitHub
commit 9b78bf9293
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 189 additions and 0 deletions

View file

@ -0,0 +1,104 @@
package system
import (
"bufio"
"context"
"html/template"
"os"
"github.com/containers/buildah/pkg/formats"
"github.com/containers/libpod/cmd/podmanV2/registry"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
eventsDescription = "Monitor podman events"
eventsCommand = &cobra.Command{
Use: "events",
Args: cobra.NoArgs,
Short: "Show podman events",
Long: eventsDescription,
PersistentPreRunE: preRunE,
RunE: eventsCmd,
Example: `podman events
podman events --filter event=create
podman events --since 1h30s`,
}
)
var (
eventOptions entities.EventsOptions
eventFormat string
)
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: eventsCommand,
})
flags := eventsCommand.Flags()
flags.StringArrayVar(&eventOptions.Filter, "filter", []string{}, "filter output")
flags.StringVar(&eventFormat, "format", "", "format the output using a Go template")
flags.BoolVar(&eventOptions.Stream, "stream", true, "stream new events; for testing only")
flags.StringVar(&eventOptions.Since, "since", "", "show all events created since timestamp")
flags.StringVar(&eventOptions.Until, "until", "", "show all events until timestamp")
_ = flags.MarkHidden("stream")
}
func eventsCmd(cmd *cobra.Command, args []string) error {
var (
err error
eventsError error
tmpl *template.Template
)
if eventFormat != formats.JSONString {
tmpl, err = template.New("events").Parse(eventFormat)
if err != nil {
return err
}
}
if len(eventOptions.Since) > 0 || len(eventOptions.Until) > 0 {
eventOptions.FromStart = true
}
eventChannel := make(chan *events.Event)
eventOptions.EventChan = eventChannel
go func() {
eventsError = registry.ContainerEngine().Events(context.Background(), eventOptions)
}()
if eventsError != nil {
return eventsError
}
w := bufio.NewWriter(os.Stdout)
for event := range eventChannel {
switch {
case eventFormat == formats.JSONString:
jsonStr, err := event.ToJSONString()
if err != nil {
return errors.Wrapf(err, "unable to format json")
}
if _, err := w.Write([]byte(jsonStr)); err != nil {
return err
}
case len(eventFormat) > 0:
if err := tmpl.Execute(w, event); err != nil {
return err
}
default:
if _, err := w.Write([]byte(event.ToHumanReadable())); err != nil {
return err
}
}
if _, err := w.Write([]byte("\n")); err != nil {
return err
}
if err := w.Flush(); err != nil {
return err
}
}
return nil
}

View file

@ -180,6 +180,31 @@ type ExecCreateResponse struct {
docker.IDResponse
}
func (e *Event) ToLibpodEvent() *events.Event {
exitCode, err := strconv.Atoi(e.Actor.Attributes["containerExitCode"])
if err != nil {
return nil
}
status, err := events.StringToStatus(e.Action)
if err != nil {
return nil
}
t, err := events.StringToType(e.Type)
if err != nil {
return nil
}
lp := events.Event{
ContainerExitCode: exitCode,
ID: e.Actor.ID,
Image: e.Actor.Attributes["image"],
Name: e.Actor.Attributes["name"],
Status: status,
Time: time.Unix(e.Time, e.TimeNano),
Type: t,
}
return &lp
}
func EventToApiEvent(e *events.Event) *Event {
return &Event{dockerEvents.Message{
Type: e.Type.String(),

View file

@ -36,6 +36,7 @@ type ContainerEngine interface {
ContainerUnmount(ctx context.Context, nameOrIds []string, options ContainerUnmountOptions) ([]*ContainerUnmountReport, error)
ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
ContainerWait(ctx context.Context, namesOrIds []string, options WaitOptions) ([]WaitReport, error)
Events(ctx context.Context, opts EventsOptions) error
HealthCheckRun(ctx context.Context, nameOrId string, options HealthCheckOptions) (*define.HealthCheckResults, error)
Info(ctx context.Context) (*define.Info, error)
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)

View file

@ -3,6 +3,7 @@ package entities
import (
"net"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/specgen"
"github.com/containers/storage/pkg/archive"
"github.com/cri-o/ocicni/pkg/ocicni"
@ -62,3 +63,12 @@ type DiffOptions struct {
type DiffReport struct {
Changes []archive.Change
}
type EventsOptions struct {
FromStart bool
EventChan chan *events.Event
Filter []string
Stream bool
Since string
Until string
}

View file

@ -0,0 +1,18 @@
//+build ABISupport
package abi
import (
"context"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/sirupsen/logrus"
)
func (ic *ContainerEngine) Events(ctx context.Context, opts entities.EventsOptions) error {
readOpts := events.ReadOptions{FromStart: opts.FromStart, Stream: opts.Stream, Filters: opts.Filter, EventChannel: opts.EventChan, Since: opts.Since, Until: opts.Until}
err := ic.Libpod.Events(readOpts)
logrus.Error(err)
return err
}

View file

@ -0,0 +1,31 @@
package tunnel
import (
"context"
"strings"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/bindings/system"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/pkg/errors"
)
func (ic *ContainerEngine) Events(ctx context.Context, opts entities.EventsOptions) error {
filters := make(map[string][]string)
if len(opts.Filter) > 0 {
for _, filter := range opts.Filter {
split := strings.Split(filter, "=")
if len(split) < 2 {
return errors.Errorf("invalid filter %q", filter)
}
filters[split[0]] = append(filters[split[0]], strings.Join(split[1:], "="))
}
}
binChan := make(chan handlers.Event)
go func() {
for e := range binChan {
opts.EventChan <- e.ToLibpodEvent()
}
}()
return system.Events(ic.ClientCxt, binChan, nil, &opts.Since, &opts.Until, filters)
}