added profiles, for joblimit and future features
also fixes to file upload, parameter reading and error handling
This commit is contained in:
		
							parent
							
								
									f28dcb2888
								
							
						
					
					
						commit
						30fb7ae1a2
					
				| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
<div class="box">
 | 
					<div class="box">
 | 
				
			||||||
    <h1 class="title">Upload a Dockerfile to toast</h1>
 | 
					    <h1 class="title">Upload a Dockerfile to toast</h1>
 | 
				
			||||||
    <p>Choose the file in your computer and click 'Submit' to proceed to validation.</p>
 | 
					    <p>Choose the file in your computer and click 'Submit' to proceed to validation.</p>
 | 
				
			||||||
    <form action="dockerfile" class="form-shell" enctype="multipart/form-data" method="post">
 | 
					    <form action="dockerfile" class="form" enctype="multipart/form-data" method="post">
 | 
				
			||||||
        <div class="file has-label is-fullwidth">
 | 
					        <div class="has-label is-fullwidth">
 | 
				
			||||||
			<label class="file-label">
 | 
								<label class="file-label">
 | 
				
			||||||
				<input class="file-input inputfile inputfile-2" id="file" type="file" />
 | 
									<input name="file" class="file-input inputfile inputfile-2" id="file" type="file" />
 | 
				
			||||||
				<label for="file"><span id="filename">Choose a Dockerfile...</span></label>
 | 
									<label for="file"><span id="filename">Choose a Dockerfile...</span></label>
 | 
				
			||||||
				<span class="file-cta"><span class="file-icon"><i class="fa fa-upload"></i></span><span class="file-label">Upload</span></span>
 | 
									<span class="file-cta"><span class="file-icon"><i class="fa fa-upload"></i></span><span class="file-label">Upload</span></span>
 | 
				
			||||||
			</label></div>
 | 
								</label></div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,8 @@
 | 
				
			||||||
   [toaster.session :as s]
 | 
					   [toaster.session :as s]
 | 
				
			||||||
   [toaster.config :as conf]
 | 
					   [toaster.config :as conf]
 | 
				
			||||||
   [toaster.ring :as ring]
 | 
					   [toaster.ring :as ring]
 | 
				
			||||||
   [toaster.views :as views])
 | 
					   [toaster.views :as views]
 | 
				
			||||||
 | 
					   [toaster.profiles :as profile])
 | 
				
			||||||
  (:gen-class))
 | 
					  (:gen-class))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defonce config (conf/load-config "toaster" conf/default-settings))
 | 
					(defonce config (conf/load-config "toaster" conf/default-settings))
 | 
				
			||||||
