github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/libpod/events/events.go (about)

     1  package events
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/hpcloud/tail"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // ErrNoJournaldLogging indicates that there is no journald logging
    14  // supported (requires libsystemd)
    15  var ErrNoJournaldLogging = errors.New("No support for journald logging")
    16  
    17  // String returns a string representation of EventerType
    18  func (et EventerType) String() string {
    19  	switch et {
    20  	case LogFile:
    21  		return "file"
    22  	case Journald:
    23  		return "journald"
    24  	case Null:
    25  		return "none"
    26  	default:
    27  		return "invalid"
    28  	}
    29  }
    30  
    31  // IsValidEventer checks if the given string is a valid eventer type.
    32  func IsValidEventer(eventer string) bool {
    33  	switch eventer {
    34  	case LogFile.String():
    35  		return true
    36  	case Journald.String():
    37  		return true
    38  	case Null.String():
    39  		return true
    40  	default:
    41  		return false
    42  	}
    43  }
    44  
    45  // NewEvent creates a event struct and populates with
    46  // the given status and time.
    47  func NewEvent(status Status) Event {
    48  	return Event{
    49  		Status: status,
    50  		Time:   time.Now(),
    51  	}
    52  }
    53  
    54  // Recycle checks if the event log has reach a limit and if so
    55  // renames the current log and starts a new one.  The remove bool
    56  // indicates the old log file should be deleted.
    57  func (e *Event) Recycle(path string, remove bool) error {
    58  	return errors.New("not implemented")
    59  }
    60  
    61  // ToJSONString returns the event as a json'ified string
    62  func (e *Event) ToJSONString() (string, error) {
    63  	b, err := json.Marshal(e)
    64  	return string(b), err
    65  }
    66  
    67  // ToHumanReadable returns human readable event as a formatted string
    68  func (e *Event) ToHumanReadable() string {
    69  	var humanFormat string
    70  	switch e.Type {
    71  	case Container, Pod:
    72  		humanFormat = fmt.Sprintf("%s %s %s %s (image=%s, name=%s)", e.Time, e.Type, e.Status, e.ID, e.Image, e.Name)
    73  	case Image:
    74  		humanFormat = fmt.Sprintf("%s %s %s %s %s", e.Time, e.Type, e.Status, e.ID, e.Name)
    75  	case System:
    76  		humanFormat = fmt.Sprintf("%s %s %s", e.Time, e.Type, e.Status)
    77  	case Volume:
    78  		humanFormat = fmt.Sprintf("%s %s %s %s", e.Time, e.Type, e.Status, e.Name)
    79  	}
    80  	return humanFormat
    81  }
    82  
    83  // NewEventFromString takes stringified json and converts
    84  // it to an event
    85  func newEventFromJSONString(event string) (*Event, error) {
    86  	e := Event{}
    87  	if err := json.Unmarshal([]byte(event), &e); err != nil {
    88  		return nil, err
    89  	}
    90  	return &e, nil
    91  
    92  }
    93  
    94  // ToString converts a Type to a string
    95  func (t Type) String() string {
    96  	return string(t)
    97  }
    98  
    99  // ToString converts a status to a string
   100  func (s Status) String() string {
   101  	return string(s)
   102  }
   103  
   104  // StringToType converts string to an EventType
   105  func StringToType(name string) (Type, error) {
   106  	switch name {
   107  	case Container.String():
   108  		return Container, nil
   109  	case Image.String():
   110  		return Image, nil
   111  	case Pod.String():
   112  		return Pod, nil
   113  	case System.String():
   114  		return System, nil
   115  	case Volume.String():
   116  		return Volume, nil
   117  	case "":
   118  		return "", ErrEventTypeBlank
   119  	}
   120  	return "", errors.Errorf("unknown event type %q", name)
   121  }
   122  
   123  // StringToStatus converts a string to an Event Status
   124  // TODO if we add more events, we might consider a go-generator to
   125  // create the switch statement
   126  func StringToStatus(name string) (Status, error) {
   127  	switch name {
   128  	case Attach.String():
   129  		return Attach, nil
   130  	case Checkpoint.String():
   131  		return Checkpoint, nil
   132  	case Cleanup.String():
   133  		return Cleanup, nil
   134  	case Commit.String():
   135  		return Commit, nil
   136  	case Create.String():
   137  		return Create, nil
   138  	case Exec.String():
   139  		return Exec, nil
   140  	case Exited.String():
   141  		return Exited, nil
   142  	case Export.String():
   143  		return Export, nil
   144  	case History.String():
   145  		return History, nil
   146  	case Import.String():
   147  		return Import, nil
   148  	case Init.String():
   149  		return Init, nil
   150  	case Kill.String():
   151  		return Kill, nil
   152  	case LoadFromArchive.String():
   153  		return LoadFromArchive, nil
   154  	case Mount.String():
   155  		return Mount, nil
   156  	case Pause.String():
   157  		return Pause, nil
   158  	case Prune.String():
   159  		return Prune, nil
   160  	case Pull.String():
   161  		return Pull, nil
   162  	case Push.String():
   163  		return Push, nil
   164  	case Refresh.String():
   165  		return Refresh, nil
   166  	case Remove.String():
   167  		return Remove, nil
   168  	case Renumber.String():
   169  		return Renumber, nil
   170  	case Restart.String():
   171  		return Restart, nil
   172  	case Restore.String():
   173  		return Restore, nil
   174  	case Save.String():
   175  		return Save, nil
   176  	case Start.String():
   177  		return Start, nil
   178  	case Stop.String():
   179  		return Stop, nil
   180  	case Sync.String():
   181  		return Sync, nil
   182  	case Tag.String():
   183  		return Tag, nil
   184  	case Unmount.String():
   185  		return Unmount, nil
   186  	case Unpause.String():
   187  		return Unpause, nil
   188  	case Untag.String():
   189  		return Untag, nil
   190  	}
   191  	return "", errors.Errorf("unknown event status %q", name)
   192  }
   193  
   194  func (e EventLogFile) getTail(options ReadOptions) (*tail.Tail, error) {
   195  	reopen := true
   196  	seek := tail.SeekInfo{Offset: 0, Whence: os.SEEK_END}
   197  	if options.FromStart || !options.Stream {
   198  		seek.Whence = 0
   199  		reopen = false
   200  	}
   201  	stream := options.Stream
   202  	if len(options.Until) > 0 {
   203  		stream = false
   204  	}
   205  	return tail.TailFile(e.options.LogFilePath, tail.Config{ReOpen: reopen, Follow: stream, Location: &seek, Logger: tail.DiscardingLogger})
   206  }