fdlcap 0.3.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +72 -0
  3. data/Rakefile +69 -0
  4. data/VERSION +1 -0
  5. data/bin/fdlcap +4 -0
  6. data/examples/deploy.rb +57 -0
  7. data/fdlcap.gemspec +98 -0
  8. data/features/fdlcap.feature +9 -0
  9. data/features/step_definitions/fdlcap_steps.rb +0 -0
  10. data/features/support/env.rb +6 -0
  11. data/lib/fdlcap/extensions/configuration.rb +34 -0
  12. data/lib/fdlcap/extensions/recipe_definition.rb +19 -0
  13. data/lib/fdlcap/recipes/autotagger.rb +51 -0
  14. data/lib/fdlcap/recipes/check_revision.rb +22 -0
  15. data/lib/fdlcap/recipes/craken.rb +5 -0
  16. data/lib/fdlcap/recipes/database.rb +204 -0
  17. data/lib/fdlcap/recipes/delayed_job.rb +28 -0
  18. data/lib/fdlcap/recipes/deploy.rb +26 -0
  19. data/lib/fdlcap/recipes/fdl_defaults.rb +16 -0
  20. data/lib/fdlcap/recipes/geminstaller.rb +53 -0
  21. data/lib/fdlcap/recipes/newrelic.rb +6 -0
  22. data/lib/fdlcap/recipes/nginx.rb +102 -0
  23. data/lib/fdlcap/recipes/passenger.rb +17 -0
  24. data/lib/fdlcap/recipes/performance.rb +78 -0
  25. data/lib/fdlcap/recipes/rake.rb +19 -0
  26. data/lib/fdlcap/recipes/rolling_restart.rb +31 -0
  27. data/lib/fdlcap/recipes/rsync.rb +42 -0
  28. data/lib/fdlcap/recipes/ruby_inline.rb +19 -0
  29. data/lib/fdlcap/recipes/sass.rb +20 -0
  30. data/lib/fdlcap/recipes/sinatra_passenger.rb +21 -0
  31. data/lib/fdlcap/recipes/slice.rb +59 -0
  32. data/lib/fdlcap/recipes/ssh.rb +42 -0
  33. data/lib/fdlcap/recipes/stages.rb +12 -0
  34. data/lib/fdlcap/recipes/symlink_configs.rb +7 -0
  35. data/lib/fdlcap/recipes/symlinks.rb +48 -0
  36. data/lib/fdlcap/recipes/thin.rb +119 -0
  37. data/lib/fdlcap/recipes/thinking_sphinx.rb +12 -0
  38. data/lib/fdlcap/recipes.rb +11 -0
  39. data/lib/fdlcap/templates/nginx.auth.conf.erb +9 -0
  40. data/lib/fdlcap/templates/nginx.conf.erb +57 -0
  41. data/lib/fdlcap/templates/nginx.vhost.conf.erb +85 -0
  42. data/lib/fdlcap.rb +3 -0
  43. data/test/fdlcap_test.rb +7 -0
  44. data/test/test_helper.rb +10 -0
  45. metadata +140 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Factory Design Labs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,72 @@
