├── gem
├── VERSION
├── lib
│ ├── ec2onrails
│ │ ├── recipes
│ │ │ └── deploy.rb
│ │ ├── version_helper.rb
│ │ ├── capistrano_utils.rb
│ │ └── recipes.rb
│ └── ec2onrails.rb
└── Rakefile
├── server
├── test
│ ├── spec
│ │ ├── test_files
│ │ │ ├── test2
│ │ │ ├── system_files1
│ │ │ │ ├── test1
│ │ │ │ ├── test2
│ │ │ │ ├── testfolder
│ │ │ │ │ └── test3
│ │ │ │ └── _manifest
│ │ │ └── system_files2
│ │ │ │ ├── test1
│ │ │ │ ├── test2
│ │ │ │ ├── testfolder
│ │ │ │ └── test3
│ │ │ │ └── _manifest
│ │ └── lib
│ │ │ ├── s3_old.yml
│ │ │ ├── system_files_manifest_spec.rb
│ │ │ └── s3_helper_spec.rb
│ ├── test_app
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ ├── images
│ │ │ │ └── rails.png
│ │ │ ├── javascripts
│ │ │ │ └── application.js
│ │ │ ├── robots.txt
│ │ │ ├── 422.html
│ │ │ ├── 404.html
│ │ │ ├── 500.html
│ │ │ └── index.html
│ │ ├── config
│ │ │ ├── ec2onrails
│ │ │ │ └── config.rb
│ │ │ ├── locales
│ │ │ │ └── en.yml
│ │ │ ├── initializers
│ │ │ │ ├── mime_types.rb
│ │ │ │ ├── inflections.rb
│ │ │ │ ├── backtrace_silencers.rb
│ │ │ │ ├── new_rails_defaults.rb
│ │ │ │ └── session_store.rb
│ │ │ ├── deploy.rb
│ │ │ ├── database.yml
│ │ │ ├── environments
│ │ │ │ ├── development.rb
│ │ │ │ ├── production.rb
│ │ │ │ └── test.rb
│ │ │ ├── routes.rb
│ │ │ ├── environment.rb
│ │ │ └── boot.rb
│ │ ├── script
│ │ │ ├── plugin
│ │ │ ├── runner
│ │ │ ├── server
│ │ │ ├── console
│ │ │ ├── destroy
│ │ │ ├── generate
│ │ │ ├── dbconsole
│ │ │ ├── performance
│ │ │ │ ├── profiler
│ │ │ │ └── benchmarker
│ │ │ └── about
│ │ ├── Capfile
│ │ ├── app
│ │ │ ├── helpers
│ │ │ │ └── application_helper.rb
│ │ │ └── controllers
│ │ │ │ ├── fast_controller.rb
│ │ │ │ ├── slow_controller.rb
│ │ │ │ ├── very_slow_controller.rb
│ │ │ │ ├── db_fast_controller.rb
│ │ │ │ └── application_controller.rb
│ │ ├── doc
│ │ │ └── README_FOR_APP
│ │ ├── test
│ │ │ ├── performance
│ │ │ │ └── browsing_test.rb
│ │ │ └── test_helper.rb
│ │ └── Rakefile
│ └── autobench.conf
├── files
│ ├── etc
│ │ ├── ec2onrails
│ │ │ ├── rails_env
│ │ │ └── roles.yml
│ │ ├── nginx
│ │ │ ├── conf.d
│ │ │ │ └── custom.conf
│ │ │ └── nginx.conf.erb
│ │ ├── aliases
│ │ ├── postfix
│ │ │ └── main.cf
│ │ ├── logrotate.d
│ │ │ ├── god
│ │ │ ├── rails
│ │ │ ├── nginx
│ │ │ └── varnish
│ │ ├── environment
│ │ ├── event.d
│ │ │ └── god
│ │ ├── README
│ │ ├── god
│ │ │ ├── notifications.god
│ │ │ ├── db_primary.god
│ │ │ ├── memcache.god
│ │ │ ├── dkim_filter.god
│ │ │ ├── web.god
│ │ │ ├── system.god
│ │ │ ├── master.conf
│ │ │ └── proxy.god
│ │ ├── default
│ │ │ ├── varnishncsa
│ │ │ └── varnish
│ │ ├── motd.tail
│ │ ├── dpkg
│ │ │ └── dpkg.cfg
│ │ ├── cron.d
│ │ │ └── ec2onrails
│ │ ├── cron.daily
│ │ │ ├── app
│ │ │ └── logrotate_post
│ │ ├── cron.hourly
│ │ │ └── app
│ │ ├── cron.weekly
│ │ │ └── app
│ │ ├── cron.monthly
│ │ │ └── app
│ │ ├── init.d
│ │ │ ├── ec2-every-startup
│ │ │ ├── ec2-first-startup
│ │ │ └── nginx
│ │ ├── sudoers
│ │ ├── memcached.conf
│ │ ├── syslog.conf
│ │ ├── ssh
│ │ │ └── sshd_config
│ │ ├── varnish
│ │ │ └── default.vcl.erb
│ │ └── mysql
│ │ │ └── my.cnf
│ └── usr
│ │ └── local
│ │ └── ec2onrails
│ │ ├── startup-scripts
│ │ ├── every-startup
│ │ │ ├── README
│ │ │ └── create-mysqld-pid-dir
│ │ └── first-startup
│ │ │ ├── README
│ │ │ ├── prepare-mysql-data-dir
│ │ │ ├── misc
│ │ │ ├── get-hostname
│ │ │ ├── setup-file-permissions
│ │ │ ├── setup-credentials
│ │ │ ├── create-dirs
│ │ │ └── generate-default-web-cert-and-key
│ │ ├── lib
│ │ ├── utils.rb
│ │ ├── god_helper.rb
│ │ ├── aws_helper.rb
│ │ ├── mysql_helper.rb
│ │ ├── system_files_manifest.rb
│ │ ├── system_files_helper.rb
│ │ ├── s3_helper.rb
│ │ ├── roles_helper.rb
│ │ └── vendor
│ │ │ └── ini.rb
│ │ ├── bin
│ │ ├── public-hostname
│ │ ├── in_role
│ │ ├── rails_env
│ │ ├── set_roles
│ │ ├── uninstall_system_files
│ │ ├── archive_file
│ │ ├── init_services
│ │ ├── set_rails_env
│ │ ├── restore_app_db
│ │ ├── rebundle
│ │ ├── install_system_files
│ │ ├── ec2_meta_data
│ │ ├── exec_runner
│ │ ├── backup_dir
│ │ └── backup_app_db
│ │ └── config
├── rakefile-wrapper
└── build
├── ami_ids.yml
├── examples
├── Capfile
├── s3.yml
└── deploy.rb
├── .gitignore
└── TODO
/gem/VERSION:
--------------------------------------------------------------------------------
1 | 0.9.11
2 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/test2:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/test_app/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/files/etc/ec2onrails/rails_env:
--------------------------------------------------------------------------------
1 | production
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files1/test1:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files1/test2:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files2/test1:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files2/test2:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files1/testfolder/test3:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files2/testfolder/test3:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/test/spec/test_files/system_files2/_manifest:
--------------------------------------------------------------------------------
1 | test1
2 | foo
3 |
--------------------------------------------------------------------------------
/server/files/etc/ec2onrails/roles.yml:
--------------------------------------------------------------------------------
1 | ---
2 | :memcache:
3 | :db_primary:
4 | :web:
5 | :proxy:
6 |
--------------------------------------------------------------------------------
/ami_ids.yml:
--------------------------------------------------------------------------------
1 | us:
2 | 32bit: ami-1501e27c
3 | 64bit: n/a
4 | eu:
5 | 32bit: n/a
6 | 64bit: n/a
7 |
--------------------------------------------------------------------------------
/server/test/test_app/config/ec2onrails/config.rb:
--------------------------------------------------------------------------------
1 | {
2 | :proxy => {
3 | :caching_enabled => true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/server/files/etc/nginx/conf.d/custom.conf:
--------------------------------------------------------------------------------
1 | # Overwrite this file with any custom configuration, it gets included inside the server directive
--------------------------------------------------------------------------------
/examples/Capfile:
--------------------------------------------------------------------------------
1 | load 'deploy' if respond_to?(:namespace) # cap2 differentiator
2 | load 'config/deploy'
3 | require 'ec2onrails/recipes'
4 |
--------------------------------------------------------------------------------
/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/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/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/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/test/test_app/public/images/rails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pauldowman/ec2onrails/HEAD/server/test/test_app/public/images/rails.png
--------------------------------------------------------------------------------
/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/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/Capfile:
--------------------------------------------------------------------------------
1 | load 'deploy' if respond_to?(:namespace) # cap2 differentiator
2 | load 'config/deploy'
3 | require 'ec2onrails/recipes'
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/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/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/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/script/performance/benchmarker:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require File.dirname(__FILE__) + '/../../config/boot'
3 | require 'commands/performance/benchmarker'
4 |
--------------------------------------------------------------------------------
/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/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/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'
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.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.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/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/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/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/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/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/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/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/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/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/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/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/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/usr/local/ec2onrails/startup-scripts/first-startup/get-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 | # 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/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/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 <= 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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | -
255 |
Use script/generate to create your models and controllers
256 | To see all available options, run it without parameters.
257 |
258 |
259 | -
260 |
Set up a default route and remove or rename this file
261 | Routes are set up in config/routes.rb.
262 |
263 |
264 | -
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 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
--------------------------------------------------------------------------------