indocker 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9667ebbc4e293dd51830ec7cae6c57455fe1b59b09722e094d76fa934564001
4
- data.tar.gz: 4912748b481273ba9cc7a69e11698ebfc14cd01d942550bb7f67f014df0b1a46
3
+ metadata.gz: 0356e417ece7294e5a5185f7cf17313d3b8f47c74895fdf0323989da110d5569
4
+ data.tar.gz: a2c04c1b66f98aa172b758be94e522901dffb2bef4d472602d70742fd93d80be
5
5
  SHA512:
6
- metadata.gz: 553570ec945812578c4a3cfc1744e5455c8e18e584cc2bb0bed4f70227d751329d147c04d07858f0bd26390f3725eb7bed2ce6f5fab4e34ee3731e065cc54499
7
- data.tar.gz: f1b46f64d4be12e0d62de23623fc3aac49fc0f10246effe8868fde2d9721d6105776ca7d06edd3e8e9d368352882125720915ca81ab2952e0e1feecd0eab51e3
6
+ metadata.gz: 38376ede23d5ce780f0234ec01f473d673b4bdfe5a2ef4e893fcf867420ae8a11bbe57df6f010d1f87289f2c970328f8bc86f1b0cde929c73c1129b4bfb0d591
7
+ data.tar.gz: 93bb3bb739fbc427e8c688e7da395088d6e60fafa68c0741d91706bc2ac50bee9fae80b7ff240be16f4c4b5e7985b9f8fa4b56c9e1e74ccd6aa036f8d9bad021
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,14 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- indocker (0.1.7)
4
+ indocker (0.1.9)
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)
14
+ pry (0.13.1)
15
+ coderay (~> 1.1)
16
+ method_source (~> 1.0)
12
17
  rake (10.5.0)
13
18
  rspec (3.9.0)
14
19
  rspec-core (~> 3.9.0)
@@ -30,8 +35,9 @@ PLATFORMS
30
35
  DEPENDENCIES
31
36
  bundler (~> 1.17)
32
37
  indocker!
38
+ pry
33
39
  rake (~> 10.0)
34
- rspec (~> 3.0)
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
@@ -0,0 +1,4 @@
1
+ FROM ruby:2.5.0
2
+
3
+ RUN some-unexisting-command
4
+ WORKDIR /app
@@ -0,0 +1,5 @@
1
+ Indocker
2
+ .define_container(:container_failing_build)
3
+ .tags('container_failing_build', 'console=true')
4
+ .image(:container_failing_build)
5
+ .networks(:app_net)
@@ -0,0 +1,3 @@
1
+ Indocker
2
+ .define_image(:container_failing_build)
3
+ .registry(:default)
@@ -0,0 +1,12 @@
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
+ container_failing_build: {
10
+ servers: [:external],
11
+ }
12
+ )
@@ -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,31 @@
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: [:ruby])
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: [:ruby])
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: [:container_failing_build])
28
+ }.to raise_error(SystemExit)
29
+ end
30
+ end
31
+ 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
@@ -88,7 +88,9 @@ module Indocker
88
88
  autoload :SshResultLogger, 'ssh_result_logger'
89
89
  autoload :DeploymentProgress, 'deployment_progress'
90
90
  autoload :DeploymentChecker, 'deployment_checker'
91
+ autoload :DeploymentPolicy, 'deployment_policy'
91
92
  autoload :CrontabRedeployRulesBuilder, 'crontab_redeploy_rules_builder'
93
+ autoload :LoggerFactory, 'logger_factory'
92
94
 
93
95
  class << self
94
96
  def set_export_command(command)
@@ -323,22 +325,26 @@ module Indocker
323
325
  force_restart: false, skip_force_restart: [], auto_confirm: false,
324
326
  require_confirmation: false)
325
327
 
