trooper 0.6.0.alpha2 → 0.6.0.beta
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/lib/trooper/action.rb +38 -4
- data/lib/trooper/actions/prepare_prerequisite_action.rb +34 -0
- data/lib/trooper/actions/restart_server_action.rb +1 -1
- data/lib/trooper/actions/setup_trooper_action.rb +33 -0
- data/lib/trooper/config/action.rb +4 -1
- data/lib/trooper/config/defaults.rb +20 -0
- data/lib/trooper/config/environment.rb +5 -0
- data/lib/trooper/configuration.rb +12 -11
- data/lib/trooper/dsl/bundler.rb +6 -2
- data/lib/trooper/dsl/rake.rb +7 -1
- data/lib/trooper/strategy.rb +61 -26
- data/lib/trooper/template/troopfile.rb +20 -11
- data/lib/trooper/version.rb +1 -1
- data/lib/trooper.rb +4 -0
- metadata +6 -3
data/lib/trooper/action.rb
CHANGED
@@ -11,27 +11,61 @@ module Trooper
|
|
11
11
|
attr_reader :name, :description, :config, :block
|
12
12
|
attr_accessor :commands
|
13
13
|
|
14
|
-
#
|
14
|
+
# Public: Define a new action.
|
15
|
+
#
|
16
|
+
# name - The name of the action.
|
17
|
+
# description - A description of action to be used in the cli output.
|
18
|
+
# block - A block containing the tasks to run in this action.
|
19
|
+
#
|
20
|
+
# Examples
|
21
|
+
#
|
15
22
|
# Action.new(:my_action, 'Does great things') { run 'touch file' }
|
23
|
+
#
|
24
|
+
# Returns a new action object.
|
16
25
|
def initialize(name, description, &block)
|
17
26
|
@name, @description, @config = name, description, {}
|
18
27
|
@commands, @block = [], block
|
19
28
|
end
|
20
29
|
|
21
|
-
#
|
30
|
+
# Public: Eval's the block passed on initialize.
|
31
|
+
#
|
32
|
+
# configuration - The configuration object to be used for block eval.
|
33
|
+
#
|
34
|
+
# Examples
|
35
|
+
#
|
36
|
+
# @action.call(config_object) # => ['touch file']
|
37
|
+
#
|
38
|
+
# Returns an array of commands(strings).
|
22
39
|
def call(configuration)
|
23
40
|
@config = configuration
|
24
41
|
eval_block(&block)
|
25
42
|
commands
|
26
43
|
end
|
27
44
|
alias :execute :call
|
28
|
-
|
29
|
-
#
|
45
|
+
|
46
|
+
# Public: Validates the action object. (NOT WORKING)
|
47
|
+
#
|
48
|
+
# Examples
|
49
|
+
#
|
50
|
+
# @action.ok? # => true
|
51
|
+
#
|
52
|
+
# Returns true.
|
30
53
|
def ok?
|
31
54
|
true
|
32
55
|
end
|
33
56
|
|
34
57
|
# run is the base run command used by the dsl
|
58
|
+
|
59
|
+
# Public: Appends command(string) to commands(array).
|
60
|
+
#
|
61
|
+
# command - A String to be added to the commands array.
|
62
|
+
#
|
63
|
+
# Examples
|
64
|
+
#
|
65
|
+
# @action.run 'touch file' # => 'touch file'
|
66
|
+
# @action.run '' # => nil
|
67
|
+
#
|
68
|
+
# Returns the command or nil.
|
35
69
|
def run(command)
|
36
70
|
commands << command if command != ''
|
37
71
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'trooper/action'
|
2
|
+
|
3
|
+
module Trooper
|
4
|
+
module Actions
|
5
|
+
|
6
|
+
class PreparePrerequisiteAction < Action
|
7
|
+
|
8
|
+
def initialize(config = {})
|
9
|
+
@name = :prepare_prerequisite
|
10
|
+
@description = "Preparing Prerequisites"
|
11
|
+
@config = config
|
12
|
+
@commands = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(configuration)
|
16
|
+
@config = configuration
|
17
|
+
@commands = []
|
18
|
+
|
19
|
+
build_commands
|
20
|
+
commands
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def build_commands
|
26
|
+
create_folders trooper_path
|
27
|
+
run "echo '#{@name}' >> #{prerequisite_list}"
|
28
|
+
run 'echo -e "Prerequisites Prepared"'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'trooper/action'
|
2
|
+
|
3
|
+
module Trooper
|
4
|
+
module Actions
|
5
|
+
|
6
|
+
class SetupTrooperAction < Action
|
7
|
+
|
8
|
+
def initialize(config = {})
|
9
|
+
@name = :setup_trooper
|
10
|
+
@description = "Setup Trooper"
|
11
|
+
@config = config
|
12
|
+
@commands = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(configuration)
|
16
|
+
@config = configuration
|
17
|
+
@commands = []
|
18
|
+
|
19
|
+
build_commands
|
20
|
+
commands
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def build_commands
|
26
|
+
create_folders path, trooper_path
|
27
|
+
run 'echo -e "Trooper Setup on Server"'
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -3,16 +3,19 @@ require 'trooper/action'
|
|
3
3
|
require 'trooper/actions/clone_repository_action'
|
4
4
|
require 'trooper/actions/install_gems_action'
|
5
5
|
require 'trooper/actions/migrate_database_action'
|
6
|
+
require 'trooper/actions/prepare_prerequisite_action'
|
6
7
|
require 'trooper/actions/restart_server_action'
|
7
8
|
require 'trooper/actions/rollback_migrate_action'
|
8
9
|
require 'trooper/actions/setup_database_action'
|
10
|
+
require 'trooper/actions/setup_trooper_action'
|
9
11
|
require 'trooper/actions/update_repository_action'
|
10
12
|
|
11
13
|
module Trooper
|
12
14
|
module Config
|
13
15
|
module Action
|
14
16
|
|
15
|
-
DEFAULT_ACTIONS = [Actions::
|
17
|
+
DEFAULT_ACTIONS = [Actions::SetupTrooperAction, Actions::PreparePrerequisiteAction,
|
18
|
+
Actions::CloneRepositoryAction, Actions::InstallGemsAction,
|
16
19
|
Actions::MigrateDatabaseAction, Actions::RestartServerAction,
|
17
20
|
Actions::RollbackMigrateAction, Actions::SetupDatabaseAction,
|
18
21
|
Actions::UpdateRepositoryAction]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'trooper/config/action'
|
2
|
+
|
3
|
+
module Trooper
|
4
|
+
module Config
|
5
|
+
module Defaults
|
6
|
+
FILE_NAME = "Troopfile"
|
7
|
+
|
8
|
+
include Trooper::Config::Action
|
9
|
+
|
10
|
+
def load_defaults!(options = {})
|
11
|
+
config[:file_name] = options[:file_name] || FILE_NAME
|
12
|
+
config[:environment] = options[:environment] || :production
|
13
|
+
config[:ruby_bin_path] = options[:ruby_bin_path] || ""
|
14
|
+
|
15
|
+
load_default_actions!
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -28,9 +28,14 @@ module Trooper
|
|
28
28
|
def path(arg)
|
29
29
|
set :application_path => "#{arg}/application"
|
30
30
|
set :trooper_path => "#{arg}/trooper"
|
31
|
+
set :prerequisite_list => "#{arg}/trooper/prerequisite_list"
|
31
32
|
set :path => arg
|
32
33
|
end
|
33
34
|
|
35
|
+
def ruby_bin_path(arg)
|
36
|
+
set :ruby_bin_path => arg.gsub(/[^\/]$/, '\1/') # /usr/local/bin/
|
37
|
+
end
|
38
|
+
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
@@ -4,15 +4,14 @@ require 'trooper/arsenal'
|
|
4
4
|
|
5
5
|
require 'trooper/config/environment'
|
6
6
|
require 'trooper/config/strategy'
|
7
|
-
require 'trooper/config/
|
7
|
+
require 'trooper/config/defaults'
|
8
8
|
|
9
9
|
module Trooper
|
10
10
|
class Configuration < Hash
|
11
|
-
FILE_NAME = "Troopfile"
|
12
11
|
|
13
12
|
include Trooper::Config::Environment
|
14
13
|
include Trooper::Config::Strategy
|
15
|
-
include Trooper::Config::
|
14
|
+
include Trooper::Config::Defaults
|
16
15
|
|
17
16
|
def self.init
|
18
17
|
gem_dir = File.dirname(__FILE__)
|
@@ -30,16 +29,14 @@ module Trooper
|
|
30
29
|
# Configuration.new({:my_override => 'settings'})
|
31
30
|
def initialize(options = {})
|
32
31
|
@loaded = false
|
33
|
-
@file_name = options[:file_name] || FILE_NAME
|
34
|
-
self[:environment] = options[:environment] || :production
|
35
32
|
|
36
|
-
|
33
|
+
load_defaults! options
|
37
34
|
load_troopfile! options
|
38
35
|
end
|
39
36
|
|
40
37
|
# returns a terminal friendly version of the configuration
|
41
38
|
def to_s
|
42
|
-
|
39
|
+
config.map {|k,v| "#{k}: #{v}" }.join("\n")
|
43
40
|
end
|
44
41
|
|
45
42
|
# will find and execute the strategy name passed
|
@@ -51,7 +48,7 @@ module Trooper
|
|
51
48
|
# a way to set variables that will be available to all actions
|
52
49
|
# set(:my_variable => 'sdsd') # => available as method in an action
|
53
50
|
def set(hash)
|
54
|
-
|
51
|
+
config.merge! hash
|
55
52
|
end
|
56
53
|
|
57
54
|
# returns true if the troopfile was loaded
|
@@ -61,6 +58,10 @@ module Trooper
|
|
61
58
|
|
62
59
|
private
|
63
60
|
|
61
|
+
def config
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
64
65
|
# loads the troopfile and sets the environment up
|
65
66
|
def load_troopfile!(options)
|
66
67
|
if troopfile?
|
@@ -70,18 +71,18 @@ module Trooper
|
|
70
71
|
load_environment!
|
71
72
|
set options
|
72
73
|
else
|
73
|
-
raise Trooper::NoConfigurationFileError, "No Configuration file (#{
|
74
|
+
raise Trooper::NoConfigurationFileError, "No Configuration file (#{self[:file_name]}) can be found!"
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
77
78
|
# returns the troopfile file object
|
78
79
|
def troopfile
|
79
|
-
File.open(
|
80
|
+
File.open(config[:file_name])
|
80
81
|
end
|
81
82
|
|
82
83
|
# returns true if the troopfile exists
|
83
84
|
def troopfile?
|
84
|
-
File.exists?(
|
85
|
+
File.exists?(config[:file_name])
|
85
86
|
end
|
86
87
|
|
87
88
|
end
|
data/lib/trooper/dsl/bundler.rb
CHANGED
@@ -3,12 +3,12 @@ module Trooper
|
|
3
3
|
module Bundler
|
4
4
|
|
5
5
|
def bundle_exec(command)
|
6
|
-
use_bundle = using_bundler? ? "bundle exec " : ""
|
6
|
+
use_bundle = using_bundler? ? "#{ruby_bin_path}bundle exec " : ""
|
7
7
|
run use_bundle + command
|
8
8
|
end
|
9
9
|
|
10
10
|
def bundle_install
|
11
|
-
run "bundle install --path #{trooper_path}/bundle --deployment --without development test" if using_bundler?
|
11
|
+
run "#{ruby_bin_path}bundle install --path #{trooper_path}/bundle --deployment --without development test" if using_bundler?
|
12
12
|
end
|
13
13
|
|
14
14
|
def rake(command)
|
@@ -20,6 +20,10 @@ module Trooper
|
|
20
20
|
def using_bundler?
|
21
21
|
File.exists? "Gemfile"
|
22
22
|
end
|
23
|
+
|
24
|
+
def ruby_bin_path
|
25
|
+
config[:ruby_bin_path] || ""
|
26
|
+
end
|
23
27
|
|
24
28
|
end
|
25
29
|
end
|
data/lib/trooper/dsl/rake.rb
CHANGED
data/lib/trooper/strategy.rb
CHANGED
@@ -8,28 +8,32 @@ module Trooper
|
|
8
8
|
def initialize(name, description, config = {}, &block)
|
9
9
|
@name, @description, @config = name, description, config
|
10
10
|
@run_list = []
|
11
|
-
|
11
|
+
@block = block if block_given?
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute(config = {})
|
15
15
|
@config = config
|
16
|
+
|
17
|
+
eval_block
|
18
|
+
|
16
19
|
Trooper.logger.debug "Configuration\n#{config}"
|
17
20
|
Trooper.logger.strategy description
|
18
21
|
successful = nil
|
19
|
-
|
22
|
+
|
20
23
|
runners.each do |runner|
|
21
24
|
begin
|
22
25
|
Trooper.logger.info "\e[4mRunning on #{runner}\n"
|
23
26
|
|
24
|
-
run_list.each do |
|
25
|
-
|
27
|
+
run_list.each do |strategy, type, name|
|
28
|
+
commands = build_commands strategy, type, name
|
29
|
+
runner_execute! runner, commands if commands
|
26
30
|
end
|
27
31
|
|
28
32
|
successful = true
|
29
33
|
Trooper.logger.success "\e[4mAll Actions Completed\n"
|
30
34
|
rescue Exception => e
|
31
35
|
Trooper.logger.error "#{e.class.to_s} : #{e.message}\n\n#{e.backtrace.join("\n")}"
|
32
|
-
|
36
|
+
|
33
37
|
successful = false
|
34
38
|
break #stop commands running on other servers
|
35
39
|
ensure
|
@@ -40,47 +44,78 @@ module Trooper
|
|
40
44
|
successful
|
41
45
|
end
|
42
46
|
|
47
|
+
def build_run_list
|
48
|
+
eval_block
|
49
|
+
run_list
|
50
|
+
end
|
51
|
+
|
43
52
|
def ok?
|
44
53
|
true
|
45
54
|
end
|
46
55
|
|
47
|
-
def call(
|
48
|
-
|
49
|
-
Arsenal.strategies[strategy_name]
|
50
|
-
|
56
|
+
def call(*strategy_names)
|
57
|
+
[*strategy_names].each do |strategy_name|
|
58
|
+
if Arsenal.strategies[strategy_name]
|
59
|
+
Arsenal.strategies[strategy_name].build_run_list.each do |action|
|
60
|
+
# strategy_name, type, name
|
61
|
+
@run_list << action
|
62
|
+
end
|
51
63
|
end
|
52
|
-
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def prerequisites(*strategy_names)
|
68
|
+
unless @run_list.detect { |a| a[2] == :prepare_prerequisite }
|
69
|
+
@run_list << [@name, :action, :prepare_prerequisite]
|
70
|
+
end
|
71
|
+
[*strategy_names].each do |strategy_name|
|
72
|
+
if Arsenal.strategies[strategy_name]
|
73
|
+
Arsenal.strategies[strategy_name].build_run_list.each do |action|
|
74
|
+
# strategy_name, type, name
|
75
|
+
@run_list << [action[0], :prerequisite, action[2]]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
53
79
|
end
|
54
80
|
|
55
81
|
def actions(*action_names)
|
56
82
|
[*action_names].each do |name|
|
57
|
-
|
83
|
+
# strategy_name, type, name
|
84
|
+
@run_list << [self.name, :action, name]
|
58
85
|
end
|
59
86
|
end
|
60
87
|
|
61
|
-
def
|
62
|
-
|
63
|
-
end
|
88
|
+
def build_commands(strategy_name, type, action_name)
|
89
|
+
action = Arsenal.actions[action_name]
|
64
90
|
|
65
|
-
|
91
|
+
if action
|
92
|
+
commands = action.call config
|
66
93
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
94
|
+
case type
|
95
|
+
when :prerequisite
|
96
|
+
commands << "echo '#{action.name}' >> #{prerequisite_list}"
|
97
|
+
commands << "echo '#{action.description}'"
|
98
|
+
commands = "touch #{prerequisite_list}; if grep -vz #{action_name} #{prerequisite_list}; then #{commands.join(' && ')}; else echo 'Already Done'; fi"
|
99
|
+
Trooper.logger.action "Prerequisite: #{action.description}"
|
71
100
|
else
|
72
|
-
|
101
|
+
Trooper.logger.action action.description
|
73
102
|
end
|
103
|
+
|
104
|
+
commands
|
105
|
+
else
|
106
|
+
raise MissingActionError, "Cant find action: #{action_name}"
|
74
107
|
end
|
75
108
|
end
|
76
109
|
|
77
|
-
def
|
78
|
-
|
110
|
+
def method_missing(method_sym, *arguments, &block)
|
111
|
+
config[method_sym] || super
|
112
|
+
end
|
79
113
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
114
|
+
private
|
115
|
+
|
116
|
+
def eval_block
|
117
|
+
if @block
|
118
|
+
instance_eval &@block
|
84
119
|
end
|
85
120
|
end
|
86
121
|
|
@@ -1,29 +1,38 @@
|
|
1
|
+
#Basic settings
|
1
2
|
user 'my_user'
|
2
3
|
hosts 'stage.example.com'
|
4
|
+
path "/fullpath/to/folder"
|
3
5
|
repository 'git@git.bar.co.uk:whatever.git'
|
4
|
-
|
6
|
+
# ruby_bin_path "/fullpath/to/ruby/bin/folder" # Define if you have issues with gems
|
5
7
|
|
6
|
-
set :my_value => 'something'
|
8
|
+
# set :my_value => 'something' # Setting a custom value
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
# Set environment specific settings and or actions
|
11
|
+
# env :stage do
|
12
|
+
# hosts 'stage.example.com', 'stage.example.com'
|
13
|
+
# set :my_value => 'something_else'
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
15
|
+
# action :my_action do
|
16
|
+
# #some action
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
# action :my_action do
|
21
|
+
# #some action
|
22
|
+
# end
|
16
23
|
|
17
|
-
|
18
|
-
|
24
|
+
strategy :setup, 'Setting up Application on the Server' do
|
25
|
+
actions :setup_trooper, :clone_repository, :setup_database
|
19
26
|
end
|
20
27
|
|
21
28
|
strategy :update, 'Update the code base on the server' do
|
29
|
+
prerequisites :setup
|
22
30
|
actions :update_repository, :install_gems
|
23
31
|
call :restart
|
24
32
|
end
|
25
33
|
|
26
34
|
strategy :deploy, 'Full deployment to the server' do
|
35
|
+
prerequisites :setup
|
27
36
|
call :update
|
28
37
|
actions :migrate_database
|
29
38
|
call :restart
|
data/lib/trooper/version.rb
CHANGED
data/lib/trooper.rb
CHANGED
@@ -11,6 +11,10 @@ module Trooper
|
|
11
11
|
class MissingStrategyError < TrooperError
|
12
12
|
end
|
13
13
|
|
14
|
+
# When a acton is not defined
|
15
|
+
class MissingActionError < TrooperError
|
16
|
+
end
|
17
|
+
|
14
18
|
# When a CLI argument is missing or badly formed
|
15
19
|
class CliArgumentError < TrooperError
|
16
20
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trooper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.0.
|
4
|
+
version: 0.6.0.beta
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-ssh
|
@@ -168,13 +168,16 @@ files:
|
|
168
168
|
- lib/trooper/actions/clone_repository_action.rb
|
169
169
|
- lib/trooper/actions/install_gems_action.rb
|
170
170
|
- lib/trooper/actions/migrate_database_action.rb
|
171
|
+
- lib/trooper/actions/prepare_prerequisite_action.rb
|
171
172
|
- lib/trooper/actions/restart_server_action.rb
|
172
173
|
- lib/trooper/actions/rollback_migrate_action.rb
|
173
174
|
- lib/trooper/actions/setup_database_action.rb
|
175
|
+
- lib/trooper/actions/setup_trooper_action.rb
|
174
176
|
- lib/trooper/actions/update_repository_action.rb
|
175
177
|
- lib/trooper/arsenal.rb
|
176
178
|
- lib/trooper/cli.rb
|
177
179
|
- lib/trooper/config/action.rb
|
180
|
+
- lib/trooper/config/defaults.rb
|
178
181
|
- lib/trooper/config/environment.rb
|
179
182
|
- lib/trooper/config/strategy.rb
|
180
183
|
- lib/trooper/configuration.rb
|
@@ -205,7 +208,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
205
208
|
version: '0'
|
206
209
|
segments:
|
207
210
|
- 0
|
208
|
-
hash:
|
211
|
+
hash: -2382425093214391347
|
209
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
210
213
|
none: false
|
211
214
|
requirements:
|