diff options
Diffstat (limited to 'pkg/adapter/runtime.go')
-rw-r--r-- | pkg/adapter/runtime.go | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index 732b89530..a0951f677 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -3,11 +3,13 @@ package adapter import ( + "bufio" "context" "io" "io/ioutil" "os" "strconv" + "text/template" "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" @@ -16,7 +18,9 @@ import ( "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" + "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" @@ -337,3 +341,92 @@ func IsImageNotFound(err error) bool { func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) { return r.Runtime.HealthCheck(c.InputArgs[0]) } + +// JoinOrCreateRootlessPod joins the specified pod if it is running or it creates a new user namespace +// if the pod is stopped +func (r *LocalRuntime) JoinOrCreateRootlessPod(pod *Pod) (bool, int, error) { + if os.Geteuid() == 0 { + return false, 0, nil + } + opts := rootless.Opts{ + Argument: pod.ID(), + } + + inspect, err := pod.Inspect() + if err != nil { + return false, 0, err + } + for _, ctr := range inspect.Containers { + prevCtr, err := r.LookupContainer(ctr.ID) + if err != nil { + return false, -1, err + } + s, err := prevCtr.State() + if err != nil { + return false, -1, err + } + if s != libpod.ContainerStateRunning && s != libpod.ContainerStatePaused { + continue + } + data, err := ioutil.ReadFile(prevCtr.Config().ConmonPidFile) + if err != nil { + return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", prevCtr.Config().ConmonPidFile) + } + conmonPid, err := strconv.Atoi(string(data)) + if err != nil { + return false, -1, errors.Wrapf(err, "cannot parse PID %q", data) + } + return rootless.JoinDirectUserAndMountNSWithOpts(uint(conmonPid), &opts) + } + + return rootless.BecomeRootInUserNSWithOpts(&opts) +} + +// Events is a wrapper to libpod to obtain libpod/podman events +func (r *LocalRuntime) Events(c *cliconfig.EventValues) error { + var ( + fromStart bool + eventsError error + ) + options, err := shared.GenerateEventOptions(c.Filter, c.Since, c.Until) + if err != nil { + return errors.Wrapf(err, "unable to generate event options") + } + tmpl, err := template.New("events").Parse(c.Format) + if err != nil { + return err + } + if len(c.Since) > 0 || len(c.Until) > 0 { + fromStart = true + } + eventChannel := make(chan *events.Event) + go func() { + eventsError = r.Runtime.Events(fromStart, c.Stream, options, eventChannel) + }() + + if eventsError != nil { + return eventsError + } + if err != nil { + return errors.Wrapf(err, "unable to tail the events log") + } + w := bufio.NewWriter(os.Stdout) + for event := range eventChannel { + if len(c.Format) > 0 { + if err := tmpl.Execute(w, event); err != nil { + return err + } + } else { + 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 +} |