mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 07:20:13 +00:00
Merge pull request #836 from brendandburns/runin
Add an API for calling RunInContainer on the kubelet.
This commit is contained in:
commit
1b24fe880a
@ -1056,7 +1056,7 @@ func TestRunInContainerNoSuchPod(t *testing.T) {
|
||||
podNamespace := "etcd"
|
||||
containerName := "containerFoo"
|
||||
output, err := kubelet.RunInContainer(
|
||||
podName+"."+podNamespace,
|
||||
GetPodFullName(&Pod{Name: podName, Namespace: podNamespace}),
|
||||
containerName,
|
||||
[]string{"ls"})
|
||||
if output != nil {
|
||||
@ -1086,7 +1086,7 @@ func TestRunInContainer(t *testing.T) {
|
||||
|
||||
cmd := []string{"ls"}
|
||||
_, err := kubelet.RunInContainer(
|
||||
podName+"."+podNamespace,
|
||||
GetPodFullName(&Pod{Name: podName, Namespace: podNamespace}),
|
||||
containerName,
|
||||
cmd)
|
||||
if fakeCommandRunner.ID != containerID {
|
||||
|
@ -65,6 +65,7 @@ type HostInterface interface {
|
||||
GetRootInfo(req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
||||
GetMachineInfo() (*info.MachineInfo, error)
|
||||
GetPodInfo(name string) (api.PodInfo, error)
|
||||
RunInContainer(name, container string, cmd []string) ([]byte, error)
|
||||
ServeLogs(w http.ResponseWriter, req *http.Request)
|
||||
}
|
||||
|
||||
@ -88,6 +89,7 @@ func (s *Server) InstallDefaultHandlers() {
|
||||
s.mux.HandleFunc("/stats/", s.handleStats)
|
||||
s.mux.HandleFunc("/logs/", s.handleLogs)
|
||||
s.mux.HandleFunc("/spec/", s.handleSpec)
|
||||
s.mux.HandleFunc("/run/", s.handleRun)
|
||||
}
|
||||
|
||||
// error serializes an error object into an HTTP response
|
||||
@ -204,6 +206,31 @@ func (s *Server) handleSpec(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
}
|
||||
|
||||
// handleRun handles requests to run a command inside a container
|
||||
func (s *Server) handleRun(w http.ResponseWriter, req *http.Request) {
|
||||
u, err := url.ParseRequestURI(req.RequestURI)
|
||||
if err != nil {
|
||||
s.error(w, err)
|
||||
return
|
||||
}
|
||||
parts := strings.Split(u.Path, "/")
|
||||
if len(parts) != 4 {
|
||||
http.Error(w, "Unexpected path for command running", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
podID := parts[2]
|
||||
container := parts[3]
|
||||
podFullName := GetPodFullName(&Pod{Name: podID, Namespace: "etcd"})
|
||||
command := strings.Split(u.Query().Get("cmd"), " ")
|
||||
data, err := s.host.RunInContainer(podFullName, container, command)
|
||||
if err != nil {
|
||||
s.error(w, err)
|
||||
return
|
||||
}
|
||||
w.Header().Add("Content-type", "text/plain")
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
// ServeHTTP responds to HTTP requests on the Kubelet
|
||||
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
defer httplog.NewLogged(req, &w).StacktraceWhen(
|
||||
|
@ -40,6 +40,7 @@ type fakeKubelet struct {
|
||||
rootInfoFunc func(query *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
||||
machineInfoFunc func() (*info.MachineInfo, error)
|
||||
logFunc func(w http.ResponseWriter, req *http.Request)
|
||||
runFunc func(podFullName, containerName string, cmd []string) ([]byte, error)
|
||||
}
|
||||
|
||||
func (fk *fakeKubelet) GetPodInfo(name string) (api.PodInfo, error) {
|
||||
@ -62,6 +63,10 @@ func (fk *fakeKubelet) ServeLogs(w http.ResponseWriter, req *http.Request) {
|
||||
fk.logFunc(w, req)
|
||||
}
|
||||
|
||||
func (fk *fakeKubelet) RunInContainer(podFullName, containerName string, cmd []string) ([]byte, error) {
|
||||
return fk.runFunc(podFullName, containerName, cmd)
|
||||
}
|
||||
|
||||
type serverTestFramework struct {
|
||||
updateChan chan interface{}
|
||||
updateReader *channelReader
|
||||
@ -288,3 +293,42 @@ func TestServeLogs(t *testing.T) {
|
||||
t.Errorf("Received wrong data: %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeRunInContainer(t *testing.T) {
|
||||
fw := newServerTest()
|
||||
output := "foo bar"
|
||||
podName := "foo"
|
||||
expectedPodName := podName + ".etcd"
|
||||
expectedContainerName := "baz"
|
||||
expectedCommand := "ls -a"
|
||||
fw.fakeKubelet.runFunc = func(podFullName, containerName string, cmd []string) ([]byte, error) {
|
||||
if podFullName != expectedPodName {
|
||||
t.Errorf("expected %s, got %s", expectedPodName, podFullName)
|
||||
}
|
||||
if containerName != expectedContainerName {
|
||||
t.Errorf("expected %s, got %s", expectedContainerName, containerName)
|
||||
}
|
||||
if strings.Join(cmd, " ") != expectedCommand {
|
||||
t.Errorf("expected: %s, got %v", expectedCommand, cmd)
|
||||
}
|
||||
|
||||
return []byte(output), nil
|
||||
}
|
||||
|
||||
resp, err := http.Get(fw.testHTTPServer.URL + "/run/" + podName + "/" + expectedContainerName + "?cmd=ls%20-a")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Got error GETing: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
// copying the response body did not work
|
||||
t.Errorf("Cannot copy resp: %#v", err)
|
||||
}
|
||||
result := string(body)
|
||||
if result != output {
|
||||
t.Errorf("expected %s, got %s", output, result)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user