| 
						 | 
					@ -82,7 +83,7 @@
 | 
				
			||||||
        (->> (fn [req conf acct]
 | 
					        (->> (fn [req conf acct]
 | 
				
			||||||
               (s/render acct
 | 
					               (s/render acct
 | 
				
			||||||
                         [:body
 | 
					                         [:body
 | 
				
			||||||
                            (views/dockerfile-upload-post req conf acct)
 | 
					                          (views/dockerfile-upload req conf acct)
 | 
				
			||||||
                          (views/dashboard acct)]))
 | 
					                          (views/dashboard acct)]))
 | 
				
			||||||
             (auth-wrap request)))
 | 
					             (auth-wrap request)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,7 +116,7 @@
 | 
				
			||||||
            (auth-wrap request)))
 | 
					            (auth-wrap request)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ;; JUST-AUTH ROUTES
 | 
					  ;; JUST-AUTH ROUTES
 | 
				
			||||||
  (GET "/login" request (s/render (s/resource s/login)))
 | 
					  (GET "/login" request (s/render-template s/login))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  (POST "/login" request
 | 
					  (POST "/login" request
 | 
				
			||||||
        (f/attempt-all
 | 
					        (f/attempt-all
 | 
				
			||||||
| 
						 | 
					@ -142,7 +143,7 @@
 | 
				
			||||||
             (s/render [:body
 | 
					             (s/render [:body
 | 
				
			||||||
                          [:h1 {:class "title"} "Logged out."]])))
 | 
					                          [:h1 {:class "title"} "Logged out."]])))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  (GET "/signup" request (s/render (s/resource s/signup)))
 | 
					  (GET "/signup" request (s/render-template s/signup))
 | 
				
			||||||
  (POST "/signup" request
 | 
					  (POST "/signup" request
 | 
				
			||||||
        (f/attempt-all
 | 
					        (f/attempt-all
 | 
				
			||||||
         [name (s/param request :name)
 | 
					         [name (s/param request :name)
 | 
				
			||||||
| 
						 | 
					@ -194,7 +195,10 @@
 | 
				
			||||||
               [:h1 {:class "title"}    "Failure activating account"]
 | 
					               [:h1 {:class "title"}    "Failure activating account"]
 | 
				
			||||||
               [:h2 {:class "subtitle"} (f/message act)]
 | 
					               [:h2 {:class "subtitle"} (f/message act)]
 | 
				
			||||||
               [:p (str "Email: " email " activation-id: " activation-id)]] "is-error")
 | 
					               [:p (str "Email: " email " activation-id: " activation-id)]] "is-error")
 | 
				
			||||||
             (s/notify [:h1 {:class "title"} (str "Account activated - " email)] "is-success"))])))
 | 
					             [:span
 | 
				
			||||||
 | 
					              (s/notify (str "Account activated: " email) "is-success")
 | 
				
			||||||
 | 
					              (profile/create email)]
 | 
				
			||||||
 | 
					             )])))
 | 
				
			||||||
  ;; -- end of JUST-AUTH
 | 
					  ;; -- end of JUST-AUTH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  (POST "/" request
 | 
					  (POST "/" request
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,30 +4,30 @@
 | 
				
			||||||
   [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]]
 | 
					 | 
				
			||||||
   [clj-storage.core :as db]
 | 
					   [clj-storage.core :as db]
 | 
				
			||||||
   [failjure.core :as f]
 | 
					   [failjure.core :as f]
 | 
				
			||||||
   [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]]
 | 
				
			||||||
   [toaster.config :refer :all]
 | 
					   [toaster.config :refer :all]
 | 
				
			||||||
   [toaster.ring :refer [jobs]]
 | 
					   [toaster.ring :refer [jobs]]
 | 
				
			||||||
 | 
					   [toaster.profiles :as profile]
 | 
				
			||||||
   [hiccup.form :as hf]))
 | 
					   [hiccup.form :as hf]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; list of arm targets to chose from
 | 
					;; list of arm targets to chose from
 | 
				
			||||||
;"beagleboneblack"
 | 
					                                        ;"beagleboneblack"
 | 
				
			||||||
;"chromeacer"
 | 
					                                        ;"chromeacer"
 | 
				
			||||||
;"chromeveyron"
 | 
					                                        ;"chromeveyron"
 | 
				
			||||||
;"droid4"
 | 
					                                        ;"droid4"
 | 
				
			||||||
;"n900"
 | 
					                                        ;"n900"
 | 
				
			||||||
;"odroidxu4"
 | 
					                                        ;"odroidxu4"
 | 
				
			||||||
;"odroidxu"
 | 
					                                        ;"odroidxu"
 | 
				
			||||||
;"ouya"
 | 
					                                        ;"ouya"
 | 
				
			||||||
;"raspi1"
 | 
					                                        ;"raspi1"
 | 
				
			||||||
;"raspi2"
 | 
					                                        ;"raspi2"
 | 
				
			||||||
;"raspi3"
 | 
					                                        ;"raspi3"
 | 
				
			||||||
;"rock64"
 | 
					                                        ;"rock64"
 | 
				
			||||||
;"sunxi"
 | 
					                                        ;"sunxi"
 | 
				
			||||||
;"turbox-twister"
 | 
					                                        ;"turbox-twister"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn- ssh-host [config]
 | 
					(defn- ssh-host [config]
 | 
				
			||||||
  (str (q config [:jenkins :user]) "@" (q config [:jenkins :host])))
 | 
					  (str (q config [:jenkins :user]) "@" (q config [:jenkins :host])))
 | 
				
			||||||
