Merge pull request #92 from djs55/go-diagnostics

moby: rewrite diagnostics server in Go
This commit is contained in:
Justin Cormack 2016-04-15 16:17:08 +01:00
commit 115373d42e
8 changed files with 162 additions and 43 deletions

View File

@ -40,7 +40,6 @@ COPY packages/docker/bin/* /usr/bin/
COPY packages/docker/etc /etc/
COPY packages/diagnostics/diagnostics /usr/bin/
COPY packages/diagnostics/diagnostics-server /usr/bin/
COPY packages/diagnostics/diagnostics-download /usr/bin/
COPY packages/diagnostics/etc /etc/
COPY packages/automount/etc /etc/
COPY packages/ntp15m/etc /etc/

View File

@ -1,5 +1,6 @@
all:
$(MAKE) -C proxy OS=linux
$(MAKE) -C diagnostics OS=linux
$(MAKE) -C transfused OS=linux
$(MAKE) -C mdnstool OS=linux
$(MAKE) -C hupper OS=linux
@ -11,6 +12,7 @@ all:
arm:
$(MAKE) -C proxy OS=linux ARCH=arm
$(MAKE) -C diagnostics OS=linux ARCH=arm
$(MAKE) -C transfused OS=linux ARCH=arm
$(MAKE) -C mdnstool OS=linux ARCH=arm
$(MAKE) -C hupper OS=linux ARCH=arm
@ -20,6 +22,7 @@ arm:
clean:
$(MAKE) -C proxy clean
$(MAKE) -C diagnostics clean
$(MAKE) -C transfused clean
$(MAKE) -C mdnstool clean
$(MAKE) -C docker clean

View File

@ -0,0 +1 @@
diagnostics-server

View File

@ -0,0 +1,15 @@
FROM golang:alpine
RUN apk update && apk add alpine-sdk
RUN mkdir -p /go/src/diagnostics
WORKDIR /go/src/diagnostics
COPY . /go/src/diagnostics
ARG GOARCH
ARG GOOS
RUN go install --ldflags '-extldflags "-fno-PIC"'
RUN [ -f /go/bin/*/diagnostics ] && mv /go/bin/*/diagnostics /go/bin/ || true

View File

@ -0,0 +1,10 @@
all: diagnostics-server
diagnostics-server: Dockerfile main.go
docker build --build-arg GOOS=$(OS) --build-arg GOARCH=$(ARCH) -t diagnostics:build .
docker run --rm diagnostics:build cat /go/bin/diagnostics > diagnostics-server
chmod 755 diagnostics-server
clean:
rm -f diagnostics-server
docker images -q diagnostics:build | xargs docker rmi -f

View File

@ -1,35 +0,0 @@
#!/bin/sh
# Gather diagnostic data and write a .tar file to stdout
TEMP=$(mktemp -d diagnoseXXXXXXX)
trap 'rm -rf "$TEMP"' EXIT
mkdir $TEMP/moby
cd $TEMP/moby
# gather diagnostic data
timeout -t 2 date > "date"
timeout -t 2 uname -a > "uname -a"
timeout -t 2 ps uax > "ps -aux"
timeout -t 2 netstat -tulpn > "netstat -tulpn"
timeout -t 2 iptables-save > "iptables-save"
timeout -t 2 ifconfig -a > "ifconfig -a"
timeout -t 2 route -n > "route -n"
timeout -t 2 brctl show > "brctl show"
timeout -t 2 dmesg > dmesg
timeout -t 2 docker ps > "docker ps"
timeout -t 2 tail /var/log/docker.log > "docker.log"
timeout -t 2 mount > "mount"
timeout -t 2 df > "df"
timeout -t 2 ls -l /var &> "ls -l var"
timeout -t 2 ls -l /var/lib &> "ls -l var_lib"
timeout -t 2 ls -l /var/lib/docker &> "ls -l var_lib_docker"
timeout -t 2 /usr/bin/diagnostics > "diagnostics"
timeout -t 2 ping -w 5 8.8.8.8 &> "ping -w 5 8.8.8.8"
timeout -t 2 cp /etc/resolv.conf .
timeout -t 2 dig docker.com > "dig docker.com"
timeout -t 2 wget -O - http://www.docker.com/ &> "wget docker.com"
# send everything to the client
cd ..
tar -c .

View File

@ -1,7 +0,0 @@
#!/bin/sh
# Allow clients (e.g. pinata diagnose) to download diagnostic data
while /bin/true; do
nc -l -p 62374 -e /usr/bin/diagnostics-download 2>> /var/log/diagnostics-server.log
done

View File

@ -0,0 +1,133 @@
package main
import (
"archive/tar"
"bytes"
"io"
"log"
"net"
"os/exec"
"path"
"strings"
"time"
)
func run(timeout time.Duration, w *tar.Writer, command string, args ...string) {
log.Printf("Running %s", command)
c := exec.Command(command, args...)
stdoutPipe, err := c.StdoutPipe()
if err != nil {
log.Fatalf("Failed to create stdout pipe: %#v", err)
}
stderrPipe, err := c.StderrPipe()
if err != nil {
log.Fatalf("Failed to create stderr pipe: %#v", err)
}
var stdoutBuffer bytes.Buffer
var stderrBuffer bytes.Buffer
done := make(chan int)
go func() {
io.Copy(&stdoutBuffer, stdoutPipe)
done <- 0
}()
go func() {
io.Copy(&stderrBuffer, stderrPipe)
done <- 0
}()
var timer *time.Timer
timer = time.AfterFunc(timeout, func() {
timer.Stop()
if c.Process != nil {
c.Process.Kill()
}
})
_ = c.Run()
<-done
<-done
timer.Stop()
name := strings.Join(append([]string{path.Base(command)}, args...), " ")
hdr := &tar.Header{
Name: name + ".stdout",
Mode: 0644,
Size: int64(stdoutBuffer.Len()),
}
if err = w.WriteHeader(hdr); err != nil {
log.Fatalln(err)
}
if _, err = w.Write(stdoutBuffer.Bytes()); err != nil {
log.Fatalln(err)
}
hdr = &tar.Header{
Name: name + ".stderr",
Mode: 0644,
Size: int64(stderrBuffer.Len()),
}
if err = w.WriteHeader(hdr); err != nil {
log.Fatalln(err)
}
if _, err = w.Write(stderrBuffer.Bytes()); err != nil {
log.Fatalln(err)
}
}
func capture(w *tar.Writer) {
t := 2 * time.Second
run(t, w, "/bin/date")
run(t, w, "/bin/uname", "-a")
run(t, w, "/bin/ps", "uax")
run(t, w, "/bin/netstat", "-tulpn")
run(t, w, "/sbin/iptables-save")
run(t, w, "/sbin/ifconfig", "-a")
run(t, w, "/sbin/route", "-n")
run(t, w, "/usr/sbin/brctl", "show")
run(t, w, "/bin/dmesg")
run(t, w, "/usr/bin/docker", "ps")
run(t, w, "/usr/bin/tail", "/var/log/docker.log")
run(t, w, "/bin/mount")
run(t, w, "/bin/df")
run(t, w, "/bin/ls", "-l", "/var")
run(t, w, "/bin/ls", "-l", "/var/lib")
run(t, w, "/bin/ls", "-l", "/var/lib/docker")
run(t, w, "/usr/bin/diagnostics")
run(t, w, "/bin/ping", "-w", "5", "8.8.8.8")
run(t, w, "/bin/cp", "/etc/resolv.conf", ".")
run(t, w, "/usr/bin/dig", "docker.com")
run(t, w, "/usr/bin/wget", "-O", "-", "http://www.docker.com/")
}
func main() {
listeners := make([]net.Listener, 0)
ip, err := net.Listen("tcp", ":62374")
if err != nil {
log.Printf("Failed to bind to TCP port 62374: %#v", err)
} else {
listeners = append(listeners, ip)
}
for _, l := range listeners {
go func(l net.Listener) {
for {
conn, err := l.Accept()
if err != nil {
log.Printf("Error accepting connection: %#v", err)
return // no more listening
}
go func(conn net.Conn) {
w := tar.NewWriter(conn)
capture(w)
if err := w.Close(); err != nil {
log.Println(err)
}
conn.Close()
}(conn)
}
}(l)
}
forever := make(chan int)
<-forever
}