bigrig 0.0.0 → 0.0.7
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 +4 -4
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/.rubocop.yml +20 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +84 -0
- data/LICENSE +28 -0
- data/README.md +191 -0
- data/Rakefile +10 -0
- data/bigrig.gemspec +29 -0
- data/bin/bigrig +113 -0
- data/lib/bigrig/actions/destroy_action.rb +21 -0
- data/lib/bigrig/actions/dev_action.rb +19 -0
- data/lib/bigrig/actions/log_action.rb +45 -0
- data/lib/bigrig/actions/run_action.rb +14 -0
- data/lib/bigrig/actions/ship_action.rb +51 -0
- data/lib/bigrig/actions.rb +5 -0
- data/lib/bigrig/dependency_graph.rb +21 -0
- data/lib/bigrig/descriptor.rb +43 -0
- data/lib/bigrig/docker_adapter.rb +129 -0
- data/lib/bigrig/models/application.rb +22 -0
- data/lib/bigrig/models/base_model.rb +7 -0
- data/lib/bigrig/models/container.rb +40 -0
- data/lib/bigrig/models.rb +3 -0
- data/lib/bigrig/output_parser.rb +52 -0
- data/lib/bigrig/runner.rb +94 -0
- data/lib/bigrig/version.rb +3 -0
- data/lib/bigrig.rb +8 -0
- data/spec/bigrig/actions/destroy_action_spec.rb +55 -0
- data/spec/bigrig/actions/dev_action_spec.rb +17 -0
- data/spec/bigrig/actions/log_action_spec.rb +33 -0
- data/spec/bigrig/actions/run_action_spec.rb +270 -0
- data/spec/bigrig/actions/ship_action_spec.rb +82 -0
- data/spec/bigrig/dependency_graph_spec.rb +19 -0
- data/spec/bigrig/descriptor_spec.rb +56 -0
- data/spec/bigrig/docker_adapter_spec.rb +409 -0
- data/spec/bigrig/models/application_spec.rb +32 -0
- data/spec/bigrig/models/container_spec.rb +115 -0
- data/spec/bigrig/output_parser_spec.rb +71 -0
- data/spec/bigrig_spec.rb +249 -0
- data/spec/data/addscontainer.json +24 -0
- data/spec/data/build/Dockerfile +2 -0
- data/spec/data/build/test +0 -0
- data/spec/data/dev.json +26 -0
- data/spec/data/duplicate.json +13 -0
- data/spec/data/env.json +12 -0
- data/spec/data/hosts_ip.json +12 -0
- data/spec/data/hosts_name.json +11 -0
- data/spec/data/links.json +13 -0
- data/spec/data/log.json +8 -0
- data/spec/data/multiple.json +13 -0
- data/spec/data/path.json +5 -0
- data/spec/data/ports.json +9 -0
- data/spec/data/profiles.json +24 -0
- data/spec/data/ship.json +5 -0
- data/spec/data/single.json +8 -0
- data/spec/data/tagandpath.json +24 -0
- data/spec/data/tiny-image.tar +0 -0
- data/spec/data/volumes.json +13 -0
- data/spec/spec_helper.rb +104 -0
- data/spec/support/bigrig_vcr +8 -0
- data/spec/support/vcr.rb +15 -0
- data/spec/vcr/Bigrig_DestroyAction/_perform/given_json_with_a_single_container/and_the_container_has_exited/should_remove_the_container.yml +392 -0
- data/spec/vcr/Bigrig_DestroyAction/_perform/given_json_with_a_single_container/and_the_container_is_running/kills_and_removes_the_container.yml +418 -0
- data/spec/vcr/Bigrig_DockerAdapter/_build/builds_the_given_directory.yml +63 -0
- data/spec/vcr/Bigrig_DockerAdapter/_build/passes_build_input_to_a_block.yml +35 -0
- data/spec/vcr/Bigrig_DockerAdapter/_container_exists_/when_the_container_does_not_exist/is_false.yml +115 -0
- data/spec/vcr/Bigrig_DockerAdapter/_container_exists_/when_the_container_exists/is_true.yml +82 -0
- data/spec/vcr/Bigrig_DockerAdapter/_image_id_by_tag/when_the_image_does_not_exist/raise_a_ImageNotFoundError.yml +172 -0
- data/spec/vcr/Bigrig_DockerAdapter/_image_id_by_tag/when_the_image_exists/returns_the_image_id.yml +148 -0
- data/spec/vcr/Bigrig_DockerAdapter/_kill/given_the_container_does_not_exist/should_raise_an_error.yml +115 -0
- data/spec/vcr/Bigrig_DockerAdapter/_kill/given_the_container_is_running/should_kill_the_container.yml +200 -0
- data/spec/vcr/Bigrig_DockerAdapter/_logs/streams_logs_to_a_block.yml +163 -0
- data/spec/vcr/Bigrig_DockerAdapter/_pull/given_a_block_to_capture_output/should_capture_output.yml +64 -0
- data/spec/vcr/Bigrig_DockerAdapter/_pull/given_the_repo_does_not_exist/raises_a_RepoNotFoundError.yml +30 -0
- data/spec/vcr/Bigrig_DockerAdapter/_pull/given_the_repo_exists/returns_the_image_id.yml +92 -0
- data/spec/vcr/Bigrig_DockerAdapter/_push/given_credentials/will_pass_login_and_password.yml +254 -0
- data/spec/vcr/Bigrig_DockerAdapter/_push/should_push_the_image.yml +482 -0
- data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_does_not_exist/raises_a_ContainerNotFoundError.yml +227 -0
- data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_exists/should_remove_the_container.yml +222 -0
- data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_is_running/raises_a_ContainerRunningError.yml +80 -0
- data/spec/vcr/Bigrig_DockerAdapter/_remove_image/when_the_image_doesnt_exist/raises_an_error.yml +115 -0
- data/spec/vcr/Bigrig_DockerAdapter/_remove_image/when_the_image_exists/removes_the_image.yml +199 -0
- data/spec/vcr/Bigrig_DockerAdapter/_run/given_an_image_id_that_exists/and_a_name/starts_the_container_with_the_right_name.yml +204 -0
- data/spec/vcr/Bigrig_DockerAdapter/_run/given_an_image_id_that_exists/and_a_name_and_env_variables/starts_the_container_with_env_set.yml +204 -0
- data/spec/vcr/Bigrig_DockerAdapter/_run/given_an_image_id_that_exists/and_a_name_and_ports/starts_the_container_with_ports_exposed.yml +230 -0
- data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_does_not_exist/returns_false.yml +115 -0
- data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_is_not_running/returns_false.yml +82 -0
- data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_is_running/returns_true.yml +103 -0
- data/spec/vcr/Bigrig_DockerAdapter/_tag/should_tag_the_image.yml +290 -0
- data/spec/vcr/Bigrig_LogAction/_perform/follows_the_log.yml +163 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_a_path/builds_the_image_before_starting_it.yml +310 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_hosts_by_ip/should_pass_hosts_to_container.yml +430 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_hosts_by_name/should_lookup_ips_for_hosts_with_a_hostname.yml +430 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_links/should_pass_links_to_the_right_container.yml +805 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_multiple_containers/launches_both_containers_in_parallel.yml +731 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_multiple_containers/spins_up_multiple_containers.yml +805 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_one_container/should_spin_up_a_single_container.yml +404 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_one_container/when_a_dead_container_exists/should_remove_existing_containers.yml +329 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes_from/should_pass_volumes_from_to_the_right_container.yml +805 -0
- data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes_from/starts_the_dependant_container_last.yml +731 -0
- data/spec/vcr/Bigrig_RunAction/_perform/when_activating_profiles_that_do_not_exist/ignores_the_missing_profile.yml +409 -0
- data/spec/vcr/Bigrig_RunAction/_perform/with_a_file_with_active_profiles/uses_the_overridden_image.yml +432 -0
- data/spec/vcr/bigrig/destroy/spec/data/single_json/kills_the_container.yml +166 -0
- data/spec/vcr/bigrig/dev/spec/data/dev_json/activates_the_dev_profile.yml +37 -0
- data/spec/vcr/bigrig/dev/spec/data/dev_json/destroys_containers_on_exit.yml +227 -0
- data/spec/vcr/bigrig/dev/spec/data/dev_json/starts_the_containers.yml +107 -0
- data/spec/vcr/bigrig/logs/spec/data/log_json/tails_the_logs.yml +163 -0
- data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/leaves_existing_env_values_alone.yml +110 -0
- data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/overrides_the_env.yml +110 -0
- data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/overrides_the_tag.yml +103 -0
- data/spec/vcr/bigrig/run/spec/data/single_json/sends_the_name_of_the_container_to_stdout.yml +75 -0
- data/spec/vcr/bigrig/run/spec/data/single_json/starts_the_container.yml +101 -0
- data/spec/vcr/bigrig/ship/spec/data/ship_json/with_a_version/-c/cleans_the_image_when_its_done.yml +212 -0
- data/spec/vcr/bigrig/ship/spec/data/ship_json/with_a_version/builds_and_pushes_the_image.yml +128 -0
- data/spec/vcr/bigrig_bin_bigrig_destroy_spec/data/single_json_kills_the_container.yml +179 -0
- data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_activates_the_dev_profile.yml +1068 -0
- data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_destroys_containers_on_exit.yml +1070 -0
- data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_starts_the_containers.yml +1068 -0
- data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_tails_the_logs.yml +1075 -0
- data/spec/vcr/bigrig_bin_bigrig_logs_spec/data/log_json_tails_the_logs.yml +69 -0
- data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_leaves_existing_env_values_alone.yml +306 -0
- data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_overrides_the_env.yml +306 -0
- data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_overrides_the_tag.yml +306 -0
- data/spec/vcr/bigrig_bin_bigrig_run_spec/data/single_json_sends_the_name_of_the_container_to_stdout.yml +306 -0
- data/spec/vcr/bigrig_bin_bigrig_run_spec/data/single_json_starts_the_container.yml +306 -0
- data/spec/vcr/bigrig_bin_bigrig_ship_spec/data/ship_json_with_a_version_-c_cleans_the_image_when_its_done.yml +335 -0
- data/spec/vcr/bigrig_bin_bigrig_ship_spec/data/ship_json_with_a_version_builds_and_pushes_the_image.yml +285 -0
- data/test/dev/shipper.json +24 -0
- data/test/logs/bigrig.json +6 -0
- data/test/logs/container1/Dockerfile +4 -0
- data/test/logs/container1/run.sh +7 -0
- data/test/logs/container2/Dockerfile +4 -0
- data/test/logs/container2/run.sh +7 -0
- data/test/ship/bigrig-1.2.3.json +1 -0
- data/test/ship/bigrig.json +5 -0
- data/test/ship/registry.json +11 -0
- data/test/ship/ship/Dockerfile +4 -0
- data/test/ship/ship/run.sh +6 -0
- data/test/volumes_from/exports_volumes/Dockerfile +8 -0
- data/test/volumes_from/exports_volumes/index.html +8 -0
- data/test/volumes_from/exports_volumes/run.sh +7 -0
- data/test/volumes_from/shipper.json +14 -0
- metadata +278 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 99b5f00bb1d9aaed030eb08d2fb4bc79e7dcdc3b
|
|
4
|
+
data.tar.gz: 988da417c88855fe554b87c35df7356baeda0165
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4fe24f80563124bb78aa7e3480a22ba901598ceef6b56567b601ed5ca8f1f4d62115cbf70381614decdf84237ce62987537399d56caba171f57cee7cd8bbb90f
|
|
7
|
+
data.tar.gz: 8ea9d97e635b3efd6ab682184afe7b82692de5abf5398070eed4dc0a7b64102069d36085c35113d7f6b1ea89550816f2f477b19f5acdc5a430a64954515c952b
|
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pkg
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
|
2
|
+
# on 2015-01-08 10:47:58 -0800 using RuboCop version 0.27.1.
|
|
3
|
+
# The point is for the user to remove these configuration records
|
|
4
|
+
# one by one as the offenses are removed from the code base.
|
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
|
6
|
+
#
|
|
7
|
+
AllCops:
|
|
8
|
+
Exclude:
|
|
9
|
+
- 'lib/bigrig/docker_api.rb'
|
|
10
|
+
- 'vendor/**/*'
|
|
11
|
+
|
|
12
|
+
Metrics/LineLength:
|
|
13
|
+
Max: 100
|
|
14
|
+
|
|
15
|
+
Style/Documentation:
|
|
16
|
+
Enabled: false
|
|
17
|
+
|
|
18
|
+
Style/DotPosition:
|
|
19
|
+
Enabled: true
|
|
20
|
+
EnforcedStyle: trailing
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
0.0.2
|
|
2
|
+
=====
|
|
3
|
+
* Profiles can add new containers
|
|
4
|
+
|
|
5
|
+
0.0.3
|
|
6
|
+
=====
|
|
7
|
+
* `bigrig ship` takes credentials
|
|
8
|
+
|
|
9
|
+
0.0.4
|
|
10
|
+
=====
|
|
11
|
+
Bump read timeout to one hour
|
|
12
|
+
|
|
13
|
+
0.0.5
|
|
14
|
+
=====
|
|
15
|
+
Add -c flag to cleanup after ship
|
|
16
|
+
|
|
17
|
+
0.0.7
|
|
18
|
+
=====
|
|
19
|
+
Add profiles to most commands
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
bigrig (0.0.7)
|
|
5
|
+
colorize (= 0.7.5)
|
|
6
|
+
docker-api (= 1.20.0)
|
|
7
|
+
gli (= 2.12.2)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
Platform (0.4.0)
|
|
13
|
+
addressable (2.3.6)
|
|
14
|
+
ast (2.0.0)
|
|
15
|
+
astrolabe (1.3.0)
|
|
16
|
+
parser (>= 2.2.0.pre.3, < 3.0)
|
|
17
|
+
coderay (1.1.0)
|
|
18
|
+
colorize (0.7.5)
|
|
19
|
+
crack (0.4.2)
|
|
20
|
+
safe_yaml (~> 1.0.0)
|
|
21
|
+
diff-lcs (1.2.5)
|
|
22
|
+
docker-api (1.20.0)
|
|
23
|
+
excon (>= 0.38.0)
|
|
24
|
+
json
|
|
25
|
+
excon (0.44.4)
|
|
26
|
+
gli (2.12.2)
|
|
27
|
+
json (1.8.2)
|
|
28
|
+
method_source (0.8.2)
|
|
29
|
+
open4 (1.3.4)
|
|
30
|
+
parser (2.2.0.pre.8)
|
|
31
|
+
ast (>= 1.1, < 3.0)
|
|
32
|
+
slop (~> 3.4, >= 3.4.5)
|
|
33
|
+
popen4 (0.1.2)
|
|
34
|
+
Platform (>= 0.4.0)
|
|
35
|
+
open4 (>= 0.4.0)
|
|
36
|
+
powerpack (0.0.9)
|
|
37
|
+
pry (0.10.1)
|
|
38
|
+
coderay (~> 1.1.0)
|
|
39
|
+
method_source (~> 0.8.1)
|
|
40
|
+
slop (~> 3.4)
|
|
41
|
+
rainbow (2.0.0)
|
|
42
|
+
rake (10.4.2)
|
|
43
|
+
rspec (3.1.0)
|
|
44
|
+
rspec-core (~> 3.1.0)
|
|
45
|
+
rspec-expectations (~> 3.1.0)
|
|
46
|
+
rspec-mocks (~> 3.1.0)
|
|
47
|
+
rspec-core (3.1.7)
|
|
48
|
+
rspec-support (~> 3.1.0)
|
|
49
|
+
rspec-expectations (3.1.2)
|
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
51
|
+
rspec-support (~> 3.1.0)
|
|
52
|
+
rspec-its (1.0.1)
|
|
53
|
+
rspec-core (>= 2.99.0.beta1)
|
|
54
|
+
rspec-expectations (>= 2.99.0.beta1)
|
|
55
|
+
rspec-mocks (3.1.3)
|
|
56
|
+
rspec-support (~> 3.1.0)
|
|
57
|
+
rspec-support (3.1.2)
|
|
58
|
+
rubocop (0.27.1)
|
|
59
|
+
astrolabe (~> 1.3)
|
|
60
|
+
parser (>= 2.2.0.pre.7, < 3.0)
|
|
61
|
+
powerpack (~> 0.0.6)
|
|
62
|
+
rainbow (>= 1.99.1, < 3.0)
|
|
63
|
+
ruby-progressbar (~> 1.4)
|
|
64
|
+
ruby-progressbar (1.7.0)
|
|
65
|
+
safe_yaml (1.0.4)
|
|
66
|
+
slop (3.6.0)
|
|
67
|
+
vcr (2.9.3)
|
|
68
|
+
webmock (1.20.4)
|
|
69
|
+
addressable (>= 2.3.6)
|
|
70
|
+
crack (>= 0.3.2)
|
|
71
|
+
|
|
72
|
+
PLATFORMS
|
|
73
|
+
ruby
|
|
74
|
+
|
|
75
|
+
DEPENDENCIES
|
|
76
|
+
bigrig!
|
|
77
|
+
popen4
|
|
78
|
+
pry
|
|
79
|
+
rake
|
|
80
|
+
rspec
|
|
81
|
+
rspec-its
|
|
82
|
+
rubocop
|
|
83
|
+
vcr (~> 2.9.3)
|
|
84
|
+
webmock (~> 1.20.4)
|
data/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Copyright (c) 2015, Constant Contact
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
8
|
+
list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
* Neither the name of bigrig nor the names of its
|
|
15
|
+
contributors may be used to endorse or promote products derived from
|
|
16
|
+
this software without specific prior written permission.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
22
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
23
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
25
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
26
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
[](https://travis-ci.org/constantcontact/bigrig)
|
|
2
|
+
# Bigrig
|
|
3
|
+
|
|
4
|
+
Bigrig manages and coordinates the lifecycle of multiple Docker containers
|
|
5
|
+
in a composite deployment strategy so you don't have to.
|
|
6
|
+
|
|
7
|
+
In its simplest form, docker looks super-easy to use. Whip up a Dockerfile,
|
|
8
|
+
fire that badboy up, and you're all done, right? Well, unfortunately
|
|
9
|
+
in reality it's rarely that straightforward.
|
|
10
|
+
|
|
11
|
+
# Scope
|
|
12
|
+
|
|
13
|
+
We want to make three things easier:
|
|
14
|
+
* Development
|
|
15
|
+
* Environemnt-specific configuration
|
|
16
|
+
* Separation of Operational Concerns
|
|
17
|
+
|
|
18
|
+
## Environment-specific configuration
|
|
19
|
+
|
|
20
|
+
Unless your ecosystem consists of the simplest possible deployment strategy,
|
|
21
|
+
you're likely going to need to be able to deploy your application to different
|
|
22
|
+
environments and you'll need the ability to configure the application in an
|
|
23
|
+
environment-specific way.
|
|
24
|
+
|
|
25
|
+
Bigrig lets you specify environment-specific configuration for all your
|
|
26
|
+
environments in one place. Having a single source-of-record for all
|
|
27
|
+
environment details means it's easier to configure a new environment and it's
|
|
28
|
+
easier to see the differences between environments.
|
|
29
|
+
|
|
30
|
+
## Separation of Operational Concerns
|
|
31
|
+
|
|
32
|
+
There's this thing called **Separation of operational concerns** and it's one
|
|
33
|
+
of the core principles that makes Docker attractive in the first place. I
|
|
34
|
+
don't care about the operating system beyond what's immediately
|
|
35
|
+
required to make my app go, and in many cases this might be all you need.
|
|
36
|
+
|
|
37
|
+
That being said, when the scope of your app grows beyond a single process
|
|
38
|
+
you've got two choices:
|
|
39
|
+
* Add more processes to your Docker-ized application
|
|
40
|
+
* Spin up more than one container and each one with a distinct job
|
|
41
|
+
|
|
42
|
+
There are those that might argue you shouldn't run more than one process
|
|
43
|
+
per container and if you count yourself among them Bigrig might be for you.
|
|
44
|
+
|
|
45
|
+
## bigrig.json
|
|
46
|
+
|
|
47
|
+
The below Bigrig metadata would be part of the project
|
|
48
|
+
`hawknewton/my-awesome-app`, sitting next to a Dockerfile that knows how to
|
|
49
|
+
generate a docker image.
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"containers": {
|
|
54
|
+
"my-awesome-app": {
|
|
55
|
+
"ports": ["80:80"],
|
|
56
|
+
"repo": "hawknewton/my-awesome-app",
|
|
57
|
+
"path": ".",
|
|
58
|
+
"env": {
|
|
59
|
+
"USE_SSL": true,
|
|
60
|
+
"CACHE_TIMEOUT": "3600"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
"logger": {
|
|
65
|
+
"repo": "hawknewton/logger",
|
|
66
|
+
"tag": "1.2.3",
|
|
67
|
+
"volumes-from": ["my-awesome-app"]
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
"profiles": {
|
|
72
|
+
"qa": {
|
|
73
|
+
"my-awesome-app": {
|
|
74
|
+
"CACHE_TIMEOUT": "10"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
"qa-1": {
|
|
79
|
+
"my-awesome-app": {
|
|
80
|
+
"hosts": [ "qa-1-database.company.com:database" ]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
"qa-2": {
|
|
85
|
+
"my-awesome-app": {
|
|
86
|
+
"hosts": [ "qa-2-database.company.com:database" ]
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
"production": {
|
|
91
|
+
"my-awesome-app": {
|
|
92
|
+
"hosts": [ "proddb12.company.com:database" ]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
"dev": {
|
|
97
|
+
"web": {
|
|
98
|
+
"env": {
|
|
99
|
+
"USE_SSL": false,
|
|
100
|
+
"CACHE_TIMEOUT": "1"
|
|
101
|
+
},
|
|
102
|
+
"links": [ "awesome-app-db:database" ]
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
"awesome-app-db": {
|
|
106
|
+
"tag": "mysql:5.5",
|
|
107
|
+
"env": {
|
|
108
|
+
"MYSQL_ROOT_PASSWORD": "rootpasswordhere",
|
|
109
|
+
"MYSQL_USER": "awesomeuser",
|
|
110
|
+
"MYSQL_PASSWORD": "awesomespassword",
|
|
111
|
+
"MYSQL_DATABASE": "awesome_db"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
A few things:
|
|
120
|
+
* You can start Bigrig with more than one active profile. In the example
|
|
121
|
+
above, you'd probably start the individual QA environments with a
|
|
122
|
+
specific profile (`qa-1`, for example) and the broader **environment class**
|
|
123
|
+
`qa`.
|
|
124
|
+
* I've included the hostname `database` for illustrative purposes, but I'd
|
|
125
|
+
advocate using something more sophisticated like a service registry to avoid
|
|
126
|
+
needing environment-specific profile entries for anything but the simplest
|
|
127
|
+
deployments.
|
|
128
|
+
* If two profiles override the same value the profile declared later in
|
|
129
|
+
`bigrig.json` wins.
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
We strive to bring the developer's environment as close to production as
|
|
134
|
+
possible (as well as the other way around). The developer uses
|
|
135
|
+
`bigrig.json` to develop their code and production uses `bigrig.json`
|
|
136
|
+
to start the application.
|
|
137
|
+
|
|
138
|
+
## QA/Production
|
|
139
|
+
|
|
140
|
+
When building your application bigrig will create an **immutable** version of
|
|
141
|
+
your `bigrig.json` that will always have the same **deterministic** behavior when
|
|
142
|
+
run. Additionally, it'll build, tag, and push all containers that contain a
|
|
143
|
+
`path` entry.
|
|
144
|
+
|
|
145
|
+
For example given a bigrig.json that looks like this:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"containers": {
|
|
150
|
+
"my-awesome-app": {
|
|
151
|
+
"ports": ["80:80"],
|
|
152
|
+
"repo": "hawknewton/my-awesome-app",
|
|
153
|
+
"path": ".",
|
|
154
|
+
"env": {
|
|
155
|
+
"USE_SSL": true,
|
|
156
|
+
"CACHE_TIMEOUT": "3600"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Running `bigrig ship 1.2.3` builds the Dockerfile in the current directory,
|
|
164
|
+
tags the resulting image, pushes that image, and creates `bigrig-1.2.3.json`
|
|
165
|
+
that looks like this:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"containers": {
|
|
170
|
+
"hawknewton/my-awesome-app": {
|
|
171
|
+
"ports": ["80:80"],
|
|
172
|
+
"repo": "hawknewton/my-awesome-app",
|
|
173
|
+
"tag": "1.2.3",
|
|
174
|
+
"env": {
|
|
175
|
+
"USE_SSL": true,
|
|
176
|
+
"CACHE_TIMEOUT": "3600"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
TODO
|
|
184
|
+
====
|
|
185
|
+
* Error handling is pretty bad
|
|
186
|
+
* Add model validation
|
|
187
|
+
|
|
188
|
+
See Also
|
|
189
|
+
========
|
|
190
|
+
* The docker guys look to be renaming `fig` to `compose`. If they added
|
|
191
|
+
profile support this project would become largely redundant.
|
data/Rakefile
ADDED
data/bigrig.gemspec
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
|
2
|
+
require File.join([File.dirname(__FILE__), 'lib', 'bigrig', 'version.rb'])
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = 'bigrig'
|
|
5
|
+
s.version = Bigrig::VERSION
|
|
6
|
+
s.author = 'Your Name Here'
|
|
7
|
+
s.email = 'your@email.address.com'
|
|
8
|
+
s.homepage = 'http://your.website.com'
|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
|
10
|
+
s.summary = 'A description of your project'
|
|
11
|
+
s.files = `git ls-files`.split('
|
|
12
|
+
')
|
|
13
|
+
s.require_paths << 'lib'
|
|
14
|
+
s.has_rdoc = true
|
|
15
|
+
s.bindir = 'bin'
|
|
16
|
+
s.executables << 'bigrig'
|
|
17
|
+
s.add_development_dependency('rake')
|
|
18
|
+
s.add_development_dependency('rspec')
|
|
19
|
+
s.add_development_dependency('rspec-its')
|
|
20
|
+
s.add_development_dependency('rubocop')
|
|
21
|
+
s.add_development_dependency('pry')
|
|
22
|
+
s.add_development_dependency('vcr', '~> 2.9.3')
|
|
23
|
+
s.add_development_dependency('webmock', '~> 1.20.4')
|
|
24
|
+
s.add_development_dependency('popen4')
|
|
25
|
+
|
|
26
|
+
s.add_runtime_dependency('gli', '2.12.2')
|
|
27
|
+
s.add_runtime_dependency('colorize', '0.7.5')
|
|
28
|
+
s.add_runtime_dependency('docker-api', '1.20.0')
|
|
29
|
+
end
|
data/bin/bigrig
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'gli'
|
|
3
|
+
require 'bigrig'
|
|
4
|
+
|
|
5
|
+
STDOUT.sync = true
|
|
6
|
+
|
|
7
|
+
include GLI::App
|
|
8
|
+
|
|
9
|
+
program_desc 'Describe your application here'
|
|
10
|
+
|
|
11
|
+
version Bigrig::VERSION
|
|
12
|
+
|
|
13
|
+
subcommand_option_handling :normal
|
|
14
|
+
arguments :strict
|
|
15
|
+
|
|
16
|
+
# desc 'Describe some switch here'
|
|
17
|
+
# switch [:s, :switch]
|
|
18
|
+
|
|
19
|
+
# desc 'Describe some flag here'
|
|
20
|
+
# default_value 'the default'
|
|
21
|
+
# arg_name 'The name of the argument'
|
|
22
|
+
# flag [:f, :flagname]
|
|
23
|
+
#
|
|
24
|
+
desc 'bigrig file'
|
|
25
|
+
default_value 'bigrig.json'
|
|
26
|
+
flag [:f, :file]
|
|
27
|
+
|
|
28
|
+
desc 'Start the applicaiton in dev mode'
|
|
29
|
+
command :dev do |c|
|
|
30
|
+
c.desc 'profiles to activate'
|
|
31
|
+
c.default_value 'dev'
|
|
32
|
+
c.flag [:p, :profiles]
|
|
33
|
+
|
|
34
|
+
c.action do |global_options, _options, _args|
|
|
35
|
+
Bigrig::DevAction.new(global_options[:active_containers]).perform
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
desc 'Prints logs from the application'
|
|
40
|
+
command :logs do |c|
|
|
41
|
+
c.desc 'profiles to activate'
|
|
42
|
+
c.flag [:p, :profiles]
|
|
43
|
+
|
|
44
|
+
c.action do |global_options, _options, _args|
|
|
45
|
+
Bigrig::LogAction.new(global_options[:active_containers]).perform
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
desc 'Spin up a bigrig application'
|
|
50
|
+
command :run do |c|
|
|
51
|
+
c.desc 'profiles to activate'
|
|
52
|
+
c.flag [:p, :profiles]
|
|
53
|
+
|
|
54
|
+
c.action do |global_options, _options, _args|
|
|
55
|
+
Bigrig::RunAction.new(global_options[:active_containers]).perform
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desc 'Stop and destroy a bigrig application'
|
|
60
|
+
command :destroy do |c|
|
|
61
|
+
c.desc 'profiles to activate'
|
|
62
|
+
c.flag [:p, :profiles]
|
|
63
|
+
|
|
64
|
+
c.action do |global_options, _options, _args|
|
|
65
|
+
Bigrig::DestroyAction.new(global_options[:active_containers]).perform
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
desc 'Build, push, and tag docker images'
|
|
70
|
+
arg_name 'version'
|
|
71
|
+
command :ship do |c|
|
|
72
|
+
c.desc 'username'
|
|
73
|
+
c.flag [:u, :username]
|
|
74
|
+
|
|
75
|
+
c.desc 'password'
|
|
76
|
+
c.flag [:p, :password]
|
|
77
|
+
|
|
78
|
+
c.desc 'email address'
|
|
79
|
+
c.flag [:e, :email]
|
|
80
|
+
|
|
81
|
+
c.desc 'remove the image after pushing'
|
|
82
|
+
c.switch [:c, :clean]
|
|
83
|
+
|
|
84
|
+
c.action do |global_options, options, args|
|
|
85
|
+
args[0] || fail('version is required')
|
|
86
|
+
creds = [:username, :password, :email].each_with_object({}) { |e, o| o[e] = options[e] }
|
|
87
|
+
|
|
88
|
+
Bigrig::ShipAction.new(global_options[:file], args[0], options[:clean], creds).perform
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
pre do |global_options, _command, options, _args|
|
|
93
|
+
profiles = options[:profiles] && options[:profiles].split(',') || []
|
|
94
|
+
active_containers = Bigrig::Descriptor.read(global_options[:file], profiles)
|
|
95
|
+
global_options[:active_containers] = active_containers.as_json
|
|
96
|
+
true
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
post do |_global, _command, _options, _args|
|
|
100
|
+
# Post logic here
|
|
101
|
+
# Use skips_post before a command to skip this
|
|
102
|
+
# block on that command only
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
on_error do |e|
|
|
106
|
+
# Error logic here
|
|
107
|
+
# return false to skip default error handling
|
|
108
|
+
puts e
|
|
109
|
+
puts e.backtrace
|
|
110
|
+
true
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
exit run(ARGV)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Bigrig
|
|
2
|
+
class DestroyAction
|
|
3
|
+
def initialize(active_containers)
|
|
4
|
+
@application = Application.from_json active_containers
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def perform
|
|
8
|
+
@application.containers.each do |container|
|
|
9
|
+
if DockerAdapter.running? container.name
|
|
10
|
+
puts "Killing container #{container.name}"
|
|
11
|
+
DockerAdapter.kill container.name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if DockerAdapter.container_exists? container.name
|
|
15
|
+
puts "Removing container #{container.name}"
|
|
16
|
+
DockerAdapter.remove_container container.name
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Bigrig
|
|
2
|
+
class DevAction
|
|
3
|
+
def initialize(active_containers)
|
|
4
|
+
@active_containers = active_containers
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def perform
|
|
8
|
+
RunAction.new(@active_containers).perform
|
|
9
|
+
[:SIGTERM, :SIGINT].each { |s| Signal.trap(s) { destroy } }
|
|
10
|
+
LogAction.new(@active_containers).perform
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def destroy
|
|
16
|
+
DestroyAction.new(@active_containers).perform
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'colorize'
|
|
2
|
+
|
|
3
|
+
module Bigrig
|
|
4
|
+
class LogAction
|
|
5
|
+
COLORS = [:green,
|
|
6
|
+
:yellow,
|
|
7
|
+
:light_blue,
|
|
8
|
+
:magenta,
|
|
9
|
+
:light_white]
|
|
10
|
+
|
|
11
|
+
def initialize(active_containers)
|
|
12
|
+
@application = Application.from_json active_containers
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def perform
|
|
16
|
+
threads = @application.containers.map do |container|
|
|
17
|
+
color = next_color
|
|
18
|
+
Thread.new do
|
|
19
|
+
DockerAdapter.logs container.name, &print_block(container.name.send color)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
threads.each(&:join)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def print_block(name)
|
|
29
|
+
proc do |stream, chunk|
|
|
30
|
+
if stream == :stderr
|
|
31
|
+
print "#{name}: #{chunk.light_red}"
|
|
32
|
+
else
|
|
33
|
+
puts "#{name}: #{chunk}"
|
|
34
|
+
end
|
|
35
|
+
$stdout.flush
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def next_color
|
|
40
|
+
@color ||= 0
|
|
41
|
+
@color += 1
|
|
42
|
+
COLORS[(@color - 1) % 5]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Bigrig
|
|
2
|
+
class ShipAction
|
|
3
|
+
def initialize(file, version, clean, credentials)
|
|
4
|
+
@file = file
|
|
5
|
+
@version = version
|
|
6
|
+
@clean = clean
|
|
7
|
+
@credentials = credentials
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def perform
|
|
11
|
+
containers.each do |_name, container|
|
|
12
|
+
container['path'] && build_and_push!(container)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
File.write outfile, JSON.dump(json)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def build_and_push!(container)
|
|
21
|
+
path = container.delete 'path'
|
|
22
|
+
repo_and_tag = "#{container['repo']}:#{@version}"
|
|
23
|
+
container['tag'] = @version
|
|
24
|
+
image = DockerAdapter.build path, &OutputParser.parser_proc
|
|
25
|
+
DockerAdapter.tag image, repo_and_tag
|
|
26
|
+
DockerAdapter.push repo_and_tag, credentials, &OutputParser.parser_proc
|
|
27
|
+
@clean && DockerAdapter.remove_image(image)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def containers
|
|
31
|
+
json['containers']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def credentials
|
|
35
|
+
@credentials && {
|
|
36
|
+
'username' => @credentials[:username],
|
|
37
|
+
'password' => @credentials[:password],
|
|
38
|
+
'email' => @credentials[:email],
|
|
39
|
+
'serveraddress' => 'https://index.docker.io/v1'
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def json
|
|
44
|
+
@json ||= JSON.parse File.read @file
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def outfile
|
|
48
|
+
"#{@file.split('.').first}-#{@version}.json"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|