mirror of
https://github.com/containers/podman
synced 2024-10-20 17:23:30 +00:00
commit
9b78bf9293
104
cmd/podmanV2/system/events.go
Normal file
104
cmd/podmanV2/system/events.go
Normal 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
|
||||
}
|
|
@ -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(),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
18
pkg/domain/infra/abi/events.go
Normal file
18
pkg/domain/infra/abi/events.go
Normal 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
|
||||
}
|
31
pkg/domain/infra/tunnel/events.go
Normal file
31
pkg/domain/infra/tunnel/events.go
Normal 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)
|
||||
}
|
Loading…
Reference in a new issue