Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for text/html Accept header #16

Merged
merged 7 commits into from
Nov 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
eremetic
eremetic.yml
docker/static
docker/templates
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: all deps test docker
.PHONY: all deps test docker copy_templates

DOCKERTAG?=eremetic
SRC=$(shell find . -name '*.go')
Expand All @@ -18,5 +18,9 @@ eremetic: ${SRC}
docker/eremetic: ${SRC}
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o $@

docker: docker/eremetic
copy_templates:
cp -r static docker
cp -r templates docker

docker: docker/eremetic copy_templates
docker build -t ${DOCKERTAG} docker
9 changes: 8 additions & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
FROM alpine:3.2
COPY eremetic /bin/eremetic

RUN mkdir -p /opt/eremetic

COPY eremetic /opt/eremetic/eremetic
COPY static /opt/eremetic/static
COPY templates /opt/eremetic/templates
COPY marathon.sh /marathon.sh

WORKDIR /opt/eremetic
CMD [ "/marathon.sh" ]
2 changes: 1 addition & 1 deletion docker/marathon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export MESSENGER_ADDRESS=`lookup_host ${HOST}${DOMAIN:+.$DOMAIN}`
export MESSENGER_PORT=$PORT1


exec /bin/eremetic
exec /opt/eremetic/eremetic
67 changes: 59 additions & 8 deletions handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package handler
import (
"encoding/json"
"fmt"
"html/template"
"io"
"io/ioutil"
"net/http"
"strings"
"time"

log "github.com/dmuth/google-go-log4go"
Expand All @@ -27,14 +29,14 @@ func AddTask(w http.ResponseWriter, r *http.Request) {
err = json.Unmarshal(body, &request)
handleError(err, w)

taskId, err := scheduleTask(scheduler, request)
taskID, err := scheduleTask(scheduler, request)
if err != nil {
writeJSON(500, err, w)
return
}

w.Header().Set("Location", fmt.Sprintf("/task/%s", taskId))
writeJSON(http.StatusAccepted, taskId, w)
w.Header().Set("Location", fmt.Sprintf("/task/%s", taskID))
writeJSON(http.StatusAccepted, taskID, w)
}

// GetTaskInfo returns information about the given task.
Expand All @@ -44,12 +46,15 @@ func GetTaskInfo(w http.ResponseWriter, r *http.Request) {
log.Debugf("Fetching task for id: %s", id)
task := runningTasks[id]

if task == (eremeticTask{}) {
writeJSON(http.StatusNotFound, nil, w)
return
if strings.Contains(r.Header.Get("Accept"), "text/html") {
renderHTML(w, r, task, id)
} else {
if task == (eremeticTask{}) {
writeJSON(http.StatusNotFound, nil, w)
return
}
writeJSON(http.StatusOK, task, w)
}

writeJSON(http.StatusOK, task, w)
}

// Run the RequestChannel Listener
Expand Down Expand Up @@ -108,3 +113,49 @@ func writeJSON(status int, data interface{}, w http.ResponseWriter) error {
w.WriteHeader(status)
return json.NewEncoder(w).Encode(data)
}

func renderHTML(w http.ResponseWriter, r *http.Request, task eremeticTask, taskID string) {
var err error
var tpl *template.Template

data := make(map[string]interface{})
funcMap := template.FuncMap{
"ToLower": strings.ToLower,
}

if task == (eremeticTask{}) {
tpl, err = template.ParseFiles("templates/error_404.html")
data["TaskID"] = taskID
} else {
tpl, err = template.New("task.html").Funcs(funcMap).ParseFiles("templates/task.html")
data = makeMap(task)
}

if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Error(err.Error())
return
}

err = tpl.Execute(w, data)
}

func makeMap(task eremeticTask) map[string]interface{} {
data := make(map[string]interface{})

data["TaskID"] = task.ID
data["CommandEnv"] = task.Command.GetEnvironment().GetVariables()
data["CommandUser"] = task.Command.GetUser()
data["Command"] = task.Command.GetValue()
// TODO: Support more than docker?
data["ContainerImage"] = task.Container.GetDocker().GetImage()
data["FrameworkID"] = task.FrameworkId
data["Hostname"] = task.Hostname
data["Name"] = task.Name
data["SlaveID"] = task.SlaveId
data["Status"] = task.Status
data["CPU"] = fmt.Sprintf("%.2f", task.TaskCPUs)
data["Memory"] = fmt.Sprintf("%.2f", task.TaskMem)

return data
}
28 changes: 28 additions & 0 deletions routes/routes.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package routes

import (
"encoding/json"
"html/template"
"net/http"
"strings"

"github.com/alde/eremetic/handler"
"github.com/alde/eremetic/types"
log "github.com/dmuth/google-go-log4go"
"github.com/gorilla/mux"
)

Expand All @@ -18,9 +24,31 @@ func Create() *mux.Router {
Handler(route.HandlerFunc)
}

router.PathPrefix("/static/").
Handler(
http.StripPrefix(
"/static/", http.FileServer(http.Dir("./static/"))))

router.NotFoundHandler = http.HandlerFunc(notFound)

return router
}

