mirror of
https://github.com/containers/podman.git
synced 2025-05-25 02:57:21 +08:00
apiv2 add bindings for logs|events
add go-bindings for logs and events. tests were also added. Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
@ -326,7 +326,6 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
builder.WriteRune(' ')
|
builder.WriteRune(' ')
|
||||||
}
|
}
|
||||||
builder.WriteString(line.Msg)
|
builder.WriteString(line.Msg)
|
||||||
|
|
||||||
// Build header and output entry
|
// Build header and output entry
|
||||||
binary.BigEndian.PutUint32(header[4:], uint32(len(header)+builder.Len()))
|
binary.BigEndian.PutUint32(header[4:], uint32(len(header)+builder.Len()))
|
||||||
if _, err := w.Write(header[:]); err != nil {
|
if _, err := w.Write(header[:]); err != nil {
|
||||||
@ -335,7 +334,6 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
if _, err := fmt.Fprint(w, builder.String()); err != nil {
|
if _, err := fmt.Fprint(w, builder.String()); err != nil {
|
||||||
log.Errorf("unable to write builder string: %q", err)
|
log.Errorf("unable to write builder string: %q", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if flusher, ok := w.(http.Flusher); ok {
|
if flusher, ok := w.(http.Flusher); ok {
|
||||||
flusher.Flush()
|
flusher.Flush()
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,6 @@ func (s *APIServer) registerEventsHandlers(r *mux.Router) error {
|
|||||||
// description: returns a string of json data describing an event
|
// description: returns a string of json data describing an event
|
||||||
// 500:
|
// 500:
|
||||||
// "$ref": "#/responses/InternalError"
|
// "$ref": "#/responses/InternalError"
|
||||||
r.Handle(VersionedPath("/events"), s.APIHandler(compat.GetEvents)).Methods(http.MethodGet)
|
r.Handle(VersionedPath("/libpod/events"), s.APIHandler(compat.GetEvents)).Methods(http.MethodGet)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -7,3 +7,12 @@
|
|||||||
// is established, users can then manage the Podman container runtime.
|
// is established, users can then manage the Podman container runtime.
|
||||||
|
|
||||||
package bindings
|
package bindings
|
||||||
|
|
||||||
|
var (
|
||||||
|
// PTrue is a convenience variable that can be used in bindings where
|
||||||
|
// a pointer to a bool (optional parameter) is required.
|
||||||
|
PTrue bool = true
|
||||||
|
// PFalse is a convenience variable that can be used in bindings where
|
||||||
|
// a pointer to a bool (optional parameter) is required.
|
||||||
|
PFalse bool = false
|
||||||
|
)
|
||||||
|
@ -139,7 +139,6 @@ func Kill(ctx context.Context, nameOrID string, signal string) error {
|
|||||||
return response.Process(nil)
|
return response.Process(nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
func Logs() {}
|
|
||||||
|
|
||||||
// Pause pauses a given container. The nameOrID can be a container name
|
// Pause pauses a given container. The nameOrID can be a container name
|
||||||
// or a partial/full ID.
|
// or a partial/full ID.
|
||||||
|
116
pkg/bindings/containers/logs.go
Normal file
116
pkg/bindings/containers/logs.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/pkg/bindings"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Logs obtains a container's logs given the options provided. The logs are then sent to the
|
||||||
|
// stdout|stderr channels as strings.
|
||||||
|
func Logs(ctx context.Context, nameOrID string, opts LogOptions, stdoutChan, stderrChan chan string) error {
|
||||||
|
conn, err := bindings.GetClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params := url.Values{}
|
||||||
|
if opts.Follow != nil {
|
||||||
|
params.Set("follow", strconv.FormatBool(*opts.Follow))
|
||||||
|
}
|
||||||
|
if opts.Since != nil {
|
||||||
|
params.Set("since", *opts.Since)
|
||||||
|
}
|
||||||
|
if opts.Stderr != nil {
|
||||||
|
params.Set("stderr", strconv.FormatBool(*opts.Stderr))
|
||||||
|
}
|
||||||
|
if opts.Stdout != nil {
|
||||||
|
params.Set("stdout", strconv.FormatBool(*opts.Stdout))
|
||||||
|
}
|
||||||
|
if opts.Tail != nil {
|
||||||
|
params.Set("tail", *opts.Tail)
|
||||||
|
}
|
||||||
|
if opts.Timestamps != nil {
|
||||||
|
params.Set("timestamps", strconv.FormatBool(*opts.Timestamps))
|
||||||
|
}
|
||||||
|
if opts.Until != nil {
|
||||||
|
params.Set("until", *opts.Until)
|
||||||
|
}
|
||||||
|
// The API requires either stdout|stderr be used. If neither are specified, we specify stdout
|
||||||
|
if opts.Stdout == nil && opts.Stderr == nil {
|
||||||
|
params.Set("stdout", strconv.FormatBool(true))
|
||||||
|
}
|
||||||
|
response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/logs", params, nameOrID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// read 8 bytes
|
||||||
|
// first byte determines stderr=2|stdout=1
|
||||||
|
// bytes 4-7 len(msg) in uint32
|
||||||
|
for {
|
||||||
|
stream, msgSize, err := readHeader(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
// In case the server side closes up shop because !follow
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return errors.Wrap(err, "unable to read log header")
|
||||||
|
}
|
||||||
|
msg, err := readMsg(response.Body, msgSize)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unable to read log message")
|
||||||
|
}
|
||||||
|
if stream == 1 {
|
||||||
|
stdoutChan <- msg
|
||||||
|
} else {
|
||||||
|
stderrChan <- msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readMsg(r io.Reader, msgSize int) (string, error) {
|
||||||
|
var msg []byte
|
||||||
|
size := msgSize
|
||||||
|
for {
|
||||||
|
b := make([]byte, size)
|
||||||
|
_, err := r.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
msg = append(msg, b...)
|
||||||
|
if len(msg) == msgSize {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
size = msgSize - len(msg)
|
||||||
|
}
|
||||||
|
return string(msg), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readHeader(r io.Reader) (byte, int, error) {
|
||||||
|
var (
|
||||||
|
header []byte
|
||||||
|
size = 8
|
||||||
|
)
|
||||||
|
for {
|
||||||
|
b := make([]byte, size)
|
||||||
|
_, err := r.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
header = append(header, b...)
|
||||||
|
if len(header) == 8 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
size = 8 - len(header)
|
||||||
|
}
|
||||||
|
stream := header[0]
|
||||||
|
msgSize := int(binary.BigEndian.Uint32(header[4:]) - 8)
|
||||||
|
return stream, msgSize, nil
|
||||||
|
}
|
13
pkg/bindings/containers/types.go
Normal file
13
pkg/bindings/containers/types.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package containers
|
||||||
|
|
||||||
|
// LogOptions describe finer control of log content or
|
||||||
|
// how the content is formatted.
|
||||||
|
type LogOptions struct {
|
||||||
|
Follow *bool
|
||||||
|
Since *string
|
||||||
|
Stderr *bool
|
||||||
|
Stdout *bool
|
||||||
|
Tail *string
|
||||||
|
Timestamps *bool
|
||||||
|
Until *string
|
||||||
|
}
|
61
pkg/bindings/system/system.go
Normal file
61
pkg/bindings/system/system.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/pkg/api/handlers"
|
||||||
|
"github.com/containers/libpod/pkg/bindings"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Events allows you to monitor libdpod related events like container creation and
|
||||||
|
// removal. The events are then passed to the eventChan provided. The optional cancelChan
|
||||||
|
// can be used to cancel the read of events and close down the HTTP connection.
|
||||||
|
func Events(ctx context.Context, eventChan chan (handlers.Event), cancelChan chan bool, since, until *string, filters map[string][]string) error {
|
||||||
|
conn, err := bindings.GetClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params := url.Values{}
|
||||||
|
if since != nil {
|
||||||
|
params.Set("since", *since)
|
||||||
|
}
|
||||||
|
if until != nil {
|
||||||
|
params.Set("until", *until)
|
||||||
|
}
|
||||||
|
if filters != nil {
|
||||||
|
filterString, err := bindings.FiltersToString(filters)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "invalid filters")
|
||||||
|
}
|
||||||
|
params.Set("filters", filterString)
|
||||||
|
}
|
||||||
|
response, err := conn.DoRequest(nil, http.MethodGet, "/events", params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cancelChan != nil {
|
||||||
|
go func() {
|
||||||
|
<-cancelChan
|
||||||
|
err = response.Body.Close()
|
||||||
|
logrus.Error(errors.Wrap(err, "unable to close event response body"))
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
dec := json.NewDecoder(response.Body)
|
||||||
|
for {
|
||||||
|
e := handlers.Event{}
|
||||||
|
if err := dec.Decode(&e); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return errors.Wrap(err, "unable to decode event response")
|
||||||
|
}
|
||||||
|
eventChan <- e
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -152,7 +152,7 @@ func (b *bindingTest) startAPIService() *gexec.Session {
|
|||||||
var (
|
var (
|
||||||
cmd []string
|
cmd []string
|
||||||
)
|
)
|
||||||
cmd = append(cmd, "--log-level=debug", "system", "service", "--timeout=0", b.sock)
|
cmd = append(cmd, "--log-level=debug", "--events-backend=file", "system", "service", "--timeout=0", b.sock)
|
||||||
return b.runPodman(cmd)
|
return b.runPodman(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,12 @@ package test_bindings
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/libpod/pkg/bindings"
|
"github.com/containers/libpod/pkg/bindings"
|
||||||
"github.com/containers/libpod/pkg/bindings/containers"
|
"github.com/containers/libpod/pkg/bindings/containers"
|
||||||
|
"github.com/containers/libpod/pkg/specgen"
|
||||||
"github.com/containers/libpod/test/utils"
|
"github.com/containers/libpod/test/utils"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@ -18,8 +20,6 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
bt *bindingTest
|
bt *bindingTest
|
||||||
s *gexec.Session
|
s *gexec.Session
|
||||||
err error
|
err error
|
||||||
falseFlag bool = false
|
|
||||||
trueFlag bool = true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
@ -55,7 +55,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman pause a running container by name", func() {
|
It("podman pause a running container by name", func() {
|
||||||
// Pausing by name should work
|
// Pausing by name should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, name)
|
err = containers.Pause(bt.conn, name)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -69,7 +69,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman pause a running container by id", func() {
|
It("podman pause a running container by id", func() {
|
||||||
// Pausing by id should work
|
// Pausing by id should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, cid)
|
err = containers.Pause(bt.conn, cid)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -83,7 +83,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman unpause a running container by name", func() {
|
It("podman unpause a running container by name", func() {
|
||||||
// Unpausing by name should work
|
// Unpausing by name should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, name)
|
err = containers.Pause(bt.conn, name)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -99,7 +99,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman unpause a running container by ID", func() {
|
It("podman unpause a running container by ID", func() {
|
||||||
// Unpausing by ID should work
|
// Unpausing by ID should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
// Pause by name
|
// Pause by name
|
||||||
err = containers.Pause(bt.conn, name)
|
err = containers.Pause(bt.conn, name)
|
||||||
@ -118,7 +118,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman pause a paused container by name", func() {
|
It("podman pause a paused container by name", func() {
|
||||||
// Pausing a paused container by name should fail
|
// Pausing a paused container by name should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, name)
|
err = containers.Pause(bt.conn, name)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -131,7 +131,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman pause a paused container by id", func() {
|
It("podman pause a paused container by id", func() {
|
||||||
// Pausing a paused container by id should fail
|
// Pausing a paused container by id should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, cid)
|
err = containers.Pause(bt.conn, cid)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -144,7 +144,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman pause a stopped container by name", func() {
|
It("podman pause a stopped container by name", func() {
|
||||||
// Pausing a stopped container by name should fail
|
// Pausing a stopped container by name should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Stop(bt.conn, name, nil)
|
err = containers.Stop(bt.conn, name, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -157,7 +157,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman pause a stopped container by id", func() {
|
It("podman pause a stopped container by id", func() {
|
||||||
// Pausing a stopped container by id should fail
|
// Pausing a stopped container by id should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Stop(bt.conn, cid, nil)
|
err = containers.Stop(bt.conn, cid, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -170,11 +170,11 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman remove a paused container by id without force", func() {
|
It("podman remove a paused container by id without force", func() {
|
||||||
// Removing a paused container without force should fail
|
// Removing a paused container without force should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, cid)
|
err = containers.Pause(bt.conn, cid)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Remove(bt.conn, cid, &falseFlag, &falseFlag)
|
err = containers.Remove(bt.conn, cid, &bindings.PFalse, &bindings.PFalse)
|
||||||
Expect(err).ToNot(BeNil())
|
Expect(err).ToNot(BeNil())
|
||||||
code, _ := bindings.CheckResponseCode(err)
|
code, _ := bindings.CheckResponseCode(err)
|
||||||
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
|
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
|
||||||
@ -191,18 +191,18 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
|
|
||||||
// Removing a paused container with force should work
|
// Removing a paused container with force should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, cid)
|
err = containers.Pause(bt.conn, cid)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Remove(bt.conn, cid, &trueFlag, &falseFlag)
|
err = containers.Remove(bt.conn, cid, &bindings.PTrue, &bindings.PFalse)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman stop a paused container by name", func() {
|
It("podman stop a paused container by name", func() {
|
||||||
// Stopping a paused container by name should fail
|
// Stopping a paused container by name should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, name)
|
err = containers.Pause(bt.conn, name)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -215,7 +215,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman stop a paused container by id", func() {
|
It("podman stop a paused container by id", func() {
|
||||||
// Stopping a paused container by id should fail
|
// Stopping a paused container by id should fail
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Pause(bt.conn, cid)
|
err = containers.Pause(bt.conn, cid)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -228,7 +228,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman stop a running container by name", func() {
|
It("podman stop a running container by name", func() {
|
||||||
// Stopping a running container by name should work
|
// Stopping a running container by name should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
_, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
_, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Stop(bt.conn, name, nil)
|
err = containers.Stop(bt.conn, name, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -242,7 +242,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
It("podman stop a running container by ID", func() {
|
It("podman stop a running container by ID", func() {
|
||||||
// Stopping a running container by ID should work
|
// Stopping a running container by ID should work
|
||||||
var name = "top"
|
var name = "top"
|
||||||
cid, err := bt.RunTopContainer(&name, &falseFlag, nil)
|
cid, err := bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = containers.Stop(bt.conn, cid, nil)
|
err = containers.Stop(bt.conn, cid, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
@ -301,8 +301,8 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
|
|
||||||
errChan = make(chan error)
|
errChan = make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
exitCode, err = containers.Wait(bt.conn, name, &unpause)
|
_, waitErr := containers.Wait(bt.conn, name, &unpause)
|
||||||
errChan <- err
|
errChan <- waitErr
|
||||||
close(errChan)
|
close(errChan)
|
||||||
}()
|
}()
|
||||||
err = containers.Unpause(bt.conn, name)
|
err = containers.Unpause(bt.conn, name)
|
||||||
@ -323,7 +323,7 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
|
|
||||||
// a container that has no healthcheck should be a 409
|
// a container that has no healthcheck should be a 409
|
||||||
var name = "top"
|
var name = "top"
|
||||||
bt.RunTopContainer(&name, &falseFlag, nil)
|
bt.RunTopContainer(&name, &bindings.PFalse, nil)
|
||||||
_, err = containers.RunHealthCheck(bt.conn, name)
|
_, err = containers.RunHealthCheck(bt.conn, name)
|
||||||
Expect(err).ToNot(BeNil())
|
Expect(err).ToNot(BeNil())
|
||||||
code, _ = bindings.CheckResponseCode(err)
|
code, _ = bindings.CheckResponseCode(err)
|
||||||
@ -357,4 +357,26 @@ var _ = Describe("Podman containers ", func() {
|
|||||||
//Expect(code).To(BeNumerically("==", http.StatusConflict))
|
//Expect(code).To(BeNumerically("==", http.StatusConflict))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("logging", func() {
|
||||||
|
stdoutChan := make(chan string, 10)
|
||||||
|
s := specgen.NewSpecGenerator(alpine.name)
|
||||||
|
s.Terminal = true
|
||||||
|
s.Command = []string{"date", "-R"}
|
||||||
|
r, err := containers.CreateWithSpec(bt.conn, s)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
err = containers.Start(bt.conn, r.ID, nil)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
_, err = containers.Wait(bt.conn, r.ID, nil)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
opts := containers.LogOptions{Stdout: &bindings.PTrue, Follow: &bindings.PTrue}
|
||||||
|
go func() {
|
||||||
|
containers.Logs(bt.conn, r.ID, opts, stdoutChan, nil)
|
||||||
|
}()
|
||||||
|
o := <-stdoutChan
|
||||||
|
o = strings.ReplaceAll(o, "\r", "")
|
||||||
|
_, err = time.Parse(time.RFC1123Z, o)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -22,8 +22,6 @@ var _ = Describe("Podman images", func() {
|
|||||||
bt *bindingTest
|
bt *bindingTest
|
||||||
s *gexec.Session
|
s *gexec.Session
|
||||||
err error
|
err error
|
||||||
falseFlag bool = false
|
|
||||||
trueFlag bool = true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
@ -76,7 +74,7 @@ var _ = Describe("Podman images", func() {
|
|||||||
//Expect(data.Size).To(BeZero())
|
//Expect(data.Size).To(BeZero())
|
||||||
|
|
||||||
// Enabling the size parameter should result in size being populated
|
// Enabling the size parameter should result in size being populated
|
||||||
data, err = images.GetImage(bt.conn, alpine.name, &trueFlag)
|
data, err = images.GetImage(bt.conn, alpine.name, &bindings.PTrue)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(data.Size).To(BeNumerically(">", 0))
|
Expect(data.Size).To(BeNumerically(">", 0))
|
||||||
})
|
})
|
||||||
@ -84,7 +82,7 @@ var _ = Describe("Podman images", func() {
|
|||||||
// Test to validate the remove image api
|
// Test to validate the remove image api
|
||||||
It("remove image", func() {
|
It("remove image", func() {
|
||||||
// Remove invalid image should be a 404
|
// Remove invalid image should be a 404
|
||||||
_, err = images.Remove(bt.conn, "foobar5000", &falseFlag)
|
_, err = images.Remove(bt.conn, "foobar5000", &bindings.PFalse)
|
||||||
Expect(err).ToNot(BeNil())
|
Expect(err).ToNot(BeNil())
|
||||||
code, _ := bindings.CheckResponseCode(err)
|
code, _ := bindings.CheckResponseCode(err)
|
||||||
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
||||||
@ -101,21 +99,21 @@ var _ = Describe("Podman images", func() {
|
|||||||
|
|
||||||
// Start a container with alpine image
|
// Start a container with alpine image
|
||||||
var top string = "top"
|
var top string = "top"
|
||||||
_, err = bt.RunTopContainer(&top, &falseFlag, nil)
|
_, err = bt.RunTopContainer(&top, &bindings.PFalse, nil)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
// we should now have a container called "top" running
|
// we should now have a container called "top" running
|
||||||
containerResponse, err := containers.Inspect(bt.conn, "top", &falseFlag)
|
containerResponse, err := containers.Inspect(bt.conn, "top", &bindings.PFalse)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(containerResponse.Name).To(Equal("top"))
|
Expect(containerResponse.Name).To(Equal("top"))
|
||||||
|
|
||||||
// try to remove the image "alpine". This should fail since we are not force
|
// try to remove the image "alpine". This should fail since we are not force
|
||||||
// deleting hence image cannot be deleted until the container is deleted.
|
// deleting hence image cannot be deleted until the container is deleted.
|
||||||
response, err = images.Remove(bt.conn, alpine.shortName, &falseFlag)
|
response, err = images.Remove(bt.conn, alpine.shortName, &bindings.PFalse)
|
||||||
code, _ = bindings.CheckResponseCode(err)
|
code, _ = bindings.CheckResponseCode(err)
|
||||||
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
|
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
|
||||||
|
|
||||||
// Removing the image "alpine" where force = true
|
// Removing the image "alpine" where force = true
|
||||||
response, err = images.Remove(bt.conn, alpine.shortName, &trueFlag)
|
response, err = images.Remove(bt.conn, alpine.shortName, &bindings.PTrue)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
// Checking if both the images are gone as well as the container is deleted
|
// Checking if both the images are gone as well as the container is deleted
|
||||||
@ -127,7 +125,7 @@ var _ = Describe("Podman images", func() {
|
|||||||
code, _ = bindings.CheckResponseCode(err)
|
code, _ = bindings.CheckResponseCode(err)
|
||||||
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
||||||
|
|
||||||
_, err = containers.Inspect(bt.conn, "top", &falseFlag)
|
_, err = containers.Inspect(bt.conn, "top", &bindings.PFalse)
|
||||||
code, _ = bindings.CheckResponseCode(err)
|
code, _ = bindings.CheckResponseCode(err)
|
||||||
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
||||||
})
|
})
|
||||||
@ -178,13 +176,13 @@ var _ = Describe("Podman images", func() {
|
|||||||
// List images with a filter
|
// List images with a filter
|
||||||
filters := make(map[string][]string)
|
filters := make(map[string][]string)
|
||||||
filters["reference"] = []string{alpine.name}
|
filters["reference"] = []string{alpine.name}
|
||||||
filteredImages, err := images.List(bt.conn, &falseFlag, filters)
|
filteredImages, err := images.List(bt.conn, &bindings.PFalse, filters)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(len(filteredImages)).To(BeNumerically("==", 1))
|
Expect(len(filteredImages)).To(BeNumerically("==", 1))
|
||||||
|
|
||||||
// List images with a bad filter
|
// List images with a bad filter
|
||||||
filters["name"] = []string{alpine.name}
|
filters["name"] = []string{alpine.name}
|
||||||
_, err = images.List(bt.conn, &falseFlag, filters)
|
_, err = images.List(bt.conn, &bindings.PFalse, filters)
|
||||||
Expect(err).ToNot(BeNil())
|
Expect(err).ToNot(BeNil())
|
||||||
code, _ := bindings.CheckResponseCode(err)
|
code, _ := bindings.CheckResponseCode(err)
|
||||||
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
|
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
|
||||||
|
@ -18,7 +18,6 @@ var _ = Describe("Podman pods", func() {
|
|||||||
s *gexec.Session
|
s *gexec.Session
|
||||||
newpod string
|
newpod string
|
||||||
err error
|
err error
|
||||||
trueFlag bool = true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
@ -57,7 +56,7 @@ var _ = Describe("Podman pods", func() {
|
|||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(len(podSummary)).To(Equal(1))
|
Expect(len(podSummary)).To(Equal(1))
|
||||||
// Adding an alpine container to the existing pod
|
// Adding an alpine container to the existing pod
|
||||||
_, err = bt.RunTopContainer(nil, &trueFlag, &newpod)
|
_, err = bt.RunTopContainer(nil, &bindings.PTrue, &newpod)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
podSummary, err = pods.List(bt.conn, nil)
|
podSummary, err = pods.List(bt.conn, nil)
|
||||||
// Verify no errors.
|
// Verify no errors.
|
||||||
@ -111,7 +110,7 @@ var _ = Describe("Podman pods", func() {
|
|||||||
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
Expect(code).To(BeNumerically("==", http.StatusNotFound))
|
||||||
|
|
||||||
// Adding an alpine container to the existing pod
|
// Adding an alpine container to the existing pod
|
||||||
_, err = bt.RunTopContainer(nil, &trueFlag, &newpod)
|
_, err = bt.RunTopContainer(nil, &bindings.PTrue, &newpod)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
// Binding needs to be modified to inspect the pod state.
|
// Binding needs to be modified to inspect the pod state.
|
||||||
|
51
pkg/bindings/test/system_test.go
Normal file
51
pkg/bindings/test/system_test.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package test_bindings
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/containers/libpod/pkg/api/handlers"
|
||||||
|
"github.com/containers/libpod/pkg/bindings/system"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/onsi/gomega/gexec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Podman system", func() {
|
||||||
|
var (
|
||||||
|
bt *bindingTest
|
||||||
|
s *gexec.Session
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
bt = newBindingTest()
|
||||||
|
bt.RestoreImagesFromCache()
|
||||||
|
s = bt.startAPIService()
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
err := bt.NewConnection()
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
s.Kill()
|
||||||
|
bt.cleanup()
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman events", func() {
|
||||||
|
eChan := make(chan handlers.Event, 1)
|
||||||
|
var messages []handlers.Event
|
||||||
|
cancelChan := make(chan bool, 1)
|
||||||
|
go func() {
|
||||||
|
for e := range eChan {
|
||||||
|
messages = append(messages, e)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
system.Events(bt.conn, eChan, cancelChan, nil, nil, nil)
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, err := bt.RunTopContainer(nil, nil, nil)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
cancelChan <- true
|
||||||
|
Expect(len(messages)).To(BeNumerically("==", 3))
|
||||||
|
})
|
||||||
|
})
|
@ -25,7 +25,6 @@ var _ = Describe("Podman volumes", func() {
|
|||||||
s *gexec.Session
|
s *gexec.Session
|
||||||
connText context.Context
|
connText context.Context
|
||||||
err error
|
err error
|
||||||
trueFlag = true
|
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
@ -107,7 +106,7 @@ var _ = Describe("Podman volumes", func() {
|
|||||||
zero := 0
|
zero := 0
|
||||||
err = containers.Stop(connText, "vtest", &zero)
|
err = containers.Stop(connText, "vtest", &zero)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
err = volumes.Remove(connText, vol.Name, &trueFlag)
|
err = volumes.Remove(connText, vol.Name, &bindings.PTrue)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user