Compare commits
No commits in common. "c277e7a6a860ff6d1c8b8364e83fb60f1fdf238e" and "d245ab99395d59d8716cd19670190378590d564e" have entirely different histories.
c277e7a6a8
...
d245ab9939
|
@ -25,17 +25,13 @@
|
||||||
[me.raynes/fs "1.4.6"]
|
[me.raynes/fs "1.4.6"]
|
||||||
[me.raynes/conch "0.8.0"]
|
[me.raynes/conch "0.8.0"]
|
||||||
;; time from joda-time
|
;; time from joda-time
|
||||||
[clj-time "0.14.4"]
|
[clj-time "0.14.4"]]
|
||||||
[clojure-humanize "0.2.2"]]
|
|
||||||
:aliases {"test" "midje"}
|
:aliases {"test" "midje"}
|
||||||
:source-paths ["src"]
|
:source-paths ["src"]
|
||||||
:resource-paths ["resources"]
|
:resource-paths ["resources"]
|
||||||
:plugins [[lein-ring "0.12.4"]]
|
:plugins [[lein-ring "0.12.4"]]
|
||||||
:ring {:init toaster.ring/init
|
:ring {:init toaster.ring/init
|
||||||
:handler toaster.handler/app
|
:handler toaster.handler/app}
|
||||||
:nrepl {:start? true
|
|
||||||
:host "localhost"
|
|
||||||
:port 40231}}
|
|
||||||
:uberwar {:init toaster.ring/init
|
:uberwar {:init toaster.ring/init
|
||||||
:handler toaster.handler/app}
|
:handler toaster.handler/app}
|
||||||
:mail toaster.handler
|
:mail toaster.handler
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
;; (s/validate Config conf)
|
;; (s/validate Config conf)
|
||||||
;; (catch Exception ex
|
;; (catch Exception ex
|
||||||
;; (f/fail (log/spy :error ["Invalid configuration: " conf ex]))))
|
;; (f/fail (log/spy :error ["Invalid configuration: " conf ex]))))
|
||||||
(get-in conf (into [:toaster] path)))
|
(get-in conf path))
|
||||||
|
|
||||||
(defn load-config [name default]
|
(defn load-config [name default]
|
||||||
(log/info (str "Loading configuration: " name))
|
(log/info (str "Loading configuration: " name))
|
||||||
|
|
|
@ -17,158 +17,153 @@
|
||||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
(ns toaster.handler
|
(ns toaster.handler
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.data.json :as json]
|
[clojure.data.json :as json]
|
||||||
[compojure.core :refer :all]
|
[compojure.core :refer :all]
|
||||||
[compojure.handler :refer :all]
|
[compojure.handler :refer :all]
|
||||||
[compojure.route :as route]
|
[compojure.route :as route]
|
||||||
[compojure.response :as response]
|
[compojure.response :as response]
|
||||||
|
|
||||||
[ring.adapter.jetty :refer :all]
|
[ring.adapter.jetty :refer :all]
|
||||||
[ring.middleware.session :refer :all]
|
[ring.middleware.session :refer :all]
|
||||||
[ring.middleware.accept :refer [wrap-accept]]
|
[ring.middleware.accept :refer [wrap-accept]]
|
||||||
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]
|
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]
|
||||||
|
|
||||||
[failjure.core :as f]
|
[failjure.core :as f]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[just-auth.core :as auth]
|
[just-auth.core :as auth]
|
||||||
|
|
||||||
[toaster.session :as s]
|
[toaster.session :as s]
|
||||||
[toaster.config :as conf]
|
[toaster.config :as conf]
|
||||||
[toaster.webpage :as web]
|
[toaster.webpage :as web]
|
||||||
[toaster.ring :as ring]
|
[toaster.ring :as ring]
|
||||||
[toaster.views :as views]
|
[toaster.views :as views]
|
||||||
[toaster.jobs :as job])
|
[toaster.jobs :as job])
|
||||||
(:gen-class))
|
(:import java.io.File)
|
||||||
|
(:gen-class))
|
||||||
|
|
||||||
(defonce config (conf/load-config "toaster" conf/default-settings))
|
(defonce config (conf/load-config "toaster" conf/default-settings))
|
||||||
|
|
||||||
(defroutes
|
(defroutes app-routes
|
||||||
app-routes
|
|
||||||
|
|
||||||
(GET "/" request (web/render "Hello World!")) ;; web/readme))
|
(GET "/" request (web/render "Hello World!"));; web/readme))
|
||||||
|
|
||||||
;; NEW ROUTES HERE
|
;; NEW ROUTES HERE
|
||||||
(GET "/upload" request
|
(GET "/upload" request
|
||||||
(->> (fn [req conf acct]
|
(->> (fn [req conf acct]
|
||||||
(web/render acct views/dockerfile-upload-form))
|
(web/render acct views/dockerfile-upload-form))
|
||||||
(s/check request)))
|
(s/check request)))
|
||||||
|
|
||||||
(POST "/dockerfile" request
|
(POST "/dockerfile" request
|
||||||
(->> views/dockerfile-upload-post
|
(->> views/dockerfile-upload-post
|
||||||
(s/check request)))
|
(s/check request)))
|
||||||
|
|
||||||
(GET "/edit" request
|
|
||||||
(->> (fn [req conf acct]
|
|
||||||
(web/render acct views/dockerfile-edit-form))
|
|
||||||
(s/check request)))
|
|
||||||
|
|
||||||
(GET "/list" request
|
(GET "/list" request
|
||||||
(->> views/list-jobs
|
(->> views/list-jobs
|
||||||
(s/check request)))
|
(s/check request)))
|
||||||
|
|
||||||
;; JUST-AUTH ROUTES
|
;; JUST-AUTH ROUTES
|
||||||
(GET "/login" request
|
(GET "/login" request
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[acct (s/check-account request)]
|
[acct (s/check-account request)]
|
||||||
(web/render acct
|
(web/render acct
|
||||||
[:div
|
[:div
|
||||||
[:h1 (str "Already logged in with account: "
|
[:h1 (str "Already logged in with account: "
|
||||||
(:email acct))]
|
(:email acct))]
|
||||||
[:h2 [:a {:href "/logout"} "Logout"]]])
|
[:h2 [:a {:href "/logout"} "Logout"]]])
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render web/login-form))))
|
(web/render web/login-form))))
|
||||||
(POST "/login" request
|
(POST "/login" request
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[username (s/param request :username)
|
[username (s/param request :username)
|
||||||
password (s/param request :password)
|
password (s/param request :password)
|
||||||
logged (auth/sign-in
|
logged (auth/sign-in
|
||||||
@ring/auth username password {})]
|
@ring/auth username password {})]
|
||||||
;; TODO: pass :ip-address in last argument map
|
;; TODO: pass :ip-address in last argument map
|
||||||
(let [session {:session {:config config
|
(let [session {:session {:config config
|
||||||
:auth logged}}]
|
:auth logged}}]
|
||||||
(conj session
|
(conj session
|
||||||
(views/list-jobs request config logged)))
|
(views/list-jobs request config logged)))
|
||||||
;; (web/render
|
;; (web/render
|
||||||
;; logged
|
;; logged
|
||||||
;; [:div
|
;; [:div
|
||||||
;; [:h1 "Logged in: " username]
|
;; [:h1 "Logged in: " username]
|
||||||
;; views/welcome-menu])))
|
;; views/welcome-menu])))
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error-page
|
(web/render-error-page
|
||||||
(str "Login failed: " (f/message e))))))
|
(str "Login failed: " (f/message e))))))
|
||||||
(GET "/session" request
|
(GET "/session" request
|
||||||
(-> (:session request) web/render-yaml web/render))
|
(-> (:session request) web/render-yaml web/render))
|
||||||
(GET "/logout" request
|
(GET "/logout" request
|
||||||
(conj {:session {:config config}}
|
(conj {:session {:config config}}
|
||||||
(web/render [:h1 "Logged out."])))
|
(web/render [:h1 "Logged out."])))
|
||||||
(GET "/signup" request
|
(GET "/signup" request
|
||||||
(web/render web/signup-form))
|
(web/render web/signup-form))
|
||||||
(POST "/signup" request
|
(POST "/signup" request
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[name (s/param request :name)
|
[name (s/param request :name)
|
||||||
email (s/param request :email)
|
email (s/param request :email)
|
||||||
password (s/param request :password)
|
password (s/param request :password)
|
||||||
repeat-password (s/param request :repeat-password)
|
repeat-password (s/param request :repeat-password)
|
||||||
activation {:activation-uri
|
activation {:activation-uri
|
||||||
(get-in request [:headers "host"])}]
|
(get-in request [:headers "host"])}]
|
||||||
(web/render
|
(web/render
|
||||||
(if (= password repeat-password)
|
(if (= password repeat-password)
|
||||||
(f/try*
|
(f/try*
|
||||||
(f/if-let-ok?
|
(f/if-let-ok?
|
||||||
[signup (auth/sign-up @ring/auth
|
[signup (auth/sign-up @ring/auth
|
||||||
name
|
name
|
||||||
email
|
email
|
||||||
password
|
password
|
||||||
activation
|
activation
|
||||||
[])]
|
[])]
|
||||||
[:div
|
[:div
|
||||||
[:h2 (str "Account created: "
|
[:h2 (str "Account created: "
|
||||||
name " <" email ">")]
|
name " <" email ">")]
|
||||||
[:h3 "Account pending activation."]]
|
[:h3 "Account pending activation."]]
|
||||||
(web/render-error
|
(web/render-error
|
||||||
(str "Failure creating account: "
|
(str "Failure creating account: "
|
||||||
(f/message signup)))))
|
(f/message signup)))))
|
||||||
(web/render-error
|
(web/render-error
|
||||||
"Repeat password didnt match")))
|
"Repeat password didnt match")))
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(web/render-error-page
|
(web/render-error-page
|
||||||
(str "Sign-up failure: " (f/message e))))))
|
(str "Sign-up failure: " (f/message e))))))
|
||||||
(GET "/activate/:email/:activation-id"
|
(GET "/activate/:email/:activation-id"
|
||||||
[email activation-id :as request]
|
[email activation-id :as request]
|
||||||
(let [activation-uri
|
(let [activation-uri
|
||||||
(str "http://"
|
(str "http://"
|
||||||
(get-in request [:headers "host"])
|
(get-in request [:headers "host"])
|
||||||
"/activate/" email "/" activation-id)]
|
"/activate/" email "/" activation-id)]
|
||||||
(web/render
|
(web/render
|
||||||
[:div
|
[:div
|
||||||
(f/if-let-failed?
|
(f/if-let-failed?
|
||||||
[act (auth/activate-account
|
[act (auth/activate-account
|
||||||
@ring/auth email
|
@ring/auth email
|
||||||
{:activation-link activation-uri})]
|
{:activation-link activation-uri})]
|
||||||
(web/render-error
|
(web/render-error
|
||||||
[:div
|
[:div
|
||||||
[:h1 "Failure activating account"]
|
[:h1 "Failure activating account"]
|
||||||
[:h2 (f/message act)]
|
[:h2 (f/message act)]
|
||||||
[:p (str "Email: " email " activation-id: " activation-id)]])
|
[:p (str "Email: " email " activation-id: " activation-id)]])
|
||||||
[:h1 (str "Account activated - " email)])])))
|
[:h1 (str "Account activated - " email)])])))
|
||||||
;; -- end of JUST-AUTH
|
;; -- end of JUST-AUTH
|
||||||
|
|
||||||
(POST "/" request
|
(POST "/" request
|
||||||
;; generic endpoint for canceled operations
|
;; generic endpoint for canceled operations
|
||||||
(web/render (s/check-account request)
|
(web/render (s/check-account request)
|
||||||
[:div {:class (str "alert alert-danger") :role "alert"}
|
[:div {:class (str "alert alert-danger") :role "alert"}
|
||||||
(s/param request :message)]))
|
(s/param request :message)]))
|
||||||
|
|
||||||
(route/resources "/")
|
(route/resources "/")
|
||||||
(route/not-found (web/render-error-page "Page Not Found"))
|
(route/not-found (web/render-error-page "Page Not Found"))
|
||||||
) ;; end of routes
|
) ;; end of routes
|
||||||
|
|
||||||
(def app
|
(def app
|
||||||
(-> (wrap-defaults app-routes ring/app-defaults)
|
(-> (wrap-defaults app-routes ring/app-defaults)
|
||||||
(wrap-accept {:mime ["text/html"]
|
(wrap-accept {:mime ["text/html"]
|
||||||
;; preference in language, fallback to english
|
;; preference in language, fallback to english
|
||||||
:language ["en" :qs 0.5
|
:language ["en" :qs 0.5
|
||||||
"it" :qs 1
|
"it" :qs 1
|
||||||
|
@ -178,9 +173,7 @@
|
||||||
|
|
||||||
;; for uberjar
|
;; for uberjar
|
||||||
(defn -main []
|
(defn -main []
|
||||||
(println "Starting ring server")
|
(println "Starting standalone jetty server on http://localhost:6060")
|
||||||
(ring/init ring/app-defaults)
|
(run-jetty app {:port 6060
|
||||||
;(run-jetty app {:port 6060
|
:host "localhost"
|
||||||
; :host "localhost"
|
:join? true}))
|
||||||
; :join? true})
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,71 +1,40 @@
|
||||||
(ns toaster.jobs
|
(ns toaster.jobs
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clj-time.core :as time]
|
[clj-time.core :as time]
|
||||||
[clj-time.coerce :as tc]
|
[clj-time.coerce :as tc]
|
||||||
[clj-storage.db.mongo :refer [create-mongo-store]]
|
[failjure.core :as f]
|
||||||
[clj-storage.core :as db]
|
[taoensso.timbre :as log :refer [debug]]
|
||||||
[failjure.core :as f]
|
[me.raynes.conch :as sh :refer [with-programs]]
|
||||||
[taoensso.timbre :as log :refer [debug]]
|
[toaster.webpage :as web]
|
||||||
[me.raynes.conch :as sh :refer [with-programs]]
|
[hiccup.form :as hf]))
|
||||||
[toaster.webpage :as web]
|
|
||||||
[toaster.config :refer :all]
|
|
||||||
[toaster.ring :refer [jobs]]
|
|
||||||
[hiccup.form :as hf]))
|
|
||||||
|
|
||||||
(defn- ssh-host [config]
|
|
||||||
(str (q config [:jenkins :user]) "@" (q config [:jenkins :host])))
|
|
||||||
|
|
||||||
|
|
||||||
(defn- sync_jobs [config arg1 arg2]
|
|
||||||
(with-programs
|
|
||||||
[ssh]
|
|
||||||
(try
|
|
||||||
(-> (ssh "-i" (q config [:jenkins :key])
|
|
||||||
(ssh-host config) "sync_jobs.py"
|
|
||||||
arg1 arg2)
|
|
||||||
(str/split #"\n"))
|
|
||||||
(catch Exception e (f/fail (str "ERROR in sync_jobs.py - " (.getMessage e)))))))
|
|
||||||
|
|
||||||
(defn- dockerlint [path]
|
|
||||||
(with-programs [node]
|
|
||||||
(try
|
|
||||||
(node "node_modules/dockerlint/bin/dockerlint.js" path)
|
|
||||||
(catch Exception e
|
|
||||||
(f/fail (str "ERROR in dockerlint - " (.getMessage e)))))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn add [path config account]
|
(defn add [path config account]
|
||||||
(with-programs [ssh scp node]
|
(with-programs [ssh scp node]
|
||||||
(let [tstamp (tc/to-long (time/now))
|
(let [tstamp (tc/to-long (time/now))
|
||||||
jobname (str (:email account) "-vm_amd64-" tstamp)
|
jobname (str (:email account) "-vm_amd64-" tstamp)
|
||||||
jobdir (str "/srv/toaster/" jobname)]
|
jobdir (str "/srv/toaster/" jobname)]
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[r_lint (dockerlint path)
|
[r_lint (node "node_modules/dockerlint/bin/dockerlint.js" path)
|
||||||
r_mkdir (ssh "-i" (q config [:jenkins :key])
|
r_mkdir (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "mkdir" "-p" jobdir )
|
||||||
(ssh-host config) "mkdir" "-p" jobdir)
|
r_scp (scp "-i" "../id_ed25519" path (str "jenkins@sdk.bridge:" jobdir))
|
||||||
r_scp (scp "-i" (q config [:jenkins :key])
|
r_job (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "sync_jobs.py" "-a" jobname)]
|
||||||
path (str (ssh-host config) ":" jobdir))
|
{:lint r_lint
|
||||||
r_job (log/spy (sync_jobs config "-a" jobname))
|
:job r_job}
|
||||||
r_store (log/spy (db/store!
|
(f/when-failed [e]
|
||||||
@jobs :jobid
|
(web/render-error-page
|
||||||
(log/spy {:jobid jobname
|
(str "Job add failure: " (f/message e))))))))
|
||||||
:email (:email account)
|
|
||||||
:account (dissoc account :password :activation-link)
|
|
||||||
:lint (if (.contains r_lint "is OK") true false)
|
|
||||||
:timestamp tstamp
|
|
||||||
:type "vm_amd64"})))]
|
|
||||||
{:lint r_lint
|
|
||||||
:job r_job}
|
|
||||||
(f/when-failed [e]
|
|
||||||
(web/render-error-page
|
|
||||||
(str "Job add failure: " (f/message e))))))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn listall [config account]
|
(defn listall [config account]
|
||||||
(sync_jobs config "-l" (:email account))
|
(with-programs [ssh]
|
||||||
;;(db/query @jobs {:email (:email account)})
|
(f/attempt-all
|
||||||
)
|
[r_ssh (ssh "-i" "../id_ed25519" "jenkins@sdk.bridge" "sync_jobs.py" "-l" (:email account))]
|
||||||
|
(str/split r_ssh #"\n")
|
||||||
|
(f/when-failed [e]
|
||||||
|
(web/render-error-page
|
||||||
|
(str "Job list failure: " (f/message e)))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,41 +37,39 @@
|
||||||
(def db (atom {}))
|
(def db (atom {}))
|
||||||
(def accts (atom {}))
|
(def accts (atom {}))
|
||||||
(def auth (atom {}))
|
(def auth (atom {}))
|
||||||
(def jobs (atom {}))
|
|
||||||
|
|
||||||
(defn init []
|
(defn init []
|
||||||
(log/merge-config!
|
(log/merge-config! {:level :debug
|
||||||
{:level :debug
|
;; #{:trace :debug :info :warn :error :fatal :report}
|
||||||
;; #{:trace :debug :info :warn :error :fatal :report}
|
|
||||||
|
;; Control log filtering by
|
||||||
;; Control log filtering by
|
;; namespaces/patterns. Useful for turning off
|
||||||
;; namespaces/patterns. Useful for turning off
|
;; logging in noisy libraries, etc.:
|
||||||
;; logging in noisy libraries, etc.:
|
;; :ns-whitelist ["agiladmin.*" "just-auth.*"]
|
||||||
;; i.e: :ns-whitelist ["agiladmin.*" "just-auth.*"]
|
:ns-blacklist ["org.eclipse.jetty.*"
|
||||||
:ns-blacklist ["org.eclipse.jetty.*"
|
"org.mongodb.driver.cluster"]})
|
||||||
"org.mongodb.driver.cluster"]})
|
|
||||||
;; ------------------
|
|
||||||
;; load configuration
|
;; load configuration
|
||||||
(reset! config (conf/load-config
|
(reset! config (conf/load-config
|
||||||
(or (System/getenv "toaster_conf") "toaster")
|
(or (System/getenv "toaster_conf") "toaster")
|
||||||
conf/default-settings))
|
conf/default-settings))
|
||||||
|
|
||||||
;; --------------------------------
|
(let [justauth-conf (get-in @config [:toaster :just-auth])]
|
||||||
;; initialize authentication stores
|
|
||||||
(let [justauth-conf (conf/q @config [:just-auth])]
|
|
||||||
;; connect database (TODO: take parameters from configuration)
|
;; connect database (TODO: take parameters from configuration)
|
||||||
(reset! db (get-mongo-db (:mongo-url justauth-conf)))
|
(reset! db (get-mongo-db (:mongo-url justauth-conf)))
|
||||||
|
|
||||||
;; create authentication stores in db
|
;; create authentication stores in db
|
||||||
(f/attempt-all
|
(f/attempt-all
|
||||||
[auth-stores (auth-db/create-auth-stores @db)]
|
[auth-conf (get-in @config [:toaster :just-auth])
|
||||||
|
auth-stores (auth-db/create-auth-stores @db)]
|
||||||
|
|
||||||
[(trans/init "lang/auth-en.yml" "lang/english.yaml")
|
[(trans/init "lang/auth-en.yml" "lang/english.yaml")
|
||||||
(reset! accts auth-stores)
|
(reset! accts auth-stores)
|
||||||
(reset! auth (auth/email-based-authentication
|
(reset! auth (auth/email-based-authentication
|
||||||
auth-stores
|
auth-stores
|
||||||
;; TODO: replace with email taken from config
|
;; TODO: replace with email taken from config
|
||||||
(dissoc (conf/q @config [:just-auth])
|
(dissoc (:just-auth (:toaster (conf/load-config
|
||||||
|
"toaster" conf/default-settings)))
|
||||||
:mongo-url :mongo-user :mongo-pass)
|
:mongo-url :mongo-user :mongo-pass)
|
||||||
{:criteria #{:email :ip-address}
|
{:criteria #{:email :ip-address}
|
||||||
:type :block
|
:type :block
|
||||||
|
@ -82,13 +80,6 @@
|
||||||
(f/when-failed [e]
|
(f/when-failed [e]
|
||||||
(log/error (str (trans/locale [:init :failure])
|
(log/error (str (trans/locale [:init :failure])
|
||||||
" - " (f/message e))))))
|
" - " (f/message e))))))
|
||||||
|
|
||||||
;; ----------------------
|
|
||||||
;; initialize jobs stores
|
|
||||||
(reset! jobs (create-mongo-store @db :job-store))
|
|
||||||
|
|
||||||
;; ------------------------------
|
|
||||||
;; log all results worth noticing
|
|
||||||
(log/info (str (trans/locale [:init :success])))
|
(log/info (str (trans/locale [:init :success])))
|
||||||
(log/debug @auth))
|
(log/debug @auth))
|
||||||
|
|
||||||
|
@ -96,7 +87,7 @@
|
||||||
(-> site-defaults
|
(-> site-defaults
|
||||||
(assoc-in [:cookies] true)
|
(assoc-in [:cookies] true)
|
||||||
(assoc-in [:security :anti-forgery]
|
(assoc-in [:security :anti-forgery]
|
||||||
(conf/q @config [:webserver :anti-forgery]))
|
(get-in @config [:webserver :anti-forgery]))
|
||||||
(assoc-in [:security :ssl-redirect]
|
(assoc-in [:security :ssl-redirect]
|
||||||
(conf/q @config [:webserver :ssl-redirect]))
|
(get-in @config [:webserver :ssl-redirect]))
|
||||||
(assoc-in [:security :hsts] true)))
|
(assoc-in [:security :hsts] true)))
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
(ns toaster.views
|
(ns toaster.views
|
||||||
(:require
|
(:require
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[clojure.contrib.humanize :as humanize :refer [datetime]]
|
;; [clojure.data.json :as json :refer [read-str]]
|
||||||
;; [clojure.data.json :as json :refer [read-str]]
|
[toaster.webpage :as web]
|
||||||
[toaster.webpage :as web]
|
[toaster.session :as s]
|
||||||
[toaster.session :as s]
|
[toaster.ring :as ring]
|
||||||
[toaster.ring :as ring]
|
[toaster.jobs :as job]
|
||||||
[toaster.jobs :as job]
|
[failjure.core :as f]
|
||||||
[failjure.core :as f]
|
[auxiliary.string :refer [strcasecmp]]
|
||||||
[auxiliary.string :refer [strcasecmp]]
|
[toaster.config :as conf]
|
||||||
[toaster.config :as conf]
|
[taoensso.timbre :as log :refer [debug]]
|
||||||
[taoensso.timbre :as log :refer [debug]]
|
[me.raynes.conch :as sh :refer [with-programs]]
|
||||||
[me.raynes.conch :as sh :refer [with-programs]]
|
[clj-time.core :as time]
|
||||||
[clj-time.core :as time]
|
[clj-time.coerce :as tc]
|
||||||
[clj-time.coerce :as tc]
|
[clj-time.local :as tl]
|
||||||
[clj-time.local :as tl]
|
[hiccup.form :as hf]))
|
||||||
[hiccup.form :as hf]))
|
|
||||||
|
|
||||||
(def dockerfile-upload-form
|
(def dockerfile-upload-form
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container-fluid"}
|
||||||
|
@ -24,90 +23,63 @@
|
||||||
[:p " Choose the file in your computer and click 'Submit' to
|
[:p " Choose the file in your computer and click 'Submit' to
|
||||||
proceed to validation."]
|
proceed to validation."]
|
||||||
[:div {:class "form-group"}
|
[:div {:class "form-group"}
|
||||||
[:form {:action "dockerfile" :method "post"
|
[:form {:action "dockerfile" :method "post"
|
||||||
:class "form-shell"
|
:class "form-shell"
|
||||||
:enctype "multipart/form-data"}
|
:enctype "multipart/form-data"}
|
||||||
[:fieldset {:class "fieldset btn btn-default btn-file btn-lg"}
|
[:fieldset {:class "fieldset btn btn-default btn-file btn-lg"}
|
||||||
[:input {:name "file" :type "file"}]]
|
[:input {:name "file" :type "file"}]]
|
||||||
;; [:fieldset {:class "fieldset-submit"}
|
;; [:fieldset {:class "fieldset-submit"}
|
||||||
[:input {:class "btn btn-primary btn-lg"
|
[:input {:class "btn btn-primary btn-lg"
|
||||||
:id "field-submit" :type "submit"
|
:id "field-submit" :type "submit"
|
||||||
:name "submit" :value "submit"}]]]])
|
:name "submit" :value "submit"}]]]])
|
||||||
|
|
||||||
(def dockerfile-edit-form
|
|
||||||
[:div {:class "container-fluid"}
|
|
||||||
[:h1 "Edit your Dockerfile to toast"]
|
|
||||||
[: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"}
|
|
||||||
[:textarea {:name "editor" :id "editor"
|
|
||||||
:rows 30 :cols 72 } "FROM: dyne/devuan:ascii"]
|
|
||||||
[:input {:class "btn btn-primary btn-lg"
|
|
||||||
:id "field-submit" :type "submit"
|
|
||||||
:name "submit" :value "submit"}]]]]
|
|
||||||
[:script "var editor = ace.edit(\"editor\");
|
|
||||||
editor.setTheme(\"ace/theme/monokai\");
|
|
||||||
editor.session.setMode(\"ace/mode/dockerfile\");"]])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(def welcome-menu
|
(def welcome-menu
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container-fluid"}
|
||||||
[:div {:class "row-fluid"}
|
[:div {:class "row-fluid"}
|
||||||
[:div {:class "row"} [:a {:href "/list"} "List all your toaster jobs"]]
|
[:div {:class "row"} [:a {:href "/list"} "List all your toaster jobs"]]
|
||||||
[:div {:class "row"} [:a {:href "/upload"} "Upload a new toaster job"]]]])
|
[:div {:class "row"} [:a {:href "/upload"} "Upload a new toaster job"]]]])
|
||||||
|
|
||||||
(defn dockerfile-upload-post [request config account]
|
(defn dockerfile-upload-post [request config account]
|
||||||
(web/render
|
(web/render
|
||||||
account
|
account
|
||||||
(let
|
(let
|
||||||
[tempfile (get-in request [:params :file :tempfile])
|
[tempfile (get-in request [:params :file :tempfile])
|
||||||
filename (get-in request [:params :file :filename])
|
filename (get-in request [:params :file :filename])
|
||||||
params (:params request)]
|
params (:params request)]
|
||||||
(cond
|
(cond
|
||||||
(> (get-in params [:file :size]) 64000)
|
(> (get-in params [:file :size]) 64000)
|
||||||
;; max upload size in bytes
|
;; max upload size in bytes
|
||||||
;; TODO: put in config
|
;; TODO: put in config
|
||||||
(web/render-error-page params "File too big in upload (64KB limit).")
|
(web/render-error-page params "File too big in upload (64KB limit).")
|
||||||
:else
|
:else
|
||||||
(let [file (io/copy tempfile (io/file "/tmp" filename))
|
(let [file (io/copy tempfile (io/file "/tmp" filename))
|
||||||
path (str "/tmp/" filename)]
|
path (str "/tmp/" filename)]
|
||||||
(io/delete-file tempfile)
|
(io/delete-file tempfile)
|
||||||
(if (not (.exists (io/file path)))
|
(if (not (.exists (io/file path)))
|
||||||
(web/render-error-page
|
(web/render-error-page
|
||||||
(log/spy :error
|
(log/spy :error
|
||||||
[:h1 (str "Uploaded file not found: " filename)]))
|
[:h1 (str "Uploaded file not found: " filename)]))
|
||||||
;; file is now in 'tmp' var
|
;; file is now in 'tmp' var
|
||||||
[:div {:class "container-fluid"}
|
[:div {:class "container-fluid"}
|
||||||
[:h1 "Job uploaded and added"]
|
[:h1 "Job uploaded and added"]
|
||||||
[:p "Log messages:"]
|
[:p "Log messages:"]
|
||||||
(web/render-yaml (job/add path config account))]))))))
|
(web/render-yaml (job/add path config account))]))))))
|
||||||
|
|
||||||
(defn list-jobs [request config account]
|
(defn list-jobs [request config account]
|
||||||
(f/attempt-all
|
(web/render
|
||||||
[joblist (job/listall config account)]
|
account
|
||||||
(web/render
|
[:div {:class "container-fluid"}
|
||||||
account
|
[:h1 (str "List all toaster jobs for " (:name account))]
|
||||||
[:div {:class "container-fluid"}
|
[:table {:class "sortable table"}
|
||||||
[:h1 (str "List all toaster jobs for " (:name account))]
|
[:thead nil
|
||||||
[:table {:class "sortable table"}
|
[:tr nil [:th nil "Date"] [:th nil "Type"] [:th nil "Actions"]]]
|
||||||
[:thead nil
|
[:tbody nil
|
||||||
[:tr nil [:th nil "Date"] [:th nil "Type"] [:th nil "Actions"]]]
|
(for [j (job/listall config account)]
|
||||||
[:tbody nil
|
(let [type (-> j (str/split #"-") second)
|
||||||
(for [j joblist]
|
tstamp (-> j (str/split #"-") last)]
|
||||||
(let [type (-> j (str/split #"-") second)
|
[:tr nil
|
||||||
tstamp (-> j (str/split #"-") last)]
|
[:td {:class "date"} (-> tstamp Long/valueOf tc/from-long tl/to-local-date-time)]
|
||||||
[:tr nil
|
[:td {:class "job"} [:a {:href (str "https://sdk.dyne.org:4443/view/web-sdk-builds/job/" j)} type]]
|
||||||
[:td {:class "date"} (-> tstamp Long/valueOf tc/from-long tl/to-local-date-time
|
[:td {:class "start-job"} (web/button "/start" "Start" (hf/hidden-field "job" j))
|
||||||
humanize/datetime)]
|
(web/button "/remove" "Remove" (hf/hidden-field "job" j))]]
|
||||||
[:td {:class "job"} [:a {:href (str "https://sdk.dyne.org:4443/view/web-sdk-builds/job/"
|
))]]]))
|
||||||
(str/replace j #"@" "AT"))} type]]
|
|
||||||
[:td {:class "start-job"} (web/button "/start" "Start" (hf/hidden-field "job" j))
|
|
||||||
(web/button "/remove" "Remove" (hf/hidden-field "job" j))]]
|
|
||||||
))]]])
|
|
||||||
(f/when-failed [e]
|
|
||||||
(web/render-error-page
|
|
||||||
(str "Job list failure: " (f/message e))))
|
|
||||||
))
|
|
||||||
|
|
|
@ -2,10 +2,8 @@ webserver:
|
||||||
anti-forgery: false
|
anti-forgery: false
|
||||||
ssl-redirect: false
|
ssl-redirect: false
|
||||||
|
|
||||||
jenkins:
|
admin:
|
||||||
host: "bridge.toaster"
|
email: jaromil@dyne.org
|
||||||
user: "jenkins"
|
|
||||||
key: "../id_ed25519"
|
|
||||||
|
|
||||||
just-auth:
|
just-auth:
|
||||||
email-server: "mail.dyne.org"
|
email-server: "mail.dyne.org"
|
||||||
|
|
Loading…
Reference in New Issue