mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Switch kubelet log command to use pod log subresource
This commit is contained in:
parent
f9156c281a
commit
556faa4590
@ -57,6 +57,7 @@ func selectContainer(pod *api.Pod, in io.Reader, out io.Writer) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewCmdLog creates a new pod log command
|
||||||
func NewCmdLog(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdLog(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "log [-f] POD [CONTAINER]",
|
Use: "log [-f] POD [CONTAINER]",
|
||||||
@ -73,6 +74,7 @@ func NewCmdLog(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunLog retrieves a pod log
|
||||||
func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return cmdutil.UsageError(cmd, "POD is required for log")
|
return cmdutil.UsageError(cmd, "POD is required for log")
|
||||||
@ -114,11 +116,12 @@ func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
|
|||||||
}
|
}
|
||||||
|
|
||||||
readCloser, err := client.RESTClient.Get().
|
readCloser, err := client.RESTClient.Get().
|
||||||
Prefix("proxy").
|
Namespace(namespace).
|
||||||
Resource("nodes").
|
Name(podID).
|
||||||
Name(pod.Spec.Host).
|
Resource("pods").
|
||||||
Suffix("containerLogs", namespace, podID, container).
|
SubResource("log").
|
||||||
Param("follow", strconv.FormatBool(follow)).
|
Param("follow", strconv.FormatBool(follow)).
|
||||||
|
Param("container", container).
|
||||||
Stream()
|
Stream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -18,9 +18,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSelectContainer(t *testing.T) {
|
func TestSelectContainer(t *testing.T) {
|
||||||
@ -145,3 +148,86 @@ func TestSelectContainer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLog(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name, version, podPath, logPath, container string
|
||||||
|
nsInQuery bool
|
||||||
|
pod *api.Pod
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "v1beta1 - pod log",
|
||||||
|
version: "v1beta1",
|
||||||
|
podPath: "/api/v1beta1/pods/foo",
|
||||||
|
logPath: "/api/v1beta1/pods/foo/log",
|
||||||
|
nsInQuery: true,
|
||||||
|
pod: testPod(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "v1beta3 - pod log",
|
||||||
|
version: "v1beta3",
|
||||||
|
podPath: "/api/v1beta3/namespaces/test/pods/foo",
|
||||||
|
logPath: "/api/v1beta3/namespaces/test/pods/foo/log",
|
||||||
|
nsInQuery: false,
|
||||||
|
pod: testPod(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
logContent := "test log content"
|
||||||
|
f, tf, codec := NewAPIFactory()
|
||||||
|
tf.Client = &client.FakeRESTClient{
|
||||||
|
Codec: codec,
|
||||||
|
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
|
||||||
|
switch p, m := req.URL.Path, req.Method; {
|
||||||
|
case p == test.podPath && m == "GET":
|
||||||
|
if test.nsInQuery {
|
||||||
|
if ns := req.URL.Query().Get("namespace"); ns != "test" {
|
||||||
|
t.Errorf("%s: did not get expected namespace: %s\n", test.name, ns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body := objBody(codec, test.pod)
|
||||||
|
return &http.Response{StatusCode: 200, Body: body}, nil
|
||||||
|
case p == test.logPath && m == "GET":
|
||||||
|
if test.nsInQuery {
|
||||||
|
if ns := req.URL.Query().Get("namespace"); ns != "test" {
|
||||||
|
t.Errorf("%s: did not get expected namespace: %s\n", test.name, ns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body := ioutil.NopCloser(bytes.NewBufferString(logContent))
|
||||||
|
return &http.Response{StatusCode: 200, Body: body}, nil
|
||||||
|
default:
|
||||||
|
// Ensures no GET is performed when deleting by name
|
||||||
|
t.Errorf("%s: unexpected request: %#v\n%#v", test.name, req.URL, req)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
tf.Namespace = "test"
|
||||||
|
tf.ClientConfig = &client.Config{Version: test.version}
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
|
cmd := NewCmdLog(f, buf)
|
||||||
|
cmd.Flags().Set("namespace", "test")
|
||||||
|
cmd.Run(cmd, []string{"foo"})
|
||||||
|
|
||||||
|
if buf.String() != logContent {
|
||||||
|
t.Errorf("%s: did not get expected log content. Got: %s", test.name, buf.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPod() *api.Pod {
|
||||||
|
return &api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
|
||||||
|
Spec: api.PodSpec{
|
||||||
|
RestartPolicy: api.RestartPolicyAlways,
|
||||||
|
DNSPolicy: api.DNSClusterFirst,
|
||||||
|
Containers: []api.Container{
|
||||||
|
{
|
||||||
|
Name: "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user