1 (in-package #:candle-aws)
3 (defvar *aws-mutex* (sb-thread:make-mutex))
4 (defvar *aws-waitq* (sb-thread:make-waitqueue))
5 (defvar *aws-state* :initial)
7 (defvar *aws-instance-id*)
8 (defvar *aws-username*)
12 (defvar *remote-work-dir*)
13 (defvar *remote-candle-location*)
15 (defmethod candle:process-job-in-system ((job-system (eql :aws)) job)
16 (sb-thread:with-mutex (*aws-mutex*)
17 ; Don't start it up until we process the first job
18 (when (eql :initial *aws-state*)
19 (setf *aws-state* :down)
20 (start-shutdown-thread))
21 (when (eql :down *aws-state*) (start-aws-box))
23 ((retn (multiple-value-list (run-job job))))
24 (setf *aws-state* :up)
25 (sb-thread:condition-broadcast *aws-waitq*)
28 (defun start-shutdown-thread ()
29 (sb-thread:make-thread
32 (sb-thread:with-mutex (*aws-mutex*)
33 (when (eql :down *aws-state*)
34 (sb-thread:condition-wait *aws-waitq* *aws-mutex*))
35 (when (eql :shutting-down-soon *aws-state*)
37 (setf *aws-state* :down))
38 (when (eql :up *aws-state*)
39 (setf *aws-state* :shutting-down-soon)))
41 :name "AWS Shutdown Thread"))
43 (defun aws-command (cmd &rest args)
44 (with-output-to-string (out)
51 :error *error-output*)))
53 (defun describe-property (property)
60 (format nil "Reservations[0].Instances[0].~A" property))))
62 (defun get-remote-state ()
63 (intern (string-upcase (describe-property "State.Name")) :keyword))
65 (defun start-aws-box ()
66 (aws-command "start-instances" "--instance-ids" *aws-instance-id*)
69 :until (eql :running (get-remote-state))
71 ; Make sure ssh and services are started up
73 (when (not (eql :running (get-remote-state)))
74 (error "Waited two minutes and still not running...?")))
76 (defun stop-aws-box ()
77 (aws-command "stop-instances" "--instance-ids" *aws-instance-id*)
80 :until (eql :stopped (get-remote-state))
82 (when (not (eql :stopped (get-remote-state)))
83 (error "Waited two minutes and still not stopped...?")))
92 (format nil "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~A" *aws-keyfile*)
93 (candle:project-dir (candle:job-project job))
94 (format nil "~A@~A:~A" *aws-username* (describe-property "PublicIpAddress") *remote-work-dir*)))
99 (with-output-to-string (out-str)
101 (sb-ext:process-exit-code
106 "StrictHostKeyChecking=no"
108 "UserKnownHostsFile=/dev/null"
111 (describe-property "PublicIpAddress")
112 (format nil "cd ~A ; ~A run" *remote-work-dir* *remote-candle-location*))
116 (values (zerop code) out)))