├── .gitignore ├── CHANGELOG ├── COPYING ├── README.textile ├── TODO ├── ami_ids.yml ├── examples ├── Capfile ├── deploy.rb └── s3.yml ├── gem ├── Rakefile ├── VERSION └── lib │ ├── ec2onrails.rb │ └── ec2onrails │ ├── capistrano_utils.rb │ ├── recipes.rb │ ├── recipes │ ├── db.rb │ ├── deploy.rb │ └── server.rb │ └── version_helper.rb └── server ├── build ├── files ├── etc │ ├── README │ ├── aliases │ ├── cron.d │ │ └── ec2onrails │ ├── cron.daily │ │ ├── app │ │ └── logrotate_post │ ├── cron.hourly │ │ └── app │ ├── cron.monthly │ │ └── app │ ├── cron.weekly │ │ └── app │ ├── default │ │ ├── varnish │ │ └── varnishncsa │ ├── denyhosts.conf │ ├── dpkg │ │ └── dpkg.cfg │ ├── ec2onrails │ │ ├── rails_env │ │ └── roles.yml │ ├── environment │ ├── event.d │ │ └── god │ ├── god │ │ ├── db_primary.god │ │ ├── dkim_filter.god │ │ ├── master.conf │ │ ├── memcache.god │ │ ├── notifications.god │ │ ├── proxy.god │ │ ├── system.god │ │ └── web.god │ ├── init.d │ │ ├── ec2-every-startup │ │ ├── ec2-first-startup │ │ └── nginx │ ├── logrotate.d │ │ ├── god │ │ ├── nginx │ │ ├── rails │ │ └── varnish │ ├── memcached.conf │ ├── motd.tail │ ├── mysql │ │ └── my.cnf │ ├── nginx │ │ ├── conf.d │ │ │ └── custom.conf │ │ └── nginx.conf.erb │ ├── postfix │ │ └── main.cf │ ├── ssh │ │ └── sshd_config │ ├── sudoers │ ├── syslog.conf │ └── varnish │ │ └── default.vcl.erb └── usr │ └── local │ └── ec2onrails │ ├── COPYING │ ├── bin │ ├── archive_file │ ├── backup_app_db │ ├── backup_dir │ ├── ec2_meta_data │ ├── exec_runner │ ├── in_role │ ├── init_services │ ├── install_system_files │ ├── optimize_mysql │ ├── public-hostname │ ├── rails_env │ ├── rebundle │ ├── restore_app_db │ ├── set_rails_env │ ├── set_roles │ └── uninstall_system_files │ ├── config │ ├── lib │ ├── aws_helper.rb │ ├── god_helper.rb │ ├── mysql_helper.rb │ ├── roles_helper.rb │ ├── s3_helper.rb │ ├── system_files_helper.rb │ ├── system_files_manifest.rb │ ├── utils.rb │ └── vendor │ │ └── ini.rb │ └── startup-scripts │ ├── every-startup │ ├── README │ └── create-mysqld-pid-dir │ └── first-startup │ ├── README │ ├── create-dirs │ ├── generate-default-web-cert-and-key │ ├── get-hostname │ ├── misc │ ├── prepare-mysql-data-dir │ ├── setup-credentials │ └── setup-file-permissions ├── rakefile-wrapper ├── rakefile.rb └── test ├── autobench.conf ├── spec ├── lib │ ├── s3_helper_spec.rb │ ├── s3_old.yml │ └── system_files_manifest_spec.rb └── test_files │ ├── system_files1 │ ├── _manifest │ ├── test1 │ ├── test2 │ └── testfolder │ │ └── test3 │ ├── system_files2 │ ├── _manifest │ ├── test1 │ ├── test2 │ └── testfolder │ │ └── test3 │ └── test2 └── test_app ├── Capfile ├── README ├── Rakefile ├── app ├── controllers │ ├── application_controller.rb │ ├── db_fast_controller.rb │ ├── fast_controller.rb │ ├── slow_controller.rb │ └── very_slow_controller.rb └── helpers │ └── application_helper.rb ├── config ├── boot.rb ├── database.yml ├── deploy.rb ├── ec2onrails │ └── config.rb ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── backtrace_silencers.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── new_rails_defaults.rb │ └── session_store.rb ├── locales │ └── en.yml └── routes.rb ├── doc └── README_FOR_APP ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── images │ └── rails.png ├── index.html ├── javascripts │ ├── application.js │ ├── controls.js │ ├── dragdrop.js │ ├── effects.js │ └── prototype.js └── robots.txt ├── script ├── about ├── console ├── dbconsole ├── destroy ├── generate ├── performance │ ├── benchmarker │ └── profiler ├── plugin ├── runner └── server └── test ├── performance └── browsing_test.rb └── test_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .loadpath 3 | .project 4 | gem/*.gemspec 5 | gem/pkg/* 6 | gem/tmp/* 7 | server/test/test_app/db/*.sqlite3 8 | server/test/test_app/log/* 9 | server/test/test_app/tmp/* 10 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | here are a list of upcoming changes or ones I'm thinking about 2 | 3 | FUTURE CHANGES 4 | [ ] when hardening server, change the SSH port 5 | 6 | [ ] do not change the Capify file. This is an issue if you want to use ec2 for staging but something else (engineyard) for production. The issue is that require 'ec2onrails/recipes' cannot be called until after the deploy file has been run because of some loading dependencies. SO, is it possible to not have this behavior, or is this making a mnt out of a mole-hill? 7 | 8 | [ ] be able to save an ami file after cap ec2onrails:setup is run... this way you can just launch more instances of that specific ami file (can we automate this? ) 9 | 10 | [ ] use mongrel_cluster from app directory (shared or directly in the app/config dir), and then default to the one at /etc/mongrel_cluster/app.yml 11 | 12 | [ ] customize roles. For example, lets say I want to have nginx publish to multiple proxy's instead of the set_roles default ones. Have a hook where I, as an end user, can extend custom roles... but where do I put it? is there a custom_roles_file location pref that is set in the cap deploy file? 13 | 14 | [ ] hook memcached into nginx... 15 | 16 | [ ] hook ssl setup hooks for nginx 17 | 18 | [ ] automatic firewall setup. The hitch is can we find the amazon user_id automatically? 19 | 20 | [ ] automatic and randomized initial mysql root password setup. Place the root password in a text file only to be read by 'root', perhaps in /etc/ec2onrails/mysq_root_passwd. 'mysqladmin -u root -h localhost password subGen1us' 21 | 22 | [ ] rename the root username for mysql, like 'update user set user="mydbadmin" where user="root";'. Make sure we do this at startup but also have a check that if a user is upgrading their server that this is switched 23 | 24 | [ ] multi-database setup. Master -> n slave(s) 25 | 26 | [ ] when generating roles file for each server, so each server knows where/how to find the internal IP of other servers in the cluster, generate this based on the roles that actually exist so arbitrary new ones can be added (recipes.rb, task :set_roles). Capistrano has a variable 'roles', that should be useable...? is an array, with Capistrano::ServerDefinition objects, which have the following attributes :host, :user, :port, :options 27 | 28 | [ ] allow memcache servers to reside on a separate host/cluster 29 | 30 | [ ] do a little memcache optimization, especially if it is its own host 31 | 32 | [ ] allow to pull memcache file from application directory ./config 33 | 34 | [ ] hook in pauls postfix changes to be able to use an external smtp provider. make it configurable: 35 | http://pauldowman.com/2008/02/17/smtp-mail-from-ec2-web-server-setup/ 36 | also see this file for updates: 37 | http://www.babbleon.co.uk/2008/05/email-with-ec2/ 38 | 39 | [ ] consolidate all logs to /mnt/log, including /mnt/app/current... it makes it easier to rotate and shuffle them off to s3 40 | 41 | [ ] hook in encryption of backup archives 42 | 43 | [ ] hook in backup of server... or should we wait for persistent storage snapshots? http://www.webmonkey.com/tutorial/Back_Up_a_Web_Server 44 | 45 | [ ] allow a non-standard ssh port (and make sure the firewall is setup correctly). modify /etc/ssh/ssh_config, update /etc/services. Also turn off root access...but only if we have another full sudo user like 'admin' 46 | 47 | [ ] should we go back to having a sudo user like 'admin' that we flip into when we need sudo access instead of root? 48 | 49 | [ ] install and setup an intrusion detection system. Do we want to do something as simple fcheck(apt-get fcheck, run with fcheck -cadsxl, and add /mnt to its exclusion list?), or something more complex like snort or prelude? fcheck is small, but simple; snort is quite complex and will either require its own capistrano role or live on the web role... plus it needs to be hooked into email and other notification paths to make it useful. 50 | 51 | [ ] make difficult security/hardening changes optional, especially if they will get in the way of getting up and running. For example, do not install denyhosts by default...or disable it if the security_hardening flag == false 52 | 53 | POSSIBLE CHANGES 54 | [ ] do not put users custom files up there until before deploy:cold? Right now I'm pushing a lot of custom stuff out there into monit which is failing because the code it is supposed to monitor is not there yet. will pushing it to "before 'deploy:cold' cause an issues" 55 | 56 | [ ] possibly put /tmp on its own mnt point, and then lock it down in /etc/fstab. Modify tmp to something like this '/dev/hda2 /tmp ext3 nodev,nosuid, noexec 0 0' 57 | this means nonone will be able to execute, or a bunch of other things, from within /tmp 58 | 59 | 60 | QUESTIONS 61 | * during setup, what do you choose for Postfix configurations? ANSWER: 62 | 63 | * why install php5? ANSWER: Can't tell... seems to run fine without it, so removing it as a direct aptitude fetch (if it is a dependency somewhere else, it will get downloaded) 64 | 65 | * WHO runs the script/migration? App or db? ANSWER: the (primary-) db does. This make sense in that you don't want every app instance running a rake db:migration. This means that the db role needs to be fully setup to handle rake db:migration, meaning the /etc/hosts file needs to contain db_primary as an alias to 127.0.0.1 66 | 67 | 68 | COMPLETED 69 | [X] preload mysql timezone information (UPDATE: not sure if this is needed...NOTE: it is not) 70 | 71 | [X] mysql optimizations are not calculating the num of cores avail correctly 72 | 73 | [X] right now cron has a task called 'app' in cron.daily, cron.hourly, cron.monthly, and cron.weekly. BUT, these are run on every server. we should probably provide some sort of mechanism so a user can specify particular jobs for particular roles NOTE: paul already thought of this with the exec_runner script that we can run from within cron 74 | 75 | [X] get all user-data and meta-data variables from the amazon image in a similar way to rightscale? Makes it dead simple to use/manipulate that information. UPDATE: rightscale gave us permission to use their open-sourced files, as long as we credit them 76 | 77 | [X] Move to Echoe? It just seems a LOT easier to setup and handle than hoe. It can remove a lot of cruft, probably including ./config, ./script, ./tasks (or most of them), and ./website (move that to the README file?... looks like would need to be moved to ./docs ). A few folks have branched ec2onrails into github before and they've all done this... 78 | 79 | [X] set -y flag when installing/updating gems UPDATE: not needed... does it automatically for the other non-interactive flags we are using 80 | 81 | [X] mysql optimizations 82 | 83 | [X] hook in ebs, and use eric's writeup as the starting point: 84 | http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663&categoryID=100 85 | 86 | 87 | [X] /etc/monit/monitrc needs to be chmod 700. see error at: http://pastie.org/251895, with custom task at http://pastie.org/251896.. Perhaps this should be solved in set_roles or init_services or something a bit higher` 88 | 89 | [X] remove the *_admin capistrano roles. can we use admin for sudo access but continue to deploy and run under a user without sudo access? It looks like we can if we add this to the recipes.rb file: 90 | set :use_sudo, true 91 | set :user, "app" 92 | set :admin_runner, "admin" 93 | UPDATE: this didn't work as then admin would need to behave as root... SO, here is what I did: 94 | * remove _admin roles AND the admin user 95 | * give app user full sudo access to begin with 96 | * have /etc/sudoers -> /etc/sudoers.full_access 97 | * after ec2onrails:setup, trigger ec2onrails:server:restrict_sudo_access 98 | - flips /etc/sudoers -> /etc/sudoers.restricted_access 99 | - at this point, the app user ONLY has access to sudo to monit 100 | * provide cap tasks to restrict or grant full sudo access 101 | 102 | [X] allow config to be able to flip between nginx and apache as proxy... 103 | 104 | [X] move to god from monit. One advantage is that right now, we don't use monit to send start/stop/restart signals to the underlying processes. Monit does not always stop mongrel, and if mongrel doesn't restart monit doesn't go in with the oh-holy 'kill -9'. So we unmonit mongrel, then use the /etc/init.d/mongrel stop to kill it. This works (quite well actually) BUT it makes it tricky because if we limit sudo access to only monit, we cannot run the /etc/init.d/*. It would be best if we provide sudo access to ONLY one process. God, supposedly, doesn't have this issue. So if we use god instead of monit, can we have god be responsible for restarts and what not? 105 | -------------------------------------------------------------------------------- /ami_ids.yml: -------------------------------------------------------------------------------- 1 | us: 2 | 32bit: ami-1501e27c 3 | 64bit: n/a 4 | eu: 5 | 32bit: n/a 6 | 64bit: n/a 7 | -------------------------------------------------------------------------------- /examples/Capfile: -------------------------------------------------------------------------------- 1 | load 'deploy' if respond_to?(:namespace) # cap2 differentiator 2 | load 'config/deploy' 3 | require 'ec2onrails/recipes' 4 | -------------------------------------------------------------------------------- /examples/deploy.rb: -------------------------------------------------------------------------------- 1 | # This is a sample Capistrano config file for EC2 on Rails. 2 | # It should be edited and customized. 3 | 4 | set :application, "yourapp" 5 | 6 | set :repository, "http://svn.foo.com/svn/#{application}/trunk" 7 | 8 | # NOTE: for some reason Capistrano requires you to have both the public and 9 | # the private key in the same folder, the public key should have the 10 | # extension ".pub". 11 | ssh_options[:keys] = ["#{ENV['HOME']}/.ssh/your-ec2-key"] 12 | 13 | # Your EC2 instances. Use the ec2-xxx....amazonaws.com hostname, not 14 | # any other name (in case you have your own DNS alias) or it won't 15 | # be able to resolve to the internal IP address. 16 | role :web, "ec2-12-xx-xx-xx.z-1.compute-1.amazonaws.com" 17 | role :memcache, "ec2-12-xx-xx-xx.z-1.compute-1.amazonaws.com" 18 | role :db, "ec2-56-xx-xx-xx.z-1.compute-1.amazonaws.com", :primary => true 19 | # role :db, "ec2-56-xx-xx-xx.z-1.compute-1.amazonaws.com", :primary => true, :ebs_vol_id => 'vol-12345abc' 20 | # optinally, you can specify Amazon's EBS volume ID if the database is persisted 21 | # via Amazon's EBS. See the main README for more information. 22 | 23 | # Whatever you set here will be taken set as the default RAILS_ENV value 24 | # on the server. Your app and your hourly/daily/weekly/monthly scripts 25 | # will run with RAILS_ENV set to this value. 26 | set :rails_env, "production" 27 | 28 | # EC2 on Rails config. 29 | # NOTE: Some of these should be omitted if not needed. 30 | set :ec2onrails_config, { 31 | # S3 bucket and "subdir" used by the ec2onrails:db:restore task 32 | # NOTE: this only applies if you are not using EBS 33 | :restore_from_bucket => "your-bucket", 34 | :restore_from_bucket_subdir => "database", 35 | 36 | # S3 bucket and "subdir" used by the ec2onrails:db:archive task 37 | # This does not affect the automatic backup of your MySQL db to S3, it's 38 | # just for manually archiving a db snapshot to a different bucket if 39 | # desired. 40 | # NOTE: this only applies if you are not using EBS 41 | :archive_to_bucket => "your-other-bucket", 42 | :archive_to_bucket_subdir => "db-archive/#{Time.new.strftime('%Y-%m-%d--%H-%M-%S')}", 43 | 44 | # Set a root password for MySQL. Run "cap ec2onrails:db:set_root_password" 45 | # to enable this. This is optional, and after doing this the 46 | # ec2onrails:db:drop task won't work, but be aware that MySQL accepts 47 | # connections on the public network interface (you should block the MySQL 48 | # port with the firewall anyway). 49 | # If you don't care about setting the mysql root password then remove this. 50 | :mysql_root_password => "your-mysql-root-password", 51 | 52 | # Any extra Ubuntu packages to install if desired 53 | # If you don't want to install extra packages then remove this. 54 | :packages => ["logwatch", "imagemagick"], 55 | 56 | # Any extra RubyGems to install if desired: can be "gemname" or if a 57 | # particular version is desired "gemname -v 1.0.1" 58 | # If you don't want to install extra rubygems then remove this 59 | # NOTE: if you are using rails 2.1, ec2onrails calls 'sudo rake gem:install', 60 | # which will install gems defined in your rails configuration 61 | :rubygems => ["rmagick", "rfacebook -v 0.9.7"], 62 | 63 | # extra security measures are taken if this is true, BUT it makes initial 64 | # experimentation and setup a bit tricky. For example, if you do not 65 | # have your ssh keys setup correctly, you will be locked out of your 66 | # server after 3 attempts for upto 3 months. 67 | :harden_server => false, 68 | 69 | #if you want to harden the server, or setup email signing, you will need to set the domain 70 | #if you use Capistrano's multistage extension (recommended!), you can add a line like this to your 71 | #environment specific file: 72 | # ec2onrails_config[:service_domain] = 'staging.mydomain.com' 73 | :service_domain => nil, 74 | 75 | # Set the server timezone. run "cap -e ec2onrails:server:set_timezone" for 76 | # details 77 | :timezone => "UTC", 78 | 79 | # Files to deploy to the server (they'll be owned by root). It's intended 80 | # mainly for customized config files for new packages installed via the 81 | # ec2onrails:server:install_packages task. Subdirectories and files inside 82 | # here will be placed in the same structure relative to the root of the 83 | # server's filesystem. 84 | # If you don't need to deploy customized config files to the server then 85 | # remove this. 86 | :server_config_files_root => "../server_configs", 87 | 88 | # If config files are deployed, some services might need to be restarted. 89 | # If you don't need to deploy customized config files to the server then 90 | # remove this. 91 | :services_to_restart => %w(postfix sysklogd), 92 | 93 | # Set an email address to forward admin mail messages to. If you don't 94 | # want to receive mail from the server (e.g. monit alert messages) then 95 | # remove this. 96 | :mail_forward_address => "you@yourdomain.com", 97 | 98 | # Set this if you want SSL to be enabled on the web server. The SSL cert 99 | # and key files need to exist on the server, The cert file should be in 100 | # /etc/ssl/certs/default.pem and the key file should be in 101 | # /etc/ssl/private/default.key (see :server_config_files_root). 102 | :enable_ssl => true 103 | } 104 | -------------------------------------------------------------------------------- /examples/s3.yml: -------------------------------------------------------------------------------- 1 | staging: 2 | aws_access_key: ABC123 3 | aws_secret_access_key: abc123abc123abc123abc123 4 | bucket_base_name: yourbucket 5 | 6 | production: 7 | aws_access_key: DEF456 8 | aws_secret_access_key: def456def456def456def456 9 | bucket_base_name: yourbucket 10 | -------------------------------------------------------------------------------- /gem/Rakefile: -------------------------------------------------------------------------------- 1 | # This rakefile is for building the EC2 on Rails gem. 2 | # To build a server AMI, see server/rakefile.rb 3 | 4 | begin 5 | require 'jeweler' 6 | Jeweler::Tasks.new do |gemspec| 7 | gemspec.name = "ec2onrails-experimental" 8 | gemspec.summary = "Client-side libraries (Capistrano tasks) for managing and deploying to EC2 on Rails servers." 9 | gemspec.description = <<-DESC.strip.gsub(/\n\s+/, " ") 10 | Deploy a Ruby on Rails app on EC2 in five minutes. 11 | EC2 on Rails is an Ubuntu Linux server image for Amazon EC2 that’s ready to run a standard 12 | Ruby on Rails application with little or no customization. 13 | It’s a Ruby on Rails virtual appliance. 14 | This gem contains Capistrano tasks to manage and deploy to an EC2 on Rails server instance. 15 | DESC 16 | if gemspec.name == "ec2onrails-experimental" 17 | experimental_warning = " *** This is the experimental, pre-release version.*** For the regular version install the gem 'ec2onrails'" 18 | gemspec.summary += experimental_warning 19 | gemspec.description += experimental_warning 20 | end 21 | gemspec.homepage = "http://ec2onrails.rubyforge.org" 22 | 23 | gemspec.authors = ['Paul Dowman', 'Adam Greene'] 24 | gemspec.email = "paul@pauldowman.com" 25 | 26 | gemspec.files.exclude 'server/**/*' 27 | gemspec.files.exclude 'test/**/*' 28 | 29 | gemspec.add_dependency('capistrano', '>= 2.5.3') 30 | gemspec.add_dependency('archive-tar-minitar', '>= 0.5.2') 31 | gemspec.add_dependency('optiflag', '>= 0.6.5') 32 | 33 | gemspec.rubyforge_project = gemspec.name 34 | Jeweler::RubyforgeTasks.new do |rubyforge| 35 | rubyforge.doc_task = "rdoc" 36 | end 37 | end 38 | Jeweler::GemcutterTasks.new 39 | rescue LoadError 40 | puts "Jeweler not available. Install it with: sudo gem install jeweler" 41 | end 42 | -------------------------------------------------------------------------------- /gem/VERSION: -------------------------------------------------------------------------------- 1 | 0.9.11 2 | -------------------------------------------------------------------------------- /gem/lib/ec2onrails.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | 20 | $:.unshift File.dirname(__FILE__) 21 | -------------------------------------------------------------------------------- /gem/lib/ec2onrails/capistrano_utils.rb: -------------------------------------------------------------------------------- 1 | module Ec2onrails 2 | module CapistranoUtils 3 | def run_local(command) 4 | result = system command 5 | raise("error: #{$?}") unless result 6 | end 7 | 8 | def run_init_script(script, arg) 9 | # TODO only restart a service if it's already started. 10 | # Aside from being smarter and more efficient, This will make sure we 11 | # aren't starting a service that shouldn't be started for the current 12 | # roles (e.g. don't start nginx when we're not in the web role) 13 | # How? Maybe need another param with the process name? 14 | sudo "/etc/init.d/#{script} #{arg}" 15 | end 16 | 17 | # return hostnames for the role named role_sym that has the specified options 18 | def hostnames_for_role(role_sym, options = {}) 19 | role = roles[role_sym] 20 | unless role 21 | return [] 22 | end 23 | # make sure we match the server with all the passed in options, BUT the server can 24 | # have additional options defined. e.g.: :primary => true and :ebs_vol_id => 'vol-1234abcd' 25 | # but we want to select the server where :primary => true 26 | role.select{|s| 27 | match = true 28 | options.each_pair{|k,v| match = false if s.options[k] != v} 29 | }.collect{|s| s.host} 30 | end 31 | 32 | # Like the capture method, but does not print out error stream and swallows 33 | # an exception if the process's exit code != 0 34 | # NOTE: this only executes on the first server in the list. Don't use this 35 | # to execute a task that has a side-effect (i.e. something that needs to be 36 | # run on all servers). 37 | def quiet_capture(command, options={}) 38 | output = "" 39 | invoke_command(command, options.merge(:once => true)) do |ch, stream, data| 40 | case stream 41 | when :out then output << data 42 | # when :err then warn "[err :: #{ch[:server]}] #{data}" 43 | end 44 | end 45 | ensure 46 | return (output || '').strip 47 | end 48 | 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /gem/lib/ec2onrails/recipes.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'fileutils' 20 | include FileUtils 21 | require 'tmpdir' 22 | require 'pp' 23 | require 'zlib' 24 | require 'archive/tar/minitar' 25 | include Archive::Tar 26 | 27 | require 'ec2onrails/version_helper' 28 | require 'ec2onrails/capistrano_utils' 29 | include Ec2onrails::CapistranoUtils 30 | 31 | 32 | 33 | Dir[File.join(File.dirname(__FILE__), "recipes/*")].find_all{|x| File.file? x}.each do |recipe| 34 | require recipe 35 | end 36 | 37 | 38 | Capistrano::Configuration.instance.load do 39 | 40 | unless ec2onrails_config 41 | raise "ec2onrails_config variable not set. (It should be a hash.)" 42 | end 43 | 44 | cfg = ec2onrails_config 45 | 46 | set :ec2onrails_version, Ec2onrails::VersionHelper.string 47 | set :deploy_to, "/mnt/app" 48 | set :use_sudo, false 49 | set :user, "app" 50 | 51 | # in case anyone is still using deploy:cold 52 | before "deploy:cold", "ec2onrails:setup" 53 | 54 | after "deploy:symlink", "ec2onrails:server:set_roles", "ec2onrails:server:init_services" 55 | after "deploy:symlink", "ec2onrails:server:purge_proxy_cache" 56 | 57 | on :load do 58 | before "deploy:symlink", "ec2onrails:server:run_rails_rake_gems_install" 59 | before "deploy:symlink", "ec2onrails:server:install_system_files" 60 | end 61 | 62 | 63 | namespace :ec2onrails do 64 | desc <<-DESC 65 | Show the AMI id's of the current images for this version of \ 66 | EC2 on Rails. 67 | DESC 68 | task :ami_ids do 69 | puts "32-bit server image (US location) for EC2 on Rails #{ec2onrails_version}: #{Ec2onrails::VersionHelper.ami_ids["us"]["32bit"]}" 70 | puts "64-bit server image (US location) for EC2 on Rails #{ec2onrails_version}: #{Ec2onrails::VersionHelper.ami_ids["us"]["64bit"]}" 71 | puts "32-bit server image (EU location) for EC2 on Rails #{ec2onrails_version}: #{Ec2onrails::VersionHelper.ami_ids["eu"]["32bit"]}" 72 | puts "64-bit server image (EU location) for EC2 on Rails #{ec2onrails_version}: #{Ec2onrails::VersionHelper.ami_ids["eu"]["64bit"]}" 73 | end 74 | 75 | desc <<-DESC 76 | Copies the public key from the server using the external "ssh" 77 | command because Net::SSH, which is used by Capistrano, needs it. 78 | This will only work if you have an ssh command in the path. 79 | If Capistrano can successfully connect to your EC2 instance you 80 | don't need to do this. It will copy from one of the servers 81 | at random, this can be overridden by specifying the HOST 82 | environment variable 83 | DESC 84 | task :get_public_key_from_server do 85 | host = find_servers_for_task(current_task).first.host 86 | privkey = ssh_options[:keys][0] 87 | pubkey = "#{privkey}.pub" 88 | msg = <<-MSG 89 | Your first key in ssh_options[:keys] is #{privkey}, presumably that's 90 | your EC2 private key. The public key will be copied from the server 91 | named '#{host}' and saved locally as #{pubkey}. Continue? [y/n] 92 | MSG 93 | choice = nil 94 | while choice != "y" && choice != "n" 95 | choice = Capistrano::CLI.ui.ask(msg).downcase 96 | msg = "Please enter 'y' or 'n'." 97 | end 98 | if choice == "y" 99 | run_local "scp -i '#{privkey}' app@#{host}:.ssh/authorized_keys #{pubkey}" 100 | end 101 | end 102 | 103 | desc <<-DESC 104 | Prepare a newly-started instance for a cold deploy. 105 | DESC 106 | task :setup do 107 | # we now have some things being included inside the app so we deploy 108 | # the app's code to the server before we do any other setup 109 | server.upload_deploy_keys 110 | deploy.setup 111 | deploy.update_code 112 | 113 | ec2onrails.server.allow_sudo do 114 | server.set_timezone 115 | server.set_mail_forward_address 116 | server.install_packages 117 | server.install_gems 118 | server.run_rails_rake_gems_install 119 | server.deploy_files # DEPRECATED, see install_system_files 120 | server.install_system_files 121 | server.set_roles 122 | server.enable_ssl if cfg[:enable_ssl] 123 | server.set_rails_env 124 | server.restart_services 125 | db.create 126 | server.harden_server 127 | db.enable_ebs 128 | db.set_root_password 129 | end 130 | end 131 | 132 | end 133 | end 134 | 135 | 136 | -------------------------------------------------------------------------------- /gem/lib/ec2onrails/recipes/deploy.rb: -------------------------------------------------------------------------------- 1 | Capistrano::Configuration.instance(:must_exist).load do 2 | 3 | # Override default start/stop/restart tasks for Passenger 4 | namespace :deploy do 5 | desc <<-DESC 6 | Overrides the default Capistrano deploy:start. 7 | DESC 8 | task :start, :roles => :web do 9 | run "touch #{current_release}/tmp/restart.txt" 10 | end 11 | 12 | desc <<-DESC 13 | Overrides the default Capistrano deploy:stop. 14 | DESC 15 | task :stop, :roles => :web do 16 | # Do nothing, 17 | end 18 | 19 | desc <<-DESC 20 | Overrides the default Capistrano deploy:restart. 21 | DESC 22 | task :restart, :roles => :web do 23 | run "touch #{current_release}/tmp/restart.txt" 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /gem/lib/ec2onrails/version_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require "yaml" 20 | 21 | module Ec2onrails 22 | module VersionHelper 23 | ROOT_DIR = File.dirname(__FILE__) + "/../.." 24 | 25 | def self.string 26 | File.read(ROOT_DIR + "/VERSION").strip 27 | end 28 | 29 | def self.ami_ids 30 | YAML::load_file(ROOT_DIR + "/ami_ids.yml") 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /server/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script wraps Eric Hammond's ec2ubuntu-build-ami script ( http://alestic.com/ ) 23 | # It passes all args directly to the ec2ubuntu-build-ami script, except for three 24 | # which it modifies to the following values: 25 | # --distribution ubuntu 26 | # --codename intrepid 27 | # --script /mnt/ec2onrails/server/rakefile-wrapper 28 | # Other than those three args (which will be ignored if given) this script should 29 | # be given the regular ec2ubuntu-build-ami args, for details see the comments at: 30 | # http://ec2ubuntu.googlecode.com/svn/trunk/bin/ec2ubuntu-build-ami 31 | 32 | require "fileutils" 33 | 34 | EC2UBUNTU_VERSION = 148 35 | 36 | unless File.exist? "/mnt/ec2ubuntu" 37 | puts "Installing yum..." 38 | system "yum install svn -y" 39 | end 40 | 41 | puts "Getting ec2ubuntu build script..." 42 | system "svn checkout -r #{EC2UBUNTU_VERSION} http://ec2ubuntu.googlecode.com/svn/trunk/ /mnt/ec2ubuntu" 43 | 44 | unless system "which rake" 45 | puts "Installing rake..." 46 | 47 | FileUtils.cd "/tmp" do 48 | system "wget http://rubyforge.org/frs/download.php/29752/rake-0.8.1.tgz" 49 | system "tar xvf rake-0.8.1.tgz" 50 | end 51 | FileUtils.cd "/tmp/rake-0.8.1" do 52 | system "ruby install.rb" 53 | end 54 | end 55 | 56 | # copy all args except the ones we want to overwrite into a new array 57 | ec2ubuntu_args = [] 58 | (0..(ARGV.size-1)).to_a.delete_if{|n| n%2!=0}.each do |n| 59 | unless %w(--distribution --codename --script).include? ARGV[n] 60 | ec2ubuntu_args << ARGV[n] 61 | ec2ubuntu_args << ARGV[n+1] 62 | end 63 | end 64 | 65 | # Call Eric Hammond's build script, passing it all the args that this script was given, 66 | # except with our own values for distribution, codename, and script 67 | system <<-EOS 68 | /mnt/ec2ubuntu/bin/ec2ubuntu-build-ami \ 69 | --distribution ubuntu \ 70 | --codename jaunty \ 71 | --script /mnt/ec2onrails/server/rakefile-wrapper \ 72 | #{ec2ubuntu_args.join(' ')} 73 | EOS 74 | 75 | -------------------------------------------------------------------------------- /server/files/etc/README: -------------------------------------------------------------------------------- 1 | You can place ERB templates anywhere under /etc and the set_roles script will 2 | process them. 3 | 4 | An ERB file named /etc/something.erb will generate an output file named 5 | /etc/something 6 | 7 | TODO document variables that are available inside the templates -------------------------------------------------------------------------------- /server/files/etc/aliases: -------------------------------------------------------------------------------- 1 | # See man 5 aliases for format 2 | 3 | # send all mail to root user. 4 | postmaster: root 5 | app: root 6 | -------------------------------------------------------------------------------- /server/files/etc/cron.d/ec2onrails: -------------------------------------------------------------------------------- 1 | # 2 | # different backup strategies depending on whether the db instance is using Amazon's EBS 3 | # 4 | 5 | # without EBS: 6 | # Incremental backup every 5 minutes 7 | */5 * * * * root test ! -f /etc/mysql/conf.d/mysql-ec2-ebs.cnf && /usr/local/ec2onrails/bin/backup_app_db --incremental 8 | 9 | # without EBS: 10 | # Full backup every day at 05:01, reset the binary logs. 11 | # First kill any incremental backup that happens to be in progress 12 | 1 5 * * * root killall -q -u root backup_app_db ; test ! -f /etc/mysql/conf.d/mysql-ec2-ebs.cnf && /usr/local/ec2onrails/bin/backup_app_db --reset 13 | 14 | # with EBS: 15 | # Full snapshot every 2 hours 16 | 11 */2 * * * root test -f /etc/mysql/conf.d/mysql-ec2-ebs.cnf && /usr/local/ec2onrails/bin/backup_app_db 17 | -------------------------------------------------------------------------------- /server/files/etc/cron.daily/app: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #NOTE: you can also call 4 | # /usr/local/ec2onrails/bin/exec_runner 5 | # to run a script under a specific role 6 | # see the file for details 7 | 8 | if test -e /mnt/app/current; then 9 | cd /mnt/app/current 10 | 11 | if test -e /mnt/app/current/script/cron/daily; then 12 | if test -f /mnt/app/current/script/cron/daily; then 13 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/cron/daily; 14 | else 15 | for f in script/cron/daily/*; do 16 | if test -f $f; then 17 | sudo -u app /usr/local/ec2onrails/bin/rails_env $f 18 | fi 19 | done 20 | fi 21 | exit 0; 22 | fi 23 | 24 | #DEPRECATED: just for old usage.... 25 | if test -e /mnt/app/current/script/daily 26 | then 27 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/daily 28 | exit 0; 29 | fi 30 | 31 | fi 32 | -------------------------------------------------------------------------------- /server/files/etc/cron.daily/logrotate_post: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | RAILS_ENV=`/usr/local/ec2onrails/bin/rails_env` 4 | 5 | if [ -x /mnt/app/current ] ; then 6 | logfile=/mnt/app/current/log/$RAILS_ENV.log-`date +%Y%m%d` 7 | if [ -e $logfile ] ; then 8 | gzip -c $logfile > $logfile.gz 9 | /usr/local/ec2onrails/bin/archive_file --file $logfile.gz --dir logs/rails && rm $logfile.gz 10 | fi 11 | fi 12 | 13 | if [ -e /mnt/log/nginx/access.log ] ; then 14 | for f in `ls /mnt/log/nginx/*.log` ; do 15 | logfile=$f-`date +%Y%m%d` 16 | if [ -e $logfile ] ; then 17 | gzip -c $logfile > $logfile.gz 18 | /usr/local/ec2onrails/bin/archive_file --file $logfile.gz --dir logs/nginx && rm $logfile.gz 19 | fi 20 | done 21 | fi 22 | 23 | logfile=/mnt/log/varnish/varnishncsa.log-`date +%Y%m%d` 24 | if [ -e $logfile ] ; then 25 | gzip -c $logfile > $logfile.gz 26 | /usr/local/ec2onrails/bin/archive_file --file $logfile.gz --dir logs/varnish && rm $logfile.gz 27 | fi 28 | 29 | logfile=/mnt/log/god/god.log-`date +%Y%m%d` 30 | if [ -e $logfile ] ; then 31 | gzip -c $logfile > $logfile.gz 32 | /usr/local/ec2onrails/bin/archive_file --file $logfile.gz --dir logs/god && rm $logfile.gz 33 | fi 34 | -------------------------------------------------------------------------------- /server/files/etc/cron.hourly/app: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #NOTE: you can also call 4 | # /usr/local/ec2onrails/bin/exec_runner 5 | # to run a script under a specific role 6 | # see the file for details 7 | 8 | if test -e /mnt/app/current; then 9 | cd /mnt/app/current 10 | 11 | if test -e /mnt/app/current/script/cron/hourly; then 12 | if test -f /mnt/app/current/script/cron/hourly; then 13 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/cron/hourly; 14 | else 15 | for f in script/cron/hourly/*; do 16 | if test -f $f; then 17 | sudo -u app /usr/local/ec2onrails/bin/rails_env $f 18 | fi 19 | done 20 | fi 21 | exit 0; 22 | fi 23 | 24 | #DEPRECATED: just for old usage.... 25 | if test -e /mnt/app/current/script/hourly 26 | then 27 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/hourly 28 | exit 0; 29 | fi 30 | 31 | fi 32 | -------------------------------------------------------------------------------- /server/files/etc/cron.monthly/app: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #NOTE: you can also call 4 | # /usr/local/ec2onrails/bin/exec_runner 5 | # to run a script under a specific role 6 | # see the file for details 7 | 8 | if test -e /mnt/app/current; then 9 | cd /mnt/app/current 10 | 11 | if test -e /mnt/app/current/script/cron/monthly; then 12 | if test -f /mnt/app/current/script/cron/monthly; then 13 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/cron/monthly; 14 | else 15 | for f in script/cron/monthly/*; do 16 | if test -f $f; then 17 | sudo -u app /usr/local/ec2onrails/bin/rails_env $f 18 | fi 19 | done 20 | fi 21 | exit 0; 22 | fi 23 | 24 | #DEPRECATED: just for old usage.... 25 | if test -e /mnt/app/current/script/monthly 26 | then 27 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/monthly 28 | exit 0; 29 | fi 30 | 31 | fi 32 | -------------------------------------------------------------------------------- /server/files/etc/cron.weekly/app: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #NOTE: you can also call 4 | # /usr/local/ec2onrails/bin/exec_runner 5 | # to run a script under a specific role 6 | # see the file for details 7 | 8 | if test -e /mnt/app/current; then 9 | cd /mnt/app/current 10 | 11 | if test -e /mnt/app/current/script/cron/weekly; then 12 | if test -f /mnt/app/current/script/cron/weekly; then 13 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/cron/weekly; 14 | else 15 | for f in script/cron/weekly/*; do 16 | if test -f $f; then 17 | sudo -u app /usr/local/ec2onrails/bin/rails_env $f 18 | fi 19 | done 20 | fi 21 | exit 0; 22 | fi 23 | 24 | #DEPRECATED: just for old usage.... 25 | if test -e /mnt/app/current/script/weekly 26 | then 27 | sudo -u app /usr/local/ec2onrails/bin/rails_env script/weekly 28 | exit 0; 29 | fi 30 | 31 | fi 32 | -------------------------------------------------------------------------------- /server/files/etc/default/varnish: -------------------------------------------------------------------------------- 1 | # Configuration file for varnish 2 | # 3 | # /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK 4 | # to be set from this shell script fragment. 5 | # 6 | 7 | # Maximum number of open files (for ulimit -n) 8 | NFILES=131072 9 | 10 | # Maximum locked memory size (for ulimit -l) 11 | # Used for locking the shared memory log in memory. If you increase log size, 12 | # you need to increase this number as well 13 | MEMLOCK=82000 14 | 15 | # Default varnish instance name is the local nodename. Can be overridden with 16 | # the -n switch, to have more instances on a single server. 17 | INSTANCE=$(uname -n) 18 | 19 | 20 | # Listen on port 80, administration on localhost:6082, and forward to 21 | # one content server selected by the vcl file, based on the request. 22 | 23 | # Use a 256 MB fixed-size cache file. 24 | # TODO figure out how to configure this so that the varnishd process 25 | # doesn't grow so large because we have little or no swap (or add 26 | # more swap space) 27 | # 28 | # TODO pre-allocate the storage space using dd 29 | # 30 | DAEMON_OPTS="-a :80 \ 31 | -T localhost:6082 \ 32 | -f /etc/varnish/default.vcl \ 33 | -s file,/mnt/varnish/varnish_storage.bin,256M" 34 | -------------------------------------------------------------------------------- /server/files/etc/default/varnishncsa: -------------------------------------------------------------------------------- 1 | # Configuration file for varnishncsa 2 | # 3 | # Uncomment this to enable logging for varnish. Please make sure you have 4 | # enough disk space for significant amounts of log data. To disable logging, 5 | # set the variable to "0", "no", or leave it unset. 6 | # 7 | # NCSA log format, to be used by HTTP log analyzers 8 | VARNISHNCSA_ENABLED=1 9 | 10 | LOGFILE=/mnt/log/varnish/varnishncsa.log 11 | 12 | -------------------------------------------------------------------------------- /server/files/etc/dpkg/dpkg.cfg: -------------------------------------------------------------------------------- 1 | # dpkg configuration file 2 | # 3 | # This file can contain default options for dpkg. All command-line 4 | # options are allowed. Values can be specified by putting them after 5 | # the option, separated by whitespace and/or an `=' sign. 6 | # 7 | 8 | # ec2onrails note: if we have a config file already up here, we want to use 9 | # that over the packages default. 10 | force-confold 11 | 12 | # Log status changes and actions to a file. 13 | log /var/log/dpkg.log 14 | -------------------------------------------------------------------------------- /server/files/etc/ec2onrails/rails_env: -------------------------------------------------------------------------------- 1 | production -------------------------------------------------------------------------------- /server/files/etc/ec2onrails/roles.yml: -------------------------------------------------------------------------------- 1 | --- 2 | :memcache: 3 | :db_primary: 4 | :web: 5 | :proxy: 6 | -------------------------------------------------------------------------------- /server/files/etc/environment: -------------------------------------------------------------------------------- 1 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/ec2onrails/bin" 2 | RUBYLIB=/usr/lib/ruby/1.8:/usr/local/lib/1.8/i486-linux:/usr/lib/site_ruby 3 | -------------------------------------------------------------------------------- /server/files/etc/event.d/god: -------------------------------------------------------------------------------- 1 | description "god monitoring daemon" 2 | 3 | start on runlevel [2345] 4 | stop on runlevel [06] 5 | 6 | exec /usr/bin/god -D -c /etc/god/master.conf -l /mnt/log/god/god.log --log-level error --no-syslog 7 | 8 | respawn 9 | -------------------------------------------------------------------------------- /server/files/etc/god/db_primary.god: -------------------------------------------------------------------------------- 1 | God.watch do |w| 2 | w.name = 'mysql' 3 | w.group = 'db_primary' 4 | w.autostart = false 5 | 6 | w.start = "/etc/init.d/mysql start" 7 | w.stop = "/etc/init.d/mysql stop" 8 | w.restart = "/etc/init.d/mysql restart" 9 | 10 | w.pid_file = "/var/run/mysqld/mysqld.pid" 11 | 12 | default_configurations(w) 13 | w.grace = 60.seconds 14 | 15 | restart_if_resource_hog(w, :memory_usage => false) 16 | end 17 | -------------------------------------------------------------------------------- /server/files/etc/god/dkim_filter.god: -------------------------------------------------------------------------------- 1 | if File.exists?('/etc/init.d/dkim-filter') 2 | #we have it installed, so lets register it with God 3 | God.watch do |w| 4 | w.name = 'dkim_filter' 5 | w.group = 'app' 6 | w.autostart = false 7 | 8 | w.start = "/etc/init.d/dkim-filter start" 9 | w.stop = "/etc/init.d/dkim-filter stop" 10 | w.restart = "/etc/init.d/dkim-filter restart" 11 | 12 | w.pid_file = "/var/run/dkim-filter/dkim-filter.pid" 13 | 14 | default_configurations(w) 15 | restart_if_resource_hog(w, :memory_usage => 20.megabytes, :cpu_usage => 10.percent) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /server/files/etc/god/master.conf: -------------------------------------------------------------------------------- 1 | # For TextMate users, change the language type (at bottom of window, next to line/column counter, to ruby) 2 | # 3 | 4 | # TODO move to event-based config 5 | 6 | applog(nil, :info, "loading /etc/god/master.conf") 7 | 8 | require '/usr/local/ec2onrails/lib/god_helper' 9 | require '/usr/local/ec2onrails/lib/roles_helper' 10 | require '/usr/local/ec2onrails/lib/utils' 11 | require "fileutils" 12 | 13 | include GodHelper 14 | include Ec2onrails::RolesHelper 15 | 16 | APP_ROOT = "/mnt/app/current" 17 | 18 | @configs = GodHelper::Configs.new 19 | 20 | God.pid_file_directory = "/var/run/god" 21 | 22 | applog(nil, :info, "About to load system configs at /etc/god/*.god") 23 | God.load "/etc/god/*.god" 24 | 25 | applog(nil, :info, "About to load application-specific configs at #{APP_ROOT}/config/god/*.god") 26 | God.load "#{APP_ROOT}/config/god/*.god" 27 | 28 | 29 | # at the end, we want to init the correct services 30 | # need to put it into a thread because god is not finished 31 | # initalizing at this point, so we need to let it finish 32 | # so we can call init_services, which calls god directly 33 | # 34 | # using a fork copies over the processing space, causing 35 | # god to reload again..and again...and again... 36 | Thread.new do 37 | sleep(2) 38 | applog(nil, :info, "initializing services....") 39 | system("/usr/local/ec2onrails/bin/init_services") 40 | end 41 | -------------------------------------------------------------------------------- /server/files/etc/god/memcache.god: -------------------------------------------------------------------------------- 1 | God.watch do |w| 2 | w.name = "memcached" 3 | w.group = 'memcache' 4 | w.autostart = false 5 | 6 | w.start = "/etc/init.d/memcached start" 7 | w.stop = "/etc/init.d/memcached stop" 8 | w.restart = "/etc/init.d/memcached restart" 9 | w.pid_file = "/var/run/memcached.pid" 10 | 11 | default_configurations(w) 12 | w.grace = 10.seconds 13 | 14 | restart_if_resource_hog(w, :memory_usage => false) 15 | end 16 | -------------------------------------------------------------------------------- /server/files/etc/god/notifications.god: -------------------------------------------------------------------------------- 1 | God::Contacts::Email.message_settings = { 2 | :from => 'root@localhost' 3 | } 4 | 5 | God::Contacts::Email.delivery_method = :sendmail 6 | 7 | God.contact(:email) do |c| 8 | c.name = 'root' 9 | c.email = 'root@localhost' 10 | c.group = 'default' 11 | end 12 | -------------------------------------------------------------------------------- /server/files/etc/god/proxy.god: -------------------------------------------------------------------------------- 1 | God.watch do |w| 2 | w.name = "varnish" 3 | w.group = "proxy" 4 | w.autostart = false 5 | 6 | w.start = "/etc/init.d/varnish start" 7 | w.stop = "/etc/init.d/varnish stop" 8 | w.restart = "/etc/init.d/varnish restart" 9 | w.pid_file = "/var/run/varnishd.pid" 10 | w.grace = 10.seconds 11 | 12 | default_configurations(w) 13 | 14 | # I'm not sure if it's very useful to monitor the varnishd memory usage, 15 | # because it writes the pid of the varnishd parent process in it's pid file, 16 | # so I assume that's what god is monitoring, and the varnishd parent starts 17 | # a child process to do the real work. 18 | # Also, the child process allocates all cache storage with malloc, so the 19 | # VSS size can get very large and depends on the amount of storage 20 | # configured. It relies on the OS to page unused portions to disk, but at 21 | # the moment we don't have much swap configured (just using the defaults 22 | # from Eric Hammond's base image). 23 | restart_if_resource_hog(w, :memory_usage => 100.megabytes, :cpu_usage => 50.percent) 24 | end 25 | 26 | God.watch do |w| 27 | w.name = "varnishncsa" 28 | w.group = "proxy" 29 | w.autostart = false 30 | 31 | w.start = "/etc/init.d/varnishncsa start" 32 | w.stop = "/etc/init.d/varnishncsa stop" 33 | w.restart = "/etc/init.d/varnishncsa restart" 34 | w.pid_file = "/var/run/varnishncsa.pid" 35 | w.grace = 10.seconds 36 | 37 | default_configurations(w) 38 | 39 | restart_if_resource_hog(w, :memory_usage => 100.megabytes, :cpu_usage => 50.percent) 40 | end 41 | -------------------------------------------------------------------------------- /server/files/etc/god/system.god: -------------------------------------------------------------------------------- 1 | God.watch do |w| 2 | w.name = "system-checks" 3 | w.start = true 4 | w.interval = 10.minutes 5 | 6 | 7 | w.behavior(:clean_pid_file) 8 | 9 | 10 | # lifecycle 11 | w.lifecycle do |on| 12 | on.condition(:disk_usage) do |c| 13 | c.mount_point = "/" 14 | c.above = 75 15 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 16 | end 17 | 18 | on.condition(:disk_usage) do |c| 19 | c.mount_point = "/mnt" 20 | c.above = 75 21 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 22 | end 23 | 24 | on.condition(:memory_usage) do |c| 25 | c.above = 80.percent 26 | c.times = [3, 5] # 3 out of 5 intervals 27 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 28 | end 29 | 30 | on.condition(:cpu_usage) do |c| 31 | c.above = 90.percent 32 | c.times = [5, 8] 33 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 34 | end 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /server/files/etc/god/web.god: -------------------------------------------------------------------------------- 1 | God.watch do |w| 2 | w.name = "nginx" 3 | w.group = 'web' 4 | 5 | w.start = "/etc/init.d/nginx start" 6 | w.stop = "/etc/init.d/nginx stop" 7 | w.restart = "/etc/init.d/nginx restart" 8 | w.pid_file = "/var/run/nginx.pid" 9 | w.autostart = false 10 | 11 | default_configurations(w) 12 | 13 | restart_if_resource_hog(w, :memory_usage => 250.megabytes) do |restart| 14 | restart.condition(:http_response_code) do |c| 15 | c.host = '127.0.0.1' 16 | c.port = in_role?(:proxy) ? 81 : 80 17 | c.path = '/nginx_status' 18 | c.code_is_not = 200 19 | c.timeout = 5.seconds 20 | c.times = [3, 5] # 3 out of 5 intervals 21 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /server/files/etc/init.d/ec2-every-startup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script runs the ec2 startup scripts 23 | 24 | # this is an ugly hack to make sure DHCP initialization is finished: 25 | sleep 15 26 | 27 | for SCRIPT in `ls -I README /usr/local/ec2onrails/startup-scripts/every-startup` ; do 28 | "/usr/local/ec2onrails/startup-scripts/every-startup/$SCRIPT" 29 | done 30 | -------------------------------------------------------------------------------- /server/files/etc/init.d/ec2-first-startup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script runs the ec2 startup scripts 23 | 24 | FILE=/mnt/.ec2onrails-first-boot 25 | 26 | if [ ! -e $FILE ] ; then 27 | 28 | # TODO improve this: 29 | # this is an ugly hack to make sure DHCP initialization is finished: 30 | sleep 15 31 | 32 | for SCRIPT in `ls -I README /usr/local/ec2onrails/startup-scripts/first-startup` ; do 33 | "/usr/local/ec2onrails/startup-scripts/first-startup/$SCRIPT" 34 | done 35 | 36 | touch $FILE 37 | fi 38 | -------------------------------------------------------------------------------- /server/files/etc/init.d/nginx: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #This is a start script for nginx. Tested on Unbuntu Edge. 4 | #Should work on Ubuntu, Debian and probably a few other Linux distros. 5 | #Change DAEMON and CONFIG_FILE if neccessary 6 | 7 | PATH=/sbin:/bin:/usr/sbin:/usr/bin 8 | 9 | 10 | #Location of nginx binary. Change path as neccessary 11 | DAEMON=/usr/sbin/nginx 12 | # DAEMON=/usr/local/nginx/sbin/nginx 13 | #Location of configuration file. Change path as neccessary 14 | CONFIG_FILE=/etc/nginx/nginx.conf 15 | # CONFIG_FILE=/usr/local/nginx/conf/nginx.conf 16 | 17 | 18 | DAEMON_OPTS="-c $CONFIG_FILE" 19 | NAME=nginx 20 | DESC="web server" 21 | PIDFILE=/var/run/$NAME.pid 22 | SCRIPTNAME=/etc/init.d/$NAME 23 | 24 | 25 | #only run if binary can be found 26 | test -x $DAEMON || exit 0 27 | 28 | set -e 29 | 30 | #import init-functions 31 | . /lib/lsb/init-functions 32 | 33 | case "$1" in 34 | start) 35 | log_daemon_msg "Starting $DESC" $NAME 36 | if ! start-stop-daemon --start --quiet\ 37 | --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS ; then 38 | log_end_msg 1 39 | else 40 | log_end_msg 0 41 | fi 42 | ;; 43 | stop) 44 | log_daemon_msg "Stopping $DESC" $NAME 45 | if start-stop-daemon --quiet --stop --oknodo --retry 30\ 46 | --pidfile $PIDFILE --exec $DAEMON; then 47 | rm -f $PIDFILE 48 | log_end_msg 0 49 | else 50 | log_end_msg 1 51 | fi 52 | ;; 53 | reload) 54 | log_daemon_msg "Reloading $DESC configuration" $NAME 55 | if start-stop-daemon --stop --signal 2 --oknodo --retry 30\ 56 | --quiet --pidfile $PIDFILE --exec $DAEMON; then 57 | if start-stop-daemon --start --quiet \ 58 | --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS ; then 59 | log_end_msg 0 60 | else 61 | log_end_msg 1 62 | fi 63 | else 64 | log_end_msg 1 65 | fi 66 | ;; 67 | restart|force-reload) 68 | $0 stop 69 | sleep 1 70 | $0 start 71 | ;; 72 | *) 73 | echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 74 | exit 1 75 | ;; 76 | esac 77 | 78 | exit 0 -------------------------------------------------------------------------------- /server/files/etc/logrotate.d/god: -------------------------------------------------------------------------------- 1 | # Rotate God log 2 | /mnt/log/god/god.log { 3 | daily 4 | rotate 7 5 | missingok 6 | dateext 7 | copytruncate 8 | } 9 | -------------------------------------------------------------------------------- /server/files/etc/logrotate.d/nginx: -------------------------------------------------------------------------------- 1 | /mnt/log/nginx/*.log { 2 | daily 3 | rotate 7 4 | missingok 5 | dateext 6 | sharedscripts 7 | postrotate 8 | if [ -f /var/run/nginx.pid ] ; then 9 | kill -USR1 `cat /var/run/nginx.pid` 10 | fi 11 | endscript 12 | } 13 | -------------------------------------------------------------------------------- /server/files/etc/logrotate.d/rails: -------------------------------------------------------------------------------- 1 | # Rotate Rails application logs 2 | /mnt/app/current/log/*.log { 3 | daily 4 | rotate 7 5 | missingok 6 | dateext 7 | copytruncate 8 | } 9 | -------------------------------------------------------------------------------- /server/files/etc/logrotate.d/varnish: -------------------------------------------------------------------------------- 1 | /mnt/log/varnish/varnish.log /mnt/log/varnish/varnishncsa.log { 2 | daily 3 | rotate 7 4 | missingok 5 | dateext 6 | sharedscripts 7 | postrotate 8 | for service in varnishlog varnishncsa; do 9 | if /usr/bin/pgrep -P 1 $service >/dev/null; then 10 | /usr/sbin/invoke-rc.d $service reload > /dev/null 11 | fi 12 | done 13 | endscript 14 | } 15 | -------------------------------------------------------------------------------- /server/files/etc/memcached.conf: -------------------------------------------------------------------------------- 1 | # memcached default config file 2 | # 2003 - Jay Bonci 3 | # This configuration file is read by the start-memcached script provided as 4 | # part of the Debian GNU/Linux distribution. 5 | 6 | # Run memcached as a daemon. This command is implied, and is not needed for the 7 | # daemon to run. See the README.Debian that comes with this package for more 8 | # information. 9 | -d 10 | 11 | # Log memcached's output to /var/log/memcached 12 | logfile /mnt/log/memcached.log 13 | 14 | # Be verbose 15 | # -v 16 | 17 | # Be even more verbose (print client commands as well) 18 | # -vv 19 | 20 | # Start with a cap of 64 megs of memory. It's reasonable, and the daemon default 21 | # Note that the daemon will grow to this size, but does not start out holding this much 22 | # memory 23 | -m 128 24 | 25 | # Default connection port is 11211 26 | -p 11211 27 | 28 | # Run the daemon as root. The start-memcached will default to running as root if no 29 | # -u command is present in this config file 30 | -u nobody 31 | 32 | # Specify which IP address to listen on. The default is to listen on all IP addresses 33 | # This parameter is one of the only security measures that memcached has, so make sure 34 | # it's listening on a firewalled interface. 35 | #-l 127.0.0.1 36 | 37 | # Limit the number of simultaneous incoming connections. The daemon default is 1024 38 | # -c 1024 39 | 40 | # Lock down all paged memory. Consult with the README and homepage before you do this 41 | # -k 42 | 43 | # Return error when memory is exhausted (rather than removing items) 44 | # -M 45 | 46 | # Maximize core file limit 47 | # -r -------------------------------------------------------------------------------- /server/files/etc/motd.tail: -------------------------------------------------------------------------------- 1 | 2 | EC2 on Rails 3 | !!VERSION!! 4 | http://rubyforge.org/projects/ec2onrails/ 5 | 6 | Copyright 2008 Paul Dowman, http://pauldowman.com/ 7 | 8 | Base AMI built using Eric Hammond's EC2 Ubuntu script: 9 | http://alestic.com/ 10 | 11 | This is free software, and you are welcome to redistribute it under 12 | certain conditions. This software comes with ABSOLUTELY NO WARRANTY. 13 | See /usr/local/ec2onrails/COPYING for details. 14 | -------------------------------------------------------------------------------- /server/files/etc/mysql/my.cnf: -------------------------------------------------------------------------------- 1 | # 2 | # The MySQL database server configuration file. 3 | # 4 | # You can copy this to one of: 5 | # - "/etc/mysql/my.cnf" to set global options, 6 | # - "~/.my.cnf" to set user-specific options. 7 | # 8 | # One can use all long options that the program supports. 9 | # Run program with --help to get a list of available options and with 10 | # --print-defaults to see which it would actually understand and use. 11 | # 12 | # For explanations see 13 | # http://dev.mysql.com/doc/mysql/en/server-system-variables.html 14 | 15 | # This will be passed to all mysql clients 16 | # It has been reported that passwords should be enclosed with ticks/quotes 17 | # escpecially if they contain "#" chars... 18 | # Remember to edit /etc/mysql/debian.cnf when changing the socket location. 19 | [client] 20 | port = 3306 21 | socket = /var/run/mysqld/mysqld.sock 22 | 23 | # Here is entries for some specific programs 24 | # The following values assume you have at least 32M ram 25 | 26 | # This was formally known as [safe_mysqld]. Both versions are currently parsed. 27 | [mysqld_safe] 28 | socket = /var/run/mysqld/mysqld.sock 29 | nice = 0 30 | 31 | [mysqld] 32 | # 33 | # * Basic Settings 34 | # 35 | user = mysql 36 | pid-file = /var/run/mysqld/mysqld.pid 37 | socket = /var/run/mysqld/mysqld.sock 38 | port = 3306 39 | basedir = /usr 40 | datadir = /mnt/mysql_data 41 | tmpdir = /mnt/mysql_data/tmp 42 | language = /usr/share/mysql/english 43 | skip-external-locking 44 | default-storage-engine = InnoDB 45 | character-set-server = utf8 46 | collation-server = utf8_general_ci 47 | 48 | # 49 | # Instead of skip-networking the default is now to listen only on 50 | # localhost which is more compatible and is not less secure. 51 | #bind-address = 127.0.0.1 52 | # 53 | # * Fine Tuning 54 | # 55 | key_buffer_size = 16M 56 | max_allowed_packet = 16M 57 | thread_stack = 128K 58 | thread_cache_size = 8 59 | #max_connections = 100 60 | #table_cache = 64 61 | #thread_concurrency = 10 62 | # 63 | # * Query Cache Configuration 64 | # 65 | query_cache_limit = 1M 66 | query_cache_size = 64M 67 | # 68 | # * Logging and Replication 69 | # 70 | # Both location gets rotated by the cronjob. 71 | # Be aware that this log type is a performance killer. 72 | #log = /var/log/mysql/mysql.log 73 | # 74 | # Error logging goes to syslog. This is a Debian improvement :) 75 | # 76 | # Here you can see queries with especially long duration 77 | log_slow_queries = /mnt/log/mysql/mysql-slow.log 78 | long_query_time = 1 79 | # log-queries-not-using-indexes 80 | # 81 | # The following can be used as easy to replay backup logs or for replication. 82 | #server-id = 1 83 | log_bin = /mnt/log/mysql/mysql-bin.log 84 | # WARNING: Using expire_logs_days without bin_log crashes the server! See README.Debian! 85 | expire_logs_days = 10 86 | max_binlog_size = 100M 87 | #binlog_do_db = include_database_name 88 | #binlog_ignore_db = include_database_name 89 | # 90 | # * BerkeleyDB 91 | # 92 | # Using BerkeleyDB is now discouraged as its support will cease in 5.1.12. 93 | skip-bdb 94 | # 95 | # * InnoDB 96 | # 97 | # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. 98 | # Read the manual for more InnoDB related options. There are many! 99 | # You might want to disable InnoDB to shrink the mysqld process by circa 100MB. 100 | #skip-innodb 101 | innodb_data_file_path=ibdata1:100M:autoextend 102 | innodb_buffer_pool_size=200M 103 | innodb_additional_mem_pool_size=20M 104 | innodb_log_file_size=128M 105 | innodb_log_buffer_size=8M 106 | innodb_flush_log_at_trx_commit=1 107 | innodb_lock_wait_timeout=20 108 | # innodb_flush_method=O_DIRECT 109 | innodb_file_per_table 110 | 111 | # 112 | # * Security Features 113 | # 114 | # Read the manual, too, if you want chroot! 115 | # chroot = /var/lib/mysql/ 116 | # 117 | # For generating SSL certificates I recommend the OpenSSL GUI "tinyca". 118 | # 119 | # ssl-ca=/etc/mysql/cacert.pem 120 | # ssl-cert=/etc/mysql/server-cert.pem 121 | # ssl-key=/etc/mysql/server-key.pem 122 | 123 | 124 | 125 | [mysqldump] 126 | quick 127 | quote-names 128 | max_allowed_packet = 16M 129 | 130 | [mysql] 131 | default-character-set = utf8 132 | #no-auto-rehash # faster start of mysql but no tab completition 133 | 134 | [isamchk] 135 | key_buffer = 16M 136 | 137 | # 138 | # * NDB Cluster 139 | # 140 | # See /usr/share/doc/mysql-server-*/README.Debian for more information. 141 | # 142 | # The following configuration is read by the NDB Data Nodes (ndbd processes) 143 | # not from the NDB Management Nodes (ndb_mgmd processes). 144 | # 145 | # [MYSQL_CLUSTER] 146 | # ndb-connectstring=127.0.0.1 147 | 148 | 149 | # 150 | # * IMPORTANT: Additional settings that can override those from this file! 151 | # 152 | !includedir /etc/mysql/conf.d/ 153 | -------------------------------------------------------------------------------- /server/files/etc/nginx/conf.d/custom.conf: -------------------------------------------------------------------------------- 1 | # Overwrite this file with any custom configuration, it gets included inside the server directive -------------------------------------------------------------------------------- /server/files/etc/nginx/nginx.conf.erb: -------------------------------------------------------------------------------- 1 | user nginx nginx; 2 | worker_processes 6; 3 | pid /var/run/nginx.pid; 4 | 5 | events { 6 | worker_connections 1024; 7 | use epoll; # linux only! 8 | } 9 | 10 | http { 11 | # global passenger settings 12 | passenger_root <%= `/usr/bin/passenger-config --root`.strip %>; 13 | passenger_default_user app; 14 | passenger_pool_idle_time 0; 15 | rails_framework_spawner_idle_time 0; 16 | rails_app_spawner_idle_time 0; 17 | 18 | # We leave passenger_max_pool_size at the default for now. (It might 19 | # eventually be an ERB variable that can be set automatically based on the 20 | # instance type and what roles it's in.) 21 | # passenger_max_pool_size 6; 22 | 23 | # We leave the rails_spawn_method at the default, but we might want a config setting 24 | # to allow it to be changed. 25 | # rails_spawn_method smart-lv2; 26 | 27 | include /etc/nginx/mime.types; 28 | 29 | # set a default type for the rare situation that 30 | # nothing matches from the mime-type include 31 | default_type application/octet-stream; 32 | 33 | # configure log format 34 | log_format main '$remote_addr [$time_local] ' 35 | '"$scheme $host $request" $status $body_bytes_sent "$http_referer" ' 36 | '"$http_user_agent" "$http_x_forwarded_for" ' 37 | '($request_time)'; 38 | 39 | access_log /mnt/log/nginx/access.log main; 40 | 41 | # main error log - Do not comment out. If you do not want the log file set this to /dev/null 42 | # use debug instead of notice if you want additional information 43 | error_log /mnt/log/nginx/error.log notice; 44 | 45 | sendfile on; 46 | 47 | tcp_nopush on; 48 | tcp_nodelay on; 49 | gzip on; 50 | gzip_http_version 1.1; 51 | gzip_vary on; 52 | gzip_comp_level 6; 53 | gzip_proxied any; 54 | gzip_types application/json application/x-javascript application/xhtml+xml application/xml application/xml+rss text/css text/javascript text/plain text/xml ; 55 | # make sure gzip does not lose large gzipped js or css files 56 | # see http://blog.leetsoft.com/2007/7/25/nginx-gzip-ssl 57 | gzip_buffers 16 8k; 58 | 59 | # Disable gzip for certain browsers. IE6 prior to SP2 doesn't handle gzip properly. 60 | gzip_disable “MSIE [1-6].(?!.*SV1)”; 61 | 62 | server { 63 | listen <%= roles[:proxy] && roles[:proxy].include?("127.0.0.1") ? 81 : 80 %>; 64 | server_name _; 65 | 66 | # server-specific passenger settings 67 | passenger_enabled on; 68 | passenger_use_global_queue on; 69 | rails_env <%= rails_env %>; 70 | 71 | # Set the max size for file uploads to 50Mb 72 | client_max_body_size 50M; 73 | 74 | # uncomment to force a redirect to www 75 | # if ($host ~* "^[ec2onrails].com$"){ 76 | # rewrite ^(.*)$ http://www.[ec2onrails].com$1 permanent; 77 | # break; 78 | # } 79 | 80 | # uncomment if you want to allow or force some or all pages to go to http:// instead of https:// 81 | # if redirecting all to https, you won't need any of the other directives below their rewrite/break 82 | # set $sub 'www'; 83 | # if ($host ~* "^(.+?)\.[ec2onrails].com$"){ 84 | # set $sub $1; 85 | # } 86 | # 87 | # if ( $uri ~* "^/.+$") { 88 | # rewrite ^(.*)$ https://$sub.[ec2onrails].com$1 permanent; 89 | # break; 90 | # } 91 | 92 | root /mnt/app/current/public; 93 | 94 | error_page 400 /400.html; 95 | error_page 500 502 504 /500.html; 96 | location = /500.html { 97 | root /mnt/app/current/public; 98 | } 99 | 100 | #hide hidden files and folders 101 | location ~ /\..+ { 102 | deny all; 103 | } 104 | 105 | #do not show the nginx version number in the server header 106 | server_tokens off; 107 | 108 | # this allows people to use images and css in their maintenance.html file 109 | if ($request_filename ~* \.(css|jpg|gif|png)$) { 110 | break; 111 | } 112 | 113 | # this allows the /nginx_status page to work, even if the maintenance 114 | # page is up. 115 | if ($uri ~* "^/nginx_status") { 116 | break; 117 | } 118 | 119 | # this allows a url /warmup that can be used to cause Passenger to 120 | # restart after restart.txt has been touched, even if the maintenance 121 | # page is up. 122 | if ($uri ~* "^/warmup") { 123 | break; 124 | } 125 | 126 | # this rewrites all the requests to the maintenance.html 127 | # page if it exists in the doc root. This is for capistrano's 128 | # disable web task 129 | if (-f $document_root/system/maintenance.html) { 130 | return 503; 131 | } 132 | error_page 503 @503; 133 | location @503 { 134 | rewrite ^(.*)$ /system/maintenance.html break; 135 | } 136 | 137 | 138 | # see http://wiki.codemongers.com/NginxHttpStubStatusModule 139 | # for more information 140 | location /nginx_status { 141 | # copied from http://blog.kovyrin.net/2006/04/29/monitoring-nginx-with-rrdtool/ 142 | stub_status on; 143 | access_log off; 144 | #only allow from localhost 145 | allow 127.0.0.1; 146 | deny all; 147 | } 148 | 149 | include /etc/nginx/conf.d/*.conf; 150 | } 151 | 152 | # This server is setup for ssl. Uncomment if 153 | # you are using ssl as well as port 80. 154 | # server { 155 | # # port to listen on. Can also be set to an IP:PORT 156 | # listen 443; 157 | # 158 | # ssl on; 159 | # ssl_certificate /etc/nginx/your_cert.crt; 160 | # ssl_certificate_key /etc/nginx/your_cert.key; 161 | # 162 | # TODO SSL support 163 | # 164 | # } 165 | } 166 | -------------------------------------------------------------------------------- /server/files/etc/postfix/main.cf: -------------------------------------------------------------------------------- 1 | mynetworks_style = host 2 | relay_domains = 3 | inet_interfaces = 127.0.0.1 4 | alias_maps = hash:/etc/aliases 5 | -------------------------------------------------------------------------------- /server/files/etc/ssh/sshd_config: -------------------------------------------------------------------------------- 1 | # Package generated configuration file 2 | # See the sshd(8) manpage for details 3 | 4 | # HARDEN OpenSSH TODO's 5 | # * specify AllowUsers 6 | # * PermitRootLogin no # turn off root login access 7 | # to do that, we will probably need to create a non-root user to escalate 8 | # privileges to from capistrano, like 'admin' 9 | # * change default port to something other than 22 10 | 11 | # What ports, IPs and protocols we listen for 12 | Port 22 13 | # Use these options to restrict which interfaces/protocols sshd will bind to 14 | #ListenAddress :: 15 | #ListenAddress 0.0.0.0 16 | Protocol 2 17 | # HostKeys for protocol version 2 18 | HostKey /etc/ssh/ssh_host_rsa_key 19 | HostKey /etc/ssh/ssh_host_dsa_key 20 | #Privilege Separation is turned on for security 21 | UsePrivilegeSeparation yes 22 | 23 | # Enable to harden the ssh host 24 | # AllowUsers admin app 25 | 26 | # Lifetime and size of ephemeral version 1 server key 27 | KeyRegenerationInterval 3600 28 | ServerKeyBits 768 29 | 30 | # Logging 31 | SyslogFacility AUTH 32 | LogLevel INFO 33 | 34 | # Authentication: 35 | LoginGraceTime 120 36 | PermitRootLogin without-password 37 | UseDNS no 38 | StrictModes yes 39 | 40 | RSAAuthentication yes 41 | PubkeyAuthentication yes 42 | #AuthorizedKeysFile %h/.ssh/authorized_keys 43 | 44 | # Don't read the user's ~/.rhosts and ~/.shosts files 45 | IgnoreRhosts yes 46 | # For this to work you will also need host keys in /etc/ssh_known_hosts 47 | RhostsRSAAuthentication no 48 | # similar for protocol version 2 49 | HostbasedAuthentication no 50 | # Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication 51 | #IgnoreUserKnownHosts yes 52 | 53 | # To enable empty passwords, change to yes (NOT RECOMMENDED) 54 | PermitEmptyPasswords no 55 | 56 | # Change to yes to enable challenge-response passwords (beware issues with 57 | # some PAM modules and threads) 58 | ChallengeResponseAuthentication no 59 | 60 | # Change to no to disable tunnelled clear text passwords 61 | PasswordAuthentication no 62 | 63 | # Kerberos options 64 | #KerberosAuthentication no 65 | #KerberosGetAFSToken no 66 | #KerberosOrLocalPasswd yes 67 | #KerberosTicketCleanup yes 68 | 69 | # GSSAPI options 70 | #GSSAPIAuthentication no 71 | #GSSAPICleanupCredentials yes 72 | 73 | X11Forwarding yes 74 | X11DisplayOffset 10 75 | PrintMotd no 76 | PrintLastLog yes 77 | TCPKeepAlive yes 78 | ClientAliveInterval 30 79 | ClientAliveCountMax 6 80 | #UseLogin no 81 | 82 | #MaxStartups 10:30:60 83 | #Banner /etc/issue.net 84 | 85 | # Allow client to pass locale environment variables 86 | AcceptEnv LANG LC_* 87 | 88 | Subsystem sftp /usr/lib/openssh/sftp-server 89 | 90 | UsePAM yes 91 | 92 | # PermitUserEnvironment yes 93 | # AcceptEnv PATH 94 | # AcceptEnv RUBYLIB 95 | 96 | GatewayPorts clientspecified 97 | -------------------------------------------------------------------------------- /server/files/etc/sudoers: -------------------------------------------------------------------------------- 1 | # /etc/sudoers 2 | # 3 | # This file MUST be edited with the 'visudo' command as root. 4 | # 5 | # See the man page for details on how to write a sudoers file. 6 | # Host alias specification 7 | 8 | Defaults !lecture,tty_tickets,!fqdn 9 | 10 | root ALL=(ALL) ALL 11 | 12 | # The 'app' user can only run /usr/bin/god using sudo, and will not be 13 | # prompted for a password 14 | app ALL = NOPASSWD: /usr/bin/god 15 | 16 | # Users in the rootequiv group can run any command using sudo, without being 17 | # prompted for a password. 18 | # By default there are nousers in this group, but some EC2 on Rails Capistrano 19 | # tasks (which log in as the 'app' user) require the ability to use sudo so 20 | # they temporarily place the app user into this group for the duration of the 21 | # task. 22 | %rootequiv ALL=(ALL) NOPASSWD: ALL 23 | 24 | # Users in the admin group can run any command via sudo, but will be 25 | # prompted for their password. 26 | # By default there are no users in this group, but if you add named 27 | # administrator accounts, add them to this group. (You might do this if you 28 | # have multiple sysadmins and you want to use separate user accounts rather 29 | # than have multiple people sharing a root account.) 30 | %admin ALL=(ALL) ALL 31 | 32 | -------------------------------------------------------------------------------- /server/files/etc/syslog.conf: -------------------------------------------------------------------------------- 1 | # /etc/syslog.conf Configuration file for syslogd. 2 | # 3 | # For more information see syslog.conf(5) 4 | # manpage. 5 | 6 | # 7 | # First some standard logfiles. Log by facility. 8 | # 9 | 10 | auth,authpriv.* /mnt/log/auth.log 11 | *.*;auth,authpriv.none -/mnt/log/syslog 12 | #cron.* /mnt/log/cron.log 13 | daemon.* -/mnt/log/daemon.log 14 | kern.* -/mnt/log/kern.log 15 | lpr.* -/mnt/log/lpr.log 16 | mail.* -/mnt/log/mail.log 17 | user.* -/mnt/log/user.log 18 | 19 | # 20 | # Logging for the mail system. Split it up so that 21 | # it is easy to write scripts to parse these files. 22 | # 23 | mail.info -/mnt/log/mail.info 24 | mail.warn -/mnt/log/mail.warn 25 | mail.err /mnt/log/mail.err 26 | 27 | # 28 | # Some `catch-all' logfiles. 29 | # 30 | *.=debug;\ 31 | auth,authpriv.none;\ 32 | news.none;mail.none -/mnt/log/debug 33 | *.=info;*.=notice;*.=warn;\ 34 | auth,authpriv.none;\ 35 | cron,daemon.none;\ 36 | mail,news.none -/mnt/log/messages 37 | 38 | # 39 | # Emergencies are sent to everybody logged in. 40 | # 41 | *.emerg * 42 | 43 | # 44 | # I like to have messages displayed on the console, but only on a virtual 45 | # console I usually leave idle. 46 | # 47 | #daemon,mail.*;\ 48 | # news.=crit;news.=err;news.=notice;\ 49 | # *.=debug;*.=info;\ 50 | # *.=notice;*.=warn /dev/tty8 51 | 52 | # The named pipe /dev/xconsole is for the `xconsole' utility. To use it, 53 | # you must invoke `xconsole' with the `-file' option: 54 | # 55 | # $ xconsole -file /dev/xconsole [...] 56 | # 57 | # NOTE: adjust the list below, or you'll go crazy if you have a reasonably 58 | # busy site.. 59 | # 60 | daemon.*;mail.*;\ 61 | news.err;\ 62 | *.=debug;*.=info;\ 63 | *.=notice;*.=warn |/dev/xconsole 64 | -------------------------------------------------------------------------------- /server/files/etc/varnish/default.vcl.erb: -------------------------------------------------------------------------------- 1 | #This is the VCL configuration file for varnish. See the vcl(7) 2 | #man page for details on VCL syntax and semantics. 3 | 4 | director director_1 round-robin { 5 | # One backend for each instance in the "web" role. If that instance is also in 6 | # the "proxy" role then it's listening on port 81, otherwise it's on port 80 7 | <% roles[:web].each_with_index do |address, i| %> 8 | { 9 | .backend = { 10 | .host = "<%= address %>"; 11 | .port = "<%= roles[:proxy] && roles[:proxy].include?(address) ? 81 : 80 %>"; 12 | .max_connections = 100; 13 | .connect_timeout = 10s; 14 | .first_byte_timeout = 60s; 15 | .between_bytes_timeout = 10s; 16 | } 17 | } 18 | <% end %> 19 | } 20 | 21 | <% unless config[:proxy] && config[:proxy][:caching_enabled] %> 22 | # redefine the vcl_recv function to disable caching if 23 | # config[:proxy][:caching_enabled] is not true for this instance. 24 | sub vcl_recv { 25 | if (req.request != "GET" && 26 | req.request != "HEAD" && 27 | req.request != "PUT" && 28 | req.request != "POST" && 29 | req.request != "TRACE" && 30 | req.request != "OPTIONS" && 31 | req.request != "DELETE") { 32 | /* Non-RFC2616 or CONNECT which is weird. */ 33 | return (pipe); 34 | } 35 | return (pass); 36 | } 37 | <% end %> 38 | 39 | 40 | # 41 | #Below is a commented-out copy of the default VCL logic. If you 42 | #redefine any of these subroutines, the built-in logic will be 43 | #appended to your code. 44 | # 45 | #sub vcl_recv { 46 | # if (req.request != "GET" && 47 | # req.request != "HEAD" && 48 | # req.request != "PUT" && 49 | # req.request != "POST" && 50 | # req.request != "TRACE" && 51 | # req.request != "OPTIONS" && 52 | # req.request != "DELETE") { 53 | # /* Non-RFC2616 or CONNECT which is weird. */ 54 | # return (pipe); 55 | # } 56 | # if (req.request != "GET" && req.request != "HEAD") { 57 | # /* We only deal with GET and HEAD by default */ 58 | # return (pass); 59 | # } 60 | # if (req.http.Authorization || req.http.Cookie) { 61 | # /* Not cacheable by default */ 62 | # return (pass); 63 | # } 64 | # return (lookup); 65 | #} 66 | # 67 | #sub vcl_pipe { 68 | # return (pipe); 69 | #} 70 | # 71 | #sub vcl_pass { 72 | # return (pass); 73 | #} 74 | # 75 | #sub vcl_hash { 76 | # set req.hash += req.url; 77 | # if (req.http.host) { 78 | # set req.hash += req.http.host; 79 | # } else { 80 | # set req.hash += server.ip; 81 | # } 82 | # return (hash); 83 | #} 84 | # 85 | #sub vcl_hit { 86 | # if (!obj.cacheable) { 87 | # return (pass); 88 | # } 89 | # return (deliver); 90 | #} 91 | # 92 | #sub vcl_miss { 93 | # return (fetch); 94 | #} 95 | # 96 | #sub vcl_fetch { 97 | # if (!obj.cacheable) { 98 | # return (pass); 99 | # } 100 | # if (obj.http.Set-Cookie) { 101 | # return (pass); 102 | # } 103 | # set obj.prefetch = -30s; 104 | # return (deliver); 105 | #} 106 | # 107 | #sub vcl_deliver { 108 | # return (deliver); 109 | #} 110 | # 111 | #sub vcl_discard { 112 | # /* XXX: Do not redefine vcl_discard{}, it is not yet supported */ 113 | # return (discard); 114 | #} 115 | # 116 | #sub vcl_prefetch { 117 | # /* XXX: Do not redefine vcl_prefetch{}, it is not yet supported */ 118 | # return (fetch); 119 | #} 120 | # 121 | #sub vcl_timeout { 122 | # /* XXX: Do not redefine vcl_timeout{}, it is not yet supported */ 123 | # return (discard); 124 | #} 125 | # 126 | #sub vcl_error { 127 | # set obj.http.Content-Type = "text/html; charset=utf-8"; 128 | # synthetic {" 129 | # 130 | # 132 | # 133 | # 134 | # "} obj.status " " obj.response {" 135 | # 136 | # 137 | #

