From 924ff5f5ef5aed2795b3d437349c80828c4eecd3 Mon Sep 17 00:00:00 2001 From: David Zuber Date: Sat, 31 Aug 2019 18:24:11 +0100 Subject: [PATCH] Initial commit --- Dockerfile | 41 +++++++++++ kind-config.yaml | 9 +++ kubedoom.go | 139 ++++++++++++++++++++++++++++++++++++++ manifest/00namespace.yaml | 4 ++ manifest/deployment.yaml | 25 +++++++ manifest/rbac.yaml | 18 +++++ manifest/service.yaml | 15 ++++ 7 files changed, 251 insertions(+) create mode 100644 Dockerfile create mode 100644 kind-config.yaml create mode 100644 kubedoom.go create mode 100644 manifest/00namespace.yaml create mode 100644 manifest/deployment.yaml create mode 100644 manifest/rbac.yaml create mode 100644 manifest/service.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..dc5e4c5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +FROM golang:1.12-alpine AS gobuild + +WORKDIR /go/src/kubedoom +ADD kubedoom.go . +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o kubedoom . + +FROM ubuntu:19.10 AS ubuntu +# make sure the package repository is up to date +RUN apt-get update + +FROM ubuntu AS ubuntu-deps +# Install dependencies +RUN apt-get install -y -o APT::Install-Suggests=0 --no-install-recommends git wget ca-certificates +RUN git clone https://github.com/GideonRed/dockerdoom.git +RUN wget http://distro.ibiblio.org/pub/linux/distributions/slitaz/sources/packages/d/doom1.wad +RUN wget -O /usr/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.15.3/bin/linux/amd64/kubectl && chmod +x /usr/bin/kubectl + +FROM ubuntu AS ubuntu-build + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get install -y -o APT::Install-Suggests=0 --no-install-recommends build-essential libsdl-mixer1.2-dev libsdl-net1.2-dev gcc + +# Setup doom +COPY --from=ubuntu-deps /dockerdoom /dockerdoom +RUN cd /dockerdoom/trunk && ./configure --enable-static && make && make install + +FROM ubuntu +RUN apt-get install -y -o APT::Install-Suggests=0 --no-install-recommends libsdl-mixer1.2 libsdl-net1.2 x11vnc xvfb netcat-openbsd + + +WORKDIR /root/ + +# Setup a password +RUN mkdir ~/.vnc && x11vnc -storepasswd 1234 ~/.vnc/passwd + +COPY --from=ubuntu-deps /doom1.wad . +COPY --from=ubuntu-deps /usr/bin/kubectl /usr/bin/ +COPY --from=ubuntu-build /usr/local/games/psdoom /usr/local/games/ +COPY --from=gobuild /go/src/kubedoom/kubedoom . + +ENTRYPOINT ["/root/kubedoom"] diff --git a/kind-config.yaml b/kind-config.yaml new file mode 100644 index 0000000..867416f --- /dev/null +++ b/kind-config.yaml @@ -0,0 +1,9 @@ +kind: Cluster +apiVersion: kind.sigs.k8s.io/v1alpha3 +nodes: +- role: control-plane +- role: worker + extraPortMappings: + - containerPort: 5900 + hostPort: 5900 + listenAddress: "127.0.0.1" # Optional, defaults to "0.0.0.0" diff --git a/kubedoom.go b/kubedoom.go new file mode 100644 index 0000000..f88d6fc --- /dev/null +++ b/kubedoom.go @@ -0,0 +1,139 @@ +package main + +//TODO: Make your container die if you die + +import ( + "flag" + //"fmt" + "log" + "net" + "os" + "os/exec" + "strings" + "time" +) + +func runCmd(cmdstring string) { + parts := strings.Split(cmdstring, " ") + cmd := exec.Command(parts[0], parts[1:len(parts)]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + log.Fatalf("The following command failed: \"%v\"\n", cmdstring) + } +} + +func outputCmd(argv []string) string { + cmd := exec.Command(argv[0], argv[1:len(argv)]...) + cmd.Stderr = os.Stderr + output, err := cmd.Output() + if err != nil { + log.Fatalf("The following command failed: \"%v\"\n", argv) + } + return string(output) +} + +func startCmd(cmdstring string) { + parts := strings.Split(cmdstring, " ") + cmd := exec.Command(parts[0], parts[1:len(parts)]...) + cmd.Stdout = os.Stdout + cmd.Stdin = os.Stdin + err := cmd.Start() + if err != nil { + log.Fatalf("The following command failed: \"%v\"\n", cmdstring) + } +} + +func startCmdSilent(cmdstring string) { + parts := strings.Split(cmdstring, " ") + cmd := exec.Command(parts[0], parts[1:len(parts)]...) + cmd.Stdin = os.Stdin + err := cmd.Start() + if err != nil { + log.Fatalf("The following command failed: \"%v\"\n", cmdstring) + } +} + +func socketLoop(listener net.Listener) { + log.Print("Socket loop") + for true { + log.Print("accept?") + conn, err := listener.Accept() + log.Print("accept!") + if err != nil { + panic(err) + } + stop := false + for !stop { + bytes := make([]byte, 40960) + log.Print("Reading") + n, err := conn.Read(bytes) + if err != nil { + stop = true + } + log.Print("got suff") + bytes = bytes[0:n] + strbytes := strings.TrimSpace(string(bytes)) + log.Printf("Received: '%s'", strbytes) + if strbytes == "list" { + // output := outputCmd(fmt.Sprintf("%v ps -q", dockerBinary)) + args := []string{"kubectl", "get", "pods", "-A", "-o", "go-template", "--template={{range .items}}{{.metadata.namespace}}/{{.metadata.name}} {{end}}"} + output := outputCmd(args) + log.Printf("output: '%s'", output) + _, err = conn.Write([]byte(output)) + if err != nil { + log.Fatal("Could not write to socker file") + } + //cmd := exec.Command("/usr/bin/docker", "inspect", "-f", "{{.Name}}", "`docker", "ps", "-q`") + // outputstr := strings.TrimSpace(output) + // pods := strings.Split(outputstr, "\n") + // for _, pod := range pods { + // log.Print(pod) + // _, err = conn.Write([]byte(pod + " ")) + // if err != nil { + // log.Fatal("Could not write to socker file") + // } + // time.Sleep(time.Duration(200) * time.Millisecond) + // } + conn.Close() + stop = true + } else if strings.HasPrefix(strbytes, "kill ") { + log.Printf("killcommand: '%s'", strbytes) + // parts := strings.Split(strbytes, " ") + // pod := strings.TrimSpace(parts[1]) + // podparts := strings.Split(pod, "/") + // namespace := podparts[0] + + // podname := podparts[1] + // log.Printf("Pod to kill: %s // %s", namespace, podname) + // cmd := exec.Command(dockerBinary, "rm", "-f", docker_id) + // go cmd.Run() + conn.Close() + stop = true + } + } + } +} + +func main() { + var asciiDisplay bool + flag.BoolVar(&asciiDisplay, "asciiDisplay", false, "Don't use fancy vnc, throw DOOM straightup on my terminal screen") + flag.Parse() + + listener, err := net.Listen("unix", "/dockerdoom.socket") + if err != nil { + log.Fatalf("Could not create socket file") + } + + if !asciiDisplay { + log.Print("Create virtual display") + startCmd("/usr/bin/Xvfb :99 -ac -screen 0 640x480x24") + time.Sleep(time.Duration(2) * time.Second) + startCmd("x11vnc -geometry 640x480 -forever -usepw -display :99") + log.Print("You can now connect to it with a VNC viewer at port 5900") + } + log.Print("Trying to start DOOM ...") + startCmdSilent("/usr/bin/env DISPLAY=:99 /usr/local/games/psdoom -warp -E1M1") + socketLoop(listener) +} diff --git a/manifest/00namespace.yaml b/manifest/00namespace.yaml new file mode 100644 index 0000000..1ee40d3 --- /dev/null +++ b/manifest/00namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: kubedoom diff --git a/manifest/deployment.yaml b/manifest/deployment.yaml new file mode 100644 index 0000000..e403659 --- /dev/null +++ b/manifest/deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + labels: + app: kubedoom + name: kubedoom + namespace: kubedoom +spec: + replicas: 1 + selector: + matchLabels: + app: kubedoom + template: + metadata: + labels: + app: kubedoom + spec: + hostNetwork: true + serviceAccountName: kubedoom + containers: + - image: kubedoom:0.1.2 + name: kubedoom + ports: + - containerPort: 5900 + name: vnc diff --git a/manifest/rbac.yaml b/manifest/rbac.yaml new file mode 100644 index 0000000..fc133ce --- /dev/null +++ b/manifest/rbac.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kubedoom + namespace: kubedoom +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubedoom +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: kubedoom + namespace: kubedoom diff --git a/manifest/service.yaml b/manifest/service.yaml new file mode 100644 index 0000000..192cbcf --- /dev/null +++ b/manifest/service.yaml @@ -0,0 +1,15 @@ +# apiVersion: v1 +# kind: Service +# metadata: +# labels: +# app: kubedoom +# name: kubedoom +# namespace: kubedoom +# spec: +# type: NodePort +# ports: +# - name: vnc +# port: 5900 +# targetPort: vnc +# selector: +# app: kubedoom