source: branches/locker-dev/locker/deploy/bin/rails @ 2276

Last change on this file since 2276 was 2276, checked in by glasgall, 9 years ago
Update instructions to user at end of script for rails 3
  • Property svn:executable set to *
File size: 7.7 KB
Line 
1#!/usr/bin/perl
2use strict;
3use FindBin qw($Bin);
4use lib $Bin;
5use onserver;
6use Tie::File;
7use Cwd;
8
9setup();
10
11sub make_db {
12    my($type) = @_;
13    print "\nCreating $type SQL database for $sname...\n";
14    open GETPWD, '-|', "/mit/scripts/sql/bin$scriptsdev/get-password";
15    ($sqlhost, $sqluser, $sqlpass) = split(/\s/, <GETPWD>);
16    close GETPWD;
17    open SQLDB, '-|', "/mit/scripts/sql/bin$scriptsdev/get-next-database", "${addrlast}_${type}";
18    $sqldb = <SQLDB>;
19    close SQLDB;
20    open SQLDB, '-|', "/mit/scripts/sql/bin$scriptsdev/create-database", $sqldb;
21    $sqldb = <SQLDB>;
22    close SQLDB;
23    if($sqldb eq "") {
24        print "\nERROR:\n";
25        print "Your SQL account failed to create a SQL database.\n";
26        print "You should log in at http://sql.mit.edu to check whether\n";
27        print "your SQL account is at its database limit or its storage limit.\n";
28        print "If you cannot determine the cause of the problem, please\n";
29        print "feel free to contact sql\@mit.edu for assistance.\n";
30        open FAILED, ">.failed";
31        close FAILED;
32        exit 1;
33    }
34    return $sqldb;
35}
36
37my $dev_db = make_db("development");
38my $test_db = make_db("test");
39my $prod_db = make_db("production");
40
41my $cwd = getcwd;
42system("rails", "new", $cwd ,"-d", "mysql");
43my $appdir = `basename $cwd`;
44chomp $appdir;
45
46open APPLICATION_RB, "config/application.rb";
47my $appclass;
48while(<APPLICATION_RB>) {
49    if (/module (\w+)\n/) {
50        $appclass = $1;
51        last;
52    }
53}
54close APPLICATION_RB;
55if (!$appclass) {
56    open FAILED, ">.failed";
57    close FAILED;
58    die "Couldn't find application class name - plase email scripts\@mit.edu with the names of your locker and the application you tried to create. Sorry!";
59}
60
61open PUBLIC_HTACCESS, ">public/.htaccess";
62print PUBLIC_HTACCESS <<EOF;
63# General Apache options
64Options +FollowSymLinks +ExecCGI
65
66# If you don't want Rails to look in certain directories,
67# use the following rewrite rules so that Apache won't rewrite certain requests
68#
69# Example:
70#   RewriteCond %{REQUEST_URI} ^/notrails.*
71#   RewriteRule .* - [L]
72
73# Redirect all requests not available on the filesystem to Rails
74# By default the cgi dispatcher is used which is very slow
75#
76# For better performance replace the dispatcher with the fastcgi one
77#
78# Example:
79#   RewriteRule ^(.*)\$ dispatch.fcgi [QSA,L]
80RewriteEngine On
81
82# If your Rails application is accessed via an Alias directive,
83# then you MUST also set the RewriteBase in this htaccess file.
84#
85# Example:
86#   Alias /myrailsapp /path/to/myrailsapp/public
87#   RewriteBase /myrailsapp
88
89RewriteRule ^\$ index.html [QSA]
90RewriteRule ^([^.]+)\$ \$1.html [QSA]
91RewriteCond %{REQUEST_FILENAME} !-f
92RewriteRule ^(.*)\$ dispatch.fcgi [QSA,L]
93
94# In case Rails experiences terminal errors
95# Instead of displaying this message you can supply a file here which will be rendered instead
96#
97# Example:
98#   ErrorDocument 500 /500.html
99
100EOF
101
102open HTACCESS, ">.htaccess";
103print HTACCESS <<EOF;
104RewriteEngine On
105RewriteRule ^(.*)\$ public/\$1 [QSA,L]
106
107EOF
108
109tie my @railsenv, 'Tie::File', 'config/environment.rb';
110unshift @railsenv, "# ENV['RAILS_ENV'] ||= 'production'";
111unshift @railsenv, "# Uncomment below to put Rails into production mode";
112unshift @railsenv, "";
113unshift @railsenv, "ENV['RAILS_RELATIVE_URL_ROOT'] = \"/$addrend\"";
114untie @railsenv;
115
116tie my @railsdb, 'Tie::File', 'config/database.yml';
117for (@railsdb) {
118    s/username:.*$/username: $sqluser/;
119    s/password:.*$/password: $sqlpass/;
120    s/host:.*$/host: $sqlhost/;
121    s/database:.*_development.*/database: $dev_db/;
122    s/database:.*_test.*/database: $test_db/;
123    s/database:.*_production.*/database: $prod_db/;
124}
125untie @railsdb;
126
127tie my @railswelcome, 'Tie::File', 'public/index.html';
128for (@railswelcome) {
129    s/Create your database/Sync your database/;
130    s/to create your database\..*/to create tables in your database.<\/p>/;
131}
132untie @railswelcome;
133
134tie my @railsfcgi, 'Tie::File', 'public/dispatch.fcgi';
135for (@railsfcgi) {
136    s/^[^#]*RailsFCGIHandler/## Commented out by scripts.mit.edu autoinstaller\n## RailsFCGIHandler/;
137}
138untie @railsfcgi;
139open RAILSFCGI, ">>public/dispatch.fcgi";
140print RAILSFCGI "#!/usr/bin/ruby\n";
141print RAILSFCGI <<EOF;
142require File.join(File.dirname(__FILE__), '../config/environment')       
143require 'rack'
144
145## Added by scripts.mit.edu autoinstaller to reload when app code changes
146Thread.abort_on_exception = true
147
148class Rack::PathInfoRewriter
149  def initialize(app)
150    \@app = app
151  end
152
153  def call(env)
154    env["SCRIPT_NAME"] = ""
155    parts = env['REQUEST_URI'].split('?')
156    env['PATH_INFO'] = parts[0]
157    env['QUERY_STRING'] = parts[1].to_s
158    \@app.call(env)
159  end
160end
161
162
163t1 = Thread.new do
164  dispatch_logger = Logger.new(File.join(Rails.root,'log/dispatcher.log'))
165
166  begin
167    Rack::Handler::FastCGI.run Rack::PathInfoRewriter.new(Rack::URLMap.new("/$appdir" => ${appclass}::Application,
168                                                                           "/" => ${appclass}::Application))
169  rescue => e
170   dispatch_logger.error(e)
171   raise e
172  end
173end
174t2 = Thread.new do
175   # List of directories to watch for changes before reload.
176   # You may want to also watch public or vendor, depending on your needs.
177   Thread.current[:watched_dirs] = ['app', 'config', 'db', 'lib']
178
179   # List of specific files to watch for changes.
180   Thread.current[:watched_files] = ['public/dispatch.fcgi',
181                                     'public/.htaccess']
182   # Sample filter: /(\.rb|\.erb)\$/.  Default filter: watch all files
183   Thread.current[:watched_extensions] = //
184   # Iterations since last reload
185   Thread.current[:iterations] = 0
186
187   def modified(file)
188     begin
189       mtime = File.stat(file).mtime
190     rescue
191       false
192     else
193       if Thread.current[:iterations] == 0
194         Thread.current[:modifications][file] = mtime
195       end
196       Thread.current[:modifications][file] != mtime
197     end
198   end
199
200   # Don't symlink yourself into a loop.  Please.  Things will still work
201   # (Linux limits your symlink depth) but you will be sad
202   def modified_dir(dir)
203     Dir.new(dir).each do |file|
204       absfile = File.join(dir, file)
205       if FileTest.directory? absfile
206         next if file == '.' or file == '..'
207         return true if modified_dir(absfile)
208       else
209         return true if Thread.current[:watched_extensions] =~ absfile &&
210           modified(absfile)
211       end
212     end
213     false
214   end
215
216   def reload
217     Thread.current[:modifications] = {}
218     Thread.current[:iterations] = 0
219     # This is a kludge, but at the same time it works.
220     # Will kill the current FCGI process so that it is reloaded
221     # at next request.
222     raise RuntimeError
223   end
224
225   Thread.current[:modifications] = {}
226   # Wait until the modify time changes, then reload.
227   while true
228     dir_modified = Thread.current[:watched_dirs].inject(false) {|z, dir| z || modified_dir(File.join(File.dirname(__FILE__), '..', dir))}
229     file_modified = Thread.current[:watched_files].inject(false) {|z, file| z || modified(File.join(File.dirname(__FILE__), '..', file))}
230     reload if dir_modified || file_modified
231     Thread.current[:iterations] += 1
232     sleep 1
233   end
234end
235
236t1.join
237t2.join
238## End of scripts.mit.edu autoinstaller additions
239EOF
240chmod 0755,'public/dispatch.fcgi';
241
242# static-cat doesn't whitelist .txt files
243chmod 0777, 'public/robots.txt'; 
244
245# have to explicitly take a dependency on fcgi
246# ruby1.9 means we need to take a dependency on minitest
247# for rails console to work
248open GEMFILE, ">>Gemfile";
249print GEMFILE "gem 'fcgi'\n";
250print GEMFILE "gem 'minitest'\n";
251close GEMFILE;
252
253print "Your application is located in:\n";
254print "  /mit/$USER/web_scripts/$addrend/\n";
255print "To run programs like rake or rails generate, run\n";
256print "  'ssh -k $USER\@scripts' and cd to the above directory.\n\n";
257press_enter;
258
259exit 0;
Note: See TracBrowser for help on using the repository browser.