328
+ deployment_policy = Indocker::DeploymentPolicy.new(
329
+ deploy_containers: containers,
330
+ deploy_tags: tags,
331
+ servers: servers,
332
+ skip_dependent: skip_dependent,
333
+ skip_containers: skip_containers,
334
+ skip_build: skip_build,
335
+ skip_deploy: skip_deploy,
336
+ skip_tags: skip_tags,
337
+ force_restart: force_restart,
338
+ skip_force_restart: skip_force_restart,
339
+ auto_confirm: auto_confirm,
340
+ require_confirmation: require_confirmation,
341
+ )
342
+
326
343
  Indocker::ConfigurationDeployer
327
- .new(Indocker.logger)
344
+ .new(logger: Indocker.logger, global_logger: Indocker.global_logger)
328
345
  .run(
329
- configuration: configuration,
330
- deploy_containers: containers,
331
- deploy_tags: tags,
332
- skip_dependent: skip_dependent,
333
- skip_containers: skip_containers,
334
- servers: servers,
335
- skip_build: skip_build,
336
- skip_deploy: skip_deploy,
337
- force_restart: force_restart,
338
- skip_tags: skip_tags,
339
- skip_force_restart: skip_force_restart,
340
- auto_confirm: auto_confirm,
341
- require_confirmation: require_confirmation,
346
+ configuration: configuration,
347
+ deployment_policy: deployment_policy
342
348
  )
343
349
  end
344
350
 
@@ -390,56 +396,26 @@ module Indocker
390
396
  Indocker::BuildContextHelper.new(Indocker.configuration, nil)
391
397
  end
392
398
 
399
+ # This logger outputs progress of the deployment
400
+ # It will not output anything for deployment without debug option
393
401
  def logger
394
402
  @logger ||= begin
395
- logger = if @log_level == Logger::DEBUG
396
- Logger.new(STDOUT)
403
+ logger_stdout = if @log_level == Logger::DEBUG
404
+ STDOUT
397
405
  else
398
- Logger.new(File.open(File::NULL, "w"))
406
+ File.open(File::NULL, "w")
399
407
  end
400
408
 
401
- logger.level = @log_level || Logger::INFO
402
-
403
- logger.formatter = proc do |severity, datetime, progname, msg|
404
- level = Logger::SEV_LABEL.index(severity)
405
-
406
- severity = case level
407
- when Logger::INFO
408
- severity.green
409
- when Logger::WARN
410
- severity.purple
411
- when Logger::DEBUG
412
- severity.yellow
413
- when Logger::ERROR
414
- severity.red
415
- when Logger::FATAL
416
- severity.red
417
- else
418
- severity
419
- end
420
-
421
- severity = severity.downcase
422
-
423
- if logger.debug?
424
- if msg == "{timestamp}"
425
- ""
426
- else
427
- "#{datetime.strftime("%Y/%m/%d %H:%M:%S")} #{severity}: #{msg}\n"
428
- end
429
- else
430
- # Use a nicer logging for not debug
431
- if msg == "{timestamp}"
432
- datetime.strftime("%Y/%m/%d %H:%M:%S\n").grey
433
- else
434
- " #{severity}: #{msg}\n"
435
- end
436
- end
437
- end
438
-
439
- logger
409
+ Indocker::LoggerFactory.create(logger_stdout, @log_level)
440
410
  end
441
411
  end
442
412
 
413
+ # Global logger would output data without dependency on how we deploy the progress
414
+ # Currently it will always output data to stdout
415
+ def global_logger
416
+ @global_logger ||= Indocker::LoggerFactory.create(STDOUT, @log_level)
417
+ end
418
+
443
419
  def set_log_level(level)
444
420
  @log_level = level
445
421
  end
@@ -3,22 +3,24 @@ require 'fileutils'
3
3
  class Indocker::BuildContext
4
4
  attr_reader :session, :server, :configuration, :helper, :logger
5
5
 
6
- def initialize(configuration:, build_server:, logger:)
6
+ def initialize(configuration:, build_server:, logger:, global_logger:)
7
7
  @configuration = configuration
