indocker 0.1.8 → 0.1.9

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.
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: []