indocker 0.1.6 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -0
  3. data/Gemfile.lock +10 -4
  4. data/README.md +13 -2
  5. data/example/indocker/bin/deploy +19 -13
  6. data/example/indocker/bounded_contexts/shared/bad_container_build/Dockerfile +3 -0
  7. data/example/indocker/bounded_contexts/shared/bad_container_build/container.rb +5 -0
  8. data/example/indocker/bounded_contexts/shared/bad_container_build/image.rb +3 -0
  9. data/example/indocker/bounded_contexts/shared/bad_container_start/Dockerfile +8 -0
  10. data/example/indocker/bounded_contexts/shared/bad_container_start/build_context/bin/run +3 -0
  11. data/example/indocker/bounded_contexts/shared/bad_container_start/container.rb +5 -0
  12. data/example/indocker/bounded_contexts/shared/bad_container_start/image.rb +3 -0
  13. data/example/indocker/bounded_contexts/shared/good_container/Dockerfile +4 -0
  14. data/example/indocker/bounded_contexts/shared/good_container/container.rb +5 -0
  15. data/example/indocker/bounded_contexts/shared/good_container/image.rb +3 -0
  16. data/example/indocker/configurations/external.rb +18 -0
  17. data/example/indocker/infrastructure/build_servers.rb +11 -0
  18. data/example/indocker/infrastructure/servers.rb +11 -0
  19. data/example/indocker/setup.rb +1 -1
  20. data/example/spec/indocker_spec.rb +39 -0
  21. data/example/spec/spec_helper.rb +39 -0
  22. data/indocker.gemspec +1 -1
  23. data/lib/indocker.rb +37 -57
  24. data/lib/indocker/build_context.rb +13 -12
  25. data/lib/indocker/build_context_pool.rb +5 -1
  26. data/lib/indocker/configuration_deployer.rb +125 -93
  27. data/lib/indocker/container_deployer.rb +17 -7
  28. data/lib/indocker/context_args.rb +2 -0
  29. data/lib/indocker/deploy_context.rb +10 -8
  30. data/lib/indocker/deployment_policy.rb +22 -0
  31. data/lib/indocker/deployment_progress.rb +7 -2
  32. data/lib/indocker/images_compiler.rb +1 -1
  33. data/lib/indocker/logger_factory.rb +37 -0
  34. data/lib/indocker/server_pool.rb +9 -1
  35. data/lib/indocker/ssh_session.rb +21 -10
  36. data/lib/indocker/version.rb +1 -1
  37. metadata +19 -5
  38. data/lib/indocker/ssh_result_logger.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69e124a571ae32781f28cbe640d3f406914c9cbbf88ebe5178d31280844c0ea6
4
- data.tar.gz: 78f3b3a06fd08188b48ad8fedae468a62ea6d9dc348442bf22fc9fdd1b6cf93d
3
+ metadata.gz: 8625d37ada817f2f83c30f154bd2ed9a104a023e5b554f4c91f3708ed4aa2770
4
+ data.tar.gz: 24950eb94bd956f7f10ad81da4330bffa78495a4852733a1bec5d0713cce4896
5
5
  SHA512:
6
- metadata.gz: d169e30efdcf9ae6c97bf01a836be681c9bdc6cf9515fc61d30b4ae57ad9368a96e7619703fe0ad54cba968123de6ce6da6b96f1272cd7eab95ea73e7ed6416c
7
- data.tar.gz: e4b61302d306cc10d85edfffd37db51b668399a6c0ebb214451693394318b389bcf106fc116ee9f2ad1cf17f301c9ba17b1b4d6031a1218351f6c5210b3bd7b0
6
+ metadata.gz: e50ef7ed88a688bb1119e55b1d1662d6827e5667cc66c61dc85933687e9d4834c785c03c7fb917a2709adf04d909f7e611f8c844741b1532211dddad340dc149
7
+ data.tar.gz: 1e52f25fff3bf09ddb7f1d097b46ad0e858555892d3b4721a628c8817a16e165694dbf3650e940eb83cb6ac05d8ded47c6359ada9d3cba39d3885ff95e9e88d0
data/Gemfile CHANGED
@@ -4,3 +4,8 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in indocker.gemspec
6
6
  gemspec
