borg-rb 0.0.1
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.
- 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
|
+
[](https://travis-ci.org/B0RG/borg)
|
6
|
+
[](https://gemnasium.com/B0RG/borg)
|
7
|
+
[](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:
|