diff --git a/emacs/init.org b/emacs/init.org index 066976f..a1d4fff 100755 --- a/emacs/init.org +++ b/emacs/init.org @@ -353,6 +353,18 @@ Load environment variables into Emacs from a shell script: process-environment))) ,@body))) + (defun call-with-env-from-file (file callback) + (let* ((env (extract-vars-from-env-file file)) + (path (assoc "PATH" env)) + (exec-path + (if path + (append (split-string (cdr path) ":") exec-path) + exec-path)) + (process-environment + (append (mapcar (lambda (elt) (format "%s=%s" (car elt) (cdr elt))) env) + process-environment))) + (funcall callback))) + (defmacro with-env (env &rest body) (declare (indent 1)) `(let* ((process-environment @@ -3080,10 +3092,144 @@ Syntax highlighting for Dockerfiles: (format "Uploaded to %s" last-s3-url) "Failed to upload to s3, check *aws-s3* buffer for details"))))) #+END_SRC +* Prodigy +[[https://github.com/rejeep/prodigy.el][Prodigy]] gives Emacs a nice way to run services (web servers, etc.). + +#+BEGIN_SRC emacs-lisp + (use-package prodigy + :commands (prodigy) + :config + (evil-collection-prodigy-setup) + (add-hook 'prodigy-view-mode-hook (lambda () (toggle-truncate-lines 1)))) + + (leader-def-key "P" #'prodigy) +#+END_SRC * Lola Some functions to make my day job easier. -** Backend services +** Services (Prodigy) +#+BEGIN_SRC emacs-lisp + (defun call-with-venv (venv callback) + (call-with-env-from-file + (substitute-in-file-name (format "$WORKON_HOME/%s/bin/activate" venv)) + callback)) + + (defun python-service-setup (venv &optional env-file) + (lambda (done) + (call-with-venv + venv + (if env-file + (lambda () + (call-with-env-from-file env-file done)) + done)))) + + (prodigy-define-service + :name "lola-server (gunicorn)" + :command "gunicorn" + :args '("-c" "server/web/gunicorn.conf.py" + "-b" "127.0.0.1:7200" + "bin.start_web:init_and_create_flask_app()") + :cwd "~/lola/lola-server" + :stop-signal 'int + :truncate-output t + :init-async (python-service-setup "lola-server" + "~/lola/lola-server/.env")) + + (prodigy-define-service + :name "lola-server celery worker" + :command "python" + :args '("bin/start_celery_worker.py" "-P" "gevent") + :cwd "~/lola/lola-server" + :stop-signal 'int + :truncate-output t + :init-async (python-service-setup "lola-server" + "~/lola/lola-server/.env")) + + (prodigy-define-service + :name "travel-service" + :command "python" + :args '("bin/start_web.py") + :cwd "~/lola/lola-travel-service" + :stop-signal 'int + :truncate-output t + :init-async (python-service-setup "travel-service" + "~/lola/lola-travel-service/.env")) + + (prodigy-define-service + :name "travel-service celery worker" + :command "python" + :args '("bin/start_celery_workers.py" + "-Q" + "default,io_pool,cpu_pool,priority_io_pool,priority_cpu_pool") + :cwd "~/lola/lola-travel-service" + :stop-signal 'int + :truncate-output t + :init-async (python-service-setup "travel-service" + "~/lola/lola-travel-service/.env")) + + (prodigy-define-service + :name "secrets" + :command "python" + :args '("bin/cmdline.py" "www") + :cwd "~/lola/secrets" + :truncate-output t + :stop-signal 'int + :init-async (python-service-setup "secrets" + "~/lola/secrets/.env")) + + (defun call-with-lola-env (callback) + (let ((process-environment + (cons (format "LOLA_ENV=%s" + (ido-completing-read+ + "Environment: " + '("local" "development" "staging"))) + process-environment))) + (funcall callback))) + + (prodigy-define-service + :name "lola-desktop" + :command "npm" + :args '("start") + :cwd "~/lola/lola-desktop" + :port 3001 + :stop-signal 'int + :init-async #'call-with-lola-env) + + (prodigy-define-service + :name "wallet" + :command "npm" + :args '("start") + :cwd "~/lola/wallet" + :stop-signal 'int + :init-async #'call-with-lola-env) + + (prodigy-define-service + :name "luigid" + :command "luigid" + :cwd "~/lola/data-pipeline" + :port 8082 + :stop-signal 'int + :init-async (python-service-setup "data-pipeline" + "~/lola/data-pipeline/.env")) + + (prodigy-define-service + :name "prometheus" + :command "prometheus" + :args '("--config.file=prometheus.yml") + :port 9090 + :stop-signal 'int + :cwd "~/prometheus") + + (prodigy-define-service + :name "priceline-service" + :command "~/lola/lola-services/priceline/bin/start.sh" + :args '("web") + :cwd "~/lola/lola-services" + :stop-signal 'int + :init-async (python-service-setup "lola-services-ZdLKpchq" + "~/lola/lola-services/priceline/.env")) +#+END_SRC +** Services (eShell) #+BEGIN_SRC emacs-lisp :lexical yes (defun run-service-in-eshell (name dir cmd &optional setup) (if-let ((buf (get-buffer name))) @@ -3099,127 +3245,6 @@ Some functions to make my day job easier. (insert cmd) (eshell-send-input))) - ;; TODO add some better process handling, e.g. gracefully kill services on restart - - (defun run-service (name program args &optional buffer-size) - (let ((bufname (format "*%s*" name))) - (apply #'make-comint-in-buffer name bufname program nil args) - (with-current-buffer bufname - (set (make-local-variable 'comint-output-filter-functions) - (cons #'comint-truncate-buffer comint-output-filter-functions)) - (set (make-local-variable 'comint-buffer-maximum-size) (or buffer-size 100)) - (toggle-truncate-lines 1)))) - - (defmacro with-venv (venv &rest body) - (declare (indent 1)) - `(with-env-from-file (substitute-in-file-name (format "$WORKON_HOME/%s/bin/activate" ,venv)) - ,@body)) - - (defun get-python-setup (venv) - (lambda () - (eshell/deactivate) - (direnv-update-directory-environment (eshell/pwd)) - (pyvenv-workon venv))) - - (defun lola-server (&optional no-gunicorn) - (interactive "P") - (with-venv "lola-server" - (with-default-directory "~/lola/lola-server" - (with-env-from-file "~/lola/lola-server/.env" - (if (not no-gunicorn) - (run-service "lola-server" - "gunicorn" - '("-c" - "server/web/gunicorn.conf.py" - "-b" - "127.0.0.1:7200" - "bin.start_web:init_and_create_flask_app()")) - (run-service "lola-server" "python" '("bin/start_web.py"))))))) - - (defun lola-server-celery-worker () - (interactive) - (with-venv "lola-server" - (with-default-directory "~/lola/lola-server" - (with-env-from-file "~/lola/lola-server/.env" - (run-service "lola-server-celery-worker" - "python" - '("bin/start_celery_worker.py" - "-P" - "gevent")))))) - - (defun lola-travel-service () - (interactive) - (with-venv "travel-service" - (with-default-directory "~/lola/lola-travel-service" - (with-env-from-file "~/lola/lola-travel-service/.env" - (run-service "lola-travel-service" "python" '("bin/start_web.py")))))) - - (defun lola-travel-service-celery () - (interactive) - (with-venv "travel-service" - (with-default-directory "~/lola/lola-travel-service" - (with-env-from-file "~/lola/lola-travel-service/.env" - (run-service "lola-travel-service-celery" - "python" - '("bin/start_celery_workers.py" - "-Q" - "default,io_pool,cpu_pool,priority_io_pool,priority_cpu_pool") - 50))))) - - (defun lola-secrets () - (interactive) - (with-venv "secrets" - (with-default-directory "~/lola/secrets" - (with-env-from-file "~/lola/secrets/.env" - (run-service "lola-secrets" "python" '("bin/cmdline.py" "www")))))) - - (defun lola-desktop (env) - (interactive - (list (ido-completing-read+ - "Environment: " - '("local" "development" "staging")))) - (with-env `(("LOLA_ENV" . ,env)) - (with-default-directory "~/lola/lola-desktop" - (run-service "lola-desktop" "npm" '("start"))))) - - (defun lola-wallet (env) - (interactive - (list (ido-completing-read+ - "Environment: " - '("local" "development" "staging")))) - (with-env `(("LOLA_ENV" . ,env)) - (with-default-directory "~/lola/wallet" - (run-service "lola-wallet" "npm" '("start"))))) - - (defun lola-run-all () - (interactive) - (let ((fns (list #'lola-travel-service - #'lola-travel-service-celery - #'lola-server - #'lola-server-celery-worker - #'lola-desktop - #'lola-wallet - #'lola-secrets))) - (mapcar #'call-interactively fns))) - - (defun run-luigid () - (interactive) - (with-venv "data-pipeline" - (with-default-directory "~/lola/data-pipeline" - (with-env-from-file "~/lola/data-pipeline/.env" - (run-service - "luigid" - "luigid" - '()))))) - - (defun run-prometheus () - (interactive) - (with-default-directory "~/prometheus" - (run-service - "prometheus" - "prometheus" - '("--config.file=prometheus.yml")))) - (defun release-manager () (interactive) (run-service-in-eshell "*release-manager*" @@ -3228,17 +3253,7 @@ Some functions to make my day job easier. (get-python-setup "gittools"))) (jdormit/define-prefix "L" "lola") - (leader-def-key "Ls" #'lola-server) - (leader-def-key "Lc" #'lola-server-celery-worker) - (leader-def-key "Lt" #'lola-travel-service) - (leader-def-key "LT" #'lola-travel-service-celery) - (leader-def-key "Ld" #'lola-desktop) - (leader-def-key "Lw" #'lola-wallet) - (leader-def-key "LS" #'lola-secrets) - (leader-def-key "LA" #'lola-run-all) - (leader-def-key "LL" #'run-luigid) (leader-def-key "Lr" #'release-manager) - (leader-def-key "LP" #'run-prometheus) #+END_SRC ** AWS-MFA