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 +4 -4
- data/Gemfile +5 -0
- data/Gemfile.lock +8 -2
- data/README.md +13 -2
- data/example/indocker/bounded_contexts/shared/container_failing_build/Dockerfile +4 -0
- data/example/indocker/bounded_contexts/shared/container_failing_build/container.rb +5 -0
- data/example/indocker/bounded_contexts/shared/container_failing_build/image.rb +3 -0
- data/example/indocker/configurations/external.rb +12 -0
- data/example/indocker/infrastructure/build_servers.rb +11 -0
- data/example/indocker/infrastructure/servers.rb +11 -0
- data/example/indocker/setup.rb +1 -1
- data/example/spec/indocker_spec.rb +31 -0
- data/example/spec/spec_helper.rb +39 -0
- data/lib/indocker.rb +32 -56
- data/lib/indocker/build_context.rb +15 -13
- data/lib/indocker/build_context_pool.rb +7 -1
- data/lib/indocker/configuration_deployer.rb +93 -97
- data/lib/indocker/container_deployer.rb +4 -1
- data/lib/indocker/deploy_context.rb +10 -8
- data/lib/indocker/deployment_policy.rb +22 -0
- data/lib/indocker/logger_factory.rb +37 -0
- data/lib/indocker/server_pool.rb +9 -1
- data/lib/indocker/version.rb +1 -1
- metadata +14 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0356e417ece7294e5a5185f7cf17313d3b8f47c74895fdf0323989da110d5569
|
|
4
|
+
data.tar.gz: a2c04c1b66f98aa172b758be94e522901dffb2bef4d472602d70742fd93d80be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38376ede23d5ce780f0234ec01f473d673b4bdfe5a2ef4e893fcf867420ae8a11bbe57df6f010d1f87289f2c970328f8bc86f1b0cde929c73c1129b4bfb0d591
|
|
7
|
+
data.tar.gz: 93bb3bb739fbc427e8c688e7da395088d6e60fafa68c0741d91706bc2ac50bee9fae80b7ff240be16f4c4b5e7985b9f8fa4b56c9e1e74ccd6aa036f8d9bad021
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
indocker (0.1.
|
|
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
|
|
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
|
+
[](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
|
-
|
|
26
|
+
indocker/bin/deploy -C external -c ruby -d
|
|
16
27
|
```
|
|
17
28
|
|
|
18
29
|
## License
|
|
@@ -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
|
)
|
data/example/indocker/setup.rb
CHANGED
|
@@ -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
|
data/lib/indocker.rb
CHANGED
|
@@ -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:
|
|
330
|
-
|
|
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
|
-
|
|
396
|
-
|
|
403
|
+
logger_stdout = if @log_level == Logger::DEBUG
|
|
404
|
+
STDOUT
|
|
397
405
|
else
|
|
398
|
-
|
|
406
|
+
File.open(File::NULL, "w")
|
|
399
407
|
end
|
|
400
408
|
|
|
401
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
@
|
|
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
|
-
@
|
|
75
|
-
@
|
|
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 =
|
|
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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
37
|
+
run!(configuration: configuration, deployment_policy: deployment_policy)
|
|
38
|
+
end
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
@global_logger.info("Deployment finished".green)
|
|
41
|
+
@global_logger.info("Total time taken: #{time.round}s".green)
|
|
42
|
+
end
|
|
43
43
|
|
|
44
|
-
|
|
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
|
-
|
|
80
|
+
remote_operations = sync_indocker(servers)
|
|
81
|
+
wait_remote_operations(remote_operations)
|
|
47
82
|
|
|
48
|
-
|
|
49
|
-
|
|
83
|
+
remote_operations = sync_env_files(deploy_servers, configuration.env_files)
|
|
84
|
+
wait_remote_operations(remote_operations)
|
|
50
85
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.uniq { |s| s.host }
|
|
86
|
+
remote_operations = pull_repositories(clonner, build_servers, configuration.repositories)
|
|
87
|
+
wait_remote_operations(remote_operations)
|
|
54
88
|
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
92
|
+
update_crontab_redeploy_rules(configuration, build_servers.first)
|
|
61
93
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
skip_build
|
|
70
|
-
skip_deploy
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
|
131
|
-
configuration
|
|
132
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
data/lib/indocker/server_pool.rb
CHANGED
|
@@ -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)
|
data/lib/indocker/version.rb
CHANGED
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.
|
|
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
|
|
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.
|
|
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: []
|