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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +20 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.md +19 -0
  7. data/Gemfile +2 -0
  8. data/Gemfile.lock +84 -0
  9. data/LICENSE +28 -0
  10. data/README.md +191 -0
  11. data/Rakefile +10 -0
  12. data/bigrig.gemspec +29 -0
  13. data/bin/bigrig +113 -0
  14. data/lib/bigrig/actions/destroy_action.rb +21 -0
  15. data/lib/bigrig/actions/dev_action.rb +19 -0
  16. data/lib/bigrig/actions/log_action.rb +45 -0
  17. data/lib/bigrig/actions/run_action.rb +14 -0
  18. data/lib/bigrig/actions/ship_action.rb +51 -0
  19. data/lib/bigrig/actions.rb +5 -0
  20. data/lib/bigrig/dependency_graph.rb +21 -0
  21. data/lib/bigrig/descriptor.rb +43 -0
  22. data/lib/bigrig/docker_adapter.rb +129 -0
  23. data/lib/bigrig/models/application.rb +22 -0
  24. data/lib/bigrig/models/base_model.rb +7 -0
  25. data/lib/bigrig/models/container.rb +40 -0
  26. data/lib/bigrig/models.rb +3 -0
  27. data/lib/bigrig/output_parser.rb +52 -0
  28. data/lib/bigrig/runner.rb +94 -0
  29. data/lib/bigrig/version.rb +3 -0
  30. data/lib/bigrig.rb +8 -0
  31. data/spec/bigrig/actions/destroy_action_spec.rb +55 -0
  32. data/spec/bigrig/actions/dev_action_spec.rb +17 -0
  33. data/spec/bigrig/actions/log_action_spec.rb +33 -0
  34. data/spec/bigrig/actions/run_action_spec.rb +270 -0
  35. data/spec/bigrig/actions/ship_action_spec.rb +82 -0
  36. data/spec/bigrig/dependency_graph_spec.rb +19 -0
  37. data/spec/bigrig/descriptor_spec.rb +56 -0
  38. data/spec/bigrig/docker_adapter_spec.rb +409 -0
  39. data/spec/bigrig/models/application_spec.rb +32 -0
  40. data/spec/bigrig/models/container_spec.rb +115 -0
  41. data/spec/bigrig/output_parser_spec.rb +71 -0
  42. data/spec/bigrig_spec.rb +249 -0
  43. data/spec/data/addscontainer.json +24 -0
  44. data/spec/data/build/Dockerfile +2 -0
  45. data/spec/data/build/test +0 -0
  46. data/spec/data/dev.json +26 -0
  47. data/spec/data/duplicate.json +13 -0
  48. data/spec/data/env.json +12 -0
  49. data/spec/data/hosts_ip.json +12 -0
  50. data/spec/data/hosts_name.json +11 -0
  51. data/spec/data/links.json +13 -0
  52. data/spec/data/log.json +8 -0
  53. data/spec/data/multiple.json +13 -0
  54. data/spec/data/path.json +5 -0
  55. data/spec/data/ports.json +9 -0
  56. data/spec/data/profiles.json +24 -0
  57. data/spec/data/ship.json +5 -0
  58. data/spec/data/single.json +8 -0
  59. data/spec/data/tagandpath.json +24 -0
  60. data/spec/data/tiny-image.tar +0 -0
  61. data/spec/data/volumes.json +13 -0
  62. data/spec/spec_helper.rb +104 -0
  63. data/spec/support/bigrig_vcr +8 -0
  64. data/spec/support/vcr.rb +15 -0
  65. data/spec/vcr/Bigrig_DestroyAction/_perform/given_json_with_a_single_container/and_the_container_has_exited/should_remove_the_container.yml +392 -0
  66. 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
  67. data/spec/vcr/Bigrig_DockerAdapter/_build/builds_the_given_directory.yml +63 -0
  68. data/spec/vcr/Bigrig_DockerAdapter/_build/passes_build_input_to_a_block.yml +35 -0
  69. data/spec/vcr/Bigrig_DockerAdapter/_container_exists_/when_the_container_does_not_exist/is_false.yml +115 -0
  70. data/spec/vcr/Bigrig_DockerAdapter/_container_exists_/when_the_container_exists/is_true.yml +82 -0
  71. data/spec/vcr/Bigrig_DockerAdapter/_image_id_by_tag/when_the_image_does_not_exist/raise_a_ImageNotFoundError.yml +172 -0
  72. data/spec/vcr/Bigrig_DockerAdapter/_image_id_by_tag/when_the_image_exists/returns_the_image_id.yml +148 -0
  73. data/spec/vcr/Bigrig_DockerAdapter/_kill/given_the_container_does_not_exist/should_raise_an_error.yml +115 -0
  74. data/spec/vcr/Bigrig_DockerAdapter/_kill/given_the_container_is_running/should_kill_the_container.yml +200 -0
  75. data/spec/vcr/Bigrig_DockerAdapter/_logs/streams_logs_to_a_block.yml +163 -0
  76. data/spec/vcr/Bigrig_DockerAdapter/_pull/given_a_block_to_capture_output/should_capture_output.yml +64 -0
  77. data/spec/vcr/Bigrig_DockerAdapter/_pull/given_the_repo_does_not_exist/raises_a_RepoNotFoundError.yml +30 -0
  78. data/spec/vcr/Bigrig_DockerAdapter/_pull/given_the_repo_exists/returns_the_image_id.yml +92 -0
  79. data/spec/vcr/Bigrig_DockerAdapter/_push/given_credentials/will_pass_login_and_password.yml +254 -0
  80. data/spec/vcr/Bigrig_DockerAdapter/_push/should_push_the_image.yml +482 -0
  81. data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_does_not_exist/raises_a_ContainerNotFoundError.yml +227 -0
  82. data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_exists/should_remove_the_container.yml +222 -0
  83. data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_is_running/raises_a_ContainerRunningError.yml +80 -0
  84. data/spec/vcr/Bigrig_DockerAdapter/_remove_image/when_the_image_doesnt_exist/raises_an_error.yml +115 -0
  85. data/spec/vcr/Bigrig_DockerAdapter/_remove_image/when_the_image_exists/removes_the_image.yml +199 -0
  86. 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
  87. 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
  88. 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
  89. data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_does_not_exist/returns_false.yml +115 -0
  90. data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_is_not_running/returns_false.yml +82 -0
  91. data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_is_running/returns_true.yml +103 -0
  92. data/spec/vcr/Bigrig_DockerAdapter/_tag/should_tag_the_image.yml +290 -0
  93. data/spec/vcr/Bigrig_LogAction/_perform/follows_the_log.yml +163 -0
  94. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_a_path/builds_the_image_before_starting_it.yml +310 -0
  95. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_hosts_by_ip/should_pass_hosts_to_container.yml +430 -0
  96. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_hosts_by_name/should_lookup_ips_for_hosts_with_a_hostname.yml +430 -0
  97. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_links/should_pass_links_to_the_right_container.yml +805 -0
  98. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_multiple_containers/launches_both_containers_in_parallel.yml +731 -0
  99. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_multiple_containers/spins_up_multiple_containers.yml +805 -0
  100. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_one_container/should_spin_up_a_single_container.yml +404 -0
  101. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_one_container/when_a_dead_container_exists/should_remove_existing_containers.yml +329 -0
  102. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes_from/should_pass_volumes_from_to_the_right_container.yml +805 -0
  103. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes_from/starts_the_dependant_container_last.yml +731 -0
  104. data/spec/vcr/Bigrig_RunAction/_perform/when_activating_profiles_that_do_not_exist/ignores_the_missing_profile.yml +409 -0
  105. data/spec/vcr/Bigrig_RunAction/_perform/with_a_file_with_active_profiles/uses_the_overridden_image.yml +432 -0
  106. data/spec/vcr/bigrig/destroy/spec/data/single_json/kills_the_container.yml +166 -0
  107. data/spec/vcr/bigrig/dev/spec/data/dev_json/activates_the_dev_profile.yml +37 -0
  108. data/spec/vcr/bigrig/dev/spec/data/dev_json/destroys_containers_on_exit.yml +227 -0
  109. data/spec/vcr/bigrig/dev/spec/data/dev_json/starts_the_containers.yml +107 -0
  110. data/spec/vcr/bigrig/logs/spec/data/log_json/tails_the_logs.yml +163 -0
  111. data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/leaves_existing_env_values_alone.yml +110 -0
  112. data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/overrides_the_env.yml +110 -0
  113. data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/overrides_the_tag.yml +103 -0
  114. data/spec/vcr/bigrig/run/spec/data/single_json/sends_the_name_of_the_container_to_stdout.yml +75 -0
  115. data/spec/vcr/bigrig/run/spec/data/single_json/starts_the_container.yml +101 -0
  116. data/spec/vcr/bigrig/ship/spec/data/ship_json/with_a_version/-c/cleans_the_image_when_its_done.yml +212 -0
  117. data/spec/vcr/bigrig/ship/spec/data/ship_json/with_a_version/builds_and_pushes_the_image.yml +128 -0
  118. data/spec/vcr/bigrig_bin_bigrig_destroy_spec/data/single_json_kills_the_container.yml +179 -0
  119. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_activates_the_dev_profile.yml +1068 -0
  120. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_destroys_containers_on_exit.yml +1070 -0
  121. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_starts_the_containers.yml +1068 -0
  122. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_tails_the_logs.yml +1075 -0
  123. data/spec/vcr/bigrig_bin_bigrig_logs_spec/data/log_json_tails_the_logs.yml +69 -0
  124. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_leaves_existing_env_values_alone.yml +306 -0
  125. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_overrides_the_env.yml +306 -0
  126. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_overrides_the_tag.yml +306 -0
  127. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/single_json_sends_the_name_of_the_container_to_stdout.yml +306 -0
  128. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/single_json_starts_the_container.yml +306 -0
  129. data/spec/vcr/bigrig_bin_bigrig_ship_spec/data/ship_json_with_a_version_-c_cleans_the_image_when_its_done.yml +335 -0
  130. data/spec/vcr/bigrig_bin_bigrig_ship_spec/data/ship_json_with_a_version_builds_and_pushes_the_image.yml +285 -0
  131. data/test/dev/shipper.json +24 -0
  132. data/test/logs/bigrig.json +6 -0
  133. data/test/logs/container1/Dockerfile +4 -0
  134. data/test/logs/container1/run.sh +7 -0
  135. data/test/logs/container2/Dockerfile +4 -0
  136. data/test/logs/container2/run.sh +7 -0
  137. data/test/ship/bigrig-1.2.3.json +1 -0
  138. data/test/ship/bigrig.json +5 -0
  139. data/test/ship/registry.json +11 -0
  140. data/test/ship/ship/Dockerfile +4 -0
  141. data/test/ship/ship/run.sh +6 -0
  142. data/test/volumes_from/exports_volumes/Dockerfile +8 -0
  143. data/test/volumes_from/exports_volumes/index.html +8 -0
  144. data/test/volumes_from/exports_volumes/run.sh +7 -0
  145. data/test/volumes_from/shipper.json +14 -0
  146. metadata +278 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ac82a5ac9205c016b1210a6aeaecfa1ea4ef5b3d
