Improving deployment process.
This commit is contained in:
@@ -39,3 +39,27 @@ create table user_app_configs(
|
|||||||
);
|
);
|
||||||
|
|
||||||
create unique index user_app_configs_user_id_idx on user_app_configs (user_id);
|
create unique index user_app_configs_user_id_idx on user_app_configs (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
create type deployment_status as enum ('queued', 'in-progress', 'complete', 'failed');
|
||||||
|
|
||||||
|
create table deployments(
|
||||||
|
id bigserial primary key,
|
||||||
|
user_id integer not null references users on delete cascade,
|
||||||
|
started timestamptz,
|
||||||
|
finished timestamptz,
|
||||||
|
status deployment_status not null default 'queued',
|
||||||
|
pid integer,
|
||||||
|
generate_configs deployment_status not null default 'queued',
|
||||||
|
terraform_custom_image deployment_status not null default 'queued',
|
||||||
|
terraform_dns deployment_status not null default 'queued',
|
||||||
|
terraform_volume_create deployment_status not null default 'queued',
|
||||||
|
terraform_volume_destroy deployment_status not null default 'queued',
|
||||||
|
terraform_machine_create deployment_status not null default 'queued',
|
||||||
|
terraform_machine_destroy deployment_status not null default 'queued',
|
||||||
|
terraform_ip_create deployment_status not null default 'queued',
|
||||||
|
terraform_ip_destroy deployment_status not null default 'queued',
|
||||||
|
log_enc text
|
||||||
|
);
|
||||||
|
|
||||||
|
create index deployments_user_id_idx on deployments (user_id);
|
||||||
|
|||||||
35
src/db.scm
35
src/db.scm
@@ -10,6 +10,10 @@
|
|||||||
update-user-selected-apps get-user-selected-apps
|
update-user-selected-apps get-user-selected-apps
|
||||||
update-user-app-config get-user-app-config
|
update-user-app-config get-user-app-config
|
||||||
update-root-domain
|
update-root-domain
|
||||||
|
create-deployment
|
||||||
|
update-deployment-status get-deployment-status
|
||||||
|
get-most-recent-deployment-status
|
||||||
|
update-deployment-in-progress
|
||||||
)
|
)
|
||||||
|
|
||||||
(import scheme
|
(import scheme
|
||||||
@@ -287,6 +291,37 @@ returning users.user_id;"
|
|||||||
(user-decrypt-from-db (alist-ref 'config_enc res) user-key user-iv user-id)
|
(user-decrypt-from-db (alist-ref 'config_enc res) user-key user-iv user-id)
|
||||||
read)))))))
|
read)))))))
|
||||||
|
|
||||||
|
(define *deployment-status*
|
||||||
|
'((queued . "queued")
|
||||||
|
(in-progress . "in-progress")
|
||||||
|
(complete . "complete")
|
||||||
|
(failed . "failed")))
|
||||||
|
(define (create-deployment conn user-id)
|
||||||
|
(value-at
|
||||||
|
(query conn
|
||||||
|
"insert into deployments(user_id) values($1) returning deployments.id;"
|
||||||
|
user-id)))
|
||||||
|
(define (update-deployment-in-progress conn deployment-id pid)
|
||||||
|
(query conn
|
||||||
|
"update deployments set status=$1, pid=$2 where id=$3;"
|
||||||
|
(alist-ref 'in-progress *deployment-status*) pid deployment-id))
|
||||||
|
|
||||||
|
(define (update-deployment-status conn deployment-id status)
|
||||||
|
(query conn "update deployments set status=$1 where id=$2;"
|
||||||
|
(alist-ref status *deployment-status*) deployment-id))
|
||||||
|
|
||||||
|
(define (get-deployment-status conn deployment-id)
|
||||||
|
(value-at (query conn "select status from deployments where id=$1;" deployment-id)))
|
||||||
|
|
||||||
|
(define (get-most-recent-deployment-status conn user-id)
|
||||||
|
(value-at (query conn "select status from deployments where user_id=$1 order by id DESC limit 1;" user-id)))
|
||||||
|
|
||||||
|
;; (with-db/transaction (lambda (db) (create-deployment db 7)))
|
||||||
|
;; (with-db/transaction (lambda (db) (get-deployment-status db 1)))
|
||||||
|
;; (with-db/transaction (lambda (db) (update-deployment-in-progress db 1 123)))
|
||||||
|
;; (with-db/transaction (lambda (db) (update-deployment-status db 1 'complete)))
|
||||||
|
;; (with-db/transaction (lambda (db) (get-most-recent-deployment-status db 7)))
|
||||||
|
|
||||||
;; (with-db/transaction (lambda (db) (create-user db 1 "t@thintz.com" "thecombjelly")))
|
;; (with-db/transaction (lambda (db) (create-user db 1 "t@thintz.com" "thecombjelly")))
|
||||||
|
|
||||||
;; (let ((user-id 7))
|
;; (let ((user-id 7))
|
||||||
|
|||||||
@@ -6,8 +6,10 @@
|
|||||||
(chicken pretty-print)
|
(chicken pretty-print)
|
||||||
(chicken process)
|
(chicken process)
|
||||||
(chicken process-context)
|
(chicken process-context)
|
||||||
|
(chicken irregex)
|
||||||
|
|
||||||
(rename srfi-1 (delete srfi1:delete))
|
(rename srfi-1 (delete srfi1:delete))
|
||||||
|
srfi-18
|
||||||
|
|
||||||
html-widgets
|
html-widgets
|
||||||
sxml-transforms
|
sxml-transforms
|
||||||
@@ -813,31 +815,79 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
("datacenter" . ,(alist-ref 'digitalocean-region service-config))
|
("datacenter" . ,(alist-ref 'digitalocean-region service-config))
|
||||||
("flatcar_stable_version" . "4230.2.3")))
|
("flatcar_stable_version" . "4230.2.3")))
|
||||||
(display "ssh_keys=[\"") (display (with-input-from-file "deploy/config/ssh-keys" read-string)) (print "\"]"))))
|
(display "ssh_keys=[\"") (display (with-input-from-file "deploy/config/ssh-keys" read-string)) (print "\"]"))))
|
||||||
(change-directory "deploy")
|
(let* ((user-id (session-get "user-id"))
|
||||||
(session-set! "pid" (process-run "make apply > make-out"))
|
(deployment-id (with-db/transaction (lambda (db) (create-deployment db user-id)))))
|
||||||
(change-directory "../")
|
(thread-start!
|
||||||
|
(lambda ()
|
||||||
|
(change-directory "deploy")
|
||||||
|
(let ((pid (process-run "make apply > make-out")))
|
||||||
|
(with-db/transaction (lambda (db) (update-deployment-in-progress db deployment-id pid)))
|
||||||
|
(change-directory "../")
|
||||||
|
(let loop ()
|
||||||
|
(thread-sleep! 1)
|
||||||
|
(receive (pid exit-normal status) (process-wait pid #t)
|
||||||
|
(if (= pid 0)
|
||||||
|
(loop)
|
||||||
|
(with-db/transaction
|
||||||
|
(lambda (db)
|
||||||
|
(update-deployment-status
|
||||||
|
db deployment-id
|
||||||
|
(if exit-normal 'complete 'failed)))))))))))
|
||||||
(schematra:redirect "/config/wizard/success"))
|
(schematra:redirect "/config/wizard/success"))
|
||||||
|
|
||||||
(get
|
(get
|
||||||
("/config/wizard/success")
|
("/config/wizard/success")
|
||||||
(receive (pid exit-normal status) (process-wait (session-get "pid") #t) ;; TODO should not rely on the user refreshing page to process-wait since that could create zombie
|
(let ((status (with-db/transaction (lambda (db) (get-most-recent-deployment-status db (session-get "user-id")))))
|
||||||
|
(output (with-input-from-file "deploy/make-out" (lambda () (read-string)))))
|
||||||
`(VStack
|
`(VStack
|
||||||
(h1
|
(h1
|
||||||
,(if (= pid 0)
|
,(case (string->symbol status)
|
||||||
"Deployment in progress"
|
((queued) "Deployment queued")
|
||||||
(if exit-normal
|
((in-progress) "Deployment in progress")
|
||||||
"Deployment complete!"
|
((complete) "Deployment complete!")
|
||||||
"Deployment failed")))
|
((failed) "Deployment failed")))
|
||||||
,@(intersperse
|
(ul (li "generate configs: "
|
||||||
(with-input-from-file "deploy/make-out"
|
,(cond ((irregex-search "terraform apply" output)
|
||||||
(lambda ()
|
"complete")
|
||||||
(letrec ((loop (lambda (out)
|
((irregex-search "mkdir -p all-apps/lb" output)
|
||||||
(let ((v (read-line)))
|
"in progress")
|
||||||
(if (eq? v #!eof)
|
(else "queued")))
|
||||||
out
|
(li "resource deployment: "
|
||||||
(loop (cons v out)))))))
|
,(cond ((irregex-search "Apply complete" output)
|
||||||
(reverse (loop '())))))
|
"complete")
|
||||||
`(br)))))
|
((irregex-search "terraform apply" output)
|
||||||
|
"in progress")
|
||||||
|
(else "queued")))
|
||||||
|
(li "custom flatcar image: "
|
||||||
|
,(cond ((irregex-search "custom_image.flatcar: Modifications complete" output)
|
||||||
|
"complete")
|
||||||
|
((irregex-search "custom_image.flatcar: Modifying" output)
|
||||||
|
"in progress")
|
||||||
|
(else "queued")))
|
||||||
|
(li "machine create: "
|
||||||
|
,(cond ((irregex-search "droplet.machine: Creation complete" output)
|
||||||
|
"complete")
|
||||||
|
((irregex-search "droplet.machine: Creating..." output)
|
||||||
|
"in progress")
|
||||||
|
(else "queued")))
|
||||||
|
(li "cleanup previous machine: "
|
||||||
|
,(cond ((irregex-search "droplet.machine: Destruction complete" output)
|
||||||
|
"complete")
|
||||||
|
((irregex-search '(: "droplet.machine (deposed object " (* alphanum) "): Destroying...") output)
|
||||||
|
"in progress")
|
||||||
|
(else "queued"))))
|
||||||
|
(pre ,output)
|
||||||
|
;; ,@(intersperse
|
||||||
|
;; (with-input-from-file "deploy/make-out"
|
||||||
|
;; (lambda ()
|
||||||
|
;; (letrec ((loop (lambda (out)
|
||||||
|
;; (let ((v (read-line)))
|
||||||
|
;; (if (eq? v #!eof)
|
||||||
|
;; out
|
||||||
|
;; (loop (cons v out)))))))
|
||||||
|
;; (reverse (loop '())))))
|
||||||
|
;; `(br))
|
||||||
|
)))
|
||||||
|
|
||||||
(schematra:schematra-install)
|
(schematra:schematra-install)
|
||||||
(schematra:schematra-start)
|
(schematra:schematra-start)
|
||||||
|
|||||||
Reference in New Issue
Block a user