In some instances, the booting of a server may hang if any commands executed within a boot script expect input from the user. For instance, if your svn server requires a user to manually accept an SSL certificate for any reason (i.e. if you have a cert for www.oursite.com, but your SVN URL is svn.oursite.com), the RB rails svn code update & db config RightScript will hang with the following message:
Error validating server certificate for 'https://svn.oursite.com:443':
- The certificate hostname does not match.
Certificate information:
- Hostname: www.oursite.com
- Valid: from Feb 12 00:00:00 2008 GMT until Feb 17 23:59:59 2009 GMT
- Issuer: www.digicert.com, DigiCert Inc, US
- Fingerprint: 3c:c5:u3:83:46:87:fc:7e:14:47:30:c9:1d:49:83:f7:fd:eb:kf:9e
(R)eject or accept (t)emporarily?
Since RightScripts are written in Ruby, we can utilize the Ruby expect package to both detect these prompts and pass input to them. But, first we need to determine which script is hanging on boot. Go to Manage -> Servers and click on the name of one of the servers that has stopped booting. Then click on the Audit Entries tab and click on the name of the last script to run successfully. At the bottom of the audit entry you should see lines that look like this:
* script completed successfully
>>>>> NEXT: RightScript <RB rails svn code update & db config v3>
If there is no audit entry regarding the RB rails svn code update & db config script (or whatever script happens to be hanging), then that script is most likely causing the error. Now click on the SSH Console button and type the following at the prompt:
$ tail /var/log/install. [PRESS TAB AND THEN RETURN]
You should now see the offending prompt at the bottom of the file (as in the svn example at the top of the article). Now we know what we need to automate.
Following with the svn example, we will need to clone the RB rails svn code update & db config script in order to alter it. Navigate to Manage -> Deployments and click on the name of the deployment that is giving you trouble. From this screen, click on the name of one of the offending servers. Click on the Actions tab for the server and find the name of the hanging script. From the script page, click on the Clone button. Now navigate to Design -> RightScripts and click on the name of the script you've just cloned. Be sure to click on its title at the top of the page and add '(clone)' to the end of its name so you can later recognize that this is a clone of an official RightScript. Now click the Edit link and let's get to work.
This is the part that's going to require a bit of digging. We need to determine which part of script is making the call to svn checkout. In our example, this can be found in the following section of code:
res=`svn #{auth_params} --quiet co #{ENV['SVN_APP_REPOSITORY']} #{canonicalized_app_dir}`
This is making the 'svn co' call that we are interested in. We need to refactor this section thusly:
require 'pty'
PTY.spawn("svn #{auth_params} --quiet co #{ENV['SVN_APP_REPOSITORY']} #{canonicalized_app_dir}") do |r_f,w_f,pid|
w_f.sync = true
$expect_verbose = false
# Instruct SVN to accept the SVN cert temporarily.
r_f.expect("(R)eject or accept (t)emporarily?") do
w_f.print("t\n")
begin
while(line = r_f.gets)
puts line
end
rescue
puts "SVN checkout completed successfully."
end
end
end
If you dig through the expect documentation a bit, you'll see that the call to PTY.spawn opens a PTY and executes the specified command. The block gives us acces to three variables:
After executing the command, we make a call to r_f.expect, which takes either a string or a regex as an argument representing the prompt that we are looking for. When the prompt is reached, we pass the 't' option with a call to w_f.print. The begin...rescue...end block merely prints the output of the command, thus waiting for the checkout command to finish.
Now we need to associate this script with the appropriate server template. Navigate to Design -> ServerTemplates, and click on the name of the appropriate template ('Rails FrontEnd v1 clone', in this example). Click on the Scripts tab. Scroll to the bottom of the page and add the private RightScript that we just created ('RB rails svn code update & db config v1 (clone)') as a boot script. Now delete any Rails FrontEnd instances in your deployment and replace them with new instances of your template to make sure that the RightScript is updated (be sure to reset the DNS_ID appropriately for each new instance).
Now drag the script to just below the orginal in the list of the boot scripts, and delete the orginal. Restart the servers, cross your fingers, and wait. Hopefully, you should be all set up.
*RS> Running RightScript <Clone RB rails svn code update & db config v1> ****
*RS> script starting at: Fri Aug 01 17:35:09 -0400 2008
Error:
uninitialized constant PTY
*RS> script duration: 0.107215 seconds
Which leads me to believe that the Expect library isn't getting loaded. Any ideas?
require 'pty'
to the script that I cloned.