Skip to content

Instantly share code, notes, and snippets.

@arichiardi
Last active July 6, 2016 22:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save arichiardi/9072fdddd0fe3ac855550718dc7eb59e to your computer and use it in GitHub Desktop.
Save arichiardi/9072fdddd0fe3ac855550718dc7eb59e to your computer and use it in GitHub Desktop.
Profile.boot for postgres in a docker
(require '[boot.pod :as pod])
(def pod-deps '[[boot/core "2.6.0" :scope "test"]
[adzerk/env "0.3.0" :scope "test"]
[me.raynes/conch "0.8.0" :scope "test"]])
(deftask postgres
[t type VAL str "The build type as string"]
(let [pod (future (pod/make-pod (update-in (get-env) [:dependencies] into pod-deps)))]
(with-pass-thru _
(pod/with-eval-in @pod
(require '[adzerk.env :as env]
'[me.raynes.conch :as sh]
'[boot.core :as core]
'[boot.util :as util])
(sh/programs docker)
;;;;;;;;;;;;;;;;;;;;;
;;; Environment ;;;
;;;;;;;;;;;;;;;;;;;;;
;; Note that these are treated as system properties, see https://github.com/adzerk-oss/env/issues/2
;; and adopt the syntax for cprop: https://github.com/tolitius/cprop#system-properties-cprop-syntax
(case ~type
"prod" (env/def
database_name "my-db"
database_username ""
database_password "")
"test" (env/def
database_name "my-db"
database_username ""
database_password "")
(env/def
database_name "my-db"
database_username ""
database_password ""))
(defn postgres-endpoint! []
(let [{:keys [stdout exit-code]} (docker "inspect" "--format" "{{ .NetworkSettings.IPAddress }}" "postgres"
{:verbose true
:throw false
:seq true})]
(when (= 0 @exit-code) ;; return nil if it fails
(str (first stdout) ":5432"))))
(defn set-env-vars! []
(let [postgres-db (get (env/env) "database_name")]
(case ~type
"prod" (env/def database_jdbc.url "")
"test" (env/def database_jdbc.url (str "jdbc:postgresql://" (postgres-endpoint!) "/" postgres-db "-test"))
(env/def database_jdbc.url (str "jdbc:postgresql://" (postgres-endpoint!) "/" postgres-db)))))
(do
(if (every? #{""} (docker "inspect" "--format" "{{ .State }}" "postgres" {:throw false :seq true}))
;; Add a new docker container
(let [postgres-user (get (env/env) "database_username")
postgres-psw (get (env/env) "database_password")
postgres-db (get (env/env) "database_subname")]
(let [{exit-code :exit-code} (docker "run" "-d"
"--name" "postgres"
"-e" (str "POSTGRES_PASSWORD=" postgres-psw)
"-e" (str "POSTGRES_USER=" postgres-user)
"-e" (str "POSTGRES_DB=" postgres-db)
"postgres:9.5.3"
{:verbose true :throw true})]
(when (= 0 @exit-code)
(util/info "Postgres is now running at %s \n" (postgres-endpoint!)))))
;; There is a container already see if it is running
(if-not (every? #{"true"} (docker "inspect" "--format" "{{ .State.Running }}" "postgres" {:throw false :seq true}))
(let [{exit-code :exit-code} (docker "start" "postgres" {:verbose true :throw true})]
(when (= 0 @exit-code)
(util/info "Postgres is now running at %s \n" (postgres-endpoint!))))
(util/info "Postgres was already running, setting env vars only...\n")))
(set-env-vars!))))))
;; Sneaky call - dangerous because it performs side effects - don't do this at home
;; The upside of executing it in a pod is that we don't introduce unnecessary dependencies
;; (transitive as well) to the main environment
;; To pass the type use:
;; boot -e type=test task1 task2 ...
(boot (postgres :type (get-env :type)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment