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/README ADDED
@@ -0,0 +1,6 @@
1
+ == Railsmachine
2
+
3
+ Doc coming soon.
4
+
5
+
6
+
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