bigrig 0.0.0 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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'