├── .gitignore ├── Gemfile ├── LICENSE ├── LICENSE.md ├── README.md ├── Rakefile ├── capistrano-foreman.gemspec └── lib ├── capistrano-foreman.rb └── capistrano ├── foreman.rb └── tasks └── foreman.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in capistrano-foreman.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Johannes Gorset 2 | Copyright (c) 2013-2014 John Bellone 3 | 4 | MIT License 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Licensed under the **MIT** license 2 | 3 | > Copyright (c) 2014 Hyper Interaktiv AS 4 | > 5 | > Permission is hereby granted, free of charge, to any person obtaining 6 | > a copy of this software and associated documentation files (the 7 | > "Software"), to deal in the Software without restriction, including 8 | > without limitation the rights to use, copy, modify, merge, publish, 9 | > distribute, sublicense, and/or sell copies of the Software, and to 10 | > permit persons to whom the Software is furnished to do so, subject to 11 | > the following conditions: 12 | > 13 | > The above copyright notice and this permission notice shall be 14 | > included in all copies or substantial portions of the Software. 15 | > 16 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | > IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | > CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | > TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | > SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Capistrano Foreman 2 | 3 | [![Code Climate](https://img.shields.io/codeclimate/github/hyperoslo/capistrano-foreman.svg?style=flat)](https://codeclimate.com/github/hyperoslo/capistrano-foreman) 4 | 5 | Capistrano tasks for foreman and upstart/systemd. 6 | 7 | ## Installation 8 | 9 | $ gem install capistrano-foreman 10 | 11 | Add this to your `Capfile`: 12 | 13 | ```ruby 14 | require 'capistrano/foreman' 15 | 16 | # Default settings 17 | set :foreman_use_sudo, false # Set to :rbenv for rbenv sudo, :rvm for rvmsudo or true for normal sudo 18 | set :foreman_roles, :all 19 | set :foreman_init_system, 'upstart' 20 | set :foreman_export_path, ->{ File.join(Dir.home, '.init') } 21 | set :foreman_app, -> { fetch(:application) } 22 | set :foreman_app_name_systemd, -> { "#{ fetch(:foreman_app) }.target" } 23 | set :foreman_options, ->{ { 24 | app: application, 25 | log: File.join(shared_path, 'log') 26 | } } 27 | ``` 28 | 29 | See [exporting options](http://ddollar.github.io/foreman/#EXPORTING) for an exhaustive list of foreman options. 30 | 31 | ## Usage 32 | 33 | Export Procfile to upstart/systemd: 34 | 35 | $ bundle exec cap production foreman:export 36 | 37 | Restart the application services: 38 | 39 | $ bundle exec cap production foreman:restart 40 | 41 | ## Credits 42 | 43 | Hyper made this. We're a digital communications agency with a passion for good code, 44 | and if you're using this library we probably want to hire you. 45 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require "bundler/gem_tasks" 3 | -------------------------------------------------------------------------------- /capistrano-foreman.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | Gem::Specification.new do |gem| 6 | gem.authors = ["Johannes Gorset", 'John Bellone'] 7 | gem.email = ["jgorset@gmail.com", 'jbellone@bloomberg.net'] 8 | gem.description = "Capistrano tasks for foreman and upstart/systemd." 9 | gem.summary = "Capistrano tasks for foreman and upstart/systemd." 10 | gem.homepage = "http://github.com/hyperoslo/capistrano-foreman" 11 | 12 | gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 13 | gem.files = `git ls-files`.split("\n") 14 | gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 15 | gem.name = "capistrano-foreman" 16 | gem.require_paths = ["lib"] 17 | gem.version = '1.4.0' 18 | 19 | gem.add_dependency 'capistrano', '~> 3.1' 20 | gem.add_dependency 'capistrano-bundler', '~> 1.1' 21 | end 22 | -------------------------------------------------------------------------------- /lib/capistrano-foreman.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperoslo/capistrano-foreman/4c08afc005de4f04000e7678b781671cb4360c56/lib/capistrano-foreman.rb -------------------------------------------------------------------------------- /lib/capistrano/foreman.rb: -------------------------------------------------------------------------------- 1 | load File.expand_path('../tasks/foreman.rb', __FILE__) 2 | -------------------------------------------------------------------------------- /lib/capistrano/tasks/foreman.rb: -------------------------------------------------------------------------------- 1 | namespace :foreman do 2 | task :setup do 3 | invoke :'foreman:export' 4 | invoke :'foreman:start' 5 | end 6 | 7 | desc 'Export the Procfile' 8 | task :export do 9 | on roles fetch(:foreman_roles) do 10 | opts = { 11 | app: fetch(:application), 12 | log: File.join(shared_path, 'log'), 13 | }.merge fetch(:foreman_options, {}) 14 | 15 | opts.merge!(host.properties.fetch(:foreman_options) || {}) 16 | 17 | execute(:mkdir, "-p", opts[:log]) 18 | 19 | within release_path do 20 | foreman_exec :foreman, 'export', 21 | fetch(:foreman_init_system), 22 | fetch(:foreman_export_path), 23 | opts.map { |opt, value| "--#{opt}=\"#{value}\"" }.join(' ') 24 | end 25 | 26 | if fetch(:foreman_init_system) == 'systemd' 27 | foreman_exec :systemctl, :'daemon-reload' 28 | end 29 | end 30 | end 31 | 32 | desc 'Start the application services' 33 | task :start do 34 | on roles fetch(:foreman_roles) do 35 | case fetch(:foreman_init_system) 36 | when 'systemd' 37 | foreman_exec :systemctl, :enable, fetch(:foreman_app_name_systemd) 38 | foreman_exec :systemctl, :start, fetch(:foreman_app_name_systemd) 39 | else 40 | foreman_exec :start, fetch(:foreman_app) 41 | end 42 | end 43 | end 44 | 45 | desc 'Stop the application services' 46 | task :stop do 47 | on roles fetch(:foreman_roles) do 48 | case fetch(:foreman_init_system) 49 | when 'systemd' 50 | foreman_exec :systemctl, :stop, fetch(:foreman_app_name_systemd) 51 | foreman_exec :systemctl, :disable, fetch(:foreman_app_name_systemd) 52 | else 53 | foreman_exec :stop, fetch(:foreman_app) 54 | end 55 | end 56 | end 57 | 58 | desc 'Restart the application services' 59 | task :restart do 60 | on roles fetch(:foreman_roles) do 61 | case fetch(:foreman_init_system) 62 | when 'systemd' 63 | foreman_exec :systemctl, :restart, fetch(:foreman_app_name_systemd) 64 | else 65 | foreman_exec :restart, fetch(:foreman_app) 66 | end 67 | end 68 | end 69 | 70 | def foreman_exec(*args) 71 | sudo_type = fetch(:foreman_use_sudo) 72 | case sudo_type.to_s 73 | when 'rbenv' 74 | # this is required because 'rbenv sudo' 75 | # is not recognized by bundle_bins 76 | args.unshift(:bundle, :exec) if args[0].to_s == "foreman" 77 | execute(:rbenv, :sudo, *args) 78 | when 'rvm' 79 | execute(:rvmsudo, *args) 80 | when 'chruby' 81 | execute(:sudo, 'chruby-exec', fetch(:chruby_ruby), '--', *args) 82 | else 83 | sudo_type ? sudo(*args) : execute(*args) 84 | end 85 | end 86 | end 87 | 88 | namespace :load do 89 | task :defaults do 90 | set :bundle_bins, fetch(:bundle_bins, []).push(:foreman) 91 | set :foreman_use_sudo, false 92 | set :foreman_init_system, 'upstart' 93 | set :foreman_export_path, '/etc/init/sites' 94 | set :foreman_roles, :all 95 | set :foreman_app, -> { fetch(:application) } 96 | set :foreman_app_name_systemd, -> { "#{ fetch(:foreman_app) }.target" } 97 | 98 | if !fetch(:rvm_map_bins).nil? 99 | set :rvm_map_bins, fetch(:rvm_map_bins).push('foreman') 100 | end 101 | end 102 | end 103 | --------------------------------------------------------------------------------