diff --git a/clojure_frontend/project.clj b/clojure_frontend/project.clj index 650af4e..6a4da44 100644 --- a/clojure_frontend/project.clj +++ b/clojure_frontend/project.clj @@ -23,6 +23,7 @@ [prismatic/schema "1.1.9"] ;; filesystem utilities [me.raynes/fs "1.4.6"] + [me.raynes/conch "0.8.0"] ;; time from joda-time [clj-time "0.14.4"]] :aliases {"test" "midje"} diff --git a/clojure_frontend/resources/public/static/img/whale_toast.jpg b/clojure_frontend/resources/public/static/img/whale_toast.jpg new file mode 100644 index 0000000..149ffd3 Binary files /dev/null and b/clojure_frontend/resources/public/static/img/whale_toast.jpg differ diff --git a/clojure_frontend/src/toaster/handler.clj b/clojure_frontend/src/toaster/handler.clj index 5f1a349..b9d32b9 100644 --- a/clojure_frontend/src/toaster/handler.clj +++ b/clojure_frontend/src/toaster/handler.clj @@ -38,7 +38,9 @@ [toaster.session :as s] [toaster.config :as conf] [toaster.webpage :as web] - [toaster.ring :as ring]) + [toaster.ring :as ring] + [toaster.views :as views] + [toaster.jobs :as job]) (:import java.io.File) (:gen-class)) @@ -49,9 +51,18 @@ (GET "/" request (web/render "Hello World!"));; web/readme)) ;; NEW ROUTES HERE + (GET "/dockerfile" request + (web/render views/dockerfile-upload-form)) + ;; (->> views/dockerfile-get + ;; (s/check request))) + (POST "/dockerfile" request + (views/dockerfile-upload-post request nil nil)) - + (GET "/list" request + (web/render [:div {:class "container-fluid"} + [:h1 "List all created jobs"] + (job/listall config)])) ;; JUST-AUTH ROUTES (GET "/login" request diff --git a/clojure_frontend/src/toaster/jobs.clj b/clojure_frontend/src/toaster/jobs.clj new file mode 100644 index 0000000..4d08c19 --- /dev/null +++ b/clojure_frontend/src/toaster/jobs.clj @@ -0,0 +1,36 @@ +(ns toaster.jobs + (:require + [clojure.string :as str] + [clojure.java.io :as io] + [failjure.core :as f] + [taoensso.timbre :as log :refer [debug]] + [me.raynes.conch :as sh :refer [with-programs]] + [toaster.webpage :as web] + [hiccup.form :as hf])) + +(defn add [path config account] + (with-programs [ssh scp] + (let [jobname "test@dyne.org-vm_amd64-12345678" ;; TODO: + jobdir (str "/srv/toaster/" jobname)] + (f/attempt-all + [r_mkdir (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "mkdir" "-p" jobdir ) + r_scp (scp "-i" "../id_ed25519" path (str "jenkins@sdk.bridge:" jobdir)) + r_ssh (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "sync_jobs.py" "-a" jobname {:verbose true})] + (f/when-failed [e] + (web/render-error-page + (str "Job add failure: " (f/message e)))))))) + + +(defn listall [config] + (with-programs [ssh] + (f/attempt-all + [r_ssh (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "sync_jobs.py" "-l" "all" {:verbose true})] + ;; (let [jobs (str/split (:stdout r_ssh) #" ")] + ;; jobs) + (:stdout r_ssh) + (f/when-failed [e] + (web/render-error-page + (str "Job list failure: " (f/message e))))))) + + + diff --git a/clojure_frontend/src/toaster/views.clj b/clojure_frontend/src/toaster/views.clj new file mode 100644 index 0000000..356ed4b --- /dev/null +++ b/clojure_frontend/src/toaster/views.clj @@ -0,0 +1,64 @@ +(ns toaster.views + (:require + [clojure.java.io :as io] + ;; [clojure.data.json :as json :refer [read-str]] + [toaster.webpage :as web] + [toaster.session :as s] + [toaster.ring :as ring] + [toaster.jobs :as job] + [failjure.core :as f] + [auxiliary.string :refer [strcasecmp]] + [toaster.config :as conf] + [taoensso.timbre :as log :refer [debug]] + [me.raynes.conch :as sh :refer [with-programs]] + [hiccup.form :as hf])) + +(def dockerfile-upload-form + [:div {:class "container-fluid"} + [:h1 "Upload a Dockerfile to toast"] + [:p " Choose the file in your computer and click 'Submit' to +proceed to validation."] + [:div {:class "form-group"} + [:form {:action "dockerfile" :method "post" + :class "form-shell" + :enctype "multipart/form-data"} + [:fieldset {:class "fieldset btn btn-default btn-file btn-lg"} + [:input {:name "file" :type "file"}]] + ;; [:fieldset {:class "fieldset-submit"} + [:input {:class "btn btn-primary btn-lg" + :id "field-submit" :type "submit" + :name "submit" :value "submit"}]]]]) + +(defn dockerfile-upload-post + [request config account] + (web/render + (let + [tempfile (get-in request [:params :file :tempfile]) + filename (get-in request [:params :file :filename]) + params (:params request)] + (cond + (> (get-in params [:file :size]) 64000) + ;; max upload size in bytes + ;; TODO: put in config + (web/render-error-page params "File too big in upload (64KB limit).") + :else + (let [file (io/copy tempfile (io/file "/tmp" filename)) + path (str "/tmp/" filename)] + (io/delete-file tempfile) + (if (not (.exists (io/file path))) + (web/render-error-page + (log/spy :error + [:h1 (str "Uploaded file not found: " filename)])) + ;; file is now in 'tmp' var + (with-programs [ssh scp] + ;; (require '[clj-time.core :as time] + ;; '[clj-time.coerce :as tc]) + ;; timestamp: (tc/to-long (time/now)) + (let [jobname "test@dyne.org-vm_amd64-12345678" ;; TODO: + jobdir (str "/srv/toaster/" jobname)] + (log/spy (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "mkdir" "-p" jobdir {:throw false})) + (log/spy (scp "-i" "../id_ed25519" path (str "jenkins@sdk.bridge:" jobdir) {:throw false})) + (log/spy (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "sync_jobs.py" "-a" jobname {:verbose true :throw false})))) + + ;; TODO: launch scripts + )))))) diff --git a/clojure_frontend/src/toaster/webpage.clj b/clojure_frontend/src/toaster/webpage.clj index 469cca8..6597763 100644 --- a/clojure_frontend/src/toaster/webpage.clj +++ b/clojure_frontend/src/toaster/webpage.clj @@ -164,9 +164,12 @@ [:span {:class "icon-bar"}] [:span {:class "icon-bar"}] [:span {:class "icon-bar"}]] - [:a {:class "navbar-brand far fa-handshake" :href "/"} "toaster"]] + [:a {:class "navbar-item " :href "/"} + [:img {:src "/static/img/whale_toast.jpg"}] + ]] + [:div {:class "collapse navbar-collapse" :id "navbarResponsive"} - [:ul {:class "nav navbar-nav hidden-sm hidden-md ml-auto"} + [:ul {:class "nav navbar-nav hidden-sm md-auto ml-auto"} ;; -- [:li {:class "divider" :role "separator"}] [:li {:class "nav-item"} @@ -189,7 +192,7 @@ [:a {:class "navbar-brand far fa-handshake" :href "/"} "toaster"]] [:div {:class "collapse navbar-collapse" :id "navbarResponsive"} - [:ul {:class "nav navbar-nav hidden-sm hidden-md ml-auto"} + [:ul {:class "nav navbar-nav hidden-sm ml-auto"} ;; -- [:li {:class "divider" :role "separator"}] ;; LIST OF RELEVANT LINKS AFTER LOGIN