@@ -723,23 +723,31 @@ h1, h2, h3, h4, h5, h6 {
( with-output-to-file ( string-append dir "/terraform.tfstate.backup" ) ( lambda ( ) ( write-string state-backup ) ) ) )
( define ( parse-deployment-log log )
( define ( search complete in-progress )
( cond ( ( irregex-search complete log )
( define ( search complete in-progress failed )
( cond ( ( irregex-search failed log )
'failed )
( ( irregex-search complete log )
'complete )
( ( irregex-search in-progress log )
'in-progress )
( else 'queued ) ) )
` ( ( generate-configs . , ( search "terraform apply" "NASSELLA_CONFIG: start" ) )
` ( ( generate-configs . , ( search "terraform apply" "NASSELLA_CONFIG: start" "Failed to install provider" ) )
;; TODO this didn't seem to work right when upgrading the flatcar image
;; log: [0m [1mdigitalocean_custom_image.flatcar: Creating... [0m [0m
;; [0m [1mdigitalocean_custom_image.flatcar: Still creating... [00m10s elapsed] [0m [0m
;; [0m [1mdigitalocean_custom_image.flatcar: Still creating... [00m20s elapsed] [0m [0m
;; [0m [1mdigitalocean_custom_image.flatcar: Still creating... [00m30s elapsed] [0m [0m
;; [0m [1mdigitalocean_custom_image.flatcar: Still creating... [00m40s elapsed] [0m [0m
( custom-image . , ( search "custom_image.flatcar: Modifications complete" "custom_image.flatcar: Modifying" ) )
( machine-create . , ( search "droplet.machine: Creation complete" "droplet.machine : Creating..." ) )
( custom-image . , ( search ' ( or "custom_image.flatcar: Modifications complete" "custom_image.flatcar: Creation complete" )
' ( or "custom_image.flatcar: Modifying" "custom_image.flatcar : Creating" )
"XXX - nothing" ) )
( machine-create . , ( search "droplet.machine: Creation complete" "droplet.machine: Creating..." "XXX - nothing" ) )
( machine-destroy . , ( search "droplet.machine: Destruction complete"
' ( : "droplet.machine (deposed object " ( * alphanum ) "): Destroying..." ) ) ) ) )
' ( : "droplet.machine (deposed object " ( * alphanum ) "): Destroying..." ) "XXX - nothing" ) )
( ip-destroy . , ( search "reserved_ip_assignment.machine: Destruction complete" "reserved_ip_assignment.machine: Destroying..." "XXX - nothing" ) )
( ip-create . , ( search "reserved_ip_assignment.machine: Creation complete" "reserved_ip_assignment.machine: Creating..." "Error Assigning reserved IP" ) )
( volume-create . , ( search "volume_attachment.machine: Creation complete" "volume_attachment.machine: Creating..." "XXX - nothing" ) )
( volume-destroy . , ( search "volume_attachment.machine: Destruction complete" "volume_attachment.machine: Destroying..." "XXX - nothing" ) ) ) )
( define ( write-config-entry name value )
( display name )
@@ -1318,7 +1326,9 @@ chmod -R 777 /opt/keys")))
( method POST ) )
( VStack
( Fieldset
( @ ( title "Size " ) )
( @ ( title "Instance Properties " ) )
( Field ( @ ( name "volume-size" ) ( label ( "Volume Size in GB (For persistent application storage)" ) )
( value , ( alist-ref 'digitalocean-volume-size config eq? "60" ) ) ) )
( Field ( @ ( element select ) ( name "size" ) ( input-style ( ( max-width "100%" ) ) ) )
,@ ( map ( lambda ( s ) ` ( option ( @ ( value , ( alist-ref 'slug s ) )
,@ ( if ( equal? ( alist-ref 'slug s ) "s-2vcpu-2gb" ) ` ( ( selected "selected" ) ) ' ( ) ) )
@@ -1338,7 +1348,8 @@ chmod -R 777 /opt/keys")))
db
( session-user-id )
instance-id
` ( ( digitalocean-size . , ( alist-ref 'size ( current-params ) ) ) ) ) ) )
` ( ( digitalocean-size . , ( alist-ref 'size ( current-params ) ) )
( digitalocean-volume-size . , ( alist-ref 'volume-size ( current-params ) ) ) ) ) ) )
( redirect ( conc "/config/wizard/review/" instance-id ) ) ) )
( get/widgets
@@ -1375,6 +1386,7 @@ chmod -R 777 /opt/keys")))
( li "Size: " , ( alist-ref 'digitalocean-size service-config ) ) )
( form
( @ ( action , ( conc "/config/wizard/review-submit/" instance-id ) ) ( method POST ) )
( input ( @ ( type "hidden" ) ( value , ( alist-ref 'force ( current-params ) ) ) ( name "force" ) ) )
( VStack
( Form-Nav ( @ ( back-to , ( conc "/config/wizard/machine2/" instance-id ) ) ( submit-button "Launch" ) ) ) ) ) ) ) ) )
@@ -1386,7 +1398,8 @@ chmod -R 777 /opt/keys")))
( with-db/transaction
( lambda ( db )
( get-most-recent-deployment-status db ( session-user-id ) instance-id ) ) ) ) ) ) )
( when ( not ( or ( eq? status 'queued ) ( eq? status 'in-progress ) ) )
( when ( or ( not ( or ( eq? status 'queued ) ( eq? status 'in-progress ) ) )
( equal? ( alist-ref 'force ( current-params ) ) "true" ) )
( let* ( ( instance-id ( alist-ref "id" ( current-params ) equal? ) )
( restic-snapshot-id ( alist-ref 'restic-snapshot-id ( current-params ) ) )
( results
@@ -1466,21 +1479,66 @@ chmod -R 777 /opt/keys")))
( write-config-entry ( car e ) ( cdr e ) ) )
` ( ( "server_type" . , ( alist-ref 'digitalocean-size service-config ) )
( "do_token" . , ( alist-ref 'digitalocean-api-token service-config ) )
( "digitalocean_volume_size" . , ( alist-ref 'digitalocean-volume-size service-config ) )
( "cloudflare_api_token" . , ( alist-ref 'cloudflare-api-token service-config ) )
( "cloudflare_zone_id" . , ( alist-ref 'cloudflare-zone-id service-config ) )
( "cloudflare_account_id" . , ( alist-ref 'cloudflare-account-id service-config ) )
( "cluster_name" . "nassella" )
( "datacenter" . , ( alist-ref 'digitalocean-region service-config ) )
;; (source <(curl -sSfL https://stable.release.flatcar-linux.net/amd64-usr/current/version.txt); echo "${FLATCAR_VERSION_ID}")
( "flatcar_stable_version" . "4593.2.1 " ) ) )
( "flatcar_stable_version" . "4593.2.2 " ) ) )
;; remove the newline that generating the ssh key adds
( display "ssh_keys=[\"" ) ( display ( string-drop-right ssh-pub-key 1 ) ) ( print "\"]" ) ) ) )
( let* ( ( instance-id ( alist-ref "id" ( current-params ) equal? ) )
( user-id ( session-user-id ) )
( app-config
( with-db/transaction
( lambda ( db )
( get-user-app-config db ( session-user-id ) instance-id ) ) ) )
( deployment-id ( with-db/transaction ( lambda ( db ) ( create-deployment db user-id instance-id ) ) ) )
( dir ( deployment-directory user-id instance-id ) ) )
( dir ( deployment-directory user-id instance-id ) )
( backup-request-id ( conc ( truncate ( time->seconds ( current-time ) ) ) "-" ( pseudo-random-integer 10000 ) ) ) )
( with-db/transaction
( lambda ( db )
( update-deployment-progress db deployment-id ' ( ( instance-backup . in-progress ) ) ) ) )
( handle-exceptions
exn
( with-db/transaction
( lambda ( db )
( update-deployment-progress db deployment-id ' ( ( instance-backup . failed ) ) ) ) )
( send-instance-control-command
( alist-ref 'root-domain app-config )
( alist-ref 'subdomain ( alist-ref 'instance-control ( alist-ref 'config app-config ) ) )
"queue-restic-snapshot-no-restart"
( alist-ref 'webhooks-secret ( alist-ref 'instance-control ( alist-ref 'config app-config ) ) )
` ( ( path . "/" )
( tag . "automated_pre_instance_update" )
;; effectively a guid, we just want something unique
( request_id . , backup-request-id )
( version . 0 ) ) ) )
( thread-start!
( lambda ( )
;; TODO add a timeout and set status to failed and error if we hit the timeout
( let ( ( start-time ( time->seconds ( current-time ) ) ) )
( let loop ( )
( thread-sleep! 1 )
( let* ( ( status-result
( handle-exceptions
exn
' ( ( status . "error" ) )
( send-instance-control-command
( alist-ref 'root-domain app-config )
( alist-ref 'subdomain ( alist-ref 'instance-control ( alist-ref 'config app-config ) ) )
"restic-snapshot-status"
( alist-ref 'webhooks-secret ( alist-ref 'instance-control ( alist-ref 'config app-config ) ) )
` ( ( request_id . , backup-request-id )
( version . 0 ) ) ) ) )
( complete ( string=? ( alist-ref 'status status-result ) "complete" ) ) )
( if ( or complete ( > ( - ( time->seconds ( current-time ) ) start-time ) 45 ) )
( with-db/transaction
( lambda ( db )
( update-deployment-progress db deployment-id ` ( ( instance-backup . , ( or ( and complete 'complete ) 'failed ) ) ) ) ) )
( loop ) ) ) ) )
( change-directory dir )
( let ( ( pid ( process-run "make apply > make-out 2>&1" ) ) )
( with-db/transaction ( lambda ( db ) ( update-deployment-in-progress db deployment-id pid ) ) )
@@ -1512,15 +1570,9 @@ chmod -R 777 /opt/keys")))
( with-db/transaction
( lambda ( db )
( update-deployment-progress db deployment-id progress )
;; TODO THIS DOESN'T WORK RIGHT FOR TERRAFORM OP FAILURES
;; like the random digital ocean error saying the IP can't be
;; updated because another operation is in progress.
;; it still registers as "success".
;; probably need to also write stderr to a file and read/store/parse that?
;; Should we parse make-out for string "Apply complete!" ?
( update-deployment-status
db user-id deployment-id
( if exit-normal 'complete 'failed )
( if ( = status 0 ) 'complete 'failed )
( with-input-from-file ( string-append dir "/make-out" ) read-string ) )
( update-user-terraform-state db user-id instance-id
( if ( eof-object? tf-state ) "" tf-state )
@@ -1542,7 +1594,7 @@ chmod -R 777 /opt/keys")))
( lambda ( db )
` ( ( status . , ( get-most-recent-deployment-status db ( session-user-id ) instance-id ) )
( progress . , ( get-most-recent-deployment-progress db ( session-user-id ) instance-id ) ) ) ) ) )
( output ( with-input-from-file ( string-append ( deployment-directory ( session-user-id ) instance-id ) "/make-out" ) read-string ) )
( output ( handle-exceptions exn "" ( with-input-from-file ( string-append ( deployment-directory ( session-user-id ) instance-id ) "/make-out" ) read-string ) ) )
( progress ( alist-ref 'progress res ) )
( status ( alist-ref 'status res ) ) )
` ( App
@@ -1554,9 +1606,14 @@ chmod -R 777 /opt/keys")))
( ( in-progress ) "Deployment in progress" )
( ( complete ) "Deployment complete!" )
( ( failed ) "Deployment failed" ) ) )
( ul ( li "generate configs : " , ( progress-status->text ( alist-ref 'generate-configs progress ) ) )
( ul ( li "perform backup : " , ( progress-status->text ( alist-ref 'instance-backup progress ) ) )
( li "generate configs: " , ( progress-status->text ( alist-ref 'generate-configs progress ) ) )
( li "custom flatcar image: " , ( progress-status->text ( alist-ref 'custom-image progress ) ) )
( li "machine create : " , ( progress-status->text ( alist-ref 'machine-create progress ) ) )
( li "application volume disconnect : " , ( progress-status->text ( alist-ref 'volume-destroy progress ) ) )
( li "instance create: " , ( progress-status->text ( alist-ref 'machine-create progress ) ) )
( li "instance mapped ip disconnect: " , ( progress-status->text ( alist-ref 'ip-destroy progress ) ) )
( li "instance mapped ip connect: " , ( progress-status->text ( alist-ref 'ip-create progress ) ) )
( li "application volume connect: " , ( progress-status->text ( alist-ref 'volume-create progress ) ) )
( li "cleanup previous machine: " , ( progress-status->text ( alist-ref 'machine-destroy progress ) ) ) )
( div
( a ( @ ( href "/dashboard" ) ) "Dashboard" )
@@ -1733,7 +1790,7 @@ chmod -R 777 /opt/keys")))
( "cluster_name" . "nassella" )
( "datacenter" . , ( alist-ref 'digitalocean-region service-config ) )
;; (source <(curl -sSfL https://stable.release.flatcar-linux.net/amd64-usr/current/version.txt); echo "${FLATCAR_VERSION_ID}")
( "f latcar_stable_version" . "4593.2.1 " ) ) )
( "F latcar_stable_version" . "4593.2.2 " ) ) )
;; remove the newline that generating the ssh key adds
( display "ssh_keys=[\"" ) ( display ( string-drop-right ssh-pub-key 1 ) ) ( print "\"]" ) ) )
;; TODO need a new table to track destroying?
@@ -1825,6 +1882,7 @@ chmod -R 777 /opt/keys")))
` ( ( ul ( li "generate configs: " , ( progress-status->text ( alist-ref 'generate-configs progress ) ) )
( li "custom flatcar image: " , ( progress-status->text ( alist-ref 'custom-image progress ) ) )
( li "machine create: " , ( progress-status->text ( alist-ref 'machine-create progress ) ) )
( li "attaching : " , ( progress-status->text ( alist-ref 'machine-create progress ) ) )
( li "cleanup previous machine: " , ( progress-status->text ( alist-ref 'machine-destroy progress ) ) ) )
( div
( a ( @ ( href "/dashboard" ) ) "Dashboard" )