railsmachine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +506 -0
- data/LICENSE +506 -0
- data/README +6 -0
- data/Rakefile +52 -0
- data/bin/railsmachine +35 -0
- data/lib/railsmachine/generators/loader.rb +20 -0
- data/lib/railsmachine/generators/railsmachine/USAGE +12 -0
- data/lib/railsmachine/generators/railsmachine/railsmachine_generator.rb +24 -0
- data/lib/railsmachine/generators/railsmachine/templates/deploy.rb +76 -0
- data/lib/railsmachine/recipes.rb +104 -0
- data/lib/railsmachine/recipes/apache.rb +70 -0
- data/lib/railsmachine/recipes/mongrel.rb +1 -0
- data/lib/railsmachine/recipes/mysql.rb +58 -0
- data/lib/railsmachine/recipes/svn.rb +42 -0
- data/lib/railsmachine/recipes/templates/httpd-ssl.conf +74 -0
- data/lib/railsmachine/recipes/templates/httpd.conf +63 -0
- data/resources/defaults.yaml +3 -0
- data/resources/pound.conf +18 -0
- data/tools/rakehelp.rb +105 -0
- metadata +86 -0
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'tools/rakehelp'
|
7
|
+
require 'fileutils'
|
8
|
+
include FileUtils
|
9
|
+
|
10
|
+
setup_tests
|
11
|
+
setup_clean ["pkg", "lib/*.bundle", "*.gem", ".config"]
|
12
|
+
|
13
|
+
setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
|
14
|
+
|
15
|
+
desc "Does a full compile, test run"
|
16
|
+
task :default => [:test, :package]
|
17
|
+
|
18
|
+
version="0.1.0"
|
19
|
+
name="railsmachine"
|
20
|
+
|
21
|
+
setup_gem(name, version) do |spec|
|
22
|
+
spec.summary = "The Rails Machine task library"
|
23
|
+
spec.description = spec.summary
|
24
|
+
spec.author="Bradley Taylor"
|
25
|
+
spec.add_dependency('capistrano', '>= 1.1.0')
|
26
|
+
spec.add_dependency('mongrel_cluster', '>= 0.2.0')
|
27
|
+
spec.has_rdoc = false
|
28
|
+
spec.files += Dir.glob("bin/*")
|
29
|
+
spec.files += Dir.glob("resources/**/*")
|
30
|
+
spec.default_executable = "railsmachine"
|
31
|
+
spec.executables = ["railsmachine"]
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
task :install => [:test, :package] do
|
36
|
+
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
37
|
+
end
|
38
|
+
|
39
|
+
task :uninstall => [:clean] do
|
40
|
+
sh %{sudo gem uninstall #{name}}
|
41
|
+
end
|
42
|
+
|
43
|
+
task :gem_source do
|
44
|
+
mkdir_p "pkg/gems"
|
45
|
+
|
46
|
+
FileList["**/*.gem"].each { |gem| mv gem, "pkg/gems" }
|
47
|
+
FileList["pkg/*.tgz"].each {|tgz| rm tgz }
|
48
|
+
rm_rf "pkg/#{name}-#{version}"
|
49
|
+
|
50
|
+
sh %{ generate_yaml_index.rb -d pkg }
|
51
|
+
sh %{ scp -r pkg/* #{ENV['SSH_USER']}@rubyforge.org:/var/www/gforge-projects/railsmachine/releases/ }
|
52
|
+
end
|
data/bin/railsmachine
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'rubygems'
|
5
|
+
rescue LoadError
|
6
|
+
# no rubygems to load, so we fail silently
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
@options = {}
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: #{$0} [options] [args]"
|
14
|
+
|
15
|
+
opts.on("-A", "--apply-to DIRECTORY",
|
16
|
+
"Create a minimal set of scripts and recipes",
|
17
|
+
"for use with capistrano to configure servers."
|
18
|
+
) { |value| @options[:apply_to] = value }
|
19
|
+
opts.on("-n", "--name APPLICATION_NAME",
|
20
|
+
"Name of application."
|
21
|
+
) { |value| @options[:application] = value }
|
22
|
+
opts.on("-d", "--domain DOMAIN_NAME",
|
23
|
+
"Domain name for application."
|
24
|
+
) { |value| @options[:domain] = value }
|
25
|
+
|
26
|
+
if ARGV.empty?
|
27
|
+
puts opts
|
28
|
+
exit
|
29
|
+
else
|
30
|
+
opts.parse!(ARGV)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'railsmachine/generators/loader'
|
35
|
+
RailsMachine::Generators::RailsLoader.load! @options
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RailsMachine
|
2
|
+
module Generators
|
3
|
+
class RailsLoader
|
4
|
+
def self.load!(options)
|
5
|
+
require "#{options[:apply_to]}/config/environment"
|
6
|
+
require "rails_generator"
|
7
|
+
require "rails_generator/scripts/generate"
|
8
|
+
|
9
|
+
Rails::Generator::Base.sources << Rails::Generator::PathSource.new(
|
10
|
+
:railsmachine, File.dirname(__FILE__))
|
11
|
+
|
12
|
+
args = ["railsmachine"]
|
13
|
+
args << (options[:application] || "Application")
|
14
|
+
args << (options[:domain] || "my.railsmachina.com")
|
15
|
+
|
16
|
+
Rails::Generator::Scripts::Generate.new.run(args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
NAME
|
2
|
+
railsmachine - creates configuration and SwitchTower tasks for server configuration.
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
railsmachine [Application name]
|
6
|
+
|
7
|
+
DESCRIPTION
|
8
|
+
This generator creates rakefiles and deployment recipes.
|
9
|
+
|
10
|
+
|
11
|
+
EXAMPLE
|
12
|
+
./script/generate railsmachine MyRockinApp
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class RailsmachineGenerator < Rails::Generator::NamedBase
|
2
|
+
attr_reader :application_name
|
3
|
+
attr_reader :domain_name
|
4
|
+
|
5
|
+
def initialize(runtime_args, runtime_options = {})
|
6
|
+
super
|
7
|
+
@application_name = self.file_name
|
8
|
+
@domain_name = @args[0]
|
9
|
+
end
|
10
|
+
|
11
|
+
def manifest
|
12
|
+
record do |m|
|
13
|
+
m.directory "config"
|
14
|
+
m.template "deploy.rb", File.join("config", "deploy.rb")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
# Override with your own usage banner.
|
21
|
+
def banner
|
22
|
+
"Usage: #{$0} railsmachine ApplicationName DomainName"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'railsmachine/recipes'
|
2
|
+
|
3
|
+
# This defines a deployment "recipe" that you can feed to capistrano
|
4
|
+
# (http://manuals.rubyonrails.com/read/book/17). It allows you to automate
|
5
|
+
# (among other things) the deployment of your application.
|
6
|
+
|
7
|
+
# =============================================================================
|
8
|
+
# REQUIRED VARIABLES
|
9
|
+
# =============================================================================
|
10
|
+
# You must always specify the application and repository for every recipe. The
|
11
|
+
# repository must be the URL of the repository you want this recipe to
|
12
|
+
# correspond to. The deploy_to path must be the path on each machine that will
|
13
|
+
# form the root of the application path.
|
14
|
+
|
15
|
+
set :application, "<%= singular_name %>"
|
16
|
+
set :deploy_to, "/var/www/apps/#{application}"
|
17
|
+
set :domain, "<%= domain_name %>"
|
18
|
+
|
19
|
+
set :user, "deploy"
|
20
|
+
set :repository, "svn+ssh://#{user}@#{domain}#{deploy_to}/repos/trunk"
|
21
|
+
set :rails_env, "production"
|
22
|
+
|
23
|
+
# Automatically symlink these directories from curent/public to shared/public.
|
24
|
+
# set :app_symlinks, %w{photo, document, asset}
|
25
|
+
|
26
|
+
# =============================================================================
|
27
|
+
# ROLES
|
28
|
+
# =============================================================================
|
29
|
+
# You can define any number of roles, each of which contains any number of
|
30
|
+
# machines. Roles might include such things as :web, or :app, or :db, defining
|
31
|
+
# what the purpose of each machine is. You can also specify options that can
|
32
|
+
# be used to single out a specific subset of boxes in a particular role, like
|
33
|
+
# :primary => true.
|
34
|
+
|
35
|
+
role :web, domain
|
36
|
+
role :app, domain
|
37
|
+
role :db, domain, :primary => true
|
38
|
+
role :scm, domain
|
39
|
+
|
40
|
+
# =============================================================================
|
41
|
+
# APACHE OPTIONS
|
42
|
+
# =============================================================================
|
43
|
+
# set :apache_server_name, domain
|
44
|
+
# set :apache_server_aliases, %w{alias1 alias2}
|
45
|
+
# set :apache_default_vhost, true # force use of apache_default_vhost_config
|
46
|
+
# set :apache_default_vhost_conf, "/etc/httpd/conf/default.conf"
|
47
|
+
# set :apache_conf, "/etc/httpd/conf/apps/#{application}.conf"
|
48
|
+
# set :apache_ctl, "/etc/init.d/httpd"
|
49
|
+
# set :apache_proxy_port, 8000
|
50
|
+
# set :apache_proxy_servers, 2
|
51
|
+
# set :apache_proxy_address, "127.0.0.1"
|
52
|
+
# set :apache_ssl_enabled, false
|
53
|
+
# set :apache_ssl_ip, "127.0.0.1"
|
54
|
+
# set :apache_ssl_forward_all, false
|
55
|
+
|
56
|
+
# =============================================================================
|
57
|
+
# MONGREL OPTIONS
|
58
|
+
# =============================================================================
|
59
|
+
# set :mongrel_servers, apache_proxy_servers
|
60
|
+
# set :mongrel_port, apache_proxy_port
|
61
|
+
# set :mongrel_address, apache_proxy_address
|
62
|
+
# set :mongrel_environment, "production"
|
63
|
+
# set :mongrel_config, "/etc/mongrel_cluster/#{application}.conf"
|
64
|
+
# set :mongrel_user, user
|
65
|
+
# set :mongrel_group, group
|
66
|
+
|
67
|
+
# =============================================================================
|
68
|
+
# MYSQL OPTIONS
|
69
|
+
# =============================================================================
|
70
|
+
|
71
|
+
|
72
|
+
# =============================================================================
|
73
|
+
# SSH OPTIONS
|
74
|
+
# =============================================================================
|
75
|
+
# ssh_options[:keys] = %w(/path/to/my/key /path/to/another/key)
|
76
|
+
# ssh_options[:port] = 25
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'railsmachine/recipes/svn'
|
2
|
+
require 'railsmachine/recipes/mysql'
|
3
|
+
require 'railsmachine/recipes/apache'
|
4
|
+
require 'railsmachine/recipes/mongrel'
|
5
|
+
|
6
|
+
Capistrano.configuration(:must_exist).load do
|
7
|
+
set :app_symlinks, nil
|
8
|
+
|
9
|
+
desc "Setup servers."
|
10
|
+
task :setup_servers do
|
11
|
+
setup_db
|
12
|
+
setup_app
|
13
|
+
setup_web
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Setup application server."
|
17
|
+
task :setup_app, :roles => :app do
|
18
|
+
set :mongrel_environment, rails_env
|
19
|
+
set :mongrel_port, apache_proxy_port
|
20
|
+
set :mongrel_servers, apache_proxy_servers
|
21
|
+
configure_mongrel_cluster
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Restart application server."
|
25
|
+
task :restart_app, :roles => :app do
|
26
|
+
restart_mongrel_cluster
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "Start application server."
|
30
|
+
task :start_app, :roles => :app do
|
31
|
+
start_mongrel_cluster
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Stop application server."
|
35
|
+
task :stop_app, :roles => :app do
|
36
|
+
stop_mongrel_cluster
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Setup web server."
|
40
|
+
task :setup_web, :roles => :web do
|
41
|
+
set :apache_server_name, domain
|
42
|
+
configure_apache
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Restart web server."
|
46
|
+
task :restart_web, :roles => :web do
|
47
|
+
restart_apache
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Reload web server configuration."
|
51
|
+
task :reload_web, :roles => :web do
|
52
|
+
reload_apache
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Start web server."
|
56
|
+
task :start_web, :roles => :web do
|
57
|
+
start_apache
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Stop web server."
|
61
|
+
task :stop_web, :roles => :web do
|
62
|
+
stop_apache
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Setup database server."
|
66
|
+
task :setup_db, :roles => :db, :only => { :primary => true } do
|
67
|
+
setup_mysql
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Setup source control server."
|
71
|
+
task :setup_scm, :roles => :scm do
|
72
|
+
setup_svn
|
73
|
+
import_svn
|
74
|
+
end
|
75
|
+
|
76
|
+
desc <<-DESC
|
77
|
+
Restart the processes on the application server by calling restart_app.
|
78
|
+
DESC
|
79
|
+
task :restart, :roles => :app do
|
80
|
+
restart_app
|
81
|
+
end
|
82
|
+
|
83
|
+
desc <<-DESC
|
84
|
+
Start the processes on the application server by calling start_app.
|
85
|
+
DESC
|
86
|
+
task :spinner, :roles => :app do
|
87
|
+
start_app
|
88
|
+
end
|
89
|
+
|
90
|
+
desc "Link up any directories."
|
91
|
+
task :after_symlink, :roles => :app do
|
92
|
+
if app_symlinks
|
93
|
+
app_symlinks.each { |link| run "ln -nfs #{shared_path}/public/#{link} #{current_path}/public/#{link}" }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Setup symlink dirs"
|
98
|
+
task :after_setup, :roles => :app do
|
99
|
+
if app_symlinks
|
100
|
+
app_symlinks.each { |link| run "mkdir #{shared_path}/#{link}" }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
Capistrano.configuration(:must_exist).load do
|
2
|
+
|
3
|
+
set :apache_server_name, nil
|
4
|
+
set :apache_conf, nil
|
5
|
+
set :apache_default_vhost, false
|
6
|
+
set :apache_default_vhost_conf, nil
|
7
|
+
set :apache_ctl, "/etc/init.d/httpd"
|
8
|
+
set :apache_server_aliases, []
|
9
|
+
set :apache_proxy_port, 8000
|
10
|
+
set :apache_proxy_servers, 2
|
11
|
+
set :apache_proxy_address, "127.0.0.1"
|
12
|
+
set :apache_ssl_enabled, false
|
13
|
+
set :apache_ssl_ip, nil
|
14
|
+
set :apache_ssl_forward_all, false
|
15
|
+
|
16
|
+
desc "Configure Apache. This uses the :use_sudo
|
17
|
+
variable to determine whether to use sudo or not. By default, :use_sudo is
|
18
|
+
set to true."
|
19
|
+
task :configure_apache, :roles => :web do
|
20
|
+
set_apache_conf
|
21
|
+
set :apache_server_name, domain unless apache_server_name
|
22
|
+
|
23
|
+
server_aliases = []
|
24
|
+
server_aliases << "www.#{domain}"
|
25
|
+
server_aliases.concat apache_server_aliases
|
26
|
+
set :apache_server_aliases_array, server_aliases
|
27
|
+
|
28
|
+
file = File.join(File.dirname(__FILE__), "templates", "httpd.conf")
|
29
|
+
buffer = render :template => File.read(file)
|
30
|
+
|
31
|
+
if apache_ssl_enabled
|
32
|
+
file = File.join(File.dirname(__FILE__), "templates", "httpd-ssl.conf")
|
33
|
+
ssl_buffer = render :template => File.read(file)
|
34
|
+
buffer += ssl_buffer
|
35
|
+
end
|
36
|
+
|
37
|
+
put buffer, "#{shared_path}/httpd.conf"
|
38
|
+
send(run_method, "cp #{shared_path}/httpd.conf #{apache_conf}")
|
39
|
+
delete "#{shared_path}/httpd.conf"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Start Apache "
|
43
|
+
task :start_apache, :roles => :web do
|
44
|
+
send(run_method, "#{apache_ctl} start")
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Restart Apache "
|
48
|
+
task :restart_apache, :roles => :web do
|
49
|
+
send(run_method, "#{apache_ctl} restart")
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Stop Apache "
|
53
|
+
task :stop_apache, :roles => :web do
|
54
|
+
send(run_method, "#{apache_ctl} stop")
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Reload Apache "
|
58
|
+
task :reload_apache, :roles => :web do
|
59
|
+
send(run_method, "#{apache_ctl} reload")
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_apache_conf
|
63
|
+
if apache_default_vhost
|
64
|
+
set :apache_conf, "/etc/httpd/conf/default.conf" unless apache_default_vhost_conf
|
65
|
+
else
|
66
|
+
set :apache_conf, "/etc/httpd/conf/apps/#{application}.conf" unless apache_conf
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'mongrel_cluster/recipes'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'capistrano'
|
3
|
+
require 'capistrano/cli'
|
4
|
+
|
5
|
+
module MySQLMethods
|
6
|
+
|
7
|
+
def execute(sql, user)
|
8
|
+
run "mysql --user=#{user} -p --execute=\"#{sql}\"" do |channel, stream, data|
|
9
|
+
handle_mysql_password(user, channel, stream, data)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def handle_mysql_password(user, channel, stream, data)
|
15
|
+
logger.info data, "[database on #{channel[:host]} asked for password]"
|
16
|
+
if data =~ /^Enter password:/
|
17
|
+
pass = Capistrano::CLI.password_prompt "Enter database password for '#{user}':"
|
18
|
+
channel.send_data "#{pass}\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Capistrano.plugin :mysql, MySQLMethods
|
24
|
+
|
25
|
+
Capistrano.configuration(:must_exist).load do
|
26
|
+
|
27
|
+
set :mysql_admin, nil
|
28
|
+
|
29
|
+
desc "Execute MySQL statements using --execute option. Set the 'sql' variable."
|
30
|
+
task :execute_mysql, :roles => :db, :only => { :primary => true } do
|
31
|
+
set_mysql_admin
|
32
|
+
mysql.execute sql, mysql_admin
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Create MySQL database and user based on config/database.yml"
|
36
|
+
task :setup_mysql, :roles => :db, :only => { :primary => true } do
|
37
|
+
# on_rollback {}
|
38
|
+
|
39
|
+
set_mysql_admin
|
40
|
+
read_config
|
41
|
+
|
42
|
+
sql = "CREATE DATABASE #{db_name};"
|
43
|
+
sql += "GRANT ALL PRIVILEGES ON #{db_name}.* TO #{db_user}@localhost IDENTIFIED BY '#{db_password}';"
|
44
|
+
mysql.execute sql, mysql_admin
|
45
|
+
end
|
46
|
+
|
47
|
+
def read_config
|
48
|
+
db_config = YAML.load_file('config/database.yml')
|
49
|
+
set :db_user, db_config[rails_env]["username"]
|
50
|
+
set :db_password, db_config[rails_env]["password"]
|
51
|
+
set :db_name, db_config[rails_env]["database"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_mysql_admin
|
55
|
+
set :mysql_admin, user unless mysql_admin
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|