8
8
  @logger = logger
9
9
  @helper = Indocker::BuildContextHelper.new(@configuration, @build_server)
10
10
  @server = build_server
11
+ @global_logger = global_logger
12
+ @compiled_images = Hash.new(false)
13
+ end
11
14
 
12
- if build_server
13
- @session = Indocker::SshSession.new(
14
- host: build_server.host,
15
- user: build_server.user,
16
- port: build_server.port,
17
- logger: @logger
18
- )
19
- end
15
+ def create_session!
16
+ return unless @server
20
17
 
21
- @compiled_images = Hash.new(false)
18
+ @session = Indocker::SshSession.new(
19
+ host: @server.host,
20
+ user: @server.user,
21
+ port: @server.port,
22
+ logger: @logger
23
+ )
22
24
  end
23
25
 
24
26
  def exec!(command)
@@ -69,10 +71,10 @@ class Indocker::BuildContext
69
71
  build_args = args.join(' ')
70
72
 
71
73
  res = Indocker::Docker.build(image.local_registry_url, build_args)
72
-
74
+
73
75
  if res.exit_status != 0
74
- @logger.error("image compilation :#{image.name} failed")
75
- @logger.error(res.stdout)
76
+ @global_logger.error("image compilation :#{image.name} failed")
77
+ @global_logger.error(res.stdout)
76
78
  exit 1
77
79
  end
78
80
 
@@ -1,17 +1,23 @@
1
1
  class Indocker::BuildContextPool
2
- def initialize(configuration:, logger:)
2
+ def initialize(configuration:, logger:, global_logger:)
3
3
  @logger = logger
4
4
  @configuration = configuration
5
+ @global_logger = global_logger
5
6
 
6
7
  @contexts = configuration.build_servers.map do |build_server|
7
8
  Indocker::BuildContext.new(
8
9
  logger: @logger,
9
10
  configuration: configuration,
10
11
  build_server: build_server,
12
+ global_logger: @global_logger,
11
13
  )
12
14
  end
13
15
  end
14
16
 
17
+ def create_sessions!
18
+ @contexts.each(&:create_session!)
19
+ end
20
+
15
21
  def get
16
22
  context = nil
17
23
 
@@ -5,108 +5,109 @@ require 'tempfile'
5
5
  class Indocker::ConfigurationDeployer
6
6
  REMOTE_OPERATION_TIMEOUT = 60
7
7
 
8
- def initialize(logger)
8
+ def initialize(logger:, global_logger:)
9
9
  Thread.abort_on_exception = true # abort all threads if exception occurs
10
10
 
11
11
  @logger = logger
12
- @global_logger = Logger.new(STDOUT)
13
- @global_logger.formatter = logger.formatter
12
+ @global_logger = global_logger
14
13
 
15
14
  @progress = Indocker::DeploymentProgress.new(
16
15
  Indocker.logger.level == Logger::DEBUG ? nil : Logger.new(STDOUT)
17
16
  )
18
17
  end
19
18
 
20
- def run(configuration:, deploy_containers:, skip_tags:, deploy_tags:, skip_dependent:,
21
- skip_containers:, servers:, skip_build:, skip_deploy:, force_restart:, skip_force_restart:,
22
- auto_confirm:, require_confirmation:)
19
+ # Launch deployment & measure the benchmark
20
+ def run(configuration:, deployment_policy:)
23
21
  build_context_pool = nil
24
22
  deployer = nil
25
23
 
26
24
  time = Benchmark.realtime do
27
- if force_restart
25
+ if deployment_policy.force_restart
28
26
  @logger.warn("WARNING. All containers will be forced to restart.")
29
27
  end
30
28
 
31
- if skip_build
29
+ if deployment_policy.skip_build
32
30
  @logger.warn("WARNING. Images build step will be skipped")
33
31
  end
34
32
 
