tannins 0.6

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.
@@ -0,0 +1 @@
1
+ pkg
@@ -0,0 +1,6 @@
1
+ [submodule "spec/rails"]
2
+ path = spec/rails
3
+ url = git@github.com:notch8/tannins-rails-fixture.git
4
+ [submodule "spec/merb"]
5
+ path = spec/merb
6
+ url = git@github.com:notch8/tannins-merb-fixture.git
@@ -0,0 +1,3 @@
1
+ == 0.1.0 / 2008-08-21
2
+
3
+ * First public release
@@ -0,0 +1,87 @@
1
+ tannins
2
+ by FIXME (your name)
3
+ FIXME (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ Variables:
8
+
9
+ user
10
+ group
11
+ use_nginx
12
+ application
13
+ mongrel_servers
14
+ precedence
15
+ server_name
16
+ ssl_required
17
+ forced_prefix
18
+
19
+ database_adapter
20
+ database_username
21
+ database_password
22
+ database_host # optional
23
+ database_socket # optional
24
+
25
+ === EC2 SPECIFIC VARIABLES
26
+
27
+ ec2_access_key
28
+ ec2_secret_key
29
+ ec2_ami_image
30
+ ec2_elastic_ip
31
+
32
+ == DEPLOY SPECIFIC VARIABLES
33
+
34
+ deploy_username
35
+ deploy_password
36
+
37
+ == APPLICATION SPECIFIC VARIABLES
38
+
39
+ github_sshkey
40
+ mysql_password
41
+
42
+ == BACKUP SPECIFIC VARIABLES
43
+
44
+ s3_id
45
+ s3_key
46
+ s3_backup_bucket
47
+
48
+ == FEATURES/PROBLEMS:
49
+
50
+ * FIXME (list of features or problems)
51
+
52
+ == SYNOPSIS:
53
+
54
+ FIXME (code sample of usage)
55
+
56
+ == REQUIREMENTS:
57
+
58
+ * FIXME (list of requirements)
59
+
60
+ == INSTALL:
61
+
62
+ * FIXME (sudo gem install, anything else)
63
+
64
+ == LICENSE:
65
+
66
+ (The MIT License)
67
+
68
+ Copyright (c) 2008 FIXME (different license?)
69
+
70
+ Permission is hereby granted, free of charge, to any person obtaining
71
+ a copy of this software and associated documentation files (the
72
+ 'Software'), to deal in the Software without restriction, including
73
+ without limitation the rights to use, copy, modify, merge, publish,
74
+ distribute, sublicense, and/or sell copies of the Software, and to
75
+ permit persons to whom the Software is furnished to do so, subject to
76
+ the following conditions:
77
+
78
+ The above copyright notice and this permission notice shall be
79
+ included in all copies or substantial portions of the Software.
80
+
81
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
82
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
83
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
84
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
85
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
86
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
87
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ load 'tasks/setup.rb'
6
+
7
+ ensure_in_path 'lib'
8
+ require 'tannins'
9
+
10
+ task :default => 'spec:run'
11
+
12
+ PROJ.name = 'tannins'
13
+ PROJ.authors = 'Rob Kaufman, Chris Petersen and Ryan Felton'
14
+ PROJ.email = 'rob@notch8.com'
15
+ PROJ.url = 'http://notch8.com'
16
+ PROJ.rubyforge.name = 'tannins'
17
+ PROJ.version = Tannins::VERSION
18
+ PROJ.spec.opts << '--color'
19
+ PROJ.ignore_file = '.bnsignore'
20
+ depend_on 'amazon-ec2'
21
+ depend_on 'mongrel_cluster'
22
+
23
+ # EOF
@@ -0,0 +1,64 @@
1
+ # $Id$
2
+ # Equivalent to a header guard in C/C++
3
+ # Used to prevent the class/module from being loaded more than once
4
+ unless defined? Tannins
5
+
6
+ module Tannins
7
+
8
+ # :stopdoc:
9
+ VERSION = '0.6'
10
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
11
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
12
+ # :startdoc:
13
+
14
+ def self.get_template(file_name)
15
+ file_path = File.join(Dir.pwd, "config", "templates", file_name)
16
+ if File.exists?(file_path)
17
+ return file_path
18
+ else
19
+ return "#{File.expand_path(File.dirname(__FILE__))}/templates"
20
+ end
21
+ end
22
+
23
+ # Returns the version string for the library.
24
+ #
25
+ def self.version
26
+ VERSION
27
+ end
28
+
29
+ # Returns the library path for the module. If any arguments are given,
30
+ # they will be joined to the end of the libray path using
31
+ # <tt>File.join</tt>.
32
+ #
33
+ def self.libpath( *args )
34
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
35
+ end
36
+
37
+ # Returns the lpath for the module. If any arguments are given,
38
+ # they will be joined to the end of the path using
39
+ # <tt>File.join</tt>.
40
+ #
41
+ def self.path( *args )
42
+ args.empty? ? PATH : ::File.join(PATH, *args)
43
+ end
44
+
45
+ # Utility method used to rquire all files ending in .rb that lie in the
46
+ # directory below this file that has the same name as the filename passed
47
+ # in. Optionally, a specific _directory_ name can be passed in such that
48
+ # the _filename_ does not have to be equivalent to the directory.
49
+ #
50
+ def self.require_all_libs_relative_to( fname, dir = nil )
51
+ dir ||= ::File.basename(fname, '.*')
52
+ search_me = ::File.expand_path(
53
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
54
+
55
+ Dir.glob(search_me).sort.each {|rb| require rb}
56
+ end
57
+
58
+ end # module Tannins
59
+
60
+ # Tannins.require_all_libs_relative_to __FILE__
61
+
62
+ end # unless defined?
63
+
64
+ # EOF
@@ -0,0 +1,27 @@
1
+ require 'erubis'
2
+ Capistrano::Configuration.instance(:must_exist).load do
3
+ namespace :gentoo do
4
+ desc "Setup Apache Configuration"
5
+ task :web_configuration_setup, :roles => :web do
6
+ sudo "mkdir -p /etc/apache2/vhosts.d"
7
+
8
+ vhost_file = Tannins.get_template("apache_vhost.erb")
9
+ common_file = Tannins.get_template("apache_common.erb")
10
+
11
+ # generate web server configuration (apache specific)
12
+ apache2_rails_conf = ::Erubis::Eruby.new(File.read(vhost_file)).result(binding)
13
+
14
+ apache2_rails_common_conf = ::Erubis::Eruby.new(File.read(common_file)).result(binding)
15
+
16
+ put apache2_rails_conf, "#{shared_path}/system/#{application}.conf"
17
+ put apache2_rails_common_conf, "#{shared_path}/system/#{application}.common"
18
+
19
+ # if apache is setup to read /etc/apache2/vhosts.d/*.conf these will get read as configuration files
20
+ # see prerequisites above for more info
21
+ sudo "ln -nfs #{shared_path}/config/#{application}.conf /etc/apache2/vhosts.d/#{precedence}_#{application}.conf"
22
+ sudo "ln -nfs #{shared_path}/config/#{application}.common /etc/apache2/vhosts.d/#{application}.common"
23
+ sudo "rc-update add apache2 default"
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,123 @@
1
+ require 'EC2'
2
+ require 'erubis'
3
+
4
+ Capistrano::Configuration.instance(:must_exist).load do
5
+ namespace :ec2 do
6
+ desc 'Creates a new EC2 instance and runs then launch_new.rb script'
7
+ task :new do
8
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
9
+
10
+ if File.exists?( "#{Dir.pwd}/config/ec2/launch_new.rb" )
11
+ user_data = File.read( "#{Dir.pwd}/config/ec2/launch_new.rb" )
12
+ else
13
+ user_data = ""
14
+ end
15
+ # user_data += File.read( "#{LIBPATH}launch_new.erb" )
16
+
17
+ processed_erb = ::Erubis::Eruby.new(File.read("#{LIBPATH}templates/launch_new.erb")).result(binding)
18
+ # raw_erb = File.read( "#{LIBPATH}launch_new.erb" )
19
+ # processed_erb = ERB.new( raw_erb )
20
+ user_data += processed_erb
21
+
22
+ ec2 = EC2::Base.new(:access_key_id => ec2_access_key, :secret_access_key => ec2_secret_key)
23
+ reservation = ec2.run_instances(:image_id => ec2_ami_image,
24
+ :keypair => "#{Dir.pwd}/config/ec2/id_rsa-gsg-keypair",
25
+ :instance_type => "m1.small",
26
+ :user_data => user_data)
27
+
28
+ reservation.instancesSet.item.each do |item|
29
+ raise Exception, "Instance did not start." unless item.instanceState.name == "pending"
30
+ puts "Instance #{item.instanceId} Startup Pending"
31
+ puts "Checking every 10 seconds to detect startup for up to 5 minutes"
32
+ tries = 0
33
+ while tries < 35
34
+ launched = ec2.describe_instances(:instance_id =>[item.instanceId]).reservationSet.item.first.instancesSet.item.first
35
+ case launched.instanceState.name
36
+ when "pending"
37
+ print '.'
38
+ $stdout.flush
39
+ sleep 10
40
+ tries += 1
41
+ when "running"
42
+ puts "running #{item.instanceId} at #{launched.dnsName}"
43
+ assign_ip(ec2, item.instanceId)
44
+ break
45
+ else
46
+ puts "error initializing instance: #{item.instanceId}"
47
+ break
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ desc 'Shuts down an instance'
55
+ task :terminate do
56
+ raise "INSTANCE_ID required" unless instance_id = ENV['INSTANCE_ID']
57
+
58
+ ec2 = EC2::Base.new(:access_key_id => ec2_access_key, :secret_access_key => ec2_secret_key)
59
+ ec2.terminate_instances(:instance_id => [instance_id])
60
+ end
61
+
62
+ desc 'Returns all of your currently running instances'
63
+ task :instances do
64
+ ec2 = EC2::Base.new(:access_key_id => ec2_access_key, :secret_access_key => ec2_secret_key)
65
+ ec2.describe_instances.reservationSet.item.each do |set|
66
+ set.instancesSet.item.each do |instance|
67
+ str = instance.instanceId
68
+ str << " ("
69
+ str << instance.instanceState.name
70
+ if instance.instanceState.name == "running"
71
+ str << " at "
72
+ str << instance.dnsName
73
+ str << " on image "
74
+ str << instance.imageId
75
+ str << " launched at "
76
+ str << instance.launchTime
77
+ end
78
+ str << ")"
79
+ puts str
80
+ end
81
+ end
82
+ end
83
+
84
+ desc "return your own amazon images."
85
+ task :images do
86
+ ec2 = EC2::Base.new(:access_key_id => ec2_access_key, :secret_access_key => ec2_secret_key)
87
+ ec2.describe_images(:owner_id => "self").imagesSet.item.each do |image|
88
+ str = image.imageId
89
+ str << " ("
90
+ str << image.imageLocation
91
+ str << ") status: ("
92
+ str <<
93
+ str << image.imageState
94
+ str << " and "
95
+ p = (image.isPublic == "true")? "public" : "private"
96
+ str << p
97
+ str << ")"
98
+ puts str
99
+ end
100
+ end
101
+
102
+ desc "change the production/staging ip to the value of INSTANCE_ID. stagings is used unless RAILS_ENV=production"
103
+ task :assign_ip do
104
+ raise "INSTANCE_ID required" unless ENV['INSTANCE_ID']
105
+ ec2 = EC2::Base.new(:access_key_id => ec2_access_key, :secret_access_key => ec2_secret_key)
106
+ assign_ip(ec2, ENV['INSTANCE_ID'], true)
107
+ end
108
+
109
+ def assign_ip(ec2, instance_id, force = false)
110
+ environment_var = ENV['RAILS_ENV'] || ENV['MERB_ENV']
111
+ if environment_var == 'production' && force
112
+ puts "Changing where the PRODUCTIOIN IP address points"
113
+ ec2.associate_address(:instance_id => instance_id, :public_ip => PRODUCTION_IP)
114
+ elsif ENV['RAILS_ENV'] == 'production'
115
+ puts "We don't move the production elastic IP automatically..."
116
+ puts "you have to force it by doing 'rake ec2:assign_ip INSTANCE_ID=#{instance_id} RAILS_ENV=production"
117
+ else
118
+ puts "Changing where the IP address points"
119
+ ec2.associate_address(:instance_id => instance_id, :public_ip => ec2_elastic_ip)
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,21 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ namespace :deploy do
3
+ desc 'restart mongrel cluster'
4
+ task :restart do
5
+ run "cd #{current_release} && mongrel_rails cluster::restart"
6
+ end
7
+
8
+ task :start do
9
+ run "cd #{current_release} && mongrel_rails cluster::start"
10
+ end
11
+
12
+ task :stop do
13
+ run "cd #{current_release} && mongrel_rails cluster::stop"
14
+ end
15
+
16
+ desc 'rails cluster status'
17
+ task :cluster_status do
18
+ run "cd #{current_release} && mongrel_rails cluster::status"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,100 @@
1
+ require 'erubis'
2
+ Capistrano::Configuration.instance(:must_exist).load do
3
+ after 'deploy:update_code', 'deploy:symlink_configs'
4
+
5
+ before 'deploy:setup', 'gentoo:set_keys'
6
+ after 'deploy:setup', 'gentoo:fix_permissions'
7
+ after 'deploy:setup', 'deploy:update'
8
+ after 'deploy:setup', 'gentoo:setup'
9
+
10
+ namespace :tannins do
11
+ desc "Copy templates over for editing"
12
+ task :copy_templates do
13
+ run_locally "mkdir -p config/templates"
14
+ run_locally "cp -r #{Tannins.path}/lib/tannins/templates/* config/templates/"
15
+ end
16
+
17
+ desc "Show which template would be used for TEMPLATE"
18
+ task :template do
19
+ puts Tannins.get_template(ENV["TEMPLATE"])
20
+ end
21
+ end
22
+
23
+ namespace :gentoo do
24
+ # =============================================================================
25
+ # CALLBACK TASKS
26
+ # =============================================================================
27
+
28
+ desc "Tasks to execute before initial setup"
29
+ task :fix_permissions do
30
+ sudo "mkdir -p /etc/mongrel_cluster"
31
+
32
+ sudo "chown -R #{user}:#{group} #{deploy_to}"
33
+ # make shared config dir to hold these config files
34
+ run "mkdir -p #{shared_path}/config"
35
+
36
+ # make a shared tmp dir for sessions
37
+ run "mkdir -p #{shared_path}/tmp"
38
+ run "mkdir -p #{shared_path}/tmp/cache"
39
+ run "mkdir -p #{shared_path}/tmp/sessions"
40
+ run "mkdir -p #{shared_path}/tmp/sockets"
41
+ # run "mkdir -p #{shared_path}/tmp/pids" # new rails construct
42
+ # create any other shared dirs
43
+ # run "mkdir -p #{shared_path}/db"
44
+ # run "mkdir -p #{shared_path}/db/ferret_index"
45
+ end
46
+
47
+ before 'gentoo:setup', 'gentoo:application_configuration_setup'
48
+ before 'gentoo:setup', 'gentoo:database_configuration_setup'
49
+ before 'gentoo:setup', 'gentoo:web_configuration_setup'
50
+
51
+ desc "Tasks to execute after initial setup"
52
+ task :setup do
53
+ rake = fetch(:rake, "rake")
54
+ run "cd #{latest_release} && #{rake} db:create db:migrate RAILS_ENV=#{rails_env}"
55
+ end
56
+
57
+ desc "Setup Database Configuration"
58
+ task :database_configuration_setup do
59
+ # generate database configuration
60
+ database_file = Tannins.get_template("database.erb")
61
+ database_conf = Erubis::Eruby.new(File.read(database_file)).result(binding)
62
+
63
+ # put database configuration in shared config dir
64
+ put database_conf, "#{shared_path}/config/database.yml"
65
+ end
66
+
67
+ desc "Add the deploy keys to the deployment user"
68
+ task :set_keys, :roles => :app do
69
+ sudo "mkdir -p #{deploy_to}"
70
+ sudo "chown -R #{user}:#{group} #{deploy_to}"
71
+
72
+ key_file = File.read("#{Dir.pwd}/config/deploy_key")
73
+ pub_file = File.read("#{Dir.pwd}/config/deploy_key.pub")
74
+ run "mkdir -p /home/#{user}/.ssh/"
75
+ put key_file, "/home/#{user}/.ssh/id_dsa"
76
+ put pub_file, "/home/#{user}/.ssh/id_dsa.pub"
77
+ sudo "chmod 600 /home/#{user}/.ssh/id_dsa"
78
+ end
79
+ end
80
+
81
+ task :testing do
82
+ puts fetch(:database_host, "")
83
+ end
84
+
85
+
86
+ namespace :deploy do
87
+
88
+ desc "Symlinks the database and mongrel cluster configs"
89
+ task :symlink_configs, :roles => [:web] do
90
+ symlink_database_config
91
+ end
92
+
93
+ desc "Link to the shared database.yml."
94
+ task :symlink_database_config, :roles => [:web] do
95
+ run "rm -f #{latest_release}/config/database.yml"
96
+ run "ln -nfs #{shared_path}/config/database.yml #{latest_release}/config/database.yml"
97
+ end
98
+ end
99
+
100
+ end