Error "} obj.status " " obj.response {"

138 | #

"} obj.response {"

139 | #

Guru Meditation:

140 | #

XID: "} req.xid {"

141 | #
142 | # Varnish 143 | #
144 | # 145 | # 146 | #"}; 147 | # return (deliver); 148 | #} 149 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/archive_file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | # This script archives a file to S3 22 | 23 | require "rubygems" 24 | require "optiflag" 25 | require "#{File.dirname(__FILE__)}/../lib/s3_helper" 26 | require "#{File.dirname(__FILE__)}/../lib/utils" 27 | 28 | include FileUtils 29 | 30 | module CommandLineArgs extend OptiFlagSet 31 | optional_flag "bucket" 32 | optional_flag "dir" 33 | optional_flag "file" 34 | and_process! 35 | end 36 | 37 | # include the hostname in the bucket name so test instances don't accidentally clobber real backups 38 | bucket = ARGV.flags.bucket 39 | dir = ARGV.flags.dir 40 | file = ARGV.flags.file 41 | exit unless File.exists?(file) 42 | 43 | @s3 = Ec2onrails::S3Helper.new(bucket, dir) 44 | @s3.store_file(file) 45 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/backup_app_db: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | #exit if the current application is not deployed, meaning there is nothing to back up! 22 | exit unless File.exists?("/mnt/app/current") 23 | 24 | require "rubygems" 25 | require "optiflag" 26 | require "fileutils" 27 | require "AWS" 28 | require "#{File.dirname(__FILE__)}/../lib/mysql_helper" 29 | require "#{File.dirname(__FILE__)}/../lib/s3_helper" 30 | require "#{File.dirname(__FILE__)}/../lib/aws_helper" 31 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 32 | 33 | require "#{File.dirname(__FILE__)}/../lib/utils" 34 | 35 | # Only run if this instance is the db_primary 36 | # The original code would run on any instance that had /etc/init.d/mysql 37 | # Which was pretty much all instances no matter what role 38 | include Ec2onrails::RolesHelper 39 | exit unless in_role?(:db_primary) 40 | 41 | 42 | module CommandLineArgs extend OptiFlagSet 43 | optional_flag "bucket" 44 | optional_flag "dir" 45 | optional_switch_flag "incremental" 46 | optional_switch_flag "reset" 47 | optional_switch_flag "no_ebs" 48 | and_process! 49 | end 50 | @mysql = Ec2onrails::MysqlHelper.new 51 | 52 | 53 | if File.exists?("/etc/mysql/conf.d/mysql-ec2-ebs.cnf") && !ARGV.flags.no_ebs 54 | # we have ebs enabled.... 55 | 56 | @aws = Ec2onrails::AwsHelper.new 57 | vols = YAML::load(File.read("/etc/ec2onrails/ebs_info.yml")) 58 | ec2 = AWS::EC2::Base.new( :access_key_id => @aws.aws_access_key, :secret_access_key => @aws.aws_secret_access_key ) 59 | 60 | #lets make sure we have space: AMAZON puts a 500 limit on the number of snapshots 61 | snaps = ec2.describe_snapshots['snapshotSet']['item'] rescue nil 62 | if snaps && snaps.size > 450 63 | # TODO: 64 | # can we make this a bit smarter? With a limit of 500, that is difficult. 65 | # possible ideas (and some commented out code below) 66 | # * only apply cleanups to the volume_ids attached to this instance 67 | # * keep the last week worth (at hrly snapshots), then daily for a month, then monthly 68 | # * a sweeper task 69 | # 70 | # vol_ids = [] 71 | # vols.each_pair{|k,v| vol_ids << v['volume_id']} 72 | # #lets only work on those that apply for these volumnes attached 73 | # snaps = snaps.collect{|sn| vol_ids.index(sn['volumeId']) ? sn : nil}.compact 74 | # # get them sorted 75 | snaps = snaps.sort_by{|snapshot| snapshot['startTime']}.reverse 76 | curr_batch = {} 77 | remaining = [] 78 | snaps[200..-1].each do |sn| 79 | next if sn.blank? || sn['status'] != 'completed' 80 | today = Date.parse(sn['startTime']).to_s 81 | if curr_batch[sn['volumeId']] != today 82 | curr_batch[sn['volumeId']] = today 83 | remaining << sn 84 | else 85 | ec2.delete_snapshot(:snapshot_id => sn['snapshotId']) 86 | end 87 | # next unless vol_ids.index(sn['volumeId']) 88 | end 89 | if remaining.size > 400 90 | puts " WARNING: still contains #{remaining.size} snapshots; removing the oldest 100 to clean up space" 91 | remaining[350..-1].each do |sn| 92 | ec2.delete_snapshot(:snapshot_id => sn['snapshotId']) 93 | end 94 | end 95 | else 96 | puts "Could not retrieve snapshots: auto archiving cleanup will not occur" unless snaps 97 | end 98 | 99 | @mysql.execute do |conn| 100 | begin 101 | conn.query "FLUSH TABLES WITH READ LOCK;" 102 | 103 | res = conn.query "SHOW MASTER STATUS" 104 | logfile, position = res.fetch_row[0..1] 105 | # puts "Snapshot occuring at: log: #{logfile}, #{position}" 106 | vols.each_pair do |mount, ebs_info| 107 | begin 108 | `sudo xfs_freeze -f #{mount}` 109 | output = ec2.create_snapshot(:volume_id => ebs_info['volume_id']) 110 | snap_id = output['CreateSnapshotResponse']['snapshotId'] rescue nil 111 | snap_id ||= output['snapshotId'] rescue nil #this is for the old version of the amazon-ec2 112 | if snap_id.nil? || snap_id.empty? 113 | puts "Snapshot for #{ebs_info['volume_id']} FAILED" 114 | exit 115 | end 116 | vol_id = ebs_info['volume_id'] 117 | ensure 118 | `sudo xfs_freeze -u #{mount}` 119 | end 120 | end 121 | ensure 122 | conn.query <<-SQL 123 | UNLOCK TABLES; 124 | SQL 125 | end 126 | end 127 | else 128 | #not persisted, so lets push the binary log files to s3 129 | # include the hostname in the bucket name so test instances don't accidentally clobber real backups 130 | bucket = ARGV.flags.bucket 131 | dir = ARGV.flags.dir || "database" 132 | @s3 = Ec2onrails::S3Helper.new(bucket, dir) 133 | @temp_dir = "/mnt/tmp/ec2onrails-backup-#{@s3.bucket_name}-#{dir.gsub(/\//, "-")}" 134 | if File.exists?(@temp_dir) 135 | puts "Temp dir exists (#{@temp_dir}), aborting. Is another backup process running?" 136 | exit 137 | end 138 | 139 | begin 140 | FileUtils.mkdir_p @temp_dir 141 | if ARGV.flags.incremental 142 | # Incremental backup 143 | @mysql.execute_sql "flush logs" 144 | logs = Dir.glob("/mnt/log/mysql/mysql-bin.[0-9]*").sort 145 | logs_to_archive = logs[0..-2] # all logs except the last 146 | logs_to_archive.each {|log| @s3.store_file log} 147 | @mysql.execute_sql "purge master logs to '#{File.basename(logs[-1])}'" 148 | else 149 | # Full backup 150 | file = "#{@temp_dir}/dump.sql.gz" 151 | @mysql.dump(file, ARGV.flags.reset) 152 | @s3.store_file file 153 | @s3.delete_files("mysql-bin") 154 | end 155 | ensure 156 | FileUtils.rm_rf(@temp_dir) 157 | end 158 | 159 | end 160 | 161 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/backup_dir: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | require "rubygems" 22 | require "optiflag" 23 | require "fileutils" 24 | require 'EC2' 25 | require "#{File.dirname(__FILE__)}/../lib/mysql_helper" 26 | require "#{File.dirname(__FILE__)}/../lib/s3_helper" 27 | require "#{File.dirname(__FILE__)}/../lib/aws_helper" 28 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 29 | 30 | require "#{File.dirname(__FILE__)}/../lib/utils" 31 | 32 | # Only run if this instance is the db_pimrary 33 | # The original code would run on any instance that had /etc/init.d/mysql 34 | # Which was pretty much all instances no matter what role 35 | include Ec2onrails::RolesHelper 36 | 37 | 38 | module CommandLineArgs extend OptiFlagSet 39 | curr_env = Ec2onrails::Utils.rails_env 40 | default_bucket = "#{curr_env}_backup" 41 | 42 | flag "dir" do 43 | description "the directory that will be tarred and compressed and put on S3 with the name DIR_#{Ec2onrails::Utils.hostname}_TIMESTAMP.tgz" 44 | end 45 | 46 | optional_flag "role" do 47 | description "The role of this server, as defined by capistrano. ex. 'db', or 'app' If not used, will be applied to all roles" 48 | end 49 | 50 | optional_flag "only_env" do 51 | description "Only apply the script if it is running within this environment" 52 | end 53 | 54 | optional_flag "bucket" do 55 | description "The s3 bucket you would like to save this backup to. Will default to #{default_bucket}" 56 | end 57 | 58 | optional_switch_flag "v" do 59 | description "let you know if the script stopped because it was running in either a different role or environment than the one specified" 60 | end 61 | 62 | and_process! 63 | end 64 | curr_env = Ec2onrails::Utils.rails_env 65 | default_bucket = "#{curr_env}_backup" 66 | 67 | verbose = ARGV.flags.v 68 | dir = ARGV.flags.dir 69 | bucket = ARGV.flags.bucket || default_bucket 70 | curr_env = Ec2onrails::Utils.rails_env 71 | default_bucket = "#{curr_env}_backup" 72 | 73 | if ARGV.flags.role && !in_role?(ARGV.flags.role.sub(/^:/, '').to_sym) 74 | puts "This script is not being run because the server is not running under the #{role} role" if verbose 75 | exit 76 | end 77 | 78 | if ARGV.flags.only_env && ARGV.flags.only_env.strip.downcase != curr_env.strip.downcase 79 | puts "This script is not being run because the server is not running under the #{curr_env} environment" if verbose 80 | exit 81 | end 82 | 83 | if !dir || File.exists?(dir) 84 | puts "The directory '#{dir}' does not exist. Please enter a valid, full path to a directory you would like backed up" if verbose 85 | end 86 | 87 | 88 | @s3 = Ec2onrails::S3Helper.new(bucket, dir) 89 | @s3.store_dir(dir, :compress => true) 90 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/ec2_meta_data: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | # 21 | # 22 | # This file helps in setting up and retrieving ec2 meta-data 23 | # If a key is passed in, it will only retrieve that key 24 | # if not, then it will return all of the meta-data formatted in yaml 25 | # 26 | 27 | require "rubygems" 28 | require "optiflag" 29 | require 'yaml' 30 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 31 | include Ec2onrails::RolesHelper 32 | 33 | CURL_OPTS = "-s -S -f -L --retry 7" 34 | META_URL = "http://169.254.169.254/latest/meta-data" 35 | 36 | 37 | module CommandLineArgs extend OptiFlagSet 38 | optional_flag "key" do 39 | description "The ec2 meta-data value you would like to look up" 40 | end 41 | and_process! 42 | end 43 | 44 | 45 | def process_files(files, root_url="") 46 | output = {} 47 | files.split.each do |file| 48 | if file =~ /\/$/ 49 | output.merge! process_files(`curl #{CURL_OPTS} #{META_URL}/#{file}`, "#{file}") 50 | else 51 | if file =~ /=/ 52 | key, data = file.split('=') 53 | else 54 | url = "#{META_URL}/#{root_url}/#{file}" 55 | data = `curl #{CURL_OPTS} #{url}` 56 | raise "Failed to fetch entry #{file}: code #{$?.exitstatus} -- #{data}" unless $?.success? 57 | end 58 | if root_url.nil? || root_url.strip.length == 0 59 | output[file] = data 60 | else 61 | output[root_url] ||= {} 62 | output[root_url][file] = data 63 | end 64 | end 65 | end 66 | output 67 | end 68 | 69 | 70 | 71 | if ARGV.flags.key 72 | puts get_metadata(ARGV.flags.key) 73 | else 74 | 75 | files = `curl #{CURL_OPTS} #{META_URL}/` 76 | raise "Failed to fetch directory: code #{$?.exitstatus} -- #{files}" unless $?.success? 77 | val = process_files(files) 78 | puts val.to_yaml 79 | end 80 | 81 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/exec_runner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | # 21 | # This script allows you to ONLY execute within a shell IF the role of 22 | # the server (as defined by capistrano) matches the role specified. 23 | # ex. 24 | # * exec_runner -role :db -exec 'echo "hello world"' 25 | # # will only run if the server is in the db role 26 | # * exec_runner -role :web -exec /some/app/specific/script/to/call 27 | # 28 | 29 | require "rubygems" 30 | require "optiflag" 31 | 32 | require "fileutils" 33 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 34 | require "#{File.dirname(__FILE__)}/../lib/utils" 35 | 36 | include Ec2onrails::RolesHelper 37 | 38 | module CommandLineArgs extend OptiFlagSet 39 | optional_flag "role" do 40 | description "The role of this server, as defined by capistrano. ex. 'db', or 'app' If not used, will be applied to all roles" 41 | end 42 | 43 | optional_flag "only_env" do 44 | description "Only apply the script if it is running within this environment" 45 | end 46 | 47 | flag "exec" do 48 | description "what to run if the role of the server matches the -role passed in" 49 | end 50 | 51 | optional_switch_flag "v" do 52 | description "let you know if the script stopped because it was running in either a different role or environment than the one specified" 53 | end 54 | 55 | and_process! 56 | end 57 | 58 | #strip out the ':', in case the user enters ':db', or ':web' 59 | if ARGV.flags.role && !in_role?(ARGV.flags.role.sub(/^:/, '').to_sym) 60 | puts "This script is not being run because the server is not running under the #{role} role" if ARGV.flags.v 61 | exit 62 | end 63 | 64 | curr_env = Ec2onrails::Utils.rails_env 65 | if ARGV.flags.only_env && ARGV.flags.only_env.strip.downcase != curr_env.strip.downcase 66 | puts "This script is not being run because the server is not running under the #{curr_env} environment" if ARGV.flags.v 67 | exit 68 | end 69 | 70 | 71 | # set the default to the current directory; makes it easier to 72 | Dir.chdir('/mnt/app/current') 73 | 74 | ENV['RAILS_ENV'] = curr_env 75 | run ARGV.flags.exec 76 | 77 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/in_role: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 22 | include Ec2onrails::RolesHelper 23 | 24 | if ARGV[0].nil? || ARGV[0] == "" 25 | puts "Missing rolename argument" 26 | exit 2 27 | end 28 | 29 | if in_role?(ARGV[0].to_sym) 30 | exit 0 31 | else 32 | exit 1 33 | end 34 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/init_services: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 22 | require "#{File.dirname(__FILE__)}/../lib/utils" 23 | 24 | include Ec2onrails::RolesHelper 25 | 26 | 27 | APP_ROOT = "/mnt/app/current" 28 | RAILS_ENV = Ec2onrails::Utils.rails_env 29 | 30 | #reload configs to pick up any new changes 31 | # Just a thought... do we really need to load god files from inside the app? They could just be installed via install_system_files, that would be simpler 32 | Dir.glob("/etc/god/*.god") + Dir.glob("/mnt/app/current/config/god/*.god").each do |f| 33 | sudo "god load '#{f}'" 34 | end 35 | 36 | 37 | roles.keys.each do |role| 38 | if in_role? role 39 | start role 40 | else 41 | stop role 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/install_system_files: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script installs system files that are included in the deployed Rails 23 | # app. The files are copied from RAILS_ROOT/config/ec2onrails/system_files 24 | # (i.e. /mnt/app/current/config/ec2onrails/system_files) to the root 25 | # of the system, keeping their subdirectories. 26 | # 27 | # For example, to replace /etc/nginx/nginx.conf with your own customized 28 | # version, you would create config/ec2onrails/system_files/nginx/nginx.conf 29 | # in your rails app. 30 | # 31 | # If the files being installed are overwriting an existing system file, 32 | # that file will be renamed to .ec2onrails_backup 33 | # 34 | # An optional "manifest" file can be created that lists all the files. 35 | # 36 | # Before installing the files, or when given the --uninstall flag, it will 37 | # remove the previously installed files. This only works if the previously 38 | # installed files had a manifest. 39 | # 40 | # This replaces the ec2onrails:server:deploy_files Capistrano task that 41 | # uploaded a set of files from anywhere on the deployer's computer. The 42 | # advantage of doing it this way is that the system config files are deployed 43 | # with the app, and kept with the app in your revision control system where 44 | # they can be branched, etc., together with the app, then uninstalled cleanly 45 | # when redeploying a different version of the app. 46 | 47 | require "fileutils" 48 | require "#{File.dirname(__FILE__)}/../lib/system_files_helper" 49 | require "#{File.dirname(__FILE__)}/../lib/utils" 50 | 51 | 52 | SYSTEM_FILES_SRC = "config/ec2onrails/system_files" 53 | 54 | app_dir = ARGV[0] || "/mnt/app/current" 55 | 56 | Ec2onrails::SystemFilesHelper.new.install_system_files(File.join(app_dir, SYSTEM_FILES_SRC)) 57 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/public-hostname: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script prints the instance's public hostname 23 | 24 | echo `curl -s http://169.254.169.254/latest/meta-data/public-hostname` 25 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/rails_env: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script runs a command with RAILS_ENV set to current value for 23 | # this instance. If a command isn't given as an argument it simply 24 | # prints the value of RAILS_ENV 25 | 26 | require "yaml" 27 | require "#{File.dirname(__FILE__)}/../lib/utils" 28 | 29 | if ARGV.any? 30 | exec "env RAILS_ENV=#{Ec2onrails::Utils.rails_env} #{ARGV.join(' ')}" 31 | else 32 | puts Ec2onrails::Utils.rails_env 33 | end 34 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/rebundle: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | fail() { 23 | echo "`basename $0`: ERROR: $1" 24 | exit 1 25 | } 26 | 27 | if [ `whoami` != 'root' ] ; then 28 | fail "This script must be run as root, use 'sudo $0'". 29 | fi 30 | 31 | . "/usr/local/ec2onrails/config" 32 | 33 | TIMESTAMP="`date '+%Y-%m-%d--%H-%M-%S'`" 34 | NEW_BUCKET_NAME="$BUCKET_BASE_NAME-image-$TIMESTAMP" 35 | 36 | if [ ! -e /usr/local/ec2-api-tools ] ; then 37 | echo "The EC2 api command-line tools don't seem to be installed." 38 | echo "To install them (and Java, which they require), press enter..." 39 | read 40 | curl http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip > /tmp/ec2-api-tools.zip || fail "couldn't download ec2-api-tools.zip" 41 | unzip /tmp/ec2-api-tools.zip -d /usr/local || fail "couldn't unzip ec2-api-tools.zip" 42 | chmod -R go-w /usr/local/ec2-api-tools* 43 | ln -sf /usr/local/ec2-api-tools-* /usr/local/ec2-api-tools 44 | aptitude install -y sun-java6-jre || fail "couldn't install Java package" 45 | fi 46 | 47 | echo "--> Clearing apt cache..." 48 | aptitude clean 49 | 50 | echo "--> Clearing sensitive files..." 51 | rm -f /root/{.bash_history,.lesshst} 52 | 53 | echo "--> Creating image..." 54 | ec2-bundle-vol -e "/root/.ssh,/home/app/.ssh,/tmp,/mnt" -d /mnt -k "$EC2_PRIVATE_KEY" -c "$EC2_CERT" -u "$AWS_ACCOUNT_ID" || fail "ec2-bundle-vol failed" 55 | 56 | echo "--> Uploading image to $NEW_BUCKET_NAME" 57 | ec2-upload-bundle -b "$NEW_BUCKET_NAME" -m /mnt/image.manifest.xml -a "$AWS_ACCESS_KEY_ID" -s "$AWS_SECRET_ACCESS_KEY" || fail "ec2-upload-bundle failed" 58 | 59 | echo "--> Registering image..." 60 | ec2-register "$NEW_BUCKET_NAME/image.manifest.xml" || fail "ec2-register failed" 61 | 62 | echo "--> Done." 63 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/restore_app_db: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | require "rubygems" 22 | require "optiflag" 23 | require "fileutils" 24 | require "#{File.dirname(__FILE__)}/../lib/mysql_helper" 25 | require "#{File.dirname(__FILE__)}/../lib/s3_helper" 26 | require "#{File.dirname(__FILE__)}/../lib/utils" 27 | 28 | module CommandLineArgs extend OptiFlagSet 29 | optional_flag "bucket" 30 | optional_flag "dir" 31 | and_process! 32 | end 33 | 34 | bucket = ARGV.flags.bucket 35 | dir = ARGV.flags.dir || "database" 36 | @s3 = Ec2onrails::S3Helper.new(bucket, dir) 37 | @mysql = Ec2onrails::MysqlHelper.new 38 | @temp_dir = "/mnt/tmp/ec2onrails-backup-#{@s3.bucket_name}-#{dir.gsub(/\//, "-")}" 39 | if File.exists?(@temp_dir) 40 | puts "Temp dir exists (#{@temp_dir}), aborting. Is another backup process running?" 41 | exit 42 | end 43 | 44 | begin 45 | FileUtils.mkdir_p @temp_dir 46 | 47 | file = "#{@temp_dir}/dump.sql.gz" 48 | @s3.retrieve_file(file) 49 | @mysql.load_from_dump(file) 50 | 51 | @s3.retrieve_files("mysql-bin.", @temp_dir) 52 | logs = Dir.glob("#{@temp_dir}/mysql-bin.[0-9]*").sort 53 | logs.each {|log| @mysql.execute_binary_log(log) } 54 | ensure 55 | FileUtils.rm_rf(@temp_dir) 56 | end 57 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/set_rails_env: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script updates the current RAILS_ENV setting for this instance 23 | 24 | require "yaml" 25 | require "erb" 26 | 27 | 28 | if ARGV.length != 1 29 | puts "usage: set_rails_env " 30 | exit 1 31 | end 32 | 33 | @rails_env = ARGV[0] 34 | 35 | File.open("/etc/ec2onrails/rails_env", 'w') do |f| 36 | f << @rails_env 37 | end 38 | 39 | # Tell god to quit, which will cause it to be restarted immediately by init. 40 | # When it restarts it keeps it's monitoring state. This causes it to reload 41 | # it's idea of RAILS_ENV because it's used in notifications. 42 | system("god quit > /dev/null") 43 | 44 | # Wait for it to restart 45 | command = "god status > /dev/null" 46 | while !system(command) 47 | sleep 1 48 | end 49 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/set_roles: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # To customize the nginx config files, you can setup a template like: 23 | # /etc/ec2onrails/balancer_members.erb 24 | # /etc/ec2onrails/nginx_upstream_members.erb 25 | 26 | 27 | require "#{File.dirname(__FILE__)}/../lib/roles_helper" 28 | include Ec2onrails::RolesHelper 29 | 30 | puts "Roles: " 31 | pp roles 32 | 33 | resolve_hostnames_in_roles_file 34 | set_hostnames 35 | process_config_file_templates 36 | 37 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/bin/uninstall_system_files: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script removes system files that were installed with the deployed Rails 23 | # app. This only works if the previously installed files had a manifest. 24 | # 25 | # See install_system_files for more info. 26 | 27 | 28 | require "fileutils" 29 | require "#{File.dirname(__FILE__)}/../lib/system_files_helper" 30 | require "#{File.dirname(__FILE__)}/../lib/utils" 31 | 32 | 33 | Ec2onrails::SystemFilesHelper.new.uninstall_system_files 34 | 35 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/config: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # This script is sourced by .bashrc and by /usr/local/ec2onrails/rebundle 3 | # You shouldn't need to change anything in here 4 | 5 | if [ -r /mnt/aws-config/config ] ; then 6 | . /mnt/aws-config/config 7 | export EC2_PRIVATE_KEY="/mnt/aws-config/$KEY_FILE_NAME" 8 | export EC2_CERT="/mnt/aws-config/$CERT_FILE_NAME" 9 | 10 | fi 11 | 12 | export EC2_HOME=/usr/local/ec2-api-tools 13 | export PATH="$PATH:$EC2_HOME/bin" 14 | 15 | if [ -e "/usr/lib/jvm/java-6-sun" ]; then export JAVA_HOME="/usr/lib/jvm/java-6-sun"; fi 16 | 17 | # Set the bash prompt to include the rails environment name 18 | case "$TERM" in 19 | xterm-color) 20 | PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]-\[\033[01;35m\]`/usr/local/ec2onrails/bin/rails_env`\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' 21 | ;; 22 | *) 23 | PS1='${debian_chroot:+($debian_chroot)}\u@\h-`/usr/local/ec2onrails/bin/rails_env`:\w\$ ' 24 | ;; 25 | esac 26 | 27 | # Set some useful aliases 28 | alias app="pushd /mnt/app/current && sudo su app && popd" 29 | alias log="tail -f /mnt/app/current/log/`/usr/local/ec2onrails/bin/rails_env`.log" 30 | alias logs="tail -f /mnt/app/current/log/*.log /mnt/log/syslog /mnt/log/*.log /mnt/log/*/*.log /mnt/log/*/*/.log" 31 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/aws_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'rubygems' 20 | require 'yaml' 21 | require 'erb' 22 | require 'fileutils' 23 | require "#{File.dirname(__FILE__)}/utils" 24 | 25 | module Ec2onrails 26 | class AwsHelper 27 | 28 | DEFAULT_CONFIG_FILE = "/mnt/app/current/config/aws.yml" 29 | DEFAULT_CONFIG_FILE_OLD = "/mnt/app/current/config/s3.yml" 30 | 31 | # make attributes available for specs 32 | attr_accessor :config_file 33 | attr_accessor :rails_env 34 | attr_accessor :aws_access_key 35 | attr_accessor :aws_secret_access_key 36 | attr_accessor :bucket_base_name 37 | 38 | def initialize(config_file = AwsHelper.default_config_file, rails_env = Utils.rails_env) 39 | @rails_env = rails_env 40 | @config_file = config_file 41 | 42 | if File.exists?(@config_file) 43 | aws_config = YAML::load(ERB.new(File.read(@config_file)).result) 44 | 45 | # try to load the section for the current RAILS_ENV 46 | section = aws_config[@rails_env] 47 | if section.nil? 48 | # fall back to keys at the root of the tree 49 | section = aws_config 50 | end 51 | 52 | @aws_access_key = section['aws_access_key'] 53 | @aws_secret_access_key = section['aws_secret_access_key'] 54 | @bucket_base_name = section['bucket_base_name'] 55 | else 56 | if !File.exists?('/mnt/aws-config/config') 57 | raise "Can't find either #{@config_file} or /mnt/aws-config/config" 58 | end 59 | @aws_access_key = get_bash_config('AWS_ACCESS_KEY_ID') 60 | @aws_secret_access_key = get_bash_config('AWS_SECRET_ACCESS_KEY') 61 | @bucket_base_name = get_bash_config('BUCKET_BASE_NAME') 62 | end 63 | end 64 | 65 | # load an env value from the shared config file 66 | def get_bash_config(name) 67 | `bash -c 'source /mnt/aws-config/config; echo $#{name}'`.strip 68 | end 69 | 70 | def self.default_config_file 71 | File.exists?(DEFAULT_CONFIG_FILE) ? DEFAULT_CONFIG_FILE : DEFAULT_CONFIG_FILE_OLD 72 | end 73 | 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/god_helper.rb: -------------------------------------------------------------------------------- 1 | module GodHelper 2 | require '/usr/local/ec2onrails/lib/roles_helper' 3 | require '/usr/local/ec2onrails/lib/utils' 4 | require 'fileutils' 5 | 6 | def default_configurations(w) 7 | w.interval = 30.seconds 8 | w.grace = 30.seconds 9 | 10 | 11 | w.behavior(:clean_pid_file) 12 | 13 | w.start_if do |start| 14 | start.condition(:process_running) do |c| 15 | c.interval = 5.seconds 16 | c.running = false 17 | end 18 | end 19 | 20 | # determine when process has finished starting 21 | w.transition([:start, :restart], :up) do |on| 22 | on.condition(:process_running) do |c| 23 | c.running = true 24 | end 25 | 26 | # failsafe 27 | on.condition(:tries) do |c| 28 | c.times = 8 29 | c.within = 2.minutes 30 | c.transition = :start 31 | end 32 | end 33 | 34 | # start if process is not running 35 | w.transition(:up, :start) do |on| 36 | on.condition(:process_exits) do |c| 37 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 38 | end 39 | end 40 | 41 | w.lifecycle do |on| 42 | on.condition(:flapping) do |c| 43 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 44 | c.to_state = [:start, :restart] 45 | c.times = 5 46 | c.within = 5.minutes 47 | c.transition = :unmonitored 48 | c.retry_in = 10.minutes 49 | c.retry_times = 5 50 | c.retry_within = 2.hours 51 | end 52 | end 53 | 54 | end 55 | 56 | def restart_if_resource_hog(w, options={}) 57 | options = {:memory_usage => 175.megabytes, :cpu_usage => 50.percent}.merge(options) 58 | w.restart_if do |restart| 59 | if options[:memory_usage] 60 | restart.condition(:memory_usage) do |c| 61 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 62 | c.above = options[:memory_usage] 63 | c.times = [3,5] 64 | end 65 | end 66 | 67 | if options[:cpu_usage] 68 | restart.condition(:cpu_usage) do |c| 69 | c.notify = {:contacts => ['default'], :category => "RAILS_ENV=#{Ec2onrails::Utils.rails_env}"} 70 | c.above = options[:cpu_usage] 71 | c.times = 5 72 | end 73 | end 74 | 75 | yield restart if block_given? 76 | 77 | end 78 | end 79 | 80 | class Configs 81 | include Ec2onrails::RolesHelper 82 | end 83 | 84 | end 85 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/mysql_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'rubygems' 20 | require 'yaml' 21 | require 'erb' 22 | require 'fileutils' 23 | require "#{File.dirname(__FILE__)}/utils" 24 | 25 | module Ec2onrails 26 | class MysqlHelper 27 | 28 | DEFAULT_CONFIG_FILE = "/mnt/app/current/config/database.yml" 29 | 30 | attr_accessor :database 31 | attr_accessor :user 32 | attr_accessor :password 33 | 34 | def initialize(config_file = DEFAULT_CONFIG_FILE, rails_env = Utils.rails_env) 35 | @rails_env = rails_env 36 | load_db_config(config_file) 37 | end 38 | 39 | def load_db_config(config_file) 40 | db_config = YAML::load(ERB.new(File.read(config_file)).result) 41 | if db_config && db_config[@rails_env].nil? 42 | puts "the rails environment '#{@rails_env}' was not found in this db config file: #{config_file}" 43 | end 44 | db_config = db_config[@rails_env] 45 | @database = db_config['database'] 46 | @user = db_config['username'] 47 | @password = db_config['password'] 48 | end 49 | 50 | def execute_sql(sql) 51 | raise "@user not set" unless @user 52 | raise "sql not given" unless sql 53 | cmd = %{mysql -u #{@user} -e "#{sql}"} 54 | cmd += " -p'#{@password}' " unless @password.nil? 55 | Utils.run cmd 56 | end 57 | 58 | def execute 59 | require "mysql" 60 | 61 | begin 62 | # connect to the MySQL server 63 | dbh = Mysql.real_connect("localhost", "#{@user}", "#{@password}", "#{@database}") 64 | yield dbh 65 | rescue Mysql::Error => e 66 | puts "Error code: #{e.errno}" 67 | puts "Error message: #{e.error}" 68 | puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate") 69 | ensure 70 | # disconnect from server 71 | dbh.close if dbh 72 | end 73 | 74 | 75 | end 76 | 77 | def dump(out_file, reset_logs) 78 | cmd = "mysqldump --quick --single-transaction --create-options -u#{@user} " 79 | if reset_logs 80 | cmd += " --flush-logs --master-data=2 --delete-master-logs " 81 | end 82 | cmd += " -p'#{@password}' " unless @password.nil? 83 | cmd += " #{@database} | gzip > #{out_file}" 84 | Utils.run cmd 85 | end 86 | 87 | def load_from_dump(in_file) 88 | cmd = "gunzip -c #{in_file} | mysql -u#{@user} " 89 | cmd += " -p'#{@password}' " unless @password.nil? 90 | cmd += " #{@database}" 91 | Utils.run cmd 92 | end 93 | 94 | def execute_binary_log(log_file) 95 | cmd = "mysqlbinlog --database=#{@database} #{log_file} | mysql -u#{@user} " 96 | cmd += " -p'#{@password}' " unless @password.nil? 97 | Utils.run cmd 98 | end 99 | end 100 | end -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/roles_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'erb' 20 | require 'fileutils' 21 | require 'net/http' 22 | require 'pp' 23 | require 'resolv' 24 | require 'socket' 25 | require 'yaml' 26 | require "#{File.dirname(__FILE__)}/utils" 27 | 28 | module Ec2onrails 29 | module RolesHelper 30 | 31 | ROLES_FILE = "/etc/ec2onrails/roles.yml" 32 | 33 | def local_address 34 | @local_address ||= get_metadata "local-ipv4" 35 | end 36 | 37 | def public_address 38 | @public_address ||= get_metadata "public-ipv4" 39 | end 40 | 41 | def roles 42 | @roles ||= resolve_all_addresses(YAML::load_file(ROLES_FILE)) 43 | end 44 | 45 | def start(role) 46 | puts "STARTING #{role} role" 47 | sudo "god start #{role}" 48 | end 49 | 50 | def stop(role) 51 | puts "STOPPING #{role} role" 52 | sudo "god stop #{role}" 53 | end 54 | 55 | def run(cmd) 56 | result = system(cmd) 57 | puts("*****ERROR: #{cmd} returned #{$?}") unless result 58 | end 59 | 60 | def sudo(cmd) 61 | run("sudo #{cmd}") 62 | end 63 | 64 | def get_metadata(type) 65 | data = Net::HTTP.get('169.254.169.254', "/latest/meta-data/#{type}").strip 66 | 67 | raise "couldn't get instance data: #{type}" if data.nil? || data.strip.length == 0 68 | # puts "#{type}: #{address}" 69 | return data 70 | end 71 | 72 | def resolve(hostname) 73 | # hostname might be an alias, so get the .amazonaws.com hostname 74 | canonical_name = Resolv.getname(IPSocket.getaddress(hostname)) 75 | 76 | # EC2's internal DNS resolves the external hostnames (*.amazonaws.com) into internal IP addresses 77 | address = IPSocket.getaddress(canonical_name).strip 78 | 79 | if address == local_address || address == public_address 80 | "127.0.0.1" 81 | else 82 | address 83 | end 84 | rescue Exception => e 85 | puts "couldn't resolve hostname '#{hostname}'" 86 | raise e 87 | end 88 | 89 | def resolve_all_addresses(original) 90 | resolved = {} 91 | original.each do |rolename, hostnames| 92 | resolved[rolename] = hostnames.map{|hostname| resolve(hostname)} if hostnames 93 | end 94 | resolved 95 | end 96 | 97 | def in_role?(role) 98 | return false unless roles[role] 99 | return roles[role].include?("127.0.0.1") 100 | end 101 | #to provide deprecated usage 102 | alias :in_role :in_role? 103 | 104 | # Re-write the roles file with the hostnames resolved 105 | def resolve_hostnames_in_roles_file 106 | File.open(ROLES_FILE, 'w') {|f| YAML.dump(roles, f)} 107 | end 108 | 109 | # write a hostname alias for each host. The hostnames will be "rolename-n" where n 110 | # is an integer 111 | def set_hostnames 112 | hosts_file = "/etc/hosts" 113 | FileUtils.cp "#{hosts_file}.original", hosts_file 114 | File.open(hosts_file, 'a') do |f| 115 | f << "\n" 116 | f << "# The following is automatically added by the EC2 on Rail set_roles script:\n" 117 | roles.each do |rolename, addresses| 118 | addresses.each_with_index do |address, i| 119 | f << "#{address} #{rolename.to_s.gsub(/_/, "-")}-#{i+1}\n" 120 | end 121 | end 122 | end 123 | 124 | # Eventually we'll remove this: 125 | if roles[:db_primary] 126 | db_primary_addr = roles[:db_primary][0] 127 | File.open(hosts_file, 'a') do |f| 128 | f << "# DEPRECATED: this is here for backwards compatibility, eventually it will be removed:\n" 129 | f << "#{db_primary_addr} db_primary\n" 130 | end 131 | end 132 | end 133 | 134 | # Process any ERB template under /etc 135 | # The output from "filename.erb" will be saved as "filename" 136 | def process_config_file_templates 137 | # Set any variables that will be needed inside the templates 138 | # We're processing ALL templates, even ones that won't be used in the current role. 139 | rails_env = Ec2onrails::Utils.rails_env 140 | config = Ec2onrails::Utils.load_ec2onrails_config 141 | roles = self.roles 142 | 143 | Dir["/etc/**/*.erb"].each do |template| 144 | puts "Processing config file template: #{template}..." 145 | STDOUT.flush 146 | # Use '<>' for ERB formatting options, it's safer than '%' but still allows lines that are ruby-only to be 147 | # omitted from the output. 148 | # For all options see: http://stdlib.rubyonrails.org/libdoc/erb/rdoc/classes/ERB.html#M000684 149 | contents = ERB.new(IO.read(template), nil, "<>").result(binding) 150 | output_file = template.sub(/\.erb$/, '') 151 | File.open(output_file, 'w'){|f| f << contents} 152 | end 153 | end 154 | 155 | end 156 | end -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/s3_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'rubygems' 20 | require 'right_aws' 21 | require 'yaml' 22 | require 'erb' 23 | require 'fileutils' 24 | require "#{File.dirname(__FILE__)}/utils" 25 | require "#{File.dirname(__FILE__)}/aws_helper" 26 | 27 | 28 | # Hack to get rid of the "warning: peer certificate won't be verified in this SSL session" message 29 | # See http://www.5dollarwhitebox.org/drupal/node/64 30 | class Net::HTTP 31 | alias_method :old_initialize, :initialize 32 | def initialize(*args) 33 | old_initialize(*args) 34 | @ssl_context = OpenSSL::SSL::SSLContext.new 35 | @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE 36 | end 37 | end 38 | 39 | 40 | module Ec2onrails 41 | class S3Helper 42 | SCRATCH_SPACE = '/mnt/tmp' 43 | 44 | # make attributes available for specs 45 | attr_accessor :dir 46 | attr_accessor :config_file 47 | attr_accessor :rails_env 48 | attr_accessor :aws_access_key 49 | attr_accessor :aws_secret_access_key 50 | attr_accessor :bucket_name 51 | 52 | def initialize(bucket_name, dir, config_file = Ec2onrails::AwsHelper.default_config_file, rails_env = Utils.rails_env) 53 | @dir = dir 54 | @config_file = config_file 55 | @rails_env = rails_env 56 | @awsHelper = Ec2onrails::AwsHelper.new(config_file, rails_env) 57 | @aws_access_key = @awsHelper.aws_access_key 58 | @aws_secret_access_key = @awsHelper.aws_secret_access_key 59 | @bucket_base_name = @awsHelper.bucket_base_name 60 | @bucket_name = bucket_name || "#{@bucket_base_name}-#{Ec2onrails::Utils.hostname}" 61 | logger = Logger.new(STDOUT) 62 | logger.level = Logger::ERROR 63 | s3 = RightAws::S3.new(@aws_access_key, @aws_secret_access_key, :logger => logger) 64 | @bucket = s3.bucket(@bucket_name, true) 65 | end 66 | 67 | def store_file(filename) 68 | @bucket.put(s3_key(filename), File.read(filename)) 69 | end 70 | 71 | def store_dir(dir, options={}) 72 | FileUtils.mkdir_p SCRATCH_SPACE 73 | compress = options[:compress] 74 | exclude = options[:exclude] 75 | 76 | #should be of the format: 77 | # mnt-app-shared_ec2-75-101-250-19__20090217-183411.tgz 78 | archive_nm = "#{Ec2onrails::Utils.hostname}__#{Time.new.strftime('%Y%m%d-%H%M%S')}" 79 | archive_nm += compress ? ".tgz" : '.tar' 80 | cmd = "cd #{SCRATCH_SPACE} && tar -cph" 81 | cmd += 'z' if compress 82 | cmd += "f #{archive_nm} -C / #{dir[1..-1]} " 83 | cmd += " --exclude=#{exclude} " if exclude 84 | system(cmd) 85 | file = "#{SCRATCH_SPACE}/#{archive_nm}" 86 | @bucket.put(s3_key(archive_nm), File.read(file)) 87 | ensure 88 | system "nice -n 15 rm -f #{file}" 89 | end 90 | 91 | def retrieve_file(file) 92 | key = s3_key(file) 93 | open(file, 'w') { |f| f.write @bucket.get(key) } 94 | end 95 | 96 | def keys(filename_prefix) 97 | prefix = @dir ? "#{@dir}/#{filename_prefix}" : filename_prefix 98 | @bucket.keys('prefix' => prefix).collect{|key| key} 99 | end 100 | 101 | def retrieve_files(filename_prefix, local_dir) 102 | keys(filename_prefix).each do |k| 103 | file = "#{local_dir}/#{File.basename(k.to_s)}" 104 | retrieve_file(file) 105 | end 106 | end 107 | 108 | def delete_files(filename_prefix) 109 | keys(filename_prefix).each { |k| k.delete } 110 | end 111 | 112 | def s3_key(file) 113 | @dir ? "#{@dir}/#{File.basename(file)}" : File.basename(file) 114 | end 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/system_files_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'fileutils' 20 | require "#{File.dirname(__FILE__)}/system_files_manifest" 21 | require "#{File.dirname(__FILE__)}/utils" 22 | 23 | module Ec2onrails 24 | class SystemFilesHelper 25 | 26 | BACKUP_FILE_EXT = ".ec2onrails_backup" 27 | INSTALLED_MANIFEST_FILE = "/etc/ec2onrails/system_files/#{SystemFilesManifest::MANIFEST_FILE_NAME}" 28 | 29 | def install_system_files(from_dir) 30 | uninstall_system_files 31 | 32 | unless File.directory?(from_dir) 33 | puts "no system files to install, #{from_dir} doesn't exist or is not a directory." 34 | return 35 | end 36 | 37 | puts "installing system files from #{from_dir}..." 38 | src_manifest = File.join from_dir, SystemFilesManifest::MANIFEST_FILE_NAME 39 | 40 | @manifest = nil 41 | if File.exists? src_manifest 42 | @manifest = Ec2onrails::SystemFilesManifest.new(from_dir) 43 | FileUtils.cp src_manifest, INSTALLED_MANIFEST_FILE 44 | end 45 | 46 | FileUtils.cd from_dir do 47 | Dir.glob("**/*").each do |f| 48 | unless File.directory?(f) || File.basename(f) == SystemFilesManifest::MANIFEST_FILE_NAME 49 | dest = File.join("/", f) 50 | backup(dest) 51 | make_dirs(dest) 52 | install_file(f, dest, @manifest) 53 | end 54 | end 55 | end 56 | end 57 | 58 | def uninstall_system_files 59 | unless File.exist? INSTALLED_MANIFEST_FILE 60 | puts "not uninstalling system files, #{INSTALLED_MANIFEST_FILE} doesn't exist." 61 | return 62 | end 63 | 64 | puts "uninstalling system files..." 65 | @manifest = Ec2onrails::SystemFilesManifest.new(INSTALLED_MANIFEST_FILE) 66 | @manifest.filenames.each do |f| 67 | file = File.join("/", f) 68 | unless File.directory?(file) 69 | FileUtils.rm file 70 | restore_backup_of file 71 | end 72 | end 73 | FileUtils.rm INSTALLED_MANIFEST_FILE 74 | end 75 | 76 | def backup(f) 77 | if File.exist?(f) 78 | puts "backing up file #{f}..." 79 | backup_file = f + BACKUP_FILE_EXT 80 | FileUtils.mv f, backup_file 81 | end 82 | end 83 | 84 | def restore_backup_of(f) 85 | backup_file = f + BACKUP_FILE_EXT 86 | if File.exist?(backup_file) 87 | puts "restoring backup of file #{f}..." 88 | FileUtils.mv backup_file, f 89 | end 90 | end 91 | 92 | def make_dirs(f) 93 | dir = File.dirname(f) 94 | unless dir == "/" 95 | puts "making dirs #{dir}..." 96 | FileUtils.mkdir_p File.dirname(f) 97 | end 98 | end 99 | 100 | def install_file(f, dest, manifest) 101 | puts "installing file #{f} into #{dest}..." 102 | FileUtils.cp f, dest 103 | if manifest 104 | Utils.run "chown #{manifest[f][:owner]} #{dest}" if manifest[f][:owner] 105 | Utils.run "chmod #{manifest[f][:mode]} #{dest}" if manifest[f][:mode] 106 | end 107 | end 108 | 109 | end 110 | end 111 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/system_files_manifest.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | module Ec2onrails 20 | class SystemFilesManifest 21 | 22 | MANIFEST_FILE_NAME = "_manifest" 23 | 24 | # dir is expected to contain a file named MANIFEST_FILE_NAME 25 | def initialize(dir_or_file) 26 | if File.directory?(dir_or_file) 27 | @dir = dir_or_file 28 | @file = File.join @dir, MANIFEST_FILE_NAME 29 | raise "Can't find manifest file: #{@file}" unless File.exists?(@file) 30 | @entries = parse(@file) 31 | raise "Manifest doesn't match entries in #{@dir}" unless validate 32 | else 33 | @dir = nil 34 | @file = dir_or_file 35 | raise "Can't find manifest file: #{@file}" unless File.exists?(@file) 36 | @entries = parse(@file) 37 | end 38 | end 39 | 40 | # Check that the manifest entries match the files in the given directory 41 | def validate 42 | errors = false 43 | # make sure there's a file for each manifest entry 44 | @entries.each_key do |filename| 45 | unless filename == MANIFEST_FILE_NAME 46 | file = File.join(@dir, filename) 47 | unless File.exist?(file) 48 | log_error "File doesn't exist: #{file}" 49 | errors = true 50 | end 51 | end 52 | end 53 | 54 | # make sure there's a manifest entry for each file 55 | Dir.glob("#{@dir}/**/*").each do |f| 56 | f = normalize(f) 57 | unless self[f] || f == MANIFEST_FILE_NAME 58 | log_error "File isn't listed in manifest: #{f}" 59 | errors = true 60 | end 61 | end 62 | 63 | return !errors 64 | end 65 | 66 | # Return the metadata for the given file 67 | def [](filename) 68 | filename = normalize(filename) 69 | @entries[filename] 70 | end 71 | 72 | def normalize(filename) 73 | return nil unless filename 74 | filename = filename.sub(/#{@dir}/, '') if @dir 75 | filename.sub(/^\//, '') 76 | end 77 | 78 | def comment_or_empty_line?(line) 79 | !!(line =~ /^\s*((#.*)|\s*)$/) 80 | end 81 | 82 | def parse(file) 83 | entries = {} 84 | contents = File.readlines(file) 85 | contents.each do |line| 86 | unless comment_or_empty_line?(line) 87 | filename = line.match(/^([^\s]+)\s*.*$/)[1] 88 | mode = $1 if line.match(/^.*\s+mode=([^\s]*).*$/) 89 | owner = $1 if line.match(/^.*\s+owner=([^\s]*).*$/) 90 | entries[filename] = {:mode => mode, :owner => owner} 91 | end 92 | end 93 | 94 | return entries 95 | end 96 | 97 | def filenames 98 | @entries.keys.sort 99 | end 100 | 101 | def log_error(message) 102 | puts message 103 | STDOUT.flush 104 | end 105 | end 106 | end 107 | 108 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/utils.rb: -------------------------------------------------------------------------------- 1 | module Ec2onrails 2 | module Utils 3 | def self.run(command) 4 | result = system command 5 | raise("error, process exited with status #{$?.exitstatus}") unless result 6 | end 7 | 8 | def self.rails_env 9 | File.read("/etc/ec2onrails/rails_env").strip 10 | end 11 | 12 | def self.hostname 13 | `hostname -s`.strip 14 | end 15 | 16 | def self.load_ec2onrails_config 17 | config_file = "/mnt/app/current/config/ec2onrails/config.rb" 18 | if File.exists?(config_file) 19 | config = eval(File.read(config_file)) 20 | else 21 | puts "#{config_file} doesn't exist" 22 | config = {} 23 | end 24 | return config 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/lib/vendor/ini.rb: -------------------------------------------------------------------------------- 1 | # from ini gem, version 0.1.1 2 | # modified to allow keys with no value to be passed in (search for MODIFIED) 3 | # 4 | # This class represents the INI file and can be used to parse, modify, 5 | # and write INI files. 6 | # 7 | class Ini 8 | 9 | # :stopdoc: 10 | class Error < StandardError; end 11 | # :startdoc: 12 | 13 | # 14 | # call-seq: 15 | # IniFile.load( filename ) 16 | # IniFile.load( filename, options ) 17 | # 18 | # Open the given _filename_ and load the contetns of the INI file. 19 | # The following _options_ can be passed to this method: 20 | # 21 | # :comment => ';' The line comment character(s) 22 | # :parameter => '=' The parameter / value separator 23 | # 24 | def self.load( filename, opts = {} ) 25 | new(filename, opts) 26 | end 27 | 28 | # 29 | # call-seq: 30 | # IniFile.new( filename ) 31 | # IniFile.new( filename, options ) 32 | # 33 | # Create a new INI file using the given _filename_. If _filename_ 34 | # exists and is a regular file, then its contents will be parsed. 35 | # The following _options_ can be passed to this method: 36 | # 37 | # :comment => ';' The line comment character(s) 38 | # :parameter => '=' The parameter / value separator 39 | # 40 | def initialize( filename, opts = {} ) 41 | @fn = filename 42 | @comment = opts[:comment] || ';' 43 | @param = opts[:parameter] || '=' 44 | @ini = Hash.new {|h,k| h[k] = Hash.new} 45 | 46 | @rgxp_comment = %r/\A\s*\z|\A\s*[#{@comment}]/ 47 | @rgxp_section = %r/\A\s*\[([^\]]+)\]/o 48 | #MODIFIED: added #{@param}?... that question mark means that we will match rows 49 | # with just a key, but no value 50 | @rgxp_param = %r/\A([^#{@param}]+)#{@param}?(.*)\z/ 51 | 52 | parse 53 | end 54 | 55 | # 56 | # call-seq: 57 | # write 58 | # write( filename ) 59 | # 60 | # Write the INI file contents to the filesystem. The given _filename_ 61 | # will be used to write the file. If _filename_ is not given, then the 62 | # named used when constructing this object will be used. 63 | # 64 | def write( filename = nil ) 65 | @fn = filename unless filename.nil? 66 | 67 | ::File.open(@fn, 'w') do |f| 68 | @ini.each do |section,hash| 69 | f.puts "[#{section}]" 70 | #MODIFY: do not print out the '=' if there is no value... PLUS remove spaces around the '=' 71 | hash.each {|param,val| f.puts val.nil? ? param : "#{param}#{@param}#{val}"} 72 | f.puts 73 | end 74 | end 75 | self 76 | end 77 | alias :save :write 78 | 79 | # 80 | # call-seq: 81 | # each {|section, parameter, value| block} 82 | # 83 | # Yield each _section_, _parameter_, _value_ in turn to the given 84 | # _block_. The method returns immediately if no block is supplied. 85 | # 86 | def each 87 | return unless block_given? 88 | @ini.each do |section,hash| 89 | hash.each do |param,val| 90 | yield section, param, val 91 | end 92 | end 93 | self 94 | end 95 | 96 | # 97 | # call-seq: 98 | # each_section {|section| block} 99 | # 100 | # Yield each _section_ in turn to the given _block_. The method returns 101 | # immediately if no block is supplied. 102 | # 103 | def each_section 104 | return unless block_given? 105 | @ini.each_key {|section| yield section} 106 | self 107 | end 108 | 109 | # 110 | # call-seq: 111 | # delete_section( section ) 112 | # 113 | # Deletes the named _section_ from the INI file. Returns the 114 | # parameter / value pairs if the section exists in the INI file. Otherwise, 115 | # returns +nil+. 116 | # 117 | def delete_section( section ) 118 | @ini.delete section.to_s 119 | end 120 | 121 | # 122 | # call-seq: 123 | # ini_file[section] 124 | # 125 | # Get the hash of parameter/value pairs for the given _section_. If the 126 | # _section_ hash does not exist it will be created. 127 | # 128 | def []( section ) 129 | return nil if section.nil? 130 | @ini[section.to_s] 131 | end 132 | 133 | # 134 | # call-seq: 135 | # has_section?( section ) 136 | # 137 | # Returns +true+ if the named _section_ exists in the INI file. 138 | # 139 | def has_section?( section ) 140 | @ini.has_key? section.to_s 141 | end 142 | 143 | # 144 | # call-seq: 145 | # sections 146 | # 147 | # Returns an array of the section names. 148 | # 149 | def sections 150 | @ini.keys 151 | end 152 | 153 | # 154 | # call-seq: 155 | # freeze 156 | # 157 | # Freeze the state of the +IniFile+ object. Any attempts to change the 158 | # object will raise an error. 159 | # 160 | def freeze 161 | super 162 | @ini.each_value {|h| h.freeze} 163 | @ini.freeze 164 | self 165 | end 166 | 167 | # 168 | # call-seq: 169 | # taint 170 | # 171 | # Marks the INI file as tainted -- this will traverse each section marking 172 | # each section as tainted as well. 173 | # 174 | def taint 175 | super 176 | @ini.each_value {|h| h.taint} 177 | @ini.taint 178 | self 179 | end 180 | 181 | # 182 | # call-seq: 183 | # dup 184 | # 185 | # Produces a duplicate of this INI file. The duplicate is independent of the 186 | # original -- i.e. the duplicate can be modified without changing the 187 | # orgiinal. The tainted state of the original is copied to the duplicate. 188 | # 189 | def dup 190 | other = super 191 | other.instance_variable_set(:@ini, Hash.new {|h,k| h[k] = Hash.new}) 192 | @ini.each_pair {|s,h| other[s].merge! h} 193 | other.taint if self.tainted? 194 | other 195 | end 196 | 197 | # 198 | # call-seq: 199 | # clone 200 | # 201 | # Produces a duplicate of this INI file. The duplicate is independent of the 202 | # original -- i.e. the duplicate can be modified without changing the 203 | # orgiinal. The tainted state and the frozen state of the original is copied 204 | # to the duplicate. 205 | # 206 | def clone 207 | other = dup 208 | other.freeze if self.frozen? 209 | other 210 | end 211 | 212 | # 213 | # call-seq: 214 | # eql?( other ) 215 | # 216 | # Returns +true+ if the _other_ object is equivalent to this INI file. For 217 | # two INI files to be equivalent, they must have the same sections with the 218 | # same parameter / value pairs in each section. 219 | # 220 | def eql?( other ) 221 | return true if equal? other 222 | return false unless other.instance_of? self.class 223 | @ini == other.instance_variable_get(:@ini) 224 | end 225 | alias :== :eql? 226 | 227 | 228 | private 229 | # 230 | # call-seq 231 | # parse 232 | # 233 | # Parse the ini file contents. 234 | # 235 | def parse 236 | return unless ::Kernel.test ?f, @fn 237 | section = nil 238 | 239 | ::File.open(@fn, 'r') do |f| 240 | while line = f.gets 241 | line = line.chomp 242 | 243 | case line 244 | # ignore blank lines and comment lines 245 | when @rgxp_comment: next 246 | 247 | # this is a section declaration 248 | when @rgxp_section: section = @ini[$1.strip] 249 | 250 | # otherwise we have a parameter 251 | when @rgxp_param 252 | begin 253 | #MODIFY: store no value as a nil instead of a blank 254 | section[$1.strip] = $2.strip.size == 0 ? nil : $2.strip 255 | rescue NoMethodError 256 | raise Error, "parameter encountered before first section" 257 | end 258 | 259 | else 260 | raise Error, "could not parse line '#{line}" 261 | end 262 | end # while 263 | end # File.open 264 | end 265 | 266 | end 267 | 268 | # EOF 269 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/every-startup/README: -------------------------------------------------------------------------------- 1 | These files are called by /etc/init.d/ec2-every-startup. 2 | 3 | They are launched via rcS.d, meaning they will be launched before OTHER 4 | Ec2 scripts, like ec2-get-credentials... so if need some of those scripts 5 | run before, call them manually 6 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/every-startup/create-mysqld-pid-dir: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # /var/run/mysqld doesn't exist until MySQL starts, but God fails if it 23 | # doesn't exist, and we use God to start MySQL. 24 | 25 | mkdir -p /var/run/mysqld 26 | chown mysql:mysql /var/run/mysqld 27 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/README: -------------------------------------------------------------------------------- 1 | These files are called by /etc/init.d/ec2-first-startup. 2 | 3 | They are launched via rcS.d, meaning they will be launched before OTHER 4 | Ec2 scripts, like ec2-get-credentials... so if need some of those scripts 5 | run before, call them manually 6 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/create-dirs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | make_dir() { 22 | mkdir -p $1 23 | if [ $2 ] ; then 24 | chown -R $2 $1 25 | fi 26 | } 27 | 28 | make_dir /mnt/app app:app 29 | 30 | #make sure it is setup to be able to be read/written by app user 31 | # Why have it owned (or even writeable) by app? Can't it just be owned by root and world readable? - Paul 32 | make_dir /etc/ec2onrails app:app 33 | make_dir /etc/ec2onrails/system_files app:app 34 | 35 | make_dir /mnt/log 36 | make_dir /mnt/log/fsck 37 | make_dir /mnt/log/god 38 | make_dir /mnt/log/mysql mysql:mysql 39 | make_dir /mnt/log/nginx nginx:nginx 40 | make_dir /mnt/log/varnish 41 | 42 | make_dir /mnt/varnish/ 43 | 44 | make_dir /mnt/tmp 45 | chmod 777 /mnt/tmp 46 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/generate-default-web-cert-and-key: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # Generate a new self-signed cert and key for https 23 | 24 | echo "Generating default self-signed SSL cert and key..." 25 | 26 | export RANDFILE=/tmp/randfile 27 | 28 | cd /tmp 29 | openssl genrsa -out server.key 1024 30 | openssl req -new -key server.key -out server.csr <. 20 | 21 | # Set the hostname to this instance's public hostname 22 | 23 | HOSTNAME=`curl -s http://169.254.169.254/latest/meta-data/local-hostname` 24 | hostname $HOSTNAME 25 | 26 | # Save it so it will be used after reboot 27 | echo $HOSTNAME > /etc/hostname 28 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/misc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | cp /etc/hosts /etc/hosts.original 23 | 24 | # make sure the db optimize is only run once... 25 | # the setup script will look for this flag, and 26 | # if it doesn't exist the db optimization won't occur 27 | touch /tmp/optimize_db_flag 28 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/prepare-mysql-data-dir: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | mkdir -p /mnt/mysql_data/tmp 23 | chown -R mysql:mysql /mnt/mysql_data/ 24 | cp -rp /var/lib/mysql/mysql /mnt/mysql_data/ 25 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-credentials: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | # 21 | # This file helps spread the root key so we can log in/deploy using the 22 | # app user instead of root, but with the same ec2 key 23 | 24 | 25 | # /etc/init.d/ec2-get-credentials is run as /etc/rc2.d/S70ec2-get-credentials, 26 | # but this script is run from /etc/rcS.d so the rc2.d scripts haven't 27 | # been run yet 28 | /etc/init.d/ec2-get-credentials 29 | 30 | mkdir -p -m 700 /home/app/.ssh 31 | cp /root/.ssh/authorized_keys /home/app/.ssh 32 | chown -R app:app /home/app/.ssh 33 | -------------------------------------------------------------------------------- /server/files/usr/local/ec2onrails/startup-scripts/first-startup/setup-file-permissions: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | # 21 | # Some of the files will need to have additional permissions than the 22 | # default settings, especially as the main app and deploy do not run 23 | # under the user 'root' but instead under the user 'app' 24 | # 25 | 26 | 27 | chmod 777 /tmp 28 | 29 | #make sure the god files hav the correct permissions set 30 | chmod 700 -R /etc/god 31 | -------------------------------------------------------------------------------- /server/rakefile-wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This file is part of EC2 on Rails. 4 | # http://rubyforge.org/projects/ec2onrails/ 5 | # 6 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 7 | # 8 | # EC2 on Rails is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # EC2 on Rails is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | 21 | 22 | # This script runs the EC2 on Rails rakefile, it's meant to be called by 23 | # Eric Hammond's Ubuntu build script: http://alestic.com/ 24 | 25 | cd `dirname $0` 26 | rake --trace 27 | -------------------------------------------------------------------------------- /server/test/autobench.conf: -------------------------------------------------------------------------------- 1 | # Autobench Configuration File 2 | 3 | # host1, host2 4 | # The hostnames of the servers under test 5 | # Eg. host1 = iis.test.com 6 | # host2 = apache.test.com 7 | 8 | file = out.tsv 9 | 10 | host1 = ec2-67-202-61-243.compute-1.amazonaws.com 11 | 12 | # uri1, uri2 13 | # The URI to test (relative to the document root). For a fair comparison 14 | # the files should be identical (although the paths to them may differ on the 15 | # different hosts) 16 | 17 | uri1 = / 18 | 19 | # port1, port2 20 | # The port number on which the servers are listening 21 | 22 | port1 = 80 23 | 24 | # low_rate, high_rate, rate_step 25 | # The 'rate' is the number of number of connections to open per second. 26 | # A series of tests will be conducted, starting at low rate, 27 | # increasing by rate step, and finishing at high_rate. 28 | # The default settings test at rates of 20,30,40,50...180,190,200 29 | 30 | low_rate = 1 31 | high_rate = 5 32 | rate_step = 1 33 | 34 | # num_conn, num_call 35 | # num_conn is the total number of connections to make during a test 36 | # num_call is the number of requests per connection 37 | # The product of num_call and rate is the the approximate number of 38 | # requests per second that will be attempted. 39 | 40 | num_conn = 1000 41 | num_call = 5 42 | 43 | # timeout sets the maximimum time (in seconds) that httperf will wait 44 | # for replies from the web server. If the timeout is exceeded, the 45 | # reply concerned is counted as an error. 46 | 47 | timeout = 10 48 | 49 | # output_fmt 50 | # sets the output type - may be either "csv", or "tsv"; 51 | 52 | output_fmt = tsv 53 | 54 | ## Config for distributed autobench (autobench_admin) 55 | # clients 56 | # comma separated list of the hostnames and portnumbers for the 57 | # autobench clients. No whitespace can appear before or after the commas. 58 | # clients = bench1.foo.com:4600,bench2.foo.com:4600,bench3.foo.com:4600 59 | 60 | #clients = localhost:4600 61 | -------------------------------------------------------------------------------- /server/test/spec/lib/s3_helper_spec.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'spec' 20 | require "#{File.dirname(__FILE__)}/../../../server/files/usr/local/ec2onrails/lib/s3_helper" 21 | 22 | REAL_S3_CONFIG = "#{File.dirname(__FILE__)}/../../../../local/s3.yml" 23 | MOCK_S3_CONFIG = "#{File.dirname(__FILE__)}/../../../examples/s3.yml" 24 | 25 | TEST_FILE_1 = "#{File.dirname(__FILE__)}/../test_files/test1" 26 | TEST_FILE_2 = "#{File.dirname(__FILE__)}/../test_files/test2" 27 | 28 | describe Ec2onrails::S3Helper do 29 | before(:each) do 30 | FileUtils.rm_f("/tmp/test*") 31 | end 32 | 33 | describe "with a mock connection" do 34 | before(:each) do 35 | bucket = mock("bucket") 36 | s3 = mock("s3") 37 | s3.stub!(:bucket).and_return bucket 38 | RightAws::S3.stub!(:new).and_return(s3) 39 | @s3_helper = Ec2onrails::S3Helper.new("bucket", nil, MOCK_S3_CONFIG, "production") 40 | end 41 | 42 | it "can load S3 config details from a config file with multiple environment sections" do 43 | @s3_helper.aws_access_key.should == "DEF456" 44 | @s3_helper.aws_secret_access_key.should == "def456def456def456def456" 45 | end 46 | 47 | it "can load S3 config details from a config file with no environment sections" do 48 | s3 = Ec2onrails::S3Helper.new("bucket", nil, "#{File.dirname(__FILE__)}/s3_old.yml", "production") 49 | s3.aws_access_key.should == "ABC123" 50 | s3.aws_secret_access_key.should == "abc123abc123abc123abc123" 51 | end 52 | 53 | it "can create an s3 key using a given filename" do 54 | @s3_helper.s3_key(TEST_FILE_1).should == "test1" 55 | end 56 | 57 | it "can create an s3 key using a given filename and a subdir name" do 58 | @s3_helper = Ec2onrails::S3Helper.new("bucket", "subdir", MOCK_S3_CONFIG, "production") 59 | @s3_helper.s3_key(TEST_FILE_1).should == "subdir/test1" 60 | end 61 | end 62 | 63 | describe "with a real connection" do 64 | # Integration tests to make sure we can use the real API 65 | # TODO these are currently broken, fix them and come up with a better way of specifying the real S3 credentials, maybe specify in ENV? 66 | before(:each) do 67 | @s3_helper = Ec2onrails::S3Helper.new("ec2onrails-test", nil, REAL_S3_CONFIG, "production") 68 | begin 69 | bucket = AWS::S3::Bucket.find(@s3_helper.bucket) 70 | bucket.delete_all 71 | # bucket.delete 72 | rescue AWS::S3::NoSuchBucket 73 | # no problem 74 | end 75 | end 76 | 77 | it "can create a bucket" do 78 | @s3_helper.create_bucket 79 | AWS::S3::Bucket.find(@s3_helper.bucket) 80 | end 81 | 82 | it "can upload a file to S3" do 83 | @s3_helper.store_file(TEST_FILE_1) 84 | AWS::S3::S3Object.find("test1", "ec2onrails-test") 85 | end 86 | 87 | it "can upload a file to S3 into a subdir" do 88 | @s3_helper = Ec2onrails::S3Helper.new("test", "subdir", REAL_S3_CONFIG, "production") 89 | @s3_helper.store_file(TEST_FILE_1) 90 | AWS::S3::S3Object.find("subdir/test1", "ec2onrails-test") 91 | end 92 | 93 | it "can retrieve a file from S3" do 94 | @s3_helper.store_file(TEST_FILE_1) 95 | AWS::S3::S3Object.find("test1", "ec2onrails-test") 96 | end 97 | 98 | it "can retrieve a file from S3 into a subdir" do 99 | @s3_helper = Ec2onrails::S3Helper.new("test", "subdir", REAL_S3_CONFIG, "production") 100 | @s3_helper.store_file(TEST_FILE_1) 101 | @s3_helper.retrieve_file("/tmp/test1") 102 | end 103 | 104 | it "can delete files with a given prefix" do 105 | @s3_helper.store_file(TEST_FILE_1) 106 | @s3_helper.store_file(TEST_FILE_2) 107 | AWS::S3::S3Object.find("test1", "ec2onrails-test") 108 | AWS::S3::S3Object.find("test2", "ec2onrails-test") 109 | @s3_helper.delete_files("test") 110 | lambda { 111 | AWS::S3::S3Object.find("test1", "ec2onrails-test") 112 | }.should raise_error 113 | lambda { 114 | AWS::S3::S3Object.find("test2", "ec2onrails-test") 115 | }.should raise_error 116 | end 117 | 118 | it "can delete files with a given prefix in a subdir" do 119 | @s3_helper = Ec2onrails::S3Helper.new("test", "subdir", REAL_S3_CONFIG, "production") 120 | @s3_helper.store_file(TEST_FILE_1) 121 | @s3_helper.store_file(TEST_FILE_2) 122 | AWS::S3::S3Object.find("subdir/test1", "ec2onrails-test") 123 | AWS::S3::S3Object.find("subdir/test2", "ec2onrails-test") 124 | @s3_helper.delete_files("test") 125 | lambda { 126 | AWS::S3::S3Object.find("subdir/test1", "ec2onrails-test") 127 | }.should raise_error 128 | lambda { 129 | AWS::S3::S3Object.find("subdir/test2", "ec2onrails-test") 130 | }.should raise_error 131 | end 132 | 133 | it "can retrieve files with a given prefix into a local dir" do 134 | @s3_helper.store_file(TEST_FILE_1) 135 | @s3_helper.store_file(TEST_FILE_2) 136 | AWS::S3::S3Object.find("test1", "ec2onrails-test") 137 | AWS::S3::S3Object.find("test2", "ec2onrails-test") 138 | @s3_helper.retrieve_files("test", "/tmp") 139 | File.exists?("/tmp/test1").should be_true 140 | File.exists?("/tmp/test2").should be_true 141 | end 142 | 143 | it "can retrieve files with a given prefix in a subdir into a local dir" do 144 | @s3_helper = Ec2onrails::S3Helper.new("test", "subdir", REAL_S3_CONFIG, "production") 145 | @s3_helper.store_file(TEST_FILE_1) 146 | @s3_helper.store_file(TEST_FILE_2) 147 | AWS::S3::S3Object.find("subdir/test1", "ec2onrails-test") 148 | AWS::S3::S3Object.find("subdir/test2", "ec2onrails-test") 149 | @s3_helper.retrieve_files("test", "/tmp") 150 | File.exists?("/tmp/test1").should be_true 151 | File.exists?("/tmp/test2").should be_true 152 | end 153 | end 154 | end -------------------------------------------------------------------------------- /server/test/spec/lib/s3_old.yml: -------------------------------------------------------------------------------- 1 | aws_access_key: ABC123 2 | aws_secret_access_key: abc123abc123abc123abc123 3 | bucket_base_name: yourbucket 4 | -------------------------------------------------------------------------------- /server/test/spec/lib/system_files_manifest_spec.rb: -------------------------------------------------------------------------------- 1 | # This file is part of EC2 on Rails. 2 | # http://rubyforge.org/projects/ec2onrails/ 3 | # 4 | # Copyright 2007 Paul Dowman, http://pauldowman.com/ 5 | # 6 | # EC2 on Rails is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # EC2 on Rails is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | require 'spec' 20 | require "#{File.dirname(__FILE__)}/../../../server/files/usr/local/ec2onrails/lib/system_files_manifest" 21 | 22 | TEST_FILES_ROOT = "#{File.dirname(__FILE__)}/../test_files" 23 | 24 | describe Ec2onrails::SystemFilesManifest do 25 | before(:each) do 26 | Ec2onrails::SystemFilesManifest.stub!(:log_error) 27 | end 28 | 29 | describe "with a valid directory that matches the manifest" do 30 | before(:each) do 31 | @dir = File.join TEST_FILES_ROOT, "system_files1" 32 | end 33 | 34 | it "can construct a new object from the directory" do 35 | Ec2onrails::SystemFilesManifest.new @dir 36 | end 37 | 38 | it "can construct a new object given the manifest file name" do 39 | Ec2onrails::SystemFilesManifest.new "#{@dir}/#{Ec2onrails::SystemFilesManifest::MANIFEST_FILE_NAME}" 40 | end 41 | 42 | it "recognizes the format of comment and empty lines" do 43 | m = Ec2onrails::SystemFilesManifest.new(@dir) 44 | m.comment_or_empty_line?("").should be_true 45 | m.comment_or_empty_line?(" ").should be_true 46 | m.comment_or_empty_line?(" ").should be_true 47 | m.comment_or_empty_line?("\t ").should be_true 48 | m.comment_or_empty_line?("#").should be_true 49 | m.comment_or_empty_line?(" #").should be_true 50 | m.comment_or_empty_line?("\t#").should be_true 51 | m.comment_or_empty_line?(" #xx ").should be_true 52 | m.comment_or_empty_line?(" #xx # ").should be_true 53 | 54 | m.comment_or_empty_line?(" x# ").should be_false 55 | m.comment_or_empty_line?(" x#xx ").should be_false 56 | m.comment_or_empty_line?("x#").should be_false 57 | end 58 | 59 | it "can provide metadata about the mode and owner of the file" do 60 | m = Ec2onrails::SystemFilesManifest.new @dir 61 | m["test1"].should == {:mode => nil, :owner => nil} 62 | m["test2"].should == {:mode => "777", :owner => "user1:user1"} 63 | m["testfolder"].should == {:mode => nil, :owner => nil} 64 | m["testfolder/test3"].should == {:mode => "700", :owner => "user2"} 65 | end 66 | 67 | it "can provide metadata about the file even if the filename has a leading slash appended" do 68 | m = Ec2onrails::SystemFilesManifest.new @dir 69 | m["/test1"].should == {:mode => nil, :owner => nil} 70 | end 71 | 72 | it "can provide metadata about the file even if the filename has the full server_files dir path appended" do 73 | m = Ec2onrails::SystemFilesManifest.new @dir 74 | m["#{@dir}/test1"].should == {:mode => nil, :owner => nil} 75 | end 76 | 77 | it "can normalize a given filename by removing the directories up to and including the server_files dir, and removing the leading slash" do 78 | m = Ec2onrails::SystemFilesManifest.new @dir 79 | m.normalize("test").should == "test" 80 | m.normalize("/test").should == "test" 81 | m.normalize("#{@dir}/test").should == "test" 82 | m.normalize("#{@dir}/x/test").should == "x/test" 83 | end 84 | 85 | it "can return all filenames as an array" do 86 | m = Ec2onrails::SystemFilesManifest.new @dir 87 | m.filenames.should == %w(test1 test2 testfolder testfolder/test3) 88 | end 89 | end 90 | 91 | describe "with a valid directory that doesn't match the manifest" do 92 | before(:each) do 93 | @dir = File.join TEST_FILES_ROOT, "system_files2" 94 | 95 | end 96 | 97 | it "should raise an error on new" do 98 | lambda {Ec2onrails::SystemFilesManifest.new @dir}.should raise_error 99 | end 100 | end 101 | 102 | describe "with a valid directory that contains no manifest" do 103 | before(:each) do 104 | @dir = File.join TEST_FILES_ROOT 105 | end 106 | 107 | it "should raise an error on new" do 108 | lambda {Ec2onrails::SystemFilesManifest.new @dir}.should raise_error 109 | end 110 | end 111 | 112 | describe "with an invalid directory" do 113 | before(:each) do 114 | @dir = "does_not_exist" 115 | end 116 | 117 | it "should raise an error on new" do 118 | lambda {Ec2onrails::SystemFilesManifest.new @dir}.should raise_error 119 | end 120 | end 121 | end 122 | 123 | -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files1/_manifest: -------------------------------------------------------------------------------- 1 | # This is a manifest file with comments 2 | 3 | # test1 has no metadata 4 | test1 5 | 6 | # test2 should have mode 777 and be owned by user1 7 | test2 mode=777 owner=user1:user1 8 | 9 | # testfolder has no metadata 10 | testfolder 11 | 12 | # test3 should be mode 700 and owned by user2 13 | testfolder/test3 mode=700 owner=user2 14 | -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files1/test1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/system_files1/test1 -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files1/test2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/system_files1/test2 -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files1/testfolder/test3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/system_files1/testfolder/test3 -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files2/_manifest: -------------------------------------------------------------------------------- 1 | test1 2 | foo 3 | -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files2/test1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/system_files2/test1 -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files2/test2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/system_files2/test2 -------------------------------------------------------------------------------- /server/test/spec/test_files/system_files2/testfolder/test3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/system_files2/testfolder/test3 -------------------------------------------------------------------------------- /server/test/spec/test_files/test2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/spec/test_files/test2 -------------------------------------------------------------------------------- /server/test/test_app/Capfile: -------------------------------------------------------------------------------- 1 | load 'deploy' if respond_to?(:namespace) # cap2 differentiator 2 | load 'config/deploy' 3 | require 'ec2onrails/recipes' 4 | -------------------------------------------------------------------------------- /server/test/test_app/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require(File.join(File.dirname(__FILE__), 'config', 'boot')) 5 | 6 | require 'rake' 7 | require 'rake/testtask' 8 | require 'rake/rdoctask' 9 | 10 | require 'tasks/rails' 11 | -------------------------------------------------------------------------------- /server/test/test_app/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | # Filters added to this controller apply to all controllers in the application. 2 | # Likewise, all the methods added will be available for all controllers. 3 | 4 | class ApplicationController < ActionController::Base 5 | helper :all # include all helpers, all the time 6 | protect_from_forgery # See ActionController::RequestForgeryProtection for details 7 | 8 | # Scrub sensitive parameters from your log 9 | # filter_parameter_logging :password 10 | end 11 | -------------------------------------------------------------------------------- /server/test/test_app/app/controllers/db_fast_controller.rb: -------------------------------------------------------------------------------- 1 | class DbFastController < ApplicationController 2 | def index 3 | ActiveRecord::Base.connection.execute("select * from schema_info") 4 | render :text => "Hello world! #{Time.now}" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /server/test/test_app/app/controllers/fast_controller.rb: -------------------------------------------------------------------------------- 1 | class FastController < ApplicationController 2 | def index 3 | render :text => "Hello world! #{Time.now}" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /server/test/test_app/app/controllers/slow_controller.rb: -------------------------------------------------------------------------------- 1 | class SlowController < ApplicationController 2 | def index 3 | sleep 1 4 | render :text => "Hello world! #{Time.now}" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /server/test/test_app/app/controllers/very_slow_controller.rb: -------------------------------------------------------------------------------- 1 | class VerySlowController < ApplicationController 2 | def index 3 | sleep 2 4 | render :text => "Hello world! #{Time.now}" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /server/test/test_app/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | # Methods added to this helper will be available to all templates in the application. 2 | module ApplicationHelper 3 | end 4 | -------------------------------------------------------------------------------- /server/test/test_app/config/boot.rb: -------------------------------------------------------------------------------- 1 | # Don't change this file! 2 | # Configure your app in config/environment.rb and config/environments/*.rb 3 | 4 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) 5 | 6 | module Rails 7 | class << self 8 | def boot! 9 | unless booted? 10 | preinitialize 11 | pick_boot.run 12 | end 13 | end 14 | 15 | def booted? 16 | defined? Rails::Initializer 17 | end 18 | 19 | def pick_boot 20 | (vendor_rails? ? VendorBoot : GemBoot).new 21 | end 22 | 23 | def vendor_rails? 24 | File.exist?("#{RAILS_ROOT}/vendor/rails") 25 | end 26 | 27 | def preinitialize 28 | load(preinitializer_path) if File.exist?(preinitializer_path) 29 | end 30 | 31 | def preinitializer_path 32 | "#{RAILS_ROOT}/config/preinitializer.rb" 33 | end 34 | end 35 | 36 | class Boot 37 | def run 38 | load_initializer 39 | Rails::Initializer.run(:set_load_path) 40 | end 41 | end 42 | 43 | class VendorBoot < Boot 44 | def load_initializer 45 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" 46 | Rails::Initializer.run(:install_gem_spec_stubs) 47 | Rails::GemDependency.add_frozen_gem_path 48 | end 49 | end 50 | 51 | class GemBoot < Boot 52 | def load_initializer 53 | self.class.load_rubygems 54 | load_rails_gem 55 | require 'initializer' 56 | end 57 | 58 | def load_rails_gem 59 | if version = self.class.gem_version 60 | gem 'rails', version 61 | else 62 | gem 'rails' 63 | end 64 | rescue Gem::LoadError => load_error 65 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) 66 | exit 1 67 | end 68 | 69 | class << self 70 | def rubygems_version 71 | Gem::RubyGemsVersion rescue nil 72 | end 73 | 74 | def gem_version 75 | if defined? RAILS_GEM_VERSION 76 | RAILS_GEM_VERSION 77 | elsif ENV.include?('RAILS_GEM_VERSION') 78 | ENV['RAILS_GEM_VERSION'] 79 | else 80 | parse_gem_version(read_environment_rb) 81 | end 82 | end 83 | 84 | def load_rubygems 85 | require 'rubygems' 86 | min_version = '1.3.1' 87 | unless rubygems_version >= min_version 88 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) 89 | exit 1 90 | end 91 | 92 | rescue LoadError 93 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) 94 | exit 1 95 | end 96 | 97 | def parse_gem_version(text) 98 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ 99 | end 100 | 101 | private 102 | def read_environment_rb 103 | File.read("#{RAILS_ROOT}/config/environment.rb") 104 | end 105 | end 106 | end 107 | end 108 | 109 | # All that for this: 110 | Rails.boot! 111 | -------------------------------------------------------------------------------- /server/test/test_app/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3-ruby (not necessary on OS X Leopard) 3 | development: 4 | adapter: sqlite3 5 | database: db/development.sqlite3 6 | pool: 5 7 | timeout: 5000 8 | 9 | # Warning: The database defined as "test" will be erased and 10 | # re-generated from your development database when you run "rake". 11 | # Do not set this db to the same as development or production. 12 | test: 13 | adapter: sqlite3 14 | database: db/test.sqlite3 15 | pool: 5 16 | timeout: 5000 17 | 18 | production: 19 | adapter: mysql 20 | database: testapp 21 | encoding: utf8 22 | username: testuser 23 | password: password 24 | host: db-primary-1 25 | -------------------------------------------------------------------------------- /server/test/test_app/config/deploy.rb: -------------------------------------------------------------------------------- 1 | set :application, "test_app" 2 | 3 | ssh_options[:keys] = [ENV['KEY']] 4 | 5 | raise "please add HOST=ec2-xxx.xx... on the command line" unless ENV['HOST'] 6 | set :host, ENV['HOST'] 7 | role :web, host 8 | role :db, host, :primary => true 9 | 10 | set :repository, "." 11 | set :scm, :none 12 | set :deploy_via, :copy 13 | 14 | set :rails_env, "production" 15 | 16 | # EC2 on Rails config 17 | set :ec2onrails_config, { 18 | :packages => [], 19 | :rubygems => [], 20 | :timezone => "Canada/Eastern", 21 | :services_to_restart => %w(sysklogd) 22 | } 23 | -------------------------------------------------------------------------------- /server/test/test_app/config/ec2onrails/config.rb: -------------------------------------------------------------------------------- 1 | { 2 | :proxy => { 3 | :caching_enabled => true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /server/test/test_app/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file 2 | 3 | # Specifies gem version of Rails to use when vendor/rails is not present 4 | RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION 5 | 6 | # Bootstrap the Rails environment, frameworks, and default configuration 7 | require File.join(File.dirname(__FILE__), 'boot') 8 | 9 | Rails::Initializer.run do |config| 10 | # Settings in config/environments/* take precedence over those specified here. 11 | # Application configuration should go into files in config/initializers 12 | # -- all .rb files in that directory are automatically loaded. 13 | 14 | # Add additional load paths for your own custom dirs 15 | # config.load_paths += %W( #{RAILS_ROOT}/extras ) 16 | 17 | # Specify gems that this application depends on and have them installed with rake gems:install 18 | # config.gem "bj" 19 | # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" 20 | # config.gem "sqlite3-ruby", :lib => "sqlite3" 21 | # config.gem "aws-s3", :lib => "aws/s3" 22 | 23 | # Only load the plugins named here, in the order given (default is alphabetical). 24 | # :all can be used as a placeholder for all plugins not explicitly named 25 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 26 | 27 | # Skip frameworks you're not going to use. To use Rails without a database, 28 | # you must remove the Active Record framework. 29 | # config.frameworks -= [ :active_record, :active_resource, :action_mailer ] 30 | 31 | # Activate observers that should always be running 32 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 33 | 34 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 35 | # Run "rake -D time" for a list of tasks for finding time zone names. 36 | config.time_zone = 'UTC' 37 | 38 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 39 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] 40 | # config.i18n.default_locale = :de 41 | end -------------------------------------------------------------------------------- /server/test/test_app/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # In the development environment your application's code is reloaded on 4 | # every request. This slows down response time but is perfect for development 5 | # since you don't have to restart the webserver when you make code changes. 6 | config.cache_classes = false 7 | 8 | # Log error messages when you accidentally call methods on nil. 9 | config.whiny_nils = true 10 | 11 | # Show full error reports and disable caching 12 | config.action_controller.consider_all_requests_local = true 13 | config.action_view.debug_rjs = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false -------------------------------------------------------------------------------- /server/test/test_app/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The production environment is meant for finished, "live" apps. 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.action_controller.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | config.action_view.cache_template_loading = true 11 | 12 | # See everything in the log (default is :info) 13 | # config.log_level = :debug 14 | 15 | # Use a different logger for distributed setups 16 | # config.logger = SyslogLogger.new 17 | 18 | # Use a different cache store in production 19 | # config.cache_store = :mem_cache_store 20 | 21 | # Enable serving of images, stylesheets, and javascripts from an asset server 22 | # config.action_controller.asset_host = "http://assets.example.com" 23 | 24 | # Disable delivery errors, bad email addresses will be ignored 25 | # config.action_mailer.raise_delivery_errors = false 26 | 27 | # Enable threaded mode 28 | # config.threadsafe! -------------------------------------------------------------------------------- /server/test/test_app/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | config.cache_classes = true 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.action_controller.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | config.action_view.cache_template_loading = true 16 | 17 | # Disable request forgery protection in test environment 18 | config.action_controller.allow_forgery_protection = false 19 | 20 | # Tell Action Mailer not to deliver emails to the real world. 21 | # The :test delivery method accumulates sent emails in the 22 | # ActionMailer::Base.deliveries array. 23 | config.action_mailer.delivery_method = :test 24 | 25 | # Use SQL instead of Active Record's schema dumper when creating the test database. 26 | # This is necessary if your schema can't be completely dumped by the schema dumper, 27 | # like if you have constraints or database-specific column types 28 | # config.active_record.schema_format = :sql -------------------------------------------------------------------------------- /server/test/test_app/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! -------------------------------------------------------------------------------- /server/test/test_app/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /server/test/test_app/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /server/test/test_app/config/initializers/new_rails_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # These settings change the behavior of Rails 2 apps and will be defaults 4 | # for Rails 3. You can remove this initializer when Rails 3 is released. 5 | 6 | if defined?(ActiveRecord) 7 | # Include Active Record class name as root for JSON serialized output. 8 | ActiveRecord::Base.include_root_in_json = true 9 | 10 | # Store the full class name (including module namespace) in STI type column. 11 | ActiveRecord::Base.store_full_sti_class = true 12 | end 13 | 14 | # Use ISO 8601 format for JSON serialized times and dates. 15 | ActiveSupport.use_standard_json_time_format = true 16 | 17 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper. 18 | # if you're including raw json in an HTML page. 19 | ActiveSupport.escape_html_entities_in_json = false -------------------------------------------------------------------------------- /server/test/test_app/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying cookie session data integrity. 4 | # If you change this key, all old sessions will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ActionController::Base.session = { 8 | :key => '_test_app_session', 9 | :secret => '14c5fbdf388960812e565662848009638c51f5e3ae38f912461c02013bdf5fbf897387c84edec80b72c2d1597d05002fd4a206c3bfe02b4dba4f77e05eb41da1' 10 | } 11 | 12 | # Use the database for sessions instead of the cookie-based default, 13 | # which shouldn't be used to store highly confidential information 14 | # (create the session table with "rake db:sessions:create") 15 | # ActionController::Base.session_store = :active_record_store 16 | -------------------------------------------------------------------------------- /server/test/test_app/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" -------------------------------------------------------------------------------- /server/test/test_app/config/routes.rb: -------------------------------------------------------------------------------- 1 | ActionController::Routing::Routes.draw do |map| 2 | # The priority is based upon order of creation: first created -> highest priority. 3 | 4 | # Sample of regular route: 5 | # map.connect 'products/:id', :controller => 'catalog', :action => 'view' 6 | # Keep in mind you can assign values other than :controller and :action 7 | 8 | # Sample of named route: 9 | # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' 10 | # This route can be invoked with purchase_url(:id => product.id) 11 | 12 | # Sample resource route (maps HTTP verbs to controller actions automatically): 13 | # map.resources :products 14 | 15 | # Sample resource route with options: 16 | # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } 17 | 18 | # Sample resource route with sub-resources: 19 | # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller 20 | 21 | # Sample resource route with more complex sub-resources 22 | # map.resources :products do |products| 23 | # products.resources :comments 24 | # products.resources :sales, :collection => { :recent => :get } 25 | # end 26 | 27 | # Sample resource route within a namespace: 28 | # map.namespace :admin do |admin| 29 | # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) 30 | # admin.resources :products 31 | # end 32 | 33 | # You can have the root of your site routed with map.root -- just remember to delete public/index.html. 34 | # map.root :controller => "welcome" 35 | 36 | # See how all your routes lay out with "rake routes" 37 | 38 | # Install the default routes as the lowest priority. 39 | # Note: These default routes make all actions in every controller accessible via GET requests. You should 40 | # consider removing the them or commenting them out if you're using named routes and resources. 41 | map.connect ':controller/:action/:id' 42 | map.connect ':controller/:action/:id.:format' 43 | end 44 | -------------------------------------------------------------------------------- /server/test/test_app/doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /server/test/test_app/public/404.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The page you were looking for doesn't exist (404) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The page you were looking for doesn't exist.