35
- if skip_deploy
33
+ if deployment_policy.skip_deploy
36
34
  @logger.warn("WARNING. Images deploy step will be skipped")
37
35
  end
38
36
 
39
- preload_containers(configuration)
37
+ run!(configuration: configuration, deployment_policy: deployment_policy)
38
+ end
40
39
 
41
- containers = find_deploy_containers(configuration, deploy_containers, deploy_tags, skip_dependent, skip_containers, servers, skip_tags, auto_confirm, require_confirmation)
42
- containers = containers.uniq {|c| c.name}
40
+ @global_logger.info("Deployment finished".green)
41
+ @global_logger.info("Total time taken: #{time.round}s".green)
42
+ end
43
43
 
44
- clonner = Indocker::Repositories::Clonner.new(configuration, @logger)
44
+ # The main flow of the deployment would happen in this method.
45
+ def run!(configuration:, deployment_policy:)
46
+ containers = find_containers_to_deploy(configuration, deployment_policy)
47
+
48
+ clonner = Indocker::Repositories::Clonner.new(configuration, @logger)
49
+ build_context_pool = Indocker::BuildContextPool.new(configuration: configuration, logger: @logger, global_logger: @global_logger)
50
+ deployer = Indocker::ContainerDeployer.new(configuration: configuration, logger: @logger)
51
+
52
+ @global_logger.info("Establishing ssh sessions to all servers...")
53
+ build_context_pool.create_sessions!
54
+ deployer.create_sessions!
55
+
56
+ build_servers = configuration
57
+ .build_servers
58
+ .uniq { |s| s.host }
59
+
60
+ deploy_servers = containers
61
+ .map(&:servers)
62
+ .flatten
63
+ .uniq { |s| s.host }
64
+
65
+ servers = (deploy_servers + build_servers).uniq { |s| s.host }
66
+
67
+ @progress.setup(
68
+ binaries_servers: servers,
69
+ build_servers: build_servers,
70
+ deploy_servers: deploy_servers,
71
+ env_files: configuration.env_files.keys,
72
+ repositories: configuration.repositories.keys,
73
+ force_restart: deployment_policy.force_restart,
74
+ skip_build: deployment_policy.skip_build,
75
+ skip_deploy: deployment_policy.skip_deploy,
76
+ containers: containers,
77
+ artifact_servers: configuration.artifact_servers,
78
+ )
45
79
 
46
- @global_logger.info("Establishing ssh sessions to all servers...")
80
+ remote_operations = sync_indocker(servers)
81
+ wait_remote_operations(remote_operations)
47
82
 
48
- build_context_pool = Indocker::BuildContextPool.new(configuration: configuration, logger: @logger)
49
- deployer = Indocker::ContainerDeployer.new(configuration: configuration, logger: @logger)
83
+ remote_operations = sync_env_files(deploy_servers, configuration.env_files)
84
+ wait_remote_operations(remote_operations)
50
85
 
51
- build_servers = configuration
52
- .build_servers
53
- .uniq { |s| s.host }
86
+ remote_operations = pull_repositories(clonner, build_servers, configuration.repositories)
87
+ wait_remote_operations(remote_operations)
54
88
 
55
- deploy_servers = containers
56
- .map(&:servers)
57
- .flatten
58
- .uniq { |s| s.host }
89
+ remote_operations = sync_artifacts(clonner, configuration.artifact_servers)
90
+ wait_remote_operations(remote_operations)
59
91
 
60
- servers = (deploy_servers + build_servers).uniq { |s| s.host }
92
+ update_crontab_redeploy_rules(configuration, build_servers.first)
61
93
 