1
+ = fdlcap
2
+
3
+ Inspired by Engine Yard's eycap (http://github.com/engineyard/eycap), fdlcap is a set of extracted cap tasks, configurations, and callbacks from various Factory Design Labs projects.
4
+
5
+ It's designed to ease some common scenarios for deploying reasonably complex apps to Engine Yard environments. It's also designed to make it easier to package up deployment logic and make it reusable.
6
+
7
+ Some of the recipes include:
8
+
9
+ - auto_tagger - provide a default set of stages and set up deploy callbacks for progressive deployment with auto_tagger (http://github.com/zilkey/auto_tagger))
10
+ - craken - set up deploy callbacks for deploying raketab files to cron with craken
11
+ - delayed_job - start/stop/restart delayed_job workers with monit and set up deploy callbacks for restarting workers
12
+ - geminstaller - set up deploy callbacks for running chad woolley's geminstaller
13
+ - newrelic - set up deploy callbacks for notifying newrelic of deployments
14
+ - rake - run arbitrary rake tasks, commands, and ruby snippets on remote servers from a single command
15
+ - rsync - pull assets from production servers to development
16
+ - sass - set up deploy callbacks for updating sass stylesheets on deploy to avoid caching issues
17
+ - slice - tail arbitrary server logs and show custom maintenance pages
18
+ - ssh - shortcut to execute ssh sessions and tunnels to remote servers
19
+ - thinking_sphinx - set up deploy callbacks for thinking sphinx
20
+ - stages - enable capistrano-ext/multistage
21
+ - database - recipies for pulling production mysql databases locally, also can push to remote db
22
+ - thin - manage a thin deployment
23
+ - nginx - control nginx as well as generate configurations
24
+
25
+ One kind of cool addition is a simple mechanism for bundling callbacks, configuration variables, and tasks into reusable recipe chunks that can easily be dropped into your deploy configuration.
26
+
27
+ For example, to automatically set up tasks and callbacks for stages, delayed_job and sass, you would add the following to deploy.rb:
28
+
29
+ use_recipe :delayed_job
30
+ use_recipe :sass
31
+ use_recipe :stages, :staging, :production
32
+
33
+ You can also create your own recipe chunks with the define_recipe method:
34
+
35
+ define_recipe :my_recipe do
36
+ # tasks, config, whatever go here
37
+ end
38
+
39
+ Then include them in your deploy.rb:
40
+
41
+ use_recipe :my_recipe
42
+
43
+ Recipes can also take arguments (such as in the stages recipe)
44
+
45
+ define_recipe :stages do |*stages|
46
+ set :stages, stages.flatten unless exists?(:stages) && !stages.empty?
47
+ require 'capistrano/ext/multistage'
48
+ end
49
+
50
+ ==Prereqs
51
+
52
+ Aside from capistrano, fdlcap depends on the following gems:
53
+
54
+ - capistrano-ext (for multistage deployments)
55
+ - engineyard-eycap (for deployment configurations and support recipes - http://github.com/engineyard/eycap)
56
+ - zilkey-auto_tagger (for rolling deploy tags via git - http://github.com/zilkey/auto_tagger)
57
+
58
+ These should all be installed automatically by rubygems when you install fdlcap.
59
+
60
+ ==Installation
61
+
62
+ sudo gem install factorylabs-fdlcap --source=http://gems.github.com
63
+
64
+ You may want to add the gem to your config.gems or geminstaller config as well.
65
+
66
+ You'll also need to add the following line to your deploy.rb:
67
+
68
+ require 'fdlcap/recipes'
69
+
70
+ == Copyright
71
+
72
+ Copyright (c) 2009 Gabe Varela and Jay Zeschin. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "fdlcap"
8
+ gem.summary = %Q{a set of capistrano recipies we use regularly at Factory Design Labs}
9
+ gem.email = "interactive@factorylabs.com"
10
+ gem.homepage = "http://github.com/factorylabs/fdlcap"
11
+ gem.authors = ["Factory Design Labs"]
12
+ gem.add_dependency('engineyard-eycap', '>= 0.4.7')
13
+ gem.add_dependency('zilkey-auto_tagger', '>= 0.0.9')
14
+ gem.add_dependency('capistrano', '>= 2.5.5')
15
+ gem.add_dependency('capistrano-ext', '>= 1.2.1')
16
+ gem.files.exclude('.gitignore')
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/*_test.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ begin
45
+ require 'cucumber/rake/task'
46
+ Cucumber::Rake::Task.new(:features)
47
+ rescue LoadError
48
+ task :features do
49
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
50
+ end
51
+ end
52
+
53
+ task :default => :test
54
+
55
+ require 'rake/rdoctask'
56
+ Rake::RDocTask.new do |rdoc|
57
+ if File.exist?('VERSION.yml')
58
+ config = YAML.load(File.read('VERSION.yml'))
59
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
60
+ else
61
+ version = ""
62
+ end
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "fdlcap #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
69
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.28
data/bin/fdlcap ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ path = ARGV[0]
4
+ File.mkdir_p File.join(path, 'deploy')
@@ -0,0 +1,57 @@
1
+ #####################
2
+ # GLOBAL VARS
3
+ #####################
4
+
5
+ require 'fdlcap/recipes'
6
+ require 'lib/recipes/ftp_server'
7
+ require 'lib/recipes/queue_daemon'
8
+
9
+ #
10
+ # Bring in fdlcap recipes
11
+ #
12
+
13
+ use_recipe :symlink_configs
14
+ use_recipe :stages, [ :express, :staging, :production, :translation ]
15
+ use_recipe :symlinks
16
+ use_recipe :geminstaller
17
+ use_recipe :delayed_job
18
+ use_recipe :release_tagger, [ :ci, :staging, :production ]
19
+ use_recipe :sass
20
+ use_recipe :thinking_sphinx
21
+ use_recipe :newrelic
22
+ use_recipe :perform_cleanup
23
+ use_recipe :craken
24
+ use_recipe :custom_maintenance_page
25
+
26
+ #
27
+ # Symlink directories
28
+ #
29
+ set :symlink_dirs, [ 'data',
30
+ 'public/images/vehicles',
31
+ 'public/images/staff',
32
+ 'db/sphinx' ]
33
+
34
+ #
35
+ # SCM config
36
+ #
37
+ set :scm, :git
38
+ set :keep_releases, 5
39
+ set :repository, "git@github.com:factorylabs/fdlcap.git"
40
+ set :deploy_via, :remote_cache
41
+
42
+ #
43
+ # Callback config
44
+ #
45
+
46
+
47
+
48
+ #
49
+ # Custom Tasks
50
+ #
51
+
52
+ namespace :retrieve do
53
+ desc "run rake retrieve:import_dag"
54
+ task :import_dag, :roles => :db do
55
+ run "cd #{current_path} && RAILS_ENV=#{rails_env} rake retrieve:import_dag"
56
+ end
57
+ end
data/fdlcap.gemspec ADDED
@@ -0,0 +1,98 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fdlcap}
8
+ s.version = "0.3.28"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Factory Design Labs"]
12
+ s.date = %q{2009-10-08}
13
+ s.default_executable = %q{fdlcap}
14
+ s.email = %q{interactive@factorylabs.com}
15
+ s.executables = ["fdlcap"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "bin/fdlcap",
26
+ "examples/deploy.rb",
27
+ "fdlcap.gemspec",
28
+ "features/fdlcap.feature",
29
+ "features/step_definitions/fdlcap_steps.rb",
30
+ "features/support/env.rb",
31
+ "lib/fdlcap.rb",
32
+ "lib/fdlcap/extensions/configuration.rb",
33
+ "lib/fdlcap/extensions/recipe_definition.rb",
34
+ "lib/fdlcap/recipes.rb",
35
+ "lib/fdlcap/recipes/autotagger.rb",
36
+ "lib/fdlcap/recipes/check_revision.rb",
37
+ "lib/fdlcap/recipes/craken.rb",
38
+ "lib/fdlcap/recipes/database.rb",
39
+ "lib/fdlcap/recipes/delayed_job.rb",
40
+ "lib/fdlcap/recipes/deploy.rb",
41
+ "lib/fdlcap/recipes/fdl_defaults.rb",
42
+ "lib/fdlcap/recipes/geminstaller.rb",
43
+ "lib/fdlcap/recipes/newrelic.rb",
44
+ "lib/fdlcap/recipes/nginx.rb",
45
+ "lib/fdlcap/recipes/passenger.rb",
46
+ "lib/fdlcap/recipes/performance.rb",
47
+ "lib/fdlcap/recipes/rake.rb",
48
+ "lib/fdlcap/recipes/rolling_restart.rb",
49
+ "lib/fdlcap/recipes/rsync.rb",
50
+ "lib/fdlcap/recipes/ruby_inline.rb",
51
+ "lib/fdlcap/recipes/sass.rb",
52
+ "lib/fdlcap/recipes/sinatra_passenger.rb",
53
+ "lib/fdlcap/recipes/slice.rb",
54
+ "lib/fdlcap/recipes/ssh.rb",
55
+ "lib/fdlcap/recipes/stages.rb",
56
+ "lib/fdlcap/recipes/symlink_configs.rb",
57
+ "lib/fdlcap/recipes/symlinks.rb",
58
+ "lib/fdlcap/recipes/thin.rb",
59
+ "lib/fdlcap/recipes/thinking_sphinx.rb",
60
+ "lib/fdlcap/templates/nginx.auth.conf.erb",
61
+ "lib/fdlcap/templates/nginx.conf.erb",
62
+ "lib/fdlcap/templates/nginx.vhost.conf.erb",
63
+ "test/fdlcap_test.rb",
64
+ "test/test_helper.rb"
65
+ ]
66
+ s.homepage = %q{http://github.com/factorylabs/fdlcap}
67
+ s.rdoc_options = ["--charset=UTF-8"]
68
+ s.require_paths = ["lib"]
69
+ s.rubygems_version = %q{1.3.5}
70
+ s.summary = %q{a set of capistrano recipies we use regularly at Factory Design Labs}
71
+ s.test_files = [
72
+ "test/fdlcap_test.rb",
73
+ "test/test_helper.rb",
74
+ "examples/deploy.rb"
75
+ ]
76
+
77
+ if s.respond_to? :specification_version then
78
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
79
+ s.specification_version = 3
80
+
81
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
82
+ s.add_runtime_dependency(%q<engineyard-eycap>, [">= 0.4.7"])
83
+ s.add_runtime_dependency(%q<zilkey-auto_tagger>, [">= 0.0.9"])
84
+ s.add_runtime_dependency(%q<capistrano>, [">= 2.5.5"])
85
+ s.add_runtime_dependency(%q<capistrano-ext>, [">= 1.2.1"])
86
+ else
87
+ s.add_dependency(%q<engineyard-eycap>, [">= 0.4.7"])
88
+ s.add_dependency(%q<zilkey-auto_tagger>, [">= 0.0.9"])
89
+ s.add_dependency(%q<capistrano>, [">= 2.5.5"])
90
+ s.add_dependency(%q<capistrano-ext>, [">= 1.2.1"])
91
+ end
92
+ else
93
+ s.add_dependency(%q<engineyard-eycap>, [">= 0.4.7"])
94
+ s.add_dependency(%q<zilkey-auto_tagger>, [">= 0.0.9"])
95
+ s.add_dependency(%q<capistrano>, [">= 2.5.5"])
96
+ s.add_dependency(%q<capistrano-ext>, [">= 1.2.1"])
97
+ end
98
+ end
@@ -0,0 +1,9 @@
1
+ Feature: something something
2
+ In order to something something
3
+ A user something something
4
+ something something something
5
+
6
+ Scenario: something something
7
+ Given inspiration
8
+ When I create a sweet new gem
9
+ Then everyone should see how awesome I am
File without changes
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'fdlcap'
3
+
4
+ require 'test/unit/assertions'
5
+
6
+ World(Test::Unit::Assertions)
@@ -0,0 +1,34 @@
1
+ class Capistrano::Configuration
2
+
3
+ ##
4
+ # Print an informative message with asterisks.
5
+
6
+ def inform(message)
7
+ puts "#{'*' * (message.length + 4)}"
8
+ puts "* #{message} *"
9
+ puts "#{'*' * (message.length + 4)}"
10
+ end
11
+
12
+ ##
13
+ # Read a file and evaluate it as an ERB template.
14
+ # Path is relative to this file's directory.
15
+
16
+ def render_erb_template(filename)
17
+ template = File.read(filename)
18
+ result = ERB.new(template).result(binding)
19
+ end
20
+
21
+ ##
22
+ # Run a command and return the result as a string.
23
+ #
24
+ # TODO May not work properly on multiple servers.
25
+
26
+ def run_and_return(cmd)
27
+ output = []
28
+ run cmd do |ch, st, data|
29
+ output << data
30
+ end
31
+ return output.to_s
32
+ end
33
+
34
+ end
@@ -0,0 +1,19 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ set :fdlcap_recipes, {}
4
+
5
+ def define_recipe(name,&block)
6
+ recipes = fetch(:fdlcap_recipes)
7
+ recipes[name] = block
8
+ end
9
+
10
+ def use_recipe(recipe, *args)
11
+ recipe_block = fetch(:fdlcap_recipes)[recipe]
12
+ if recipe_block
13
+ recipe_block.call(*args)
14
+ else
15
+ raise ArgumentError, "Recipe => :#{recipe} not found"
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,51 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ define_recipe :release_tagger do |*stages|
3
+ # Set up some default stages
4
+ set :autotagger_stages, stages.flatten unless exists?(:autotagger_stages) && !stages.empty?
5
+
6
+ # This needs to be loaded after the stages are set up
7
+ require 'release_tagger'
8
+
9
+ set :keep_release_tags, 5 unless exists?(:keep_release_tags)
10
+ namespace :release_tagger do
11
+ desc "remove old tags, similar to keep_releases"
12
+ task :remove_previous_tags, :roles => :app do
13
+ keep_tags = fetch(:keep_release_tags, 5)
14
+ tags = `git tag`
15
+ tags = tags.split
16
+ stage_tags = {}
17
+ tags.each do |tag|
18
+ stage = tag.split('/').first
19
+ stage_tags[stage] = [] unless stage_tags.key?(stage)
20
+ stage_tags[stage] << tag
21
+ end
22
+
23
+ stage_tags.each do |stage, tags|
24
+ # remove all tags but the last n number
25
+ tags[0..-(keep_tags + 1)].each do |tag|
26
+ puts `git tag -d #{tag}`
27
+ puts `git push origin :refs/tags/#{tag}`
28
+ end
29
+ end
30
+ end
31
+
32
+ desc "remove all local stage tags before release_tagger fetches all tags"
33
+ task :remove_local_stage_tags, :roles => :app do
34
+ autotagger_stages.each do |stage|
35
+ puts `git tag -l #{stage}/* | xargs git tag -d`
36
+ end if fetch(:perform_remove_local_stage_tags, true)
37
+ end
38
+ end
39
+
40
+ # Run release tagger to get the right release for the deploy
41
+ before "deploy:update_code", "release_tagger:remove_local_stage_tags"
42
+ before "deploy:update_code", "release_tagger:set_branch"
43
+
44
+ before "deploy:cleanup", "release_tagger:create_tag"
45
+ before "deploy:cleanup", "release_tagger:write_tag_to_shared"
46
+ before "deploy:cleanup", "release_tagger:remove_previous_tags"
47
+ before "deploy:cleanup", "release_tagger:print_latest_tags"
48
+
49
+
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ define_recipe :check_revision do
4
+ before "deploy:update_code", "deploy:check_revision"
5
+
6
+ namespace :deploy do
7
+ desc "Make sure there is something to deploy"
8
+ task :check_revision, :roles => [:web] do
9
+ unless `git rev-parse HEAD` == `git rev-parse origin/master`
10
+ puts ""
11
+ puts " \033[1;33m**************************************************\033[0m"
12
+ puts " \033[1;33m* WARNING: HEAD is not the same as origin/master *\033[0m"
13
+ puts " \033[1;33m**************************************************\033[0m"
14
+ puts ""
15
+
16
+ exit
17
+ end
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+ define_recipe :craken do
3
+ after "deploy:update", "craken:install"
4
+ end
5
+ end