bigrig 0.0.0 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/constantcontact/bigrig.svg?branch=master)](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
|