4
- data.tar.gz: 4432ef121babf48862b9d4befb15c1a077280ede
3
+ metadata.gz: 99b5f00bb1d9aaed030eb08d2fb4bc79e7dcdc3b
4
+ data.tar.gz: 988da417c88855fe554b87c35df7356baeda0165
5
5
  SHA512:
6
- metadata.gz: df0ee8a7881784b97c7e983c11e52f9c2453488113c87864e45209739a246b180d841f88c2826fa755c2c1da6f67c0a58887689de72e9d2e4166b62dfc4b6ecc
7
- data.tar.gz: d8d9ce2f48ece6aa483249b6b1120a711678659288821eb36b46d818cc3d63710b5d940b0207e4936c2aaed18378a161d8d45691bae1bc92d7dcff0a2abf8ef0
6
+ metadata.gz: 4fe24f80563124bb78aa7e3480a22ba901598ceef6b56567b601ed5ca8f1f4d62115cbf70381614decdf84237ce62987537399d56caba171f57cee7cd8bbb90f
7
+ data.tar.gz: 8ea9d97e635b3efd6ab682184afe7b82692de5abf5398070eed4dc0a7b64102069d36085c35113d7f6b1ea89550816f2f477b19f5acdc5a430a64954515c952b
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format doc
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
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
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
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
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
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
5
+ require 'rake/clean'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: [:spec, :rubocop]
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,14 @@
1
+ module Bigrig
2
+ class RunAction
3
+ attr_accessor :application
4
+
5
+ def initialize(active_containers)
6
+ application = Application.from_json active_containers
7
+ @runner = Runner.new application
8
+ end
9
+
10
+ def perform
11
+ @runner.run
12
+ end
13
+ end
14
+ 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
@@ -0,0 +1,5 @@
1
+ require 'bigrig/actions/destroy_action'
2
+ require 'bigrig/actions/log_action'
3
+ require 'bigrig/actions/run_action'
4
+ require 'bigrig/actions/dev_action'
5
+ require 'bigrig/actions/ship_action'