finished logs functionality and tests

pull/108/head
aprindle 2016-05-23 12:52:39 -07:00
parent 77919b82b0
commit 706f974751
6 changed files with 133 additions and 16 deletions

49
cmd/minikube/cmd/logs.go Normal file
View File

@ -0,0 +1,49 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"log"
"os"
"github.com/docker/machine/libmachine"
"github.com/spf13/cobra"
"k8s.io/minikube/pkg/minikube/cluster"
"k8s.io/minikube/pkg/minikube/constants"
)
// logsCmd represents the logs command
var logsCmd = &cobra.Command{
Use: "logs",
Short: "Gets the logs of the running localkube instance, used for debugging minikube, not user code.",
Long: `Gets the logs of the running localkube instance, used for debugging minikube, not user code.`,
Run: func(cmd *cobra.Command, args []string) {
api := libmachine.NewClient(constants.Minipath, constants.MakeMiniPath("certs"))
defer api.Close()
s, err := cluster.GetHostLogs(api)
if err != nil {
log.Println("Error getting machine logs:", err)
os.Exit(1)
}
fmt.Fprintln(os.Stdout, s)
},
}
func init() {
RootCmd.AddCommand(logsCmd)
}

View File

@ -243,19 +243,10 @@ func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
// GetHostDockerEnv gets the necessary docker env variables to allow the use of docker through minikube's vm
func GetHostDockerEnv(api libmachine.API) (map[string]string, error) {
exists, err := api.Exists(constants.MachineName)
host, err := checkIfApiExistsAndLoad(api)
if err != nil {
return nil, err
}
if !exists {
return nil, fmt.Errorf("Machine does not exist")
}
host, err := api.Load(constants.MachineName)
if err != nil {
return nil, err
}
ip, err := host.Driver.GetIP()
if err != nil {
return nil, err
@ -272,3 +263,32 @@ func GetHostDockerEnv(api libmachine.API) (map[string]string, error) {
}
return envMap, nil
}
// GetHostLogs gets the localkube logs of the host VM.
func GetHostLogs(api libmachine.API) (string, error) {
host, err := checkIfApiExistsAndLoad(api)
if err != nil {
return "", err
}
s, err := host.RunSSHCommand(logsCommand)
if err != nil {
return "", nil
}
return s, err
}
func checkIfApiExistsAndLoad(api libmachine.API) (*host.Host, error) {
exists, err := api.Exists(constants.MachineName)
if err != nil {
return nil, err
}
if !exists {
return nil, fmt.Errorf("Machine does not exist for api.Exists(%s)", constants.MachineName)
}
host, err := api.Load(constants.MachineName)
if err != nil {
return nil, err
}
return host, nil
}

View File

@ -327,7 +327,7 @@ func TestSetupCerts(t *testing.T) {
contents, _ := ioutil.ReadFile(cert)
transferred := s.Transfers.Bytes()
if !bytes.Contains(transferred, contents) {
t.Fatalf("Certificate not copied. Expected transfers to contain %s. It was: %s", contents, transferred)
t.Fatalf("Certificate not copied. Expected transfers to contain: %s. It was: %s", contents, transferred)
}
}
}
@ -361,3 +361,30 @@ func TestGetHostDockerEnv(t *testing.T) {
}
}
}
func TestHostGetLogs(t *testing.T) {
api := tests.NewMockAPI()
s, _ := tests.NewSSHServer()
port, err := s.Start()
if err != nil {
t.Fatalf("Error starting ssh server: %s", err)
}
d := &tests.MockDriver{
Port: port,
BaseDriver: drivers.BaseDriver{
IPAddress: "127.0.0.1",
SSHKeyPath: "",
},
}
api.Hosts[constants.MachineName] = &host.Host{Driver: d}
if _, err := GetHostLogs(api); err != nil {
t.Fatalf("Error getting host logs: %s", err)
}
if _, ok := s.Commands[logsCommand]; !ok {
t.Fatalf("Expected command not run: %s", logsCommand)
}
}

View File

@ -16,6 +16,13 @@ limitations under the License.
package cluster
import "fmt"
const (
remoteLocalKubeErrPath = "/var/log/localkube.err"
remoteLocalKubeOutPath = "/var/log/localkube.out"
)
var startCommand = `
# Run with nohup so it stays up. Redirect logs to useful places.
PATH=/usr/local/sbin:$PATH nohup sudo /usr/local/bin/localkube start --generate-certs=false > /var/log/localkube.out 2> /var/log/localkube.err < /dev/null &
@ -23,3 +30,5 @@ PATH=/usr/local/sbin:$PATH nohup sudo /usr/local/bin/localkube start --generate-
// Kill any running instances.
var stopCommand = "killall localkube | true"
var logsCommand = fmt.Sprintf("tail -n +1 %s %s", remoteLocalKubeErrPath, remoteLocalKubeOutPath)

View File

@ -17,7 +17,6 @@ limitations under the License.
package sshutil
import (
"strings"
"testing"
"github.com/docker/machine/libmachine/drivers"
@ -49,8 +48,8 @@ func TestNewSSHClient(t *testing.T) {
t.Fatalf("Error!")
}
if !strings.Contains(s.Commands[0], cmd) {
t.Fatalf("Expected command: %s, got %s", cmd, s.Commands[0])
if _, ok := s.Commands[cmd]; !ok {
t.Fatalf("Expected command: %s", cmd)
}
}

View File

@ -21,6 +21,7 @@ import (
"crypto/rand"
"crypto/rsa"
"io"
"log"
"net"
"strconv"
@ -31,7 +32,7 @@ import (
type SSHServer struct {
Config *ssh.ServerConfig
// Commands stores the raw commands executed against the server.
Commands []string
Commands map[string]int
Connected bool
Transfers *bytes.Buffer
}
@ -43,6 +44,7 @@ func NewSSHServer() (*SSHServer, error) {
s.Config = &ssh.ServerConfig{
NoClientAuth: true,
}
s.Commands = make(map[string]int)
private, err := rsa.GenerateKey(rand.Reader, 2014)
if err != nil {
@ -56,6 +58,10 @@ func NewSSHServer() (*SSHServer, error) {
return s, nil
}
type execRequest struct {
Command string
}
// Start starts the mock SSH Server, and returns the port it's listening on.
func (s *SSHServer) Start() (int, error) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
@ -88,7 +94,14 @@ func (s *SSHServer) Start() (int, error) {
req := <-requests
req.Reply(true, nil)
s.Commands = append(s.Commands, string(req.Payload))
//Note: string(req.Payload) adds additional characters to start of input, execRequest used to solve this issue
var cmd execRequest
if err := ssh.Unmarshal(req.Payload, &cmd); err != nil {
log.Println("Unmarshall encountered error: %s", err)
return
}
s.Commands[cmd.Command] = 1
channel.SendRequest("exit-status", false, []byte{0, 0, 0, 0})
// Store anything that comes in over stdin.