| 
						 | 
					@ -51,12 +51,22 @@
 | 
				
			||||||
      (catch Exception e
 | 
					      (catch Exception e
 | 
				
			||||||
        (f/fail (str "ERROR in dockerlint - " (.getMessage e)))))))
 | 
					        (f/fail (str "ERROR in dockerlint - " (.getMessage e)))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn count [id]
 | 
				
			||||||
 | 
					  (f/attempt-all
 | 
				
			||||||
 | 
					   [joblist (db/query @jobs {:email id})]
 | 
				
			||||||
 | 
					   (clojure.core/count joblist)
 | 
				
			||||||
 | 
					   (f/when-failed [e]
 | 
				
			||||||
 | 
					     (f/fail "jobs/count :: " (f/message 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_ascii-" tstamp)
 | 
					          jobname (str (:email account) "-vm_amd64_ascii-" tstamp)
 | 
				
			||||||
          jobdir (str "/srv/toaster/" jobname)]
 | 
					          jobdir (str "/srv/toaster/" jobname)]
 | 
				
			||||||
 | 
					      (f/if-let-ok? [joblimit (profile/get-joblimit (:email account))]
 | 
				
			||||||
 | 
					        (if (>= (count (:email account)) joblimit)
 | 
				
			||||||
 | 
					          (f/fail "Job limit is reached, trash some to free slots")
 | 
				
			||||||
          (f/attempt-all
 | 
					          (f/attempt-all
 | 
				
			||||||
           [r_lint (dockerlint path)
 | 
					           [r_lint (dockerlint path)
 | 
				
			||||||
            r_mkdir (ssh "-i" (q config [:jenkins :key])
 | 
					            r_mkdir (ssh "-i" (q config [:jenkins :key])
 | 
				
			||||||
| 
						 | 
					@ -75,7 +85,6 @@
 | 
				
			||||||
           {:lint r_lint
 | 
					           {:lint r_lint
 | 
				
			||||||
            :job  r_job}
 | 
					            :job  r_job}
 | 
				
			||||||
           (f/when-failed [e]
 | 
					           (f/when-failed [e]
 | 
				
			||||||
                       (f/fail (str "Job add '" jobname "' failure: " (f/message e))))))))
 | 
					             (f/fail (str "Job add '" jobname "' failure :: " (f/message e))))))
 | 
				
			||||||
 | 
					        (f/fail (str "Cannot find profile " (:email account) " :: "
 | 
				
			||||||
 | 
					                      (f/message joblimit)))))))
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					(ns toaster.profiles
 | 
				
			||||||
 | 
					  (:require
 | 
				
			||||||
 | 
					   [clojure.string :as str]
 | 
				
			||||||
 | 
					   [clojure.java.io :as io]
 | 
				
			||||||
 | 
					   [clj-time.core :as time]
 | 
				
			||||||
 | 
					   [clj-time.coerce :as tc]
 | 
				
			||||||
 | 
					   [clj-storage.db.mongo :refer [create-mongo-store]]
 | 
				
			||||||
 | 
					   [clj-storage.core :as db]
 | 
				
			||||||
 | 
					   [failjure.core :as f]
 | 
				
			||||||
 | 
					   [taoensso.timbre :as log :refer [debug]]
 | 
				
			||||||
 | 
					   [me.raynes.conch :as sh :refer [with-programs]]
 | 
				
			||||||
 | 
					   [toaster.config :refer :all]
 | 
				
			||||||
 | 
					   [toaster.ring :refer [jobs profiles]]
 | 
				
			||||||
 | 
					   [toaster.bulma :refer [render-yaml]]
 | 
				
			||||||
 | 
					   [hiccup.form :as hf]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn create [id]
 | 
				
			||||||
 | 
					  (let [profile {:email id
 | 
				
			||||||
 | 
					                 :joblimit 3 ; default
 | 
				
			||||||
 | 
					                 :roles ["noob"]
 | 
				
			||||||
 | 
					                 :lastlogin (tc/to-long (time/now))}]
 | 
				
			||||||
 | 
					    (db/store! @profiles :email profile)
 | 
				
			||||||
 | 
					    (render-yaml profile)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn- fetch-profile [id]
 | 
				
			||||||
 | 
					  (f/if-let-ok? [profile (db/fetch @profiles id)]
 | 
				
			||||||
 | 
					    profile
 | 
				
			||||||
 | 
					    (f/fail (str "Profile not found " id " :: " (f/message profile)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn get-joblimit [id]
 | 
				
			||||||
 | 
					  (f/ok-> id fetch-profile (get :joblimit)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn has-role [id role]
 | 
				
			||||||
 | 
					  (f/ok-> id fetch-profile (get :roles)
 | 
				
			||||||
 | 
					          clojure.core/set (contains? role)))
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -33,11 +33,14 @@
 | 
				
			||||||
   [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]]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;; generic webapp stores
 | 
				
			||||||
(def config (atom {}))
 | 
					(def config (atom {}))
 | 
				
			||||||
(def db     (atom {}))
 | 
					(def db     (atom {}))
 | 
				
			||||||
(def accts  (atom {}))
 | 
					(def accts  (atom {}))
 | 
				
			||||||
(def auth   (atom {}))
 | 
					(def auth   (atom {}))
 | 
				
			||||||
 | 
					;; app specific stores
 | 
				
			||||||
(def jobs     (atom {}))
 | 
					(def jobs     (atom {}))
 | 
				
			||||||
 | 
					(def profiles (atom {}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn init []
 | 
					(defn init []
 | 
				
			||||||
  (log/merge-config!
 | 
					  (log/merge-config!
 | 
				
			||||||
| 
						 | 
					@ -86,6 +89,8 @@
 | 
				
			||||||
  ;; ----------------------
 | 
					  ;; ----------------------
 | 
				
			||||||
  ;; initialize jobs stores
 | 
					  ;; initialize jobs stores
 | 
				
			||||||
  (reset! jobs (create-mongo-store @db :job-store))
 | 
					  (reset! jobs (create-mongo-store @db :job-store))
 | 
				
			||||||
 | 
					  ;; initialize profile stores
 | 
				
			||||||
 | 
					  (reset! profiles (create-mongo-store @db :profile-store))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ;; ------------------------------
 | 
					  ;; ------------------------------
 | 
				
			||||||
  ;; log all results worth noticing
 | 
					  ;; log all results worth noticing
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,11 +20,12 @@
 | 
				
			||||||
(defonce footer "templates/body_footer.html")
 | 
					(defonce footer "templates/body_footer.html")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn param [request param]
 | 
					(defn param [request param]
 | 
				
			||||||
  (let [value
 | 
					  (let [p (if (coll? param)
 | 
				
			||||||
        (get-in request
 | 
					            (into [:params] param)
 | 
				
			||||||
                (conj [:params] param))]
 | 
					            (conj [:params] param))
 | 
				
			||||||
 | 
					        value (get-in request p)]
 | 
				
			||||||
    (if (nil? value)
 | 
					    (if (nil? value)
 | 
				
			||||||
      (f/fail (str "Parameter not found: " param))
 | 
					      (f/fail (str "Parameter not found: " p))
 | 
				
			||||||
      value)))
 | 
					      value)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; TODO: not working?
 | 
					;; TODO: not working?
 | 
				
			||||||
| 
						 | 
					@ -70,9 +71,12 @@
 | 
				
			||||||
       (= tclass "is-warning") (log/warn msg)
 | 
					       (= tclass "is-warning") (log/warn msg)
 | 
				
			||||||
       (= tclass "is-success") (log/info msg)
 | 
					       (= tclass "is-success") (log/info msg)
 | 
				
			||||||
       (= tclass "is-primary") (log/debug msg))
 | 
					       (= tclass "is-primary") (log/debug msg))
 | 
				
			||||||
   [:div {:class (str "notification " tclass " has-text-centered")} msg])))
 | 
					     [:div {:class (str "notification " tclass " has-text-centered")} msg]
 | 
				
			||||||
 | 
					     )))
 | 
				
			||||||
;; shortcut
 | 
					;; shortcut
 | 
				
			||||||
(defn error [msg fail] (notify (str msg " :: " (f/message fail)) "is-danger"))
 | 
					(defn error
 | 
				
			||||||
 | 
					  ([msg] (notify msg "is-danger"))
 | 
				
			||||||
 | 
					  ([msg fail] (notify (str msg " :: " (f/message fail)) "is-danger")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn render
 | 
					(defn render
 | 
				
			||||||
  "render a full webpage using headers, navbar, body and footer"
 | 
					  "render a full webpage using headers, navbar, body and footer"
 | 
				
			||||||
| 
						 | 
					@ -84,4 +88,30 @@
 | 
				
			||||||
            (resource head)
 | 
					            (resource head)
 | 
				
			||||||
            (conj body (resource footer)))}))
 | 
					            (conj body (resource footer)))}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn render-template
 | 
				
			||||||
 | 
					  "render an html from resources using headers, navbar, body and footer"
 | 
				
			||||||
 | 
					  ([body] (render-template nil body))
 | 
				
			||||||
 | 
					  ([account body]
 | 
				
			||||||
 | 
					   {:headers {"Content-Type"
 | 
				
			||||||
 | 
					              "text/html; charset=utf-8"}
 | 
				
			||||||
 | 
					    :body (str "<!DOCTYPE html>\n<html>"
 | 
				
			||||||
 | 
					               (resource head)
 | 
				
			||||||
 | 
					               "\n<!-- body -->\n"
 | 
				
			||||||
 | 
					               (resource body)
 | 
				
			||||||
 | 
					               "\n<!-- end of body -->\n"
 | 
				
			||||||
 | 
					               (resource footer))}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defn render-html
 | 
				
			||||||
 | 
					  "render an html from resources using headers, navbar, body and footer"
 | 
				
			||||||
 | 
					  ([body] (render-template nil body))
 | 
				
			||||||
 | 
					  ([account body]
 | 
				
			||||||
 | 
					   {:headers {"Content-Type"
 | 
				
			||||||
 | 
					              "text/html; charset=utf-8"}
 | 
				
			||||||
 | 
					    :body (str "<!DOCTYPE html>\n<html>"
 | 
				
			||||||
 | 
					               (resource head)
 | 
				
			||||||
 | 
					               "\n<!-- body -->\n"
 | 
				
			||||||
 | 
					               body ;; html text string
 | 
				
			||||||
 | 
					               "\n<!-- end of body -->\n"
 | 
				
			||||||
 | 
					               (resource footer))}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn render-error [err] (->> "is-danger" (notify err) render))
 | 
					(defn render-error [err] (->> "is-danger" (notify err) render))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,29 +60,31 @@
 | 
				
			||||||
            (web/button "/remove" "\uD83D\uDDD1" (hf/hidden-field "jobid" jobid))]]]
 | 
					            (web/button "/remove" "\uD83D\uDDD1" (hf/hidden-field "jobid" jobid))]]]
 | 
				
			||||||
         ))]]])
 | 
					         ))]]])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defn dockerfile-upload-post [request config account]
 | 
					(defn dockerfile-upload [request config account]
 | 
				
			||||||
  (f/attempt-all
 | 
					  (f/attempt-all
 | 
				
			||||||
   [tempfile (s/param request [:file :tempfile])
 | 
					   [tempfile (s/param request [:file :tempfile])
 | 
				
			||||||
    filename (s/param request [:file :filename])
 | 
					    filename (s/param request [:file :filename])
 | 
				
			||||||
    filesize (s/param request [:file :size])]
 | 
					    params (log/spy (:params request))]
 | 
				
			||||||
   (cond
 | 
					   (if (> (s/param request [:file :size]) 64000)
 | 
				
			||||||
     (> filesize 64000)
 | 
					 | 
				
			||||||
     ;; TODO: put filesize limit in config
 | 
					     ;; TODO: put filesize limit in config
 | 
				
			||||||
     (s/notify "File too big in upload (64KB limit)" "is-danger")
 | 
					     (s/error "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)))
 | 
				
			||||||
         (s/notify (str "Uploaded file not found: " filename) "is-danger")
 | 
					         (s/error (str "Uploaded file not found: " filename))
 | 
				
			||||||
         ;; file is now in 'tmp' var
 | 
					         ;; file is now in 'tmp' var
 | 
				
			||||||
         (f/if-let-ok? [newjob (job/add path config account)]
 | 
					         (f/attempt-all
 | 
				
			||||||
 | 
					          [newjob (job/add path config account)]
 | 
				
			||||||
          [:div {:class "container"}
 | 
					          [:div {:class "container"}
 | 
				
			||||||
           [:h1 {:class "title"} "Job uploaded and added"]
 | 
					           [:h1 {:class "title"} "Job uploaded and added"]
 | 
				
			||||||
           [:p "Log messages:"]
 | 
					           [:p "Log messages:"]
 | 
				
			||||||
           (web/render-yaml newjob)]
 | 
					           (web/render-yaml newjob)]
 | 
				
			||||||
          ;; else when job/add is not-ok
 | 
					          ;; else when job/add is not-ok
 | 
				
			||||||
           (s/error "Error adding job" newjob)))))
 | 
					          (f/when-failed [e]
 | 
				
			||||||
 | 
					            (s/error "Error adding job" e))
 | 
				
			||||||
 | 
					          ))))
 | 
				
			||||||
   (f/when-failed [e]
 | 
					   (f/when-failed [e]
 | 
				
			||||||
     (s/error "Upload file error" e))))
 | 
					     (s/error "Upload file error" e))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,7 +109,7 @@
 | 
				
			||||||
    jobfound (db/query @ring/jobs {:jobid jobid})
 | 
					    jobfound (db/query @ring/jobs {:jobid jobid})
 | 
				
			||||||
    r_rmjob (db/delete! @ring/jobs jobid)
 | 
					    r_rmjob (db/delete! @ring/jobs jobid)
 | 
				
			||||||
    r_sync (job/sync_jobs config "-d" jobid)]
 | 
					    r_sync (job/sync_jobs config "-d" jobid)]
 | 
				
			||||||
   (s/notify (str "Job removed: "  jobid) "is-primary")
 | 
					   (s/notify (str "Job removed :: "  jobid) "is-primary")
 | 
				
			||||||
   (f/when-failed [e]
 | 
					   (f/when-failed [e]
 | 
				
			||||||
     (s/error "Failure removing job" e))))
 | 
					     (s/error "Failure removing job" e))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue