borg-rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +41 -0
- data/.travis.yml +6 -0
- data/Capfile +1 -0
- data/Gemfile +2 -0
- data/README.md +85 -0
- data/bin/borg +17 -0
- data/bin/borgify +33 -0
- data/borg.gemspec +27 -0
- data/cap/applications/app1.rb +15 -0
- data/cap/initializers/output.rb +4 -0
- data/cap/initializers/performance.rb +42 -0
- data/cap/initializers/role_reset.rb +12 -0
- data/cap/initializers/sigint.rb +9 -0
- data/lib/borg/cli/applications.rb +66 -0
- data/lib/borg/configuration/applications.rb +49 -0
- data/lib/borg/configuration/assimilator.rb +14 -0
- data/lib/borg/configuration/stages.rb +42 -0
- data/lib/borg/errors.rb +4 -0
- data/lib/borg/server/base.rb +29 -0
- data/lib/borg/servers/base.rb +21 -0
- data/lib/borg/version.rb +3 -0
- data/lib/borg.rb +8 -0
- data/skeleton/Capfile +9 -0
- data/skeleton/Gemfile +3 -0
- data/skeleton/cap/applications/.gitkeep +0 -0
- data/skeleton/cap/initializers/.gitkeep +0 -0
- data/skeleton/cap/recipies/.gitkeep +0 -0
- data/skeleton/lib/.gitkeep +0 -0
- data/skeleton/mygem.gemspec.skeleton +20 -0
- data/spec/lib/borg/cli/applications_spec.rb +164 -0
- data/spec/lib/borg/configuration/applications_spec.rb +70 -0
- data/spec/lib/borg/configuration/assimilator_spec.rb +23 -0
- data/spec/lib/borg/configuration/stages_spec.rb +71 -0
- data/spec/spec_helper.rb +3 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmUyMjY1NWY1ZGQxY2IzMWI0NWY5OGJiZDA4ZWY1NzczM2ZhYzBkZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NjQ2ZjUwN2I1MzU0ZGM3NmViNzFkY2QzNjZjNTMyMGNlMWRkNzQ5MA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MTMxMDRmYTQ1ZWY2ZDk2NTEwMWM5NjhmNzExYjVlOWU0MGEyNmMzZDRhZWU5
|
10
|
+
ZWQ4YTgyMGY3ZTAyZTUwY2Q0ZGJiN2I5N2ZiMGQ5YjE2NWQ2N2U5NTk4N2Fk
|
11
|
+
ODJmZTNlZjhhYTAxMzFmOWI3NmVlMmQ3ZGU0ZjU4MWFjNWE4YzQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzBkOTZjZmIyM2NiNGM5NDE2NDA2OGJlMDdiZjc3MmE5NmQyMmQ4Yjk3ODVh
|
14
|
+
NTJmMjQ5ODYxNWI1ZWQzODRjOGJlYTBlNmVjYTA4MDZhMGM3Y2ZhYTgxNjlj
|
15
|
+
MmIwMjA4NDQ5ZjY4MTQ2Yzk5YWIyYmNkNzhhYzk5NGFlNWEwZDg=
|
data/.gitignore
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
Gemfile.lock
|
6
|
+
InstalledFiles
|
7
|
+
coverage
|
8
|
+
lib/bundler/man
|
9
|
+
pkg
|
10
|
+
rdoc
|
11
|
+
spec/reports
|
12
|
+
test/tmp
|
13
|
+
test/version_tmp
|
14
|
+
tmp
|
15
|
+
|
16
|
+
# Local Ruby Dev Configs
|
17
|
+
.rvmrc
|
18
|
+
|
19
|
+
# YARD artifacts
|
20
|
+
.yardoc
|
21
|
+
_yardoc
|
22
|
+
doc/
|
23
|
+
|
24
|
+
# JetBrains IDE files
|
25
|
+
*.iml
|
26
|
+
*.ipr
|
27
|
+
*.iws
|
28
|
+
.idea/
|
29
|
+
|
30
|
+
# OS X
|
31
|
+
.DS_Store
|
32
|
+
.AppleDouble
|
33
|
+
.LSOverride
|
34
|
+
Icon
|
35
|
+
|
36
|
+
# Thumbnails
|
37
|
+
._*
|
38
|
+
|
39
|
+
# Files that might appear on external disk
|
40
|
+
.Spotlight-V100
|
41
|
+
.Trashes
|
data/.travis.yml
ADDED
data/Capfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
load 'lib/borg'
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Borg
|
2
|
+
This is a project inspired by Caphub. It expands on the concept and makes it into a framework for multi application
|
3
|
+
deployment.
|
4
|
+
|
5
|
+
[![Build Status](https://travis-ci.org/B0RG/borg.png?branch=master)](https://travis-ci.org/B0RG/borg)
|
6
|
+
[![Dependency Status](https://gemnasium.com/B0RG/borg.png)](https://gemnasium.com/B0RG/borg)
|
7
|
+
[![Code Climate](https://codeclimate.com/github/B0RG/borg.png)](https://codeclimate.com/github/B0RG/borg)
|
8
|
+
|
9
|
+
# Setup
|
10
|
+
## Deployer Package
|
11
|
+
|
12
|
+
`borgify` Sets up the following structure
|
13
|
+
|
14
|
+
```
|
15
|
+
my-deployer-package
|
16
|
+
├── cap
|
17
|
+
| ├── applications
|
18
|
+
| | ├── application1.rb
|
19
|
+
│ | └── application2.rb
|
20
|
+
| ├── initilizers
|
21
|
+
| | ├── initilizer1.rb
|
22
|
+
│ | └── initilizer2.rb
|
23
|
+
| └── recipies
|
24
|
+
| ├── recipie1.rb
|
25
|
+
│ └── recipie2.rb
|
26
|
+
├── Capfile
|
27
|
+
├── Gemfile
|
28
|
+
└── Gemfile.lock
|
29
|
+
```
|
30
|
+
|
31
|
+
### Default Capfile contents
|
32
|
+
```
|
33
|
+
# provides a performance report at the end of execution
|
34
|
+
# set :borg_performance_reports, true
|
35
|
+
|
36
|
+
# runs on :exit events when ctrl-c is hit
|
37
|
+
# set :borg_sigint_triggers_exit, true
|
38
|
+
|
39
|
+
load 'borg'
|
40
|
+
# load any other borg gems here.
|
41
|
+
# NOTE: require ends up causing the initializers to be called every time a config is loaded.
|
42
|
+
|
43
|
+
```
|
44
|
+
|
45
|
+
## Services Package
|
46
|
+
`borgify plugin` Sets up the following structure
|
47
|
+
|
48
|
+
```
|
49
|
+
my-service-package
|
50
|
+
├── cap
|
51
|
+
| ├── initilizers
|
52
|
+
| | ├── initilizer1.rb
|
53
|
+
│ | └── initilizer2.rb
|
54
|
+
| └── recipies
|
55
|
+
| ├── recipie1.rb
|
56
|
+
│ └── recipie2.rb
|
57
|
+
├── my-service-package.gemspec
|
58
|
+
├── Gemfile
|
59
|
+
└── Gemfile.lock
|
60
|
+
```
|
61
|
+
|
62
|
+
### Guidelines
|
63
|
+
* While working on this there was a realization that the if you write a "on :exit" event then make sure it is executable
|
64
|
+
even if it is called when ctrl-c is hit.
|
65
|
+
|
66
|
+
## Borg Application Config
|
67
|
+
Borg provides a application and stage config setup.
|
68
|
+
One can define applications with the format.
|
69
|
+
``` ruby
|
70
|
+
application :app_name do
|
71
|
+
do things needed to setup the application environment.
|
72
|
+
end
|
73
|
+
|
74
|
+
stage :app_name, :stage_name do
|
75
|
+
do things for specific stage for the applications.
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
By default borg looks for application confi files in cap/applications and loads all those files.
|
80
|
+
If multiple application and stage blocks with the same parameters are defined
|
81
|
+
then all the blocks will be run for that application/stage.
|
82
|
+
|
83
|
+
The CLI enforces that all configs be specified at the start. Consider the command `borg app1:stage1 app2 deploy`
|
84
|
+
will result in config app1:stage1, all configs for app2 (1 config for each stage, if there is no stage it assumes the app is the only stage)
|
85
|
+
to be load and the deploy task be run against all of them.
|
data/bin/borg
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'capistrano/cli'
|
4
|
+
require 'borg/cli/applications'
|
5
|
+
require 'borg/configuration/applications'
|
6
|
+
require 'borg/configuration/stages'
|
7
|
+
require 'borg/configuration/assimilator'
|
8
|
+
require 'erb'
|
9
|
+
|
10
|
+
require 'borg/errors'
|
11
|
+
require 'borg/server/base'
|
12
|
+
require 'borg/servers/base'
|
13
|
+
|
14
|
+
# Ensure ruby 1.9.X
|
15
|
+
raise "Ruby 1.9.X required" unless RUBY_VERSION =~ /^1\.9\.\d$/
|
16
|
+
|
17
|
+
Capistrano::CLI.execute
|
data/bin/borgify
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'fileutils'
|
3
|
+
plugin = (ARGV.count == 1 and ARGV[0] == "plugin")
|
4
|
+
|
5
|
+
if ARGV.empty? or plugin
|
6
|
+
skeleton_dir = File.expand_path('../../skeleton', __FILE__)
|
7
|
+
gem_name = File.basename(Dir.pwd)
|
8
|
+
|
9
|
+
puts "Copying Skeleton"
|
10
|
+
FileUtils.cp_r("#{skeleton_dir}/.", ".")
|
11
|
+
|
12
|
+
puts "Creating lib/#{gem_name}.rb"
|
13
|
+
File.open("lib/#{gem_name}.rb", 'w') { |file| file.write("assimilate '#{gem_name}'") }
|
14
|
+
|
15
|
+
puts "Removing unnecessary files and folders"
|
16
|
+
if plugin
|
17
|
+
FileUtils.rm_r "cap/applications"
|
18
|
+
FileUtils.rm_r "Capfile"
|
19
|
+
FileUtils.rm_r "Gemfile"
|
20
|
+
puts "Setting up gemspec file"
|
21
|
+
FileUtils.mv "mygem.gemspec.skeleton", "#{gem_name}.gemspec"
|
22
|
+
else
|
23
|
+
FileUtils.rm_r "mygem.gemspec.skeleton"
|
24
|
+
end
|
25
|
+
|
26
|
+
else
|
27
|
+
# display help if parameters input
|
28
|
+
puts <<-HELP
|
29
|
+
borgify only supports to ways of calling it.
|
30
|
+
borgify # to setup deployment project
|
31
|
+
borgify plugin # to setup a pluging for borg
|
32
|
+
HELP
|
33
|
+
end
|
data/borg.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'borg/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "borg-rb"
|
8
|
+
s.version = Borg::VERSION
|
9
|
+
s.authors = ["Identified"]
|
10
|
+
s.email = ["phil@identified.com", "tejas@identified.com"]
|
11
|
+
s.description = %q{Ruby-based software provisioning and deployment framework}
|
12
|
+
s.summary = %q{Ruby-based software provisioning and deployment framework}
|
13
|
+
s.homepage = "https://github.com/B0RG/borg"
|
14
|
+
s.license = "MIT"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency "capistrano"
|
22
|
+
s.add_dependency "capistrano_colors"
|
23
|
+
s.add_dependency "colored"
|
24
|
+
s.add_dependency "term-ansicolor"
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec"
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
_cset :borg_performance_reports, true
|
2
|
+
if borg_performance_reports
|
3
|
+
# source: https://github.com/PagerDuty/pd-cap-recipes/blob/master/lib/pd-cap-recipes/tasks/performance.rb
|
4
|
+
start_times = {}
|
5
|
+
end_times = {}
|
6
|
+
order = []
|
7
|
+
|
8
|
+
on :before do
|
9
|
+
order << [:start, current_task]
|
10
|
+
start_times[current_task] = Time.now
|
11
|
+
end
|
12
|
+
|
13
|
+
on :after do
|
14
|
+
order << [:end, current_task]
|
15
|
+
end_times[current_task] = Time.now
|
16
|
+
end
|
17
|
+
|
18
|
+
on :exit do
|
19
|
+
print_report(start_times, end_times, order) if order.count > 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def print_report(start_times, end_times, order)
|
23
|
+
def l(s)
|
24
|
+
logger.info s
|
25
|
+
end
|
26
|
+
|
27
|
+
l " Performance Report"
|
28
|
+
l "=========================================================="
|
29
|
+
indent = 0
|
30
|
+
(order + [nil]).each_cons(2) do |payload1, payload2|
|
31
|
+
action, task = payload1
|
32
|
+
if action == :start
|
33
|
+
l "#{".." * indent}#{task.fully_qualified_name}" unless task == payload2.last
|
34
|
+
indent += 1
|
35
|
+
else
|
36
|
+
indent -= 1
|
37
|
+
l "#{".." * indent}#{task.fully_qualified_name} #{(end_times[task] - start_times[task]).to_i}s"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
l "=========================================================="
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Borg
|
2
|
+
module CLI
|
3
|
+
module Applications
|
4
|
+
def self.included(base) #:nodoc:
|
5
|
+
base.send :alias_method, :execute_requested_actions_without_applications, :execute_requested_actions
|
6
|
+
base.send :alias_method, :execute_requested_actions, :execute_requested_actions_with_applications
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute_requested_actions_with_applications(config)
|
10
|
+
|
11
|
+
load_applications config
|
12
|
+
|
13
|
+
separate_actions_and_applications config
|
14
|
+
|
15
|
+
if options[:applications].empty? or Thread.current[:borg_application]
|
16
|
+
Thread.current[:borg_application].load_into config if Thread.current[:borg_application]
|
17
|
+
execute_requested_actions_without_applications(config)
|
18
|
+
else
|
19
|
+
options[:applications].each do |app|
|
20
|
+
puts "Executing commands in context of #{app.name}"
|
21
|
+
Thread.current[:borg_application] = app
|
22
|
+
execute!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def load_applications config
|
30
|
+
# load applications
|
31
|
+
unless @apps_loaded
|
32
|
+
Dir["./cap/applications/**/*.rb"].each do |file|
|
33
|
+
config.load file
|
34
|
+
end
|
35
|
+
@apps_loaded = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def separate_actions_and_applications config
|
40
|
+
options[:applications] = []
|
41
|
+
found_non_application = false
|
42
|
+
options[:actions] = Array(options[:actions]).keep_if do |action|
|
43
|
+
app, stg = action.split(":").map(&:to_sym)
|
44
|
+
ret = if config.applications[app] and config.applications[app].stages[stg]
|
45
|
+
options[:applications] << config.applications[app].stages[stg]
|
46
|
+
false
|
47
|
+
elsif config.applications[app] and stg.nil?
|
48
|
+
if config.applications[app].stages.empty?
|
49
|
+
options[:applications] << config.applications[app]
|
50
|
+
else
|
51
|
+
config.applications[app].stages.each{|name, stg| options[:applications] << stg}
|
52
|
+
end
|
53
|
+
false
|
54
|
+
else
|
55
|
+
found_non_application = true
|
56
|
+
true
|
57
|
+
end
|
58
|
+
raise ArgumentError, "Can not have non application configs between application configs" if !ret and found_non_application
|
59
|
+
ret
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Capistrano::CLI.send :include, Borg::CLI::Applications
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Borg
|
2
|
+
module Configuration
|
3
|
+
module Applications
|
4
|
+
|
5
|
+
def self.included(base) #:nodoc:
|
6
|
+
base.send :alias_method, :initialize_without_applications, :initialize
|
7
|
+
base.send :alias_method, :initialize, :initialize_with_applications
|
8
|
+
end
|
9
|
+
attr_reader :applications
|
10
|
+
|
11
|
+
def initialize_with_applications(*args) #:nodoc:
|
12
|
+
initialize_without_applications(*args)
|
13
|
+
@applications = {}
|
14
|
+
end
|
15
|
+
private :initialize_with_applications
|
16
|
+
|
17
|
+
def application (name, &block)
|
18
|
+
name = name.to_sym
|
19
|
+
namespace name do
|
20
|
+
desc "Load Application #{name} (All Stages if any)"
|
21
|
+
task :default do
|
22
|
+
@applications[name].execute
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@applications[name] ||= Application.new(name, @namespaces[name])
|
26
|
+
@applications[name].execution_blocks << block if block_given?
|
27
|
+
end
|
28
|
+
|
29
|
+
class Application
|
30
|
+
attr_accessor :execution_blocks
|
31
|
+
attr_accessor :stages
|
32
|
+
attr_reader :name
|
33
|
+
|
34
|
+
def initialize name, namespace
|
35
|
+
@execution_blocks = []
|
36
|
+
@name = name
|
37
|
+
@namespace = namespace
|
38
|
+
@stages = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
def load_into config
|
42
|
+
@execution_blocks.each {|blk| config.load &blk}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Capistrano::Configuration.send :include, Borg::Configuration::Applications
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Borg
|
2
|
+
module Configuration
|
3
|
+
module Assimilator
|
4
|
+
def assimilate gem_name
|
5
|
+
gem_home = Gem::Specification.find_by_name(gem_name).gem_dir
|
6
|
+
Dir["#{gem_home}/cap/initializers/**/*.rb"].each do |file|
|
7
|
+
load file
|
8
|
+
end
|
9
|
+
@load_paths << "#{gem_home}/cap"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
Capistrano::Configuration.send :include, Borg::Configuration::Assimilator
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Borg
|
2
|
+
module Configuration
|
3
|
+
module Stages
|
4
|
+
|
5
|
+
def stage (app, name, &block)
|
6
|
+
app = app.to_sym
|
7
|
+
name = name.to_sym
|
8
|
+
application app unless @applications[app]
|
9
|
+
|
10
|
+
namespace app do
|
11
|
+
desc "Load Application #{app} and Stage #{name}"
|
12
|
+
task name do
|
13
|
+
@applications[app].stages[name].execute
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@applications[app].stages[name] ||= Stage.new(name, @applications[app])
|
17
|
+
@applications[app].stages[name].execution_blocks << block
|
18
|
+
end
|
19
|
+
|
20
|
+
class Stage
|
21
|
+
attr_accessor :execution_blocks
|
22
|
+
attr_accessor :parent
|
23
|
+
def name
|
24
|
+
"#{parent.name}:#{@name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize name, parent
|
28
|
+
@execution_blocks = []
|
29
|
+
@name = name
|
30
|
+
@parent = parent
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_into config
|
34
|
+
parent.load_into config
|
35
|
+
@execution_blocks.each {|blk| config.load &blk}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Capistrano::Configuration.send :include, Borg::Configuration::Stages
|
data/lib/borg/errors.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Borg
|
2
|
+
module Server
|
3
|
+
class Base < ::Capistrano::ServerDefinition
|
4
|
+
|
5
|
+
def self.create opts
|
6
|
+
unimplemented "Use a subclass of Borg::Server::Base that implements the create functionality."
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
unimplemented "Use a subclass of Borg::Server::Base that implements the start functionality."
|
11
|
+
end
|
12
|
+
|
13
|
+
def stop
|
14
|
+
unimplemented "Use a subclass of Borg::Server::Base that implements the stop functionality."
|
15
|
+
end
|
16
|
+
|
17
|
+
def destroy
|
18
|
+
unimplemented "Use a subclass of Borg::Server::Base that implements the destroy functionality."
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def unimplemented msg
|
24
|
+
raise Borg::UnimplementedError.new msg
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Borg
|
2
|
+
module Servers
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
def all
|
6
|
+
unimplemented "Use a subclass of Borg::Servers::Base that implements the all functionality."
|
7
|
+
end
|
8
|
+
|
9
|
+
def [] name
|
10
|
+
all.select{|s| s.name == name}.first
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def unimplemented msg
|
16
|
+
raise Borg::UnimplementedError.new msg
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/borg/version.rb
ADDED
data/lib/borg.rb
ADDED
data/skeleton/Capfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# provides a performance report at the end of execution
|
2
|
+
# set :borg_performance_reports, true
|
3
|
+
|
4
|
+
# runs on :exit events when ctrl-c is hit
|
5
|
+
# set :borg_sigint_triggers_exit, true
|
6
|
+
|
7
|
+
load 'borg.rb'
|
8
|
+
# load any other borg gems here.
|
9
|
+
# NOTE: require ends up causing the initializers to be called every time a config is loaded.
|
data/skeleton/Gemfile
ADDED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift 'lib'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = raise "fill gem name here"
|
5
|
+
s.version = raise "fill gem version here"
|
6
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
7
|
+
s.summary = raise "fill gem summary here"
|
8
|
+
s.homepage = raise "fill gem homepage here"
|
9
|
+
s.email = raise "fill gem contact emails here"
|
10
|
+
s.authors = raise "fill gem author names here"
|
11
|
+
s.has_rdoc = false
|
12
|
+
|
13
|
+
s.files = %w( README.md Rakefile LICENSE )
|
14
|
+
s.files += Dir.glob("lib/**/*")
|
15
|
+
s.files += Dir.glob("cap/**/*")
|
16
|
+
|
17
|
+
s.description = raise "fill gem description here"
|
18
|
+
|
19
|
+
s.add_dependency "borg-rb"
|
20
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'borg/cli/applications'
|
3
|
+
|
4
|
+
describe Borg::CLI::Applications do
|
5
|
+
before :each do
|
6
|
+
@config = double("config1")
|
7
|
+
@files = %w{cap/applications/app1.rb cap/applications/app1/stg1.rb cap/applications/app1/stg2.rb}
|
8
|
+
Dir.stub("[]").and_return(@files)
|
9
|
+
@cli = Capistrano::CLI.new([])
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#load_applications when called" do
|
13
|
+
before do
|
14
|
+
@files.each { |f| @config.should_receive(:load).with(f) }
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should load all files in ./cap/applications/**/*.rb" do
|
18
|
+
@cli.send :load_applications, @config
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with a second call" do
|
22
|
+
before do
|
23
|
+
@cli.send :load_applications, @config
|
24
|
+
@config2 = double("config2")
|
25
|
+
@files.each { |f| @config2.should_not_receive(:load).with(f) }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not load all files in ./cap/applications/**/*.rb for further calls" do
|
29
|
+
@cli.send :load_applications, @config2
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "#separate_actions_and_applications when called" do
|
35
|
+
before do
|
36
|
+
@cli.instance_eval do
|
37
|
+
@options = {}
|
38
|
+
@options[:actions] = %w{app1 app2:stg1 app2:stg3 test test2}
|
39
|
+
end
|
40
|
+
@config.stub(:applications).and_return({
|
41
|
+
app1: double("app1"),
|
42
|
+
app2: double("app2")
|
43
|
+
})
|
44
|
+
@config.applications[:app1].stub(:stages).and_return({})
|
45
|
+
@config.applications[:app2].stub(:stages).and_return({
|
46
|
+
stg1: double("stg1"),
|
47
|
+
stg2: double("stg2")
|
48
|
+
})
|
49
|
+
end
|
50
|
+
it "should remove all applications from actions" do
|
51
|
+
@cli.send :separate_actions_and_applications, @config
|
52
|
+
@cli.options[:actions].should == %w{app2:stg3 test test2}
|
53
|
+
@cli.options[:applications].should == [
|
54
|
+
@config.applications[:app1],
|
55
|
+
@config.applications[:app2].stages[:stg1]
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should queue both stages if app2" do
|
60
|
+
@cli.instance_eval do
|
61
|
+
@options[:actions] = %w{app1 app2 test test2}
|
62
|
+
end
|
63
|
+
|
64
|
+
@cli.send :separate_actions_and_applications, @config
|
65
|
+
|
66
|
+
@cli.options[:actions].should == %w{test test2}
|
67
|
+
@cli.options[:applications].should == [
|
68
|
+
@config.applications[:app1],
|
69
|
+
@config.applications[:app2].stages[:stg1],
|
70
|
+
@config.applications[:app2].stages[:stg2]
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should raise exception if configs are not isolated to start of the actions list" do
|
75
|
+
@cli.instance_eval do
|
76
|
+
@options[:actions] << "app2:stg2"
|
77
|
+
end
|
78
|
+
expect{ @cli.send(:separate_actions_and_applications, @config)}.to raise_error(ArgumentError, "Can not have non application configs between application configs")
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "#execute_requested_actions_with_applications when called" do
|
84
|
+
before do
|
85
|
+
|
86
|
+
@cli.instance_eval do
|
87
|
+
@apps_loaded = true
|
88
|
+
@options = {}
|
89
|
+
@options[:actions] = %w{app1 app2:stg1 app2:stg3 test test2}
|
90
|
+
@options[:applications] = []
|
91
|
+
end
|
92
|
+
@config.stub(:applications).and_return({})
|
93
|
+
|
94
|
+
@cli.stub(:execute_requested_actions_without_applications)
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should load applications" do
|
99
|
+
@cli.should_receive(:load_applications).with(@config)
|
100
|
+
@cli.execute_requested_actions_with_applications @config
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should separate actions and applications" do
|
104
|
+
@cli.should_receive(:separate_actions_and_applications).with(@config)
|
105
|
+
@cli.execute_requested_actions_with_applications @config
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should call #execute_requested_actions_without_applications when there is an empty applications list" do
|
109
|
+
@cli.should_receive(:execute_requested_actions_without_applications).with(@config)
|
110
|
+
@cli.execute_requested_actions_with_applications @config
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when applications exist" do
|
114
|
+
before do
|
115
|
+
apps = [double(:app1), double(:app2)]
|
116
|
+
apps[0].stub(:name).and_return(:app1)
|
117
|
+
apps[1].stub(:name).and_return(:app2)
|
118
|
+
@cli.instance_eval do
|
119
|
+
@options[:applications] = apps
|
120
|
+
end
|
121
|
+
@cli.stub(:puts)
|
122
|
+
end
|
123
|
+
|
124
|
+
after do
|
125
|
+
Thread.current[:borg_application] = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should call call execute! for each application" do
|
129
|
+
@cli.stub(:load_applications)
|
130
|
+
@cli.stub(:separate_actions_and_applications)
|
131
|
+
@cli.should_receive(:execute!).with().twice
|
132
|
+
@cli.execute_requested_actions_with_applications @config
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should set Thread's borg_application" do
|
136
|
+
@cli.stub(:load_applications)
|
137
|
+
@cli.stub(:separate_actions_and_applications)
|
138
|
+
@cli.stub(:execute!) do
|
139
|
+
@cli.options[:applications].should include Thread.current[:borg_application]
|
140
|
+
end
|
141
|
+
@cli.execute_requested_actions_with_applications @config
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should call #execute_requested_actions_without_applications when Thread's borg_application is set" do
|
145
|
+
Thread.current[:borg_application] = @cli.options[:applications][0]
|
146
|
+
@cli.stub(:load_applications)
|
147
|
+
@cli.stub(:separate_actions_and_applications)
|
148
|
+
@cli.should_receive(:execute_requested_actions_without_applications).with(@config)
|
149
|
+
@cli.options[:applications][0].stub(:load_into)
|
150
|
+
@cli.execute_requested_actions_with_applications @config
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should load the application's config when Thread's borg_application is set" do
|
154
|
+
Thread.current[:borg_application] = @cli.options[:applications][0]
|
155
|
+
@cli.stub(:load_applications)
|
156
|
+
@cli.stub(:separate_actions_and_applications)
|
157
|
+
@cli.stub(:execute_requested_actions_without_applications)
|
158
|
+
@cli.options[:applications][0].should_receive(:load_into)
|
159
|
+
@cli.execute_requested_actions_with_applications @config
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'borg/configuration/applications'
|
3
|
+
|
4
|
+
describe Borg::Configuration::Applications do
|
5
|
+
it "should be included into Capistrano::Configuration" do
|
6
|
+
Capistrano::Configuration.ancestors.should include Borg::Configuration::Applications
|
7
|
+
end
|
8
|
+
|
9
|
+
context "when a new Capistrano::Configuration is initialized" do
|
10
|
+
subject { Capistrano::Configuration.new }
|
11
|
+
it "should initialize the applications hash" do
|
12
|
+
expect(subject.applications).to eq({})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when an applications is defined" do
|
17
|
+
before do
|
18
|
+
@config = Capistrano::Configuration.new
|
19
|
+
@config.load do
|
20
|
+
application "app1" do
|
21
|
+
test_notice "You have called app1"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
subject { @config }
|
26
|
+
|
27
|
+
it "should symobolize the name" do
|
28
|
+
expect(subject.applications[:app1].name).to eq :app1
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should create a namespace app1 with task default and a description" do
|
32
|
+
expect(subject.namespaces[:app1]).to be_true
|
33
|
+
expect(subject.namespaces[:app1].tasks[:default]).to be_true
|
34
|
+
expect(subject.namespaces[:app1].tasks[:default].desc).to be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should add it to applications hash and have a block" do
|
38
|
+
expect(subject.applications[:app1].class).to eq Borg::Configuration::Applications::Application
|
39
|
+
expect(subject.applications[:app1].execution_blocks.count).to eq 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe Borg::Configuration::Applications::Application do
|
45
|
+
it "should be initialize all variables" do
|
46
|
+
app1 = Borg::Configuration::Applications::Application.new(:app1, double("namespace app1"))
|
47
|
+
expect(app1.stages).to eq({})
|
48
|
+
expect(app1.name).to eq(:app1)
|
49
|
+
expect(app1.execution_blocks).to eq([])
|
50
|
+
end
|
51
|
+
|
52
|
+
context "an applications with 2 blocks" do
|
53
|
+
before do
|
54
|
+
@app1 = Borg::Configuration::Applications::Application.new(:app1, double("namespace app1"))
|
55
|
+
@app1.execution_blocks << -> {
|
56
|
+
raise "block 1 called"
|
57
|
+
}
|
58
|
+
@app1.execution_blocks << -> {
|
59
|
+
raise "block 2 called"
|
60
|
+
}
|
61
|
+
end
|
62
|
+
context "when #load_into is called" do
|
63
|
+
it "should all blocks into the provided config" do
|
64
|
+
config = double("test config")
|
65
|
+
config.should_receive(:load).twice
|
66
|
+
@app1.load_into config
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'borg/configuration/assimilator'
|
3
|
+
|
4
|
+
describe Borg::Configuration::Assimilator do
|
5
|
+
it "should be included into Capistrano::Configuration" do
|
6
|
+
Capistrano::Configuration.new.should respond_to :assimilate
|
7
|
+
end
|
8
|
+
|
9
|
+
context "when assimilate('borg') is called" do
|
10
|
+
subject { Capistrano::Configuration.new }
|
11
|
+
it "should loads all the initializers" do
|
12
|
+
Dir["cap/initializers/**/*.rb"].each do |file|
|
13
|
+
subject.should_receive(:load).with(File.expand_path(file))
|
14
|
+
end
|
15
|
+
subject.assimilate ('borg-rb')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should add the cap directory to teh load path" do
|
19
|
+
Dir.stub("[]").and_return([])
|
20
|
+
lambda { subject.assimilate ('borg-rb') }.should change(subject.load_paths, :count).by 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'borg/configuration/applications'
|
3
|
+
require 'borg/configuration/stages'
|
4
|
+
|
5
|
+
describe Borg::Configuration::Stages do
|
6
|
+
it "should be included into Capistrano::Configuration" do
|
7
|
+
Capistrano::Configuration.ancestors.should include Borg::Configuration::Stages
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when an applications is defined" do
|
11
|
+
before do
|
12
|
+
@config = Capistrano::Configuration.new
|
13
|
+
@config.load do
|
14
|
+
stage "app1", "stg1" do
|
15
|
+
test_notice "You have called app1 stg1"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
subject { @config }
|
20
|
+
|
21
|
+
it "should create application since it does not exist" do
|
22
|
+
expect(subject.applications[:app1]).to be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should symobolize the name" do
|
26
|
+
expect(subject.applications[:app1].stages.keys.first).to eq :stg1
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should create a namespace app1 with task stg1 and a description" do
|
30
|
+
expect(subject.namespaces[:app1]).to be_true
|
31
|
+
expect(subject.namespaces[:app1].tasks[:stg1]).to be_true
|
32
|
+
expect(subject.namespaces[:app1].tasks[:stg1].desc).to be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should add it to applications hash and have a block" do
|
36
|
+
expect(subject.applications[:app1].stages[:stg1].class).to eq Borg::Configuration::Stages::Stage
|
37
|
+
expect(subject.applications[:app1].stages[:stg1].execution_blocks.count).to eq 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Borg::Configuration::Stages::Stage do
|
43
|
+
it "should be initialize all variables" do
|
44
|
+
parent = double "app1"
|
45
|
+
parent.stub(:name).and_return :app1
|
46
|
+
stg1 = Borg::Configuration::Stages::Stage.new(:stg1, parent)
|
47
|
+
expect(stg1.name).to eq("app1:stg1")
|
48
|
+
expect(stg1.parent).to eq(parent)
|
49
|
+
expect(stg1.execution_blocks).to eq([])
|
50
|
+
end
|
51
|
+
|
52
|
+
context "a stage with 2 blocks" do
|
53
|
+
before do
|
54
|
+
@stg1 = Borg::Configuration::Stages::Stage.new(:stg1, double("app1"))
|
55
|
+
@stg1.execution_blocks << -> {
|
56
|
+
raise "block 1 called"
|
57
|
+
}
|
58
|
+
@stg1.execution_blocks << -> {
|
59
|
+
raise "block 2 called"
|
60
|
+
}
|
61
|
+
end
|
62
|
+
context "when #load_into is called" do
|
63
|
+
it "should all blocks into the provided config" do
|
64
|
+
config = double("test config")
|
65
|
+
@stg1.parent.should_receive(:load_into).with(config)
|
66
|
+
config.should_receive(:load).twice
|
67
|
+
@stg1.load_into config
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: borg-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Identified
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capistrano
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: capistrano_colors
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colored
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: term-ansicolor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Ruby-based software provisioning and deployment framework
|
84
|
+
email:
|
85
|
+
- phil@identified.com
|
86
|
+
- tejas@identified.com
|
87
|
+
executables:
|
88
|
+
- borg
|
89
|
+
- borgify
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- .gitignore
|
94
|
+
- .travis.yml
|
95
|
+
- Capfile
|
96
|
+
- Gemfile
|
97
|
+
- README.md
|
98
|
+
- bin/borg
|
99
|
+
- bin/borgify
|
100
|
+
- borg.gemspec
|
101
|
+
- cap/applications/app1.rb
|
102
|
+
- cap/initializers/output.rb
|
103
|
+
- cap/initializers/performance.rb
|
104
|
+
- cap/initializers/role_reset.rb
|
105
|
+
- cap/initializers/sigint.rb
|
106
|
+
- lib/borg.rb
|
107
|
+
- lib/borg/cli/applications.rb
|
108
|
+
- lib/borg/configuration/applications.rb
|
109
|
+
- lib/borg/configuration/assimilator.rb
|
110
|
+
- lib/borg/configuration/stages.rb
|
111
|
+
- lib/borg/errors.rb
|
112
|
+
- lib/borg/server/base.rb
|
113
|
+
- lib/borg/servers/base.rb
|
114
|
+
- lib/borg/version.rb
|
115
|
+
- skeleton/Capfile
|
116
|
+
- skeleton/Gemfile
|
117
|
+
- skeleton/cap/applications/.gitkeep
|
118
|
+
- skeleton/cap/initializers/.gitkeep
|
119
|
+
- skeleton/cap/recipies/.gitkeep
|
120
|
+
- skeleton/lib/.gitkeep
|
121
|
+
- skeleton/mygem.gemspec.skeleton
|
122
|
+
- spec/lib/borg/cli/applications_spec.rb
|
123
|
+
- spec/lib/borg/configuration/applications_spec.rb
|
124
|
+
- spec/lib/borg/configuration/assimilator_spec.rb
|
125
|
+
- spec/lib/borg/configuration/stages_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
homepage: https://github.com/B0RG/borg
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ! '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.0.3
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: Ruby-based software provisioning and deployment framework
|
151
|
+
test_files:
|
152
|
+
- spec/lib/borg/cli/applications_spec.rb
|
153
|
+
- spec/lib/borg/configuration/applications_spec.rb
|
154
|
+
- spec/lib/borg/configuration/assimilator_spec.rb
|
155
|
+
- spec/lib/borg/configuration/stages_spec.rb
|
156
|
+
- spec/spec_helper.rb
|
157
|
+
has_rdoc:
|