Merge pull request #7238 from csrwng/use_log_subresource

Switch kubelet log command to use pod log subresource
pull/6/head
Clayton Coleman 2015-04-24 15:16:50 -04:00
commit 9d0042e760
2 changed files with 93 additions and 4 deletions

View File

@ -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 {
cmd := &cobra.Command{
Use: "log [-f] POD [CONTAINER]",
@ -73,6 +74,7 @@ func NewCmdLog(f *cmdutil.Factory, out io.Writer) *cobra.Command {
return cmd
}
// RunLog retrieves a pod log
func RunLog(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
if len(args) == 0 {
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().
Prefix("proxy").
Resource("nodes").
Name(pod.Spec.Host).
Suffix("containerLogs", namespace, podID, container).
Namespace(namespace).
Name(podID).
Resource("pods").
SubResource("log").
Param("follow", strconv.FormatBool(follow)).
Param("container", container).
Stream()
if err != nil {
return err

View File

@ -18,9 +18,12 @@ package cmd
import (
"bytes"
"io/ioutil"
"net/http"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
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",
},
},
},
}
}