* Move tracing exporter registration This doesn't belong in the library and should be configured by the consumer of the opencensus package. * Rename `vkublet` package to `node` `vkubelet` does not convey any information to the consumers of the package. Really it would be nice to move this package to the root of the repo, but then you wind up with... interesting... import semantics due to the repo name... and after thinking about it some, a subpackage is really not so bad as long as it has a name that convey's some information. `node` was chosen since this package deals with all the semantics of operating a node in Kubernetes.
81 lines
2.0 KiB
Go
81 lines
2.0 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/pkg/errors"
|
|
"github.com/virtual-kubelet/virtual-kubelet/errdefs"
|
|
"github.com/virtual-kubelet/virtual-kubelet/log"
|
|
)
|
|
|
|
// ContainerLogsHandlerFunc is used in place of backend implementations for getting container logs
|
|
type ContainerLogsHandlerFunc func(ctx context.Context, namespace, podName, containerName string, opts ContainerLogOpts) (io.ReadCloser, error)
|
|
|
|
// ContainerLogOpts are used to pass along options to be set on the container
|
|
// log stream.
|
|
type ContainerLogOpts struct {
|
|
Tail int
|
|
Since time.Duration
|
|
LimitBytes int
|
|
Timestamps bool
|
|
}
|
|
|
|
// HandleContainerLogs creates an http handler function from a provider to serve logs from a pod
|
|
func HandleContainerLogs(h ContainerLogsHandlerFunc) http.HandlerFunc {
|
|
if h == nil {
|
|
return NotImplemented
|
|
}
|
|
return handleError(func(w http.ResponseWriter, req *http.Request) error {
|
|
vars := mux.Vars(req)
|
|
if len(vars) != 3 {
|
|
return errdefs.NotFound("not found")
|
|
}
|
|
|
|
ctx := req.Context()
|
|
|
|
namespace := vars["namespace"]
|
|
pod := vars["pod"]
|
|
container := vars["container"]
|
|
tail := 10
|
|
q := req.URL.Query()
|
|
|
|
if queryTail := q.Get("tailLines"); queryTail != "" {
|
|
t, err := strconv.Atoi(queryTail)
|
|
if err != nil {
|
|
return errdefs.AsInvalidInput(errors.Wrap(err, "could not parse \"tailLines\""))
|
|
}
|
|
tail = t
|
|
}
|
|
|
|
// TODO(@cpuguy83): support v1.PodLogOptions
|
|
// The kubelet decoding here is not straight forward, so this needs to be disected
|
|
|
|
opts := ContainerLogOpts{
|
|
Tail: tail,
|
|
}
|
|
|
|
logs, err := h(ctx, namespace, pod, container, opts)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error getting container logs?)")
|
|
}
|
|
|
|
defer logs.Close()
|
|
|
|
req.Header.Set("Transfer-Encoding", "chunked")
|
|
|
|
if _, ok := w.(writeFlusher); !ok {
|
|
log.G(ctx).Debug("http response writer does not support flushes")
|
|
}
|
|
|
|
if _, err := io.Copy(flushOnWrite(w), logs); err != nil {
|
|
return errors.Wrap(err, "error writing response to client")
|
|
}
|
|
return nil
|
|
})
|
|
}
|