func notFound(w http.ResponseWriter, r *http.Request) {
if strings.Contains(r.Header.Get("Accept"), "text/html") {
tpl, err := template.ParseFiles("templates/error_404.html")
if err == nil {
tpl.Execute(w, nil)
return
}
log.Error(err.Error())
}

w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusNotFound)
json.NewEncoder(w).Encode(nil)
}

var routes = types.Routes{
types.Route{
Name: "AddTask",
Expand Down
11 changes: 11 additions & 0 deletions static/css/semantic.min.css

Large diffs are not rendered by default.

98 changes: 98 additions & 0 deletions static/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
.error_message {
float: left;
left: 35em;
top: 5em;
}

.ui.list > .item {
display: flex !important;
}

.main.container {
padding-top: 50px;
}

.container_section {
padding-top: 20px;
}

.column .header {
padding-bottom: 40px;
}

.ui.cpu.icon.svg {
background: url("/static/images/cpu.svg");
background-size: 100% 100%;
}
.ui.ram.icon.svg {
background: url("/static/images/ram.svg");
background-size: 100% 100%;
}

.label.task_staging {
background-color: #00b5ad !important;
border-color: #00b5ad !important;
color: #fff !important;
}

.label.task_failed {
background-color: #db2828 !important;
border-color: #db2828 !important;
color: #fff !important;
}

.label.task_lost {
background-color: #a333c8 !important;
border-color: #a333c8 !important;
color: #fff !important;
}

.label.task_killed {
background-color: #f2711c !important;
border-color: #f2711c !important;
color: #fff !important;
}

.label.task_finished {
background-color: #21ba45 !important;
border-color: #21ba45 !important;
color: #fff !important;
}

@font-face {
font-family: "fontcustom";
src: url("./themes/default/assets/fonts/fontcustom_cb066050d5b786186aa0e7f121427d8b.eot");
src: url("./themes/default/assets/fonts/fontcustom_cb066050d5b786186aa0e7f121427d8b.eot?#iefix") format("embedded-opentype"),
url("./themes/default/assets/fonts/fontcustom_cb066050d5b786186aa0e7f121427d8b.woff") format("woff"),
url("./themes/default/assets/fonts/fontcustom_cb066050d5b786186aa0e7f121427d8b.ttf") format("truetype"),
url("./themes/default/assets/fonts/fontcustom_cb066050d5b786186aa0e7f121427d8b.svg#fontcustom") format("svg");
font-weight: normal;
font-style: normal;
}

@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: "fontcustom";
src: url("./themes/default/assets/fonts/fontcustom_cb066050d5b786186aa0e7f121427d8b.svg#fontcustom") format("svg");
}
}

[data-icon]:before { content: attr(data-icon); }

[data-icon]:before,
.docker:before {
display: inline-block;
font-family: "fontcustom";
font-style: normal;
font-weight: normal;
font-variant: normal;
line-height: 1;
text-decoration: inherit;
text-rendering: optimizeLegibility;
text-transform: none;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-smoothing: antialiased;
}

.docker:before { content: "\f100"; }
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file added static/css/themes/default/assets/fonts/icons.ttf
Binary file not shown.
Binary file added static/css/themes/default/assets/fonts/icons.woff
Binary file not shown.
Binary file not shown.
55 changes: 55 additions & 0 deletions static/images/cpu.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/images/disappointed_minion.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.