27 |

You may have mistyped the address or the page may have moved.

28 |
29 | 30 | -------------------------------------------------------------------------------- /server/test/test_app/public/422.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The change you wanted was rejected (422) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The change you wanted was rejected.

27 |

Maybe you tried to change something you didn't have access to.

28 |
29 | 30 | -------------------------------------------------------------------------------- /server/test/test_app/public/500.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | We're sorry, but something went wrong (500) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

We're sorry, but something went wrong.

27 |

We've been notified about this issue and we'll take a look at it shortly.

28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /server/test/test_app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/test_app/public/favicon.ico -------------------------------------------------------------------------------- /server/test/test_app/public/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pauldowman/ec2onrails/cea7c67757133767f80d7659f4f6f11a07f4fe94/server/test/test_app/public/images/rails.png -------------------------------------------------------------------------------- /server/test/test_app/public/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Ruby on Rails: Welcome aboard 7 | 181 | 182 | 183 | 204 | 205 | 206 |
207 | 237 | 238 |
239 | 243 | 244 | 248 | 249 |
250 |

Getting started

251 |

Here’s how to get rolling:

252 | 253 |
    254 |
  1. 255 |

    Use script/generate to create your models and controllers

    256 |

    To see all available options, run it without parameters.

    257 |
  2. 258 | 259 |
  3. 260 |

    Set up a default route and remove or rename this file

    261 |

    Routes are set up in config/routes.rb.

    262 |
  4. 263 | 264 |
  5. 265 |

    Create your database

    266 |

    Run rake db:migrate to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

    267 |
  6. 268 |