7
+
8
+ group :test do
9
+ gem 'rspec'
10
+ gem 'pry'
11
+ end
@@ -1,15 +1,20 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- indocker (0.1.6)
4
+ indocker (0.1.11)
5
5
  net-ssh
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ coderay (1.1.3)
10
11
  diff-lcs (1.3)
12
+ method_source (1.0.0)
11
13
  net-ssh (6.1.0)
12
- rake (10.5.0)
14
+ pry (0.13.1)
15
+ coderay (~> 1.1)
16
+ method_source (~> 1.0)
17
+ rake (12.3.3)
13
18
  rspec (3.9.0)
14
19
  rspec-core (~> 3.9.0)
15
20
  rspec-expectations (~> 3.9.0)
@@ -30,8 +35,9 @@ PLATFORMS
30
35
  DEPENDENCIES
31
36
  bundler (~> 1.17)
32
37
  indocker!
33
- rake (~> 10.0)
34
- rspec (~> 3.0)
38
+ pry
39
+ rake (~> 12.3.3)
40
+ rspec
35
41
 
36
42
  BUNDLED WITH
37
43
  1.17.3
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # InDocker
2
2
 
3
+ [![Codeship Status for ArtStation/indocker](https://app.codeship.com/projects/bf8888c0-b7e4-0138-fc1f-7e2faa53772a/status?branch=master)](https://app.codeship.com/projects/404716)
4
+
3
5
  Docker Containers Deployment
4
6
 
5
7
  ## Installation
@@ -8,11 +10,20 @@ Docker Containers Deployment
8
10
  $ gem install indocker
9
11
  ```
10
12
 
11
- ## Development: Launch example app
13
+ ## Development: Launch example app locally
14
+
15
+ ```ruby
16
+ cd example
17
+ indocker/bin/deploy -C dev -c ruby -d
18
+ ```
19
+
20
+ ## Development: Launch example with external host
21
+
22
+ NOTE: Default external host requires extra permissions.
12
23
 
13
24
  ```ruby
14
25
  cd example
15
- bundle exec indocker/bin/deploy -C dev -c ruby -d
26
+ indocker/bin/deploy -C external -c ruby -d
16
27
  ```
17
28
 
18
29
  ## License
@@ -8,9 +8,10 @@ configurations = list_configurations(File.expand_path(File.join(__dir__, '../con
8
8
  ARGV << '-h' if ARGV.empty?
9
9
 
10
10
  options = {
11
- skip_build: false,
12
- force_restart: false,
13
- skip_tags: [],
11
+ skip_build: false,
12
+ skip_deploy: false,
13
+ force_restart: false,
14
+ skip_tags: [],
14
15
  skip_force_restart: [],
15
16
  }
16
17
 
@@ -61,6 +62,10 @@ OptionParser.new do |opts|
61
62
  options[:skip_build] = true
62
63
  end
63
64
 
65
+ opts.on("-b", "--skip-deploy", "Skip image deploy") do |val|
66
+ options[:skip_deploy] = true
67
+ end
68
+
64
69
  opts.on("-y", "--auto-confirm", "Automatically confirm deployment") do |val|
65
70
  options[:auto_confirm] = true
66
71
  end
@@ -106,15 +111,16 @@ Indocker.set_configuration_name(options[:configuration])
106
111
  require_relative '../setup'
107
112
 
108
113
  Indocker.deploy(
109
- containers: options[:containers] || [],
110
- tags: options[:tags] || [],
111
- skip_containers: options[:skip_containers] || [],
112
- skip_dependent: !!options[:skip_dependent],
113
- servers: options[:servers] || [],
114
- skip_build: options[:skip_build],
115
- force_restart: options[:force_restart],
116
- skip_tags: options[:skip_tags] || [],
117
- skip_force_restart: options[:skip_force_restart] || [],
118
- auto_confirm: !!options[:auto_confirm],
114
+ containers: options[:containers] || [],
115
+ tags: options[:tags] || [],
116
+ skip_containers: options[:skip_containers] || [],
117
+ skip_dependent: !!options[:skip_dependent],
118
+ servers: options[:servers] || [],
119
+ skip_build: options[:skip_build],
120
+ skip_deploy: options[:skip_deploy],
121
+ force_restart: options[:force_restart],
122
+ skip_tags: options[:skip_tags] || [],
123
+ skip_force_restart: options[:skip_force_restart] || [],
124
+ auto_confirm: !!options[:auto_confirm],
119
125
  require_confirmation: !!options[:require_confirmation],
120
126
  )
@@ -0,0 +1,3 @@
1
+ FROM ruby:2.5.0
2
+
3
+ RUN some-unexisting-command
@@ -0,0 +1,5 @@
1
+ Indocker
2
+ .define_container(:bad_container_build)
3
+ .tags('bad_container_build', 'console=true')
4
+ .image(:bad_container_build)
5
+ .networks(:app_net)
@@ -0,0 +1,3 @@
1
+ Indocker
2
+ .define_image(:bad_container_build)
3
+ .registry(:default)
@@ -0,0 +1,8 @@
1
+ FROM ruby:2.5.0
2
+
3
+ RUN mkdir /app
4
+ WORKDIR /app
5
+
6
+ COPY bin bin
7
+
8
+ CMD ["bin/run"]
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ raise "Some error"
@@ -0,0 +1,5 @@
1
+ Indocker
2
+ .define_container(:bad_container_start)
3
+ .tags('bad_container_start', 'console=true')
4
+ .image(:bad_container_start)
5
+ .networks(:app_net)
@@ -0,0 +1,3 @@
1
+ Indocker
2
+ .define_image(:bad_container_start)
3
+ .registry(:default)
@@ -0,0 +1,4 @@
1
+ FROM ruby:2.5.0
2
+
3
+ RUN mkdir /app
4
+ WORKDIR /app
@@ -0,0 +1,5 @@
1
+ Indocker
2
+ .define_container(:good_container)
3
+ .tags('good_container', 'console=true')
4
+ .image(:good_container)
5
+ .networks(:app_net)
@@ -0,0 +1,3 @@
1
+ Indocker
2
+ .define_image(:good_container)
3
+ .registry(:default)
@@ -0,0 +1,18 @@
1
+ Indocker
2
+ .build_configuration(:external)
3
+ .use_registry(:dev, as: :default)
4
+ .use_build_server(:external_bs)
5
+ .enabled_containers(
6
+ ruby: {
7
+ servers: [:external],
8
+ },
9
+ good_container: {
10
+ servers: [:external],
11
+ },
12
+ bad_container_build: {
13
+ servers: [:external],
14
+ },
15
+ bad_container_start: {
16
+ servers: [:external],
17
+ }
18
+ )
@@ -5,4 +5,15 @@ Indocker.add_build_server(
5
5
  user: `whoami`.strip,
6
6
  port: 22
7
7
  )
8
+ )
9
+
10
+ external_host = ENV['INDOCKER_EXTERNAL_HOST'] || 'indocker.artstn.ninja'
11
+ external_user = ENV['INDOCKER_EXTERNAL_USER'] || 'indocker'
12
+ Indocker.add_build_server(
13
+ Indocker::BuildServer.new(
14
+ name: :external_bs,
15
+ host: external_host,
16
+ user: external_user,
17
+ port: 22
18
+ )
8
19
  )
@@ -5,4 +5,15 @@ Indocker.add_server(
5
5
  user: `whoami`.strip,
6
6
  port: 22
7
7
  )
8
+ )
9
+
10
+ external_host = ENV['INDOCKER_EXTERNAL_HOST'] || 'indocker.artstn.ninja'
11
+ external_user = ENV['INDOCKER_EXTERNAL_USER'] || 'indocker'
12
+ Indocker.add_server(
13
+ Indocker::Server.new(
14
+ name: :external,
15
+ host: external_host,
16
+ user: external_user,
17
+ port: 22
18
+ )
8
19
  )
@@ -3,7 +3,7 @@ require 'indocker'
3
3
  root_dir = File.join(__dir__, '..', '..')
4
4
 
5
5
  Indocker.set_root_dir(__dir__)
6
- Indocker.set_deploy_dir(File.join(root_dir, 'tmp', 'deployment'))
6
+ Indocker.set_deploy_dir('~/deployment')
7
7
 
8
8
  Indocker.set_dockerignore [
9
9
  'Dockerfile',
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Indocker do
4
+ it "has a version number" do
5
+ expect(Indocker::VERSION).not_to be nil
6
+ end
7
+
8
+ describe "successful deployment" do
9
+ it "doesn't raise any error" do
10
+ expect{
11
+ launch_deployment(containers: [:good_container])
12
+ }.to_not raise_error
13
+ end
14
+
15
+ it "shows a message about successful deploy" do
16
+ allow(Indocker.global_logger).to receive(:info).at_least(:once)
17
+
18
+ launch_deployment(containers: [:good_container])
19
+
20
+ expect(Indocker.global_logger).to have_received(:info).at_least(:once).with(/Deployment finished/)
21
+ end
22
+ end
23
+
24
+ describe "failed build" do
25
+ it "exits with an error" do
26
+ expect{
27
+ launch_deployment(containers: [:bad_container_build])
28
+ }.to raise_error(SystemExit)
29
+ end
30
+ end
31
+
32
+ describe "failed start" do
33
+ it "exits without error" do
34
+ expect{
35
+ launch_deployment(containers: [:bad_container_start])
36
+ }.to_not raise_error(SystemExit)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require "bundler/setup"
2
+ require "indocker"
3
+ require "pry"
4
+
5
+ RSpec.configure do |config|
6
+ # Enable flags like --only-failures and --next-failure
7
+ config.example_status_persistence_file_path = ".rspec_status"
8
+
9
+ # Disable RSpec exposing methods globally on `Module` and `main`
10
+ config.disable_monkey_patching!
11
+
12
+ config.expect_with :rspec do |c|
13
+ c.syntax = :expect
14
+ end
15
+ end
16
+
17
+ def launch_deployment(options = {})
18
+ require_relative '../indocker/bin/utils/configurations'
19
+
20
+ Indocker.set_configuration_name(options[:configuration] || "external")
21
+ require_relative '../indocker/setup'
22
+
23
+ Indocker.set_log_level(options[:debug] ? Logger::DEBUG : Logger::INFO)
24
+
25
+ Indocker.deploy(
26
+ containers: options[:containers] || [],
27
+ tags: options[:tags] || [],
28
+ skip_containers: options[:skip_containers] || [],
29
+ skip_dependent: !!options[:skip_dependent],
30
+ servers: options[:servers] || [],
31
+ skip_build: options[:skip_build],
32
+ skip_deploy: options[:skip_deploy],
33
+ force_restart: options[:force_restart],
34
+ skip_tags: options[:skip_tags] || [],
35
+ skip_force_restart: options[:skip_force_restart] || [],
36
+ auto_confirm: !!options[:auto_confirm],
37
+ require_confirmation: !!options[:require_confirmation],
38
+ )
39
+ end
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_dependency "net-ssh"
27
27
  spec.add_development_dependency "bundler", "~> 1.17"
28
- spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rake", "~> 12.3.3"
29
29
  spec.add_development_dependency "rspec", "~> 3.0"
30
30
  end
@@ -85,10 +85,11 @@ module Indocker
85
85
  autoload :IndockerHelper, 'indocker_helper'
86
86
  autoload :ImagesCompiler, 'images_compiler'
87
87
  autoload :ContainerRunner, 'container_runner'
88
- autoload :SshResultLogger, 'ssh_result_logger'
89
88
  autoload :DeploymentProgress, 'deployment_progress'
90
89
  autoload :DeploymentChecker, 'deployment_checker'
90
+ autoload :DeploymentPolicy, 'deployment_policy'
91
91
  autoload :CrontabRedeployRulesBuilder, 'crontab_redeploy_rules_builder'
92
+ autoload :LoggerFactory, 'logger_factory'
92
93
 
93
94
  class << self
94
95
  def set_export_command(command)
@@ -318,22 +319,31 @@ module Indocker
318
319
  builder
319
320
  end
320
321
 
321
- def deploy(containers: [], skip_tags: [], tags: [], skip_dependent: false, skip_containers: [], servers: [], skip_build: false, force_restart: false, skip_force_restart: [], auto_confirm: false, require_confirmation: false)
322
+ def deploy(containers: [], skip_tags: [], tags: [], skip_dependent: false,
323
+ skip_containers: [], servers: [], skip_build: false, skip_deploy: false,
324
+ force_restart: false, skip_force_restart: [], auto_confirm: false,
325
+ require_confirmation: false)
326
+
327
+ deployment_policy = Indocker::DeploymentPolicy.new(
328
+ deploy_containers: containers,
329
+ deploy_tags: tags,
330
+ servers: servers,
331
+ skip_dependent: skip_dependent,
332
+ skip_containers: skip_containers,
333
+ skip_build: skip_build,
334
+ skip_deploy: skip_deploy,
335
+ skip_tags: skip_tags,
336
+ force_restart: force_restart,
337
+ skip_force_restart: skip_force_restart,
338
+ auto_confirm: auto_confirm,
339
+ require_confirmation: require_confirmation,
340
+ )
341
+
322
342
  Indocker::ConfigurationDeployer
323
- .new(Indocker.logger)
343
+ .new(logger: Indocker.logger, global_logger: Indocker.global_logger)
324
344
  .run(
325
- configuration: configuration,
326
- deploy_containers: containers,
327
- deploy_tags: tags,
328
- skip_dependent: skip_dependent,
329
- skip_containers: skip_containers,
330
- servers: servers,
331
- skip_build: skip_build,
332
- force_restart: force_restart,
333
- skip_tags: skip_tags,
334
- skip_force_restart: skip_force_restart,
335
- auto_confirm: auto_confirm,
336
- require_confirmation: require_confirmation,
345
+ configuration: configuration,
346
+ deployment_policy: deployment_policy
337
347
  )
338
348
  end
339
349
 
@@ -385,56 +395,26 @@ module Indocker
385
395
  Indocker::BuildContextHelper.new(Indocker.configuration, nil)
386
396
  end
387
397
 
398
+ # This logger outputs progress of the deployment
399
+ # It will not output anything for deployment without debug option
388
400
  def logger
389
401
  @logger ||= begin
390
- logger = if @log_level == Logger::DEBUG
391
- Logger.new(STDOUT)
402
+ logger_stdout = if @log_level == Logger::DEBUG
403
+ STDOUT
392
404
  else
393
- Logger.new(File.open(File::NULL, "w"))
394
- end
395
-
396
- logger.level = @log_level || Logger::INFO
397
-
398
- logger.formatter = proc do |severity, datetime, progname, msg|
399
- level = Logger::SEV_LABEL.index(severity)
400
-
401
- severity = case level
402
- when Logger::INFO
403
- severity.green
404
- when Logger::WARN
405
- severity.purple
406
- when Logger::DEBUG
407
- severity.yellow
408
- when Logger::ERROR
409
- severity.red
410
- when Logger::FATAL
411
- severity.red
412
- else
413
- severity
414
- end
415
-
416
- severity = severity.downcase
417
-
418
- if logger.debug?
419
- if msg == "{timestamp}"
420
- ""
421
- else
422
- "#{datetime.strftime("%Y/%m/%d %H:%M:%S")} #{severity}: #{msg}\n"
423
- end
424
- else
425
- # Use a nicer logging for not debug
426
- if msg == "{timestamp}"
427
- datetime.strftime("%Y/%m/%d %H:%M:%S\n").grey
428
- else
429
- " #{severity}: #{msg}\n"
430
- end
431
- end
405
+ File.open(File::NULL, "w")
432
406
  end
433
407
 
434
- logger
408
+ Indocker::LoggerFactory.create(logger_stdout, @log_level)
435
409
  end
436
410
  end
437
411
 
412
+ # Global logger would output data without dependency on how we deploy the progress
413
+ # Currently it will always output data to stdout
414
+ def global_logger
415
+ @global_logger ||= Indocker::LoggerFactory.create(STDOUT, @log_level)
416
+ end
417
+
438
418
  def set_log_level(level)
439
419
  @log_level = level
440
420
  end