62
- @progress.setup(
63
- binaries_servers: servers,
64
- build_servers: build_servers,
65
- deploy_servers: deploy_servers,
66
- env_files: configuration.env_files.keys,
67
- repositories: configuration.repositories.keys,
68
- force_restart: force_restart,
69
- skip_build: skip_build,
70
- skip_deploy: skip_deploy,
71
- containers: containers,
72
- artifact_servers: configuration.artifact_servers,
94
+ containers.uniq.each do |container|
95
+ recursively_deploy_container(
96
+ configuration,
97
+ deployer,
98
+ build_context_pool,
99
+ container,
100
+ containers,
101
+ deployment_policy.skip_build,
102
+ deployment_policy.skip_deploy,
103
+ deployment_policy.force_restart,
104
+ deployment_policy.skip_force_restart
73
105
  )
74
-
75
- remote_operations = sync_indocker(servers)
76
- wait_remote_operations(remote_operations)
77
-
78
- remote_operations = sync_env_files(deploy_servers, configuration.env_files)
79
- wait_remote_operations(remote_operations)
80
-
81
- remote_operations = pull_repositories(clonner, build_servers, configuration.repositories)
82
- wait_remote_operations(remote_operations)
83
-
84
- remote_operations = sync_artifacts(clonner, configuration.artifact_servers)
85
- wait_remote_operations(remote_operations)
86
-
87
- update_crontab_redeploy_rules(configuration, build_servers.first)
88
-
89
- containers.uniq.each do |container|
90
- recursively_deploy_container(
91
- configuration,
92
- deployer,
93
- build_context_pool,
94
- container,
95
- containers,
96
- skip_build,
97
- skip_deploy,
98
- force_restart,
99
- skip_force_restart
100
- )
101
- end
102
-
103
- Thread
104
- .list
105
- .each { |t| t.join if t != Thread.current }
106
106
  end
107
107
 
108
- @global_logger.info("Deployment finished".green)
109
- @global_logger.info("Total time taken: #{time.round}s".green)
108
+ Thread
109
+ .list
110
+ .each { |t| t.join if t != Thread.current }
110
111
  ensure
111
112
  build_context_pool.close_sessions if build_context_pool
112
113
  deployer.close_sessions if deployer
@@ -127,23 +128,18 @@ class Indocker::ConfigurationDeployer
127
128
  end
128
129
  end
129
130
 
130
- def preload_containers(configuration)
131
- configuration.enabled_containers.each do |container_name|
132
- path = Indocker.container_files[container_name]
133
- require path
134
- end
135
- end
136
-
137
- def find_deploy_containers(configuration, deploy_containers, deploy_tags, skip_dependent, skip_containers, servers, skip_tags, auto_confirm, require_confirmation)
131
+ def find_containers_to_deploy(configuration, deployment_policy)
132
+ load_enabled_containers(configuration)
133
+
138
134
  containers = []
139
135
 
140
- deploy_tags.each do |tag|
136
+ deployment_policy.deploy_tags.each do |tag|
141
137
  containers += configuration.containers.select do |container|
142
138
  container.tags.include?(tag)
143
139
  end
144
140
  end
145
141
 
146
- skip_containers.each do |name|
142
+ deployment_policy.skip_containers.each do |name|
147
143
  container = configuration.containers.detect do |container|
148
144
  container.name == name
149
145
  end
@@ -160,7 +156,7 @@ class Indocker::ConfigurationDeployer
160
156
  end
161
157
  end
162
158
 
163
- deploy_containers.each do |name|
159
+ deployment_policy.deploy_containers.each do |name|
164
160
  container = configuration.containers.detect do |container|
165
161
  container.name == name
166
162
  end
@@ -174,17 +170,17 @@ class Indocker::ConfigurationDeployer
174
170
  end
175
171
  end
176
172
 
177
- if deploy_tags.empty? && deploy_containers.empty?
173
+ if deployment_policy.deploy_tags.empty? && deployment_policy.deploy_containers.empty?
178
174
  containers = configuration.containers.select do |container|
179
175
  configuration.enabled_containers.include?(container.name)
180
176
  end
181
177
  end
182
178
 
183
- if !skip_dependent
179
+ if !deployment_policy.skip_dependent
184
180
  containers = collect_dependent_containers(containers)
185
181
  end
186
182
 
187
- if !skip_dependent
183
+ if !deployment_policy.skip_dependent
188
184
  containers = collect_soft_dependent_containers(containers, configuration)
189
185
  end
190
186
 
@@ -197,13 +193,13 @@ class Indocker::ConfigurationDeployer
197
193
 
198
194
  containers = containers
199
195
  .select { |container| configuration.container_enabled?(container) }
200
- .select { |container| !skip_containers.include?(container.name) }
196
+ .select { |container| !deployment_policy.skip_containers.include?(container.name) }
201
197
  .select { |container|
202
- (skip_tags & container.tags).empty?
198
+ (deployment_policy.skip_tags & container.tags).empty?
203
199
  }
204
200
 
205
- if !servers.empty?
206
- containers = containers.select {|c| !(c.servers.map(&:name) & servers).empty? }
201
+ if !deployment_policy.servers.empty?
202
+ containers = containers.select {|c| !(c.servers.map(&:name) & deployment_policy.servers).empty? }
207
203
  end
208
204
 
209
205
  if containers.empty?
@@ -212,6 +208,7 @@ class Indocker::ConfigurationDeployer
212
208
  else
213
209
  @global_logger.info("Following containers will be deployed:")
214
210
 
211
+ servers = deployment_policy.servers
215
212
  if servers.empty?
216
213
  servers = containers.map(&:servers).flatten.uniq.map(&:name)
217
214
  end
@@ -229,7 +226,7 @@ class Indocker::ConfigurationDeployer
229
226
  end
230
227
  end
231
228
 
232
- if (require_confirmation || configuration.confirm_deployment) && !auto_confirm
229
+ if (deployment_policy.require_confirmation || configuration.confirm_deployment) && !deployment_policy.auto_confirm
233
230
  @global_logger.info("\n")
234
231
  @global_logger.info("Do you want to continue deployment? (y or n)")
235
232
  result = gets.chomp
@@ -240,7 +237,14 @@ class Indocker::ConfigurationDeployer
240
237
  end
241
238
  end
242
239
 
243
- containers
240
+ containers.uniq {|c| c.name}
241
+ end
242
+ end
243
+
244
+ def load_enabled_containers(configuration)
245
+ configuration.enabled_containers.each do |container_name|
246
+ path = Indocker.container_files[container_name]
247
+ require path
244
248
  end
245
249
  end
246
250
 
@@ -349,7 +353,6 @@ class Indocker::ConfigurationDeployer
349
353
  end
350
354
 
351
355
  def pull_repositories(clonner, servers, repositories)
352
- @logger.info("{timestamp}")
353
356
  @logger.info("Clonning/pulling repositories")
354
357
 
355
358
  remote_operations = []
@@ -402,7 +405,6 @@ class Indocker::ConfigurationDeployer
402
405
  end
403
406
 
404
407
  def sync_artifacts(clonner, artifact_servers)
405
- @logger.info("{timestamp}")
406
408
  @logger.info("Syncing git artifacts")
407
409
 
408
410
  remote_operations = []
@@ -454,8 +456,6 @@ class Indocker::ConfigurationDeployer
454
456
  redeploy_containers = configuration.containers.select {|c| c.redeploy_schedule}.uniq
455
457
  return if redeploy_containers.empty?
456
458
 
457
- @logger.info("{timestamp}")
458
-
459
459
  deploy_user = "#{server.user}@#{server.host}"
460
460
  crontab_filepath = Indocker.redeploy_crontab_path
461
461
 
@@ -480,8 +480,6 @@ class Indocker::ConfigurationDeployer
480
480
  end
481
481
 
482
482
  def sync_indocker(servers)
483
- @logger.info("{timestamp}")
484
-
485
483
  servers.map do |server|
486
484
  @progress.start_syncing_binaries(server)
487
485
 
@@ -512,8 +510,6 @@ class Indocker::ConfigurationDeployer
512
510
  end
513
511
 
514
512
  def sync_env_files(servers, env_files)
515
- @logger.info("{timestamp}")
516
-
517
513
  remote_operations = []
518
514
 
519
515
  servers.map do |server|
@@ -14,6 +14,10 @@ class Indocker::ContainerDeployer
14
14
  @deployed_servers = {}
15
15
  end
16
16
 
17
+ def create_sessions!
18
+ @server_pool.create_sessions!
19
+ end
20
+
17
21
  def deploy(container, force_restart, skip_force_restart, progress)
18
22
  return if @deployed_containers[container]
19
23
 
@@ -34,7 +38,6 @@ class Indocker::ContainerDeployer
34
38
 
35
39
  exec_proc.call do
36
40
  deploy_context = @server_pool.get(server)
37
- @logger.info("{timestamp}")
38
41
  @logger.info("Deploying container: #{container.name.to_s.green} to #{server.user}@#{server.host}")
39
42
 
40
43
  command_output = @logger.debug? ? "" : " > /dev/null"
@@ -9,15 +9,17 @@ class Indocker::DeployContext
9
9
  @configuration = configuration
10
10
  @server = server
11
11
  @restart_policy = Indocker::Containers::RestartPolicy.new(configuration, logger)
12
+ end
12
13
 
13
- if server
14
- @session = Indocker::SshSession.new(
15
- host: server.host,
16
- user: server.user,
17
- port: server.port,
18
- logger: @logger
19
- )
20
- end
14
+ def create_session!
15
+ return unless @server
16
+
17
+ @session = Indocker::SshSession.new(
18
+ host: @server.host,
19
+ user: @server.user,
20
+ port: @server.port,
21
+ logger: @logger
22
+ )
21
23
  end
22
24
 
23
25
  def exec!(command)
@@ -0,0 +1,22 @@
1
+ class Indocker::DeploymentPolicy
2
+ attr_reader :deploy_containers, :deploy_tags, :servers,
3
+ :skip_dependent, :skip_tags, :skip_containers, :skip_build, :skip_deploy,
4
+ :force_restart, :skip_force_restart, :auto_confirm, :require_confirmation
5
+
6
+ def initialize(deploy_containers:, deploy_tags:, servers:,
7
+ skip_dependent:, skip_tags:, skip_containers:, skip_build:, skip_deploy:,
8
+ force_restart:, skip_force_restart:, auto_confirm:, require_confirmation:)
9
+ @deploy_containers = deploy_containers
10
+ @deploy_tags = deploy_tags
11
+ @servers = servers
12
+ @skip_dependent = skip_dependent
13
+ @skip_tags = skip_tags
14
+ @skip_containers = skip_containers
15
+ @skip_build = skip_build
16
+ @skip_deploy = skip_deploy
17
+ @force_restart = force_restart
18
+ @skip_force_restart = skip_force_restart
19
+ @auto_confirm = auto_confirm
20
+ @require_confirmation = require_confirmation
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ class Indocker::LoggerFactory
2
+ class << self
3
+ def create(stdout, level = nil)
4
+ logger = Logger.new(stdout)
5
+
6
+ logger.level = level || Logger::INFO
7
+
8
+ logger.formatter = proc do |severity, datetime, progname, msg|
9
+ level = Logger::SEV_LABEL.index(severity)
10
+
11
+ severity = case level
12
+ when Logger::INFO
13
+ severity.green
14
+ when Logger::WARN
15
+ severity.purple
16
+ when Logger::DEBUG
17
+ severity.yellow
18
+ when Logger::ERROR
19
+ severity.red
20
+ when Logger::FATAL
21
+ severity.red
22
+ else
23
+ severity
24
+ end
25
+
26
+ severity = severity.downcase
27
+ if logger.debug?
28
+ "#{datetime.strftime("%Y/%m/%d %H:%M:%S")} #{severity}: #{msg}\n"
29
+ else
30
+ " #{severity}: #{msg}\n"
31
+ end
32
+ end
33
+
34
+ logger
35
+ end
36
+ end
37
+ end
@@ -12,12 +12,20 @@ class Indocker::ServerPool
12
12
  end
13
13
  end
14
14
 
15
+ def create_sessions!
16
+ @contexts.each(&:create_session!)
17
+ end
18
+
19
+ # NOTE: get is a bad name here, because we create a new connection.
20
+ # TODO: why we create a new connection here?
15
21
  def get(server)
16
- Indocker::DeployContext.new(
22
+ context = Indocker::DeployContext.new(
17
23
  logger: @logger,
18
24
  configuration: @configuration,
19
25
  server: server,
20
26
  )
27
+ context.create_session!
28
+ context
21
29
  end
22
30
 
23
31
  def each(&proc)
@@ -1,3 +1,3 @@
1
1
  module Indocker
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: indocker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  - Iskander Khaziev
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-07-23 00:00:00.000000000 Z
12
+ date: 2020-08-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
@@ -88,15 +88,21 @@ files:
88
88
  - example/indocker/bin/remote/compile
89
89
  - example/indocker/bin/remote/run
90
90
  - example/indocker/bin/utils/configurations.rb
91
+ - example/indocker/bounded_contexts/shared/container_failing_build/Dockerfile
92
+ - example/indocker/bounded_contexts/shared/container_failing_build/container.rb
93
+ - example/indocker/bounded_contexts/shared/container_failing_build/image.rb
91
94
  - example/indocker/bounded_contexts/shared/ruby/Dockerfile
92
95
  - example/indocker/bounded_contexts/shared/ruby/container.rb
93
96
  - example/indocker/bounded_contexts/shared/ruby/image.rb
94
97
  - example/indocker/configurations/dev.rb
98
+ - example/indocker/configurations/external.rb
95
99
  - example/indocker/infrastructure/build_servers.rb
96
100
  - example/indocker/infrastructure/networks.rb
97
101
  - example/indocker/infrastructure/registries.rb
98
102
  - example/indocker/infrastructure/servers.rb
99
103
  - example/indocker/setup.rb
104
+ - example/spec/indocker_spec.rb
105
+ - example/spec/spec_helper.rb
100
106
  - indocker.gemspec
101
107
  - lib/indocker.rb
102
108
  - lib/indocker/artifacts/git.rb
@@ -120,6 +126,7 @@ files:
120
126
  - lib/indocker/crontab_redeploy_rules_builder.rb
121
127
  - lib/indocker/deploy_context.rb
122
128
  - lib/indocker/deployment_checker.rb
129
+ - lib/indocker/deployment_policy.rb
123
130
  - lib/indocker/deployment_progress.rb
124
131
  - lib/indocker/docker.rb
125
132
  - lib/indocker/docker_run_args.rb
@@ -134,6 +141,7 @@ files:
134
141
  - lib/indocker/images/templates_compiler.rb
135
142
  - lib/indocker/images_compiler.rb
136
143
  - lib/indocker/indocker_helper.rb
144
+ - lib/indocker/logger_factory.rb
137
145
  - lib/indocker/network.rb
138
146
  - lib/indocker/network_helper.rb
139
147
  - lib/indocker/registries/abstract.rb
@@ -159,7 +167,7 @@ homepage: https://github.com/ArtStation/indocker
159
167
  licenses:
160
168
  - MIT
161
169
  metadata: {}
162
- post_install_message:
170
+ post_install_message:
163
171
  rdoc_options: []
164
172
  require_paths:
165
173
  - lib
@@ -174,8 +182,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
182
  - !ruby/object:Gem::Version
175
183
  version: '0'
176
184
  requirements: []
177
- rubygems_version: 3.0.3
178
- signing_key:
185
+ rubygems_version: 3.0.8
186
+ signing_key:
179
187
  specification_version: 4
180
188
  summary: Docker Containers Deployment
181
189
  test_files: []