269 |
270 |
271 | 272 | 273 |
274 | 275 | -------------------------------------------------------------------------------- /server/test/test_app/public/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // Place your application-specific JavaScript functions and classes here 2 | // This file is automatically included by javascript_include_tag :defaults 3 | -------------------------------------------------------------------------------- /server/test/test_app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /server/test/test_app/script/about: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" 4 | require 'commands/about' -------------------------------------------------------------------------------- /server/test/test_app/script/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/console' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/dbconsole: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/dbconsole' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/destroy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/destroy' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/generate' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/performance/benchmarker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../../config/boot' 3 | require 'commands/performance/benchmarker' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/performance/profiler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../../config/boot' 3 | require 'commands/performance/profiler' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/plugin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/plugin' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/runner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/runner' 4 | -------------------------------------------------------------------------------- /server/test/test_app/script/server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | require 'commands/server' 4 | -------------------------------------------------------------------------------- /server/test/test_app/test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'performance_test_help' 3 | 4 | # Profiling results for each test method are written to tmp/performance. 5 | class BrowsingTest < ActionController::PerformanceTest 6 | def test_homepage 7 | get '/' 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /server/test/test_app/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") 3 | require 'test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Transactional fixtures accelerate your tests by wrapping each test method 7 | # in a transaction that's rolled back on completion. This ensures that the 8 | # test database remains unchanged so your fixtures don't have to be reloaded 9 | # between every test method. Fewer database queries means faster tests. 10 | # 11 | # Read Mike Clark's excellent walkthrough at 12 | # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting 13 | # 14 | # Every Active Record database supports transactions except MyISAM tables 15 | # in MySQL. Turn off transactional fixtures in this case; however, if you 16 | # don't care one way or the other, switching from MyISAM to InnoDB tables 17 | # is recommended. 18 | # 19 | # The only drawback to using transactional fixtures is when you actually 20 | # need to test transactions. Since your test is bracketed by a transaction, 21 | # any transactions started in your code will be automatically rolled back. 22 | self.use_transactional_fixtures = true 23 | 24 | # Instantiated fixtures are slow, but give you @david where otherwise you 25 | # would need people(:david). If you don't want to migrate your existing 26 | # test cases which use the @david style and don't mind the speed hit (each 27 | # instantiated fixtures translates to a database query per test method), 28 | # then set this back to true. 29 | self.use_instantiated_fixtures = false 30 | 31 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 32 | # 33 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 34 | # -- they do not yet inherit this setting 35 | fixtures :all 36 | 37 | # Add more helper methods to be used by all tests here... 38 | end 39 | --------------------------------------------------------------------------------