indocker 0.1.12 → 0.1.13
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/.ruby-version +1 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +8 -2
- data/example/indocker/bounded_contexts/shared/bad_container_build/container.rb +2 -1
- data/example/indocker/bounded_contexts/shared/bad_container_start/container.rb +2 -1
- data/example/indocker/bounded_contexts/shared/daemon_container/Dockerfile +4 -0
- data/example/indocker/bounded_contexts/shared/daemon_container/container.rb +6 -0
- data/example/indocker/bounded_contexts/shared/daemon_container/image.rb +3 -0
- data/example/indocker/bounded_contexts/shared/good_container/container.rb +2 -1
- data/example/indocker/bounded_contexts/shared/ruby/container.rb +2 -1
- data/example/indocker/configurations/external.rb +6 -1
- data/example/indocker/infrastructure/artifacts.rb +10 -0
- data/example/indocker/setup.rb +1 -0
- data/indocker.gemspec +1 -0
- data/lib/indocker.rb +24 -12
- data/lib/indocker/build_context.rb +6 -41
- data/lib/indocker/container_deployer.rb +12 -23
- data/lib/indocker/crontab_redeploy_rules_builder.rb +2 -1
- data/lib/indocker/deploy_context.rb +4 -32
- data/lib/indocker/docker_run_args.rb +2 -2
- data/lib/indocker/images/image_compiler.rb +0 -1
- data/lib/indocker/{configuration_deployer.rb → launchers/configuration_deployer.rb} +29 -30
- data/lib/indocker/{container_runner.rb → launchers/container_runner.rb} +2 -3
- data/lib/indocker/{images_compiler.rb → launchers/images_compiler.rb} +1 -2
- data/lib/indocker/{network.rb → networks/network.rb} +1 -1
- data/lib/indocker/{network_helper.rb → networks/network_helper.rb} +1 -1
- data/lib/indocker/server_pools/build_server_connection.rb +15 -0
- data/lib/indocker/server_pools/build_server_pool.rb +40 -0
- data/lib/indocker/server_pools/deploy_server_connection.rb +17 -0
- data/lib/indocker/server_pools/deploy_server_pool.rb +33 -0
- data/lib/indocker/server_pools/server_connection.rb +36 -0
- data/lib/indocker/version.rb +1 -1
- data/lib/indocker/{volume_helper.rb → volumes/volume_helper.rb} +1 -1
- metadata +32 -12
- data/example/spec/indocker_spec.rb +0 -39
- data/example/spec/spec_helper.rb +0 -39
- data/lib/indocker/build_context_pool.rb +0 -42
- data/lib/indocker/server_pool.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbe3ccb46e2212e0f4792ff6d528e3da20efbcf793c519b29dc76bd3cf1f2393
|
4
|
+
data.tar.gz: a7971075ca1ce8febaef30db0217c9d353536fc2f0f792def4fbf898ba68333c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7f1a7abced7f6fcf440218bd407714e4a8f53f897d752218493ee3162193a8cdf2eeadd5a204bc8c03b9c263617dd0d97b7f09ede7818bdb79638a61d7aabc8
|
7
|
+
data.tar.gz: e51552f9e3de3a1a27b028e74a4ea6d00efe04db6ca31e59a15cc323e49374f48968ea00b94f4147debff6696ac8a88ba317a59e85f4d8ce1d6ccd6ff2641839
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
indocker (0.1.
|
4
|
+
indocker (0.1.13)
|
5
5
|
net-ssh
|
6
6
|
|
7
7
|
GEM
|
@@ -9,6 +9,7 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
coderay (1.1.3)
|
11
11
|
diff-lcs (1.3)
|
12
|
+
docile (1.3.2)
|
12
13
|
method_source (1.0.0)
|
13
14
|
net-ssh (6.1.0)
|
14
15
|
pry (0.13.1)
|
@@ -28,6 +29,10 @@ GEM
|
|
28
29
|
diff-lcs (>= 1.2.0, < 2.0)
|
29
30
|
rspec-support (~> 3.9.0)
|
30
31
|
rspec-support (3.9.2)
|
32
|
+
simplecov (0.18.5)
|
33
|
+
docile (~> 1.1)
|
34
|
+
simplecov-html (~> 0.11)
|
35
|
+
simplecov-html (0.12.2)
|
31
36
|
|
32
37
|
PLATFORMS
|
33
38
|
ruby
|
@@ -37,7 +42,8 @@ DEPENDENCIES
|
|
37
42
|
indocker!
|
38
43
|
pry
|
39
44
|
rake (~> 12.3.3)
|
40
|
-
rspec
|
45
|
+
rspec (~> 3.0)
|
46
|
+
simplecov (~> 0.18.5)
|
41
47
|
|
42
48
|
BUNDLED WITH
|
43
49
|
1.17.3
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Indocker.add_artifact(
|
2
|
+
Indocker::Artifacts::Git.new(
|
3
|
+
name: :indocker_readme,
|
4
|
+
remote_name: 'origin',
|
5
|
+
remote_url: 'https://github.com/ArtStation/indocker.git',
|
6
|
+
branch: :master,
|
7
|
+
source_path: './README.md',
|
8
|
+
target_path: File.join(Indocker.deploy_dir, 'README.md'),
|
9
|
+
)
|
10
|
+
)
|
data/example/indocker/setup.rb
CHANGED
@@ -18,6 +18,7 @@ require_relative 'infrastructure/registries'
|
|
18
18
|
require_relative 'infrastructure/servers'
|
19
19
|
require_relative 'infrastructure/build_servers'
|
20
20
|
require_relative 'infrastructure/networks'
|
21
|
+
require_relative 'infrastructure/artifacts'
|
21
22
|
|
22
23
|
Indocker.set_bounded_contexts_dir(File.join(__dir__, 'bounded_contexts'))
|
23
24
|
|
data/indocker.gemspec
CHANGED
data/lib/indocker.rb
CHANGED
@@ -50,6 +50,7 @@ module Indocker
|
|
50
50
|
autoload :Local, 'volumes/local'
|
51
51
|
autoload :External, 'volumes/external'
|
52
52
|
autoload :Repository, 'volumes/repository'
|
53
|
+
autoload :VolumeHelper, 'volumes/volume_helper'
|
53
54
|
end
|
54
55
|
|
55
56
|
module EnvFiles
|
@@ -61,30 +62,41 @@ module Indocker
|
|
61
62
|
autoload :Git, 'artifacts/git'
|
62
63
|
end
|
63
64
|
|
65
|
+
module Networks
|
66
|
+
autoload :Network, 'networks/network'
|
67
|
+
autoload :NetworkHelper, 'networks/network_helper'
|
68
|
+
end
|
69
|
+
|
70
|
+
module Launchers
|
71
|
+
autoload :ConfigurationDeployer, 'launchers/configuration_deployer'
|
72
|
+
autoload :ImagesCompiler, 'launchers/images_compiler'
|
73
|
+
autoload :ContainerRunner, 'launchers/container_runner'
|
74
|
+
end
|
75
|
+
|
76
|
+
module ServerPools
|
77
|
+
autoload :ServerConnection, 'server_pools/server_connection'
|
78
|
+
autoload :DeployServerPool, 'server_pools/deploy_server_pool'
|
79
|
+
autoload :DeployServerConnection, 'server_pools/deploy_server_connection'
|
80
|
+
autoload :BuildServerPool, 'server_pools/build_server_pool'
|
81
|
+
autoload :BuildServerConnection, 'server_pools/build_server_connection'
|
82
|
+
end
|
83
|
+
|
64
84
|
autoload :HashMerger, 'hash_merger'
|
65
85
|
autoload :BuildServer, 'build_server'
|
66
86
|
autoload :Server, 'server'
|
67
|
-
autoload :ConfigurationDeployer, 'configuration_deployer'
|
68
87
|
autoload :SshSession, 'ssh_session'
|
69
|
-
autoload :BuildContextPool, 'build_context_pool'
|
70
88
|
autoload :BuildContext, 'build_context'
|
71
89
|
autoload :BuildContextHelper, 'build_context_helper'
|
72
90
|
autoload :Shell, 'shell'
|
73
91
|
autoload :Docker, 'docker'
|
74
92
|
autoload :ContextArgs, 'context_args'
|
75
|
-
autoload :Network, 'network'
|
76
93
|
autoload :ContainerDeployer, 'container_deployer'
|
77
|
-
autoload :ServerPool, 'server_pool'
|
78
94
|
autoload :DeployContext, 'deploy_context'
|
79
95
|
autoload :ContainerHelper, 'container_helper'
|
80
96
|
autoload :DockerRunArgs, 'docker_run_args'
|
81
|
-
autoload :VolumeHelper, 'volume_helper'
|
82
|
-
autoload :NetworkHelper, 'network_helper'
|
83
97
|
autoload :Rsync, 'rsync'
|
84
98
|
autoload :EnvFileHelper, 'env_file_helper'
|
85
99
|
autoload :IndockerHelper, 'indocker_helper'
|
86
|
-
autoload :ImagesCompiler, 'images_compiler'
|
87
|
-
autoload :ContainerRunner, 'container_runner'
|
88
100
|
autoload :SshResultLogger, 'ssh_result_logger'
|
89
101
|
autoload :DeploymentProgress, 'deployment_progress'
|
90
102
|
autoload :DeploymentChecker, 'deployment_checker'
|
@@ -172,7 +184,7 @@ module Indocker
|
|
172
184
|
raise ArgumentError.new("network :#{name} was already defined")
|
173
185
|
end
|
174
186
|
|
175
|
-
networks.push(Indocker::Network.new(name))
|
187
|
+
networks.push(Indocker::Networks::Network.new(name))
|
176
188
|
end
|
177
189
|
|
178
190
|
def container_files
|
@@ -340,7 +352,7 @@ module Indocker
|
|
340
352
|
require_confirmation: require_confirmation,
|
341
353
|
)
|
342
354
|
|
343
|
-
Indocker::ConfigurationDeployer
|
355
|
+
Indocker::Launchers::ConfigurationDeployer
|
344
356
|
.new(logger: Indocker.logger, global_logger: Indocker.global_logger)
|
345
357
|
.run(
|
346
358
|
configuration: configuration,
|
@@ -369,7 +381,7 @@ module Indocker
|
|
369
381
|
end
|
370
382
|
|
371
383
|
def compile(images:, skip_dependent:)
|
372
|
-
Indocker::ImagesCompiler
|
384
|
+
Indocker::Launchers::ImagesCompiler
|
373
385
|
.new(Indocker.logger)
|
374
386
|
.compile(
|
375
387
|
configuration: configuration,
|
@@ -379,7 +391,7 @@ module Indocker
|
|
379
391
|
end
|
380
392
|
|
381
393
|
def run(container_name, force_restart)
|
382
|
-
Indocker::ContainerRunner
|
394
|
+
Indocker::Launchers::ContainerRunner
|
383
395
|
.new(Indocker.logger)
|
384
396
|
.run(
|
385
397
|
configuration: configuration,
|
@@ -1,55 +1,18 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
3
|
class Indocker::BuildContext
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :configuration, :logger, :global_logger, :helper
|
5
5
|
|
6
|
-
def initialize(configuration:,
|
6
|
+
def initialize(configuration:, logger:, global_logger:)
|
7
7
|
@configuration = configuration
|
8
8
|
@logger = logger
|
9
9
|
@helper = Indocker::BuildContextHelper.new(@configuration, @build_server)
|
10
|
-
@server = build_server
|
11
10
|
@global_logger = global_logger
|
12
|
-
@compiled_images = Hash.new(false)
|
13
|
-
end
|
14
|
-
|
15
|
-
def create_session!
|
16
|
-
return unless @server
|
17
|
-
|
18
|
-
@session = Indocker::SshSession.new(
|
19
|
-
host: @server.host,
|
20
|
-
user: @server.user,
|
21
|
-
port: @server.port,
|
22
|
-
logger: @logger
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
|
-
def exec!(command)
|
27
|
-
@session.exec!(command)
|
28
|
-
end
|
29
|
-
|
30
|
-
def close_session
|
31
|
-
@session.close if @session
|
32
|
-
end
|
33
|
-
|
34
|
-
def image_compiled?(image)
|
35
|
-
@compiled_images[image]
|
36
|
-
end
|
37
|
-
|
38
|
-
def set_busy(flag)
|
39
|
-
@busy = !!flag
|
40
|
-
end
|
41
|
-
|
42
|
-
def busy?
|
43
|
-
!!@busy
|
44
|
-
end
|
45
|
-
|
46
|
-
def set_compiled(image)
|
47
|
-
@compiled_images[image] = true
|
48
11
|
end
|
49
12
|
|
50
13
|
def build_image(image, build_dir, args: [])
|
51
14
|
image_name = image.image_name
|
52
|
-
registry
|
15
|
+
registry = image.registry
|
53
16
|
tag = image.tag
|
54
17
|
|
55
18
|
FileUtils.cd(build_dir) do
|
@@ -79,7 +42,9 @@ class Indocker::BuildContext
|
|
79
42
|
end
|
80
43
|
|
81
44
|
Indocker::Docker.tag(image.local_registry_url, image.registry_url)
|
82
|
-
|
45
|
+
if image.registry_url != image.local_registry_url
|
46
|
+
Indocker::Docker.tag(image.local_registry_url, image.local_registry_url)
|
47
|
+
end
|
83
48
|
|
84
49
|
if !image.registry.is_local?
|
85
50
|
Indocker::Docker.push(image.registry_url)
|
@@ -5,7 +5,7 @@ class Indocker::ContainerDeployer
|
|
5
5
|
@configuration = configuration
|
6
6
|
@logger = logger
|
7
7
|
|
8
|
-
@server_pool = Indocker::
|
8
|
+
@server_pool = Indocker::ServerPools::DeployServerPool.new(
|
9
9
|
configuration: @configuration,
|
10
10
|
logger: logger
|
11
11
|
)
|
@@ -14,10 +14,6 @@ class Indocker::ContainerDeployer
|
|
14
14
|
@deployed_servers = {}
|
15
15
|
end
|
16
16
|
|
17
|
-
def create_sessions!
|
18
|
-
@server_pool.create_sessions!
|
19
|
-
end
|
20
|
-
|
21
17
|
def deploy(container, force_restart, skip_force_restart, progress)
|
22
18
|
return if @deployed_containers[container]
|
23
19
|
|
@@ -37,30 +33,23 @@ class Indocker::ContainerDeployer
|
|
37
33
|
end
|
38
34
|
|
39
35
|
exec_proc.call do
|
40
|
-
|
36
|
+
deploy_server = @server_pool.create_connection!(server)
|
41
37
|
@logger.info("Deploying container: #{container.name.to_s.green} to #{server.user}@#{server.host}")
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
result = deploy_context
|
51
|
-
.session
|
52
|
-
.exec!(
|
53
|
-
"cd #{Indocker::IndockerHelper.indocker_dir} && ./bin/remote/run -C #{Indocker.configuration_name} -c #{container.name} #{debug_options} #{command_output} #{force_restart_options}"
|
39
|
+
result = deploy_server
|
40
|
+
.run_container_remotely(
|
41
|
+
configuration_name: Indocker.configuration_name,
|
42
|
+
container_name: container.name,
|
43
|
+
force_restart: force_restart && !skip_force_restart.include?(container.name)
|
54
44
|
)
|
55
45
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
exit 1 if result.exit_code != 0
|
46
|
+
if result.exit_code != 0
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
61
50
|
@logger.info("Container deployment to #{server.user}@#{server.host} finished: #{container.name.to_s.green}")
|
62
51
|
|
63
|
-
|
52
|
+
deploy_server.close_session
|
64
53
|
progress.finish_deploying_container(container, server)
|
65
54
|
end
|
66
55
|
end
|
@@ -8,7 +8,7 @@ PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sb
|
|
8
8
|
CRONTAB
|
9
9
|
|
10
10
|
LOG_FILE = "/var/log/indocker-redeploy-%{env}.log"
|
11
|
-
COMMAND = "export TERM=xterm
|
11
|
+
COMMAND = "export TERM=xterm;%{deploy_dir}/indocker/bin/deploy -C %{env} -f -B -y -c %{container_name}"
|
12
12
|
REDEPLOY_RULE = %Q{%{schedule} echo `date` "- %{command}..." >> %{log_file}; %{command} 1>/dev/null 2>>%{log_file}; echo `date` "- done, exitcode = $?" >> %{log_file}}
|
13
13
|
|
14
14
|
def initialize(configuration:, logger:)
|
@@ -41,6 +41,7 @@ PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sb
|
|
41
41
|
COMMAND % {
|
42
42
|
env: env,
|
43
43
|
container_name: container.name,
|
44
|
+
deploy_dir: Indocker.deploy_dir
|
44
45
|
}
|
45
46
|
end
|
46
47
|
|
@@ -2,42 +2,14 @@ require 'digest'
|
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
4
|
class Indocker::DeployContext
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :configuration, :logger
|
6
6
|
|
7
|
-
def initialize(logger:, configuration
|
7
|
+
def initialize(logger:, configuration:)
|
8
8
|
@logger = logger
|
9
9
|
@configuration = configuration
|
10
|
-
@server = server
|
11
10
|
@restart_policy = Indocker::Containers::RestartPolicy.new(configuration, logger)
|
12
11
|
end
|
13
12
|
|
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
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
def exec!(command)
|
26
|
-
@session.exec!(command)
|
27
|
-
end
|
28
|
-
|
29
|
-
def close_session
|
30
|
-
@session.close if @session
|
31
|
-
end
|
32
|
-
|
33
|
-
def set_busy(flag)
|
34
|
-
@busy = !!flag
|
35
|
-
end
|
36
|
-
|
37
|
-
def busy?
|
38
|
-
!!@busy
|
39
|
-
end
|
40
|
-
|
41
13
|
def deploy(container, force_restart)
|
42
14
|
@logger.info("Deploying container: #{container.name.to_s.green}")
|
43
15
|
@logger.debug("Deploy dir: #{Indocker.deploy_dir}")
|
@@ -46,14 +18,14 @@ class Indocker::DeployContext
|
|
46
18
|
|
47
19
|
container.networks.each do |network|
|
48
20
|
Indocker::Docker.create_network(
|
49
|
-
Indocker::NetworkHelper.name(@configuration.name, network)
|
21
|
+
Indocker::Networks::NetworkHelper.name(@configuration.name, network)
|
50
22
|
)
|
51
23
|
end
|
52
24
|
|
53
25
|
container.volumes.each do |volume|
|
54
26
|
if volume.is_a?(Indocker::Volumes::External)
|
55
27
|
Indocker::Docker.create_volume(
|
56
|
-
Indocker::VolumeHelper.name(@configuration.name, volume)
|
28
|
+
Indocker::Volumes::VolumeHelper.name(@configuration.name, volume)
|
57
29
|
)
|
58
30
|
end
|
59
31
|
end
|
@@ -159,7 +159,7 @@ class Indocker::DockerRunArgs
|
|
159
159
|
if volume.is_a?(Indocker::Volumes::Local)
|
160
160
|
args.push("-v #{volume.local_path}:#{volume.path}")
|
161
161
|
elsif volume.is_a?(Indocker::Volumes::External)
|
162
|
-
name = Indocker::VolumeHelper.name(configuration.name, volume)
|
162
|
+
name = Indocker::Volumes::VolumeHelper.name(configuration.name, volume)
|
163
163
|
args.push("-v #{name}:#{volume.path}")
|
164
164
|
elsif volume.is_a?(Indocker::Volumes::Repository)
|
165
165
|
repository = configuration.repositories.fetch(volume.repository_name) do
|
@@ -173,7 +173,7 @@ class Indocker::DockerRunArgs
|
|
173
173
|
end
|
174
174
|
|
175
175
|
container.networks.each do |network|
|
176
|
-
name = Indocker::NetworkHelper.name(configuration.name, network)
|
176
|
+
name = Indocker::Networks::NetworkHelper.name(configuration.name, network)
|
177
177
|
args.push("--network #{name}")
|
178
178
|
end
|
179
179
|
|
@@ -2,7 +2,7 @@ require 'timeout'
|
|
2
2
|
require 'benchmark'
|
3
3
|
require 'tempfile'
|
4
4
|
|
5
|
-
class Indocker::ConfigurationDeployer
|
5
|
+
class Indocker::Launchers::ConfigurationDeployer
|
6
6
|
REMOTE_OPERATION_TIMEOUT = 60
|
7
7
|
|
8
8
|
def initialize(logger:, global_logger:)
|
@@ -14,13 +14,11 @@ class Indocker::ConfigurationDeployer
|
|
14
14
|
@progress = Indocker::DeploymentProgress.new(
|
15
15
|
Indocker.logger.level == Logger::DEBUG ? nil : Logger.new(STDOUT)
|
16
16
|
)
|
17
|
+
@compiled_images = Hash.new(false)
|
17
18
|
end
|
18
19
|
|
19
20
|
# Launch deployment & measure the benchmark
|
20
21
|
def run(configuration:, deployment_policy:)
|
21
|
-
build_context_pool = nil
|
22
|
-
deployer = nil
|
23
|
-
|
24
22
|
time = Benchmark.realtime do
|
25
23
|
if deployment_policy.force_restart
|
26
24
|
@logger.warn("WARNING. All containers will be forced to restart.")
|
@@ -46,12 +44,11 @@ class Indocker::ConfigurationDeployer
|
|
46
44
|
containers = find_containers_to_deploy(configuration, deployment_policy)
|
47
45
|
|
48
46
|
clonner = Indocker::Repositories::Clonner.new(configuration, @logger)
|
49
|
-
|
47
|
+
build_server_pool = Indocker::ServerPools::BuildServerPool.new(configuration: configuration, logger: @logger)
|
50
48
|
deployer = Indocker::ContainerDeployer.new(configuration: configuration, logger: @logger)
|
51
49
|
|
52
50
|
@global_logger.info("Establishing ssh sessions to all servers...")
|
53
|
-
|
54
|
-
deployer.create_sessions!
|
51
|
+
build_server_pool.create_sessions!
|
55
52
|
|
56
53
|
build_servers = configuration
|
57
54
|
.build_servers
|
@@ -95,7 +92,7 @@ class Indocker::ConfigurationDeployer
|
|
95
92
|
recursively_deploy_container(
|
96
93
|
configuration,
|
97
94
|
deployer,
|
98
|
-
|
95
|
+
build_server_pool,
|
99
96
|
container,
|
100
97
|
containers,
|
101
98
|
deployment_policy.skip_build,
|
@@ -109,7 +106,7 @@ class Indocker::ConfigurationDeployer
|
|
109
106
|
.list
|
110
107
|
.each { |t| t.join if t != Thread.current }
|
111
108
|
ensure
|
112
|
-
|
109
|
+
build_server_pool.close_sessions if build_server_pool
|
113
110
|
deployer.close_sessions if deployer
|
114
111
|
end
|
115
112
|
|
@@ -272,12 +269,12 @@ class Indocker::ConfigurationDeployer
|
|
272
269
|
result.uniq
|
273
270
|
end
|
274
271
|
|
275
|
-
def compile_image(configuration, image,
|
276
|
-
return if
|
272
|
+
def compile_image(configuration, image, build_server)
|
273
|
+
return if @compiled_images[image]
|
277
274
|
|
278
275
|
image.dependent_images.each do |dependent_image|
|
279
|
-
next if
|
280
|
-
compile_image(configuration, dependent_image,
|
276
|
+
next if @compiled_images[image]
|
277
|
+
compile_image(configuration, dependent_image, build_server)
|
281
278
|
end
|
282
279
|
|
283
280
|
compiler = Indocker::Images::ImageCompiler.new
|
@@ -287,32 +284,30 @@ class Indocker::ConfigurationDeployer
|
|
287
284
|
result = nil
|
288
285
|
|
289
286
|
time = Benchmark.realtime do
|
290
|
-
result =
|
291
|
-
.
|
292
|
-
|
293
|
-
|
287
|
+
result = build_server
|
288
|
+
.compile_image_remotely(
|
289
|
+
configuration_name: Indocker.configuration_name,
|
290
|
+
image_name: image.name
|
294
291
|
)
|
295
292
|
end
|
296
293
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
exit 1 if result.exit_code != 0
|
294
|
+
if result.exit_code != 0
|
295
|
+
exit 1
|
296
|
+
end
|
302
297
|
|
303
298
|
@logger.info("Image compilation completed #{image.name.to_s.green}. Time taken: #{time}")
|
304
299
|
|
305
|
-
|
300
|
+
@compiled_images[image] = true
|
306
301
|
end
|
307
302
|
|
308
|
-
def recursively_deploy_container(configuration, deployer,
|
303
|
+
def recursively_deploy_container(configuration, deployer, build_server_pool, container,
|
309
304
|
containers, skip_build, skip_deploy, force_restart, skip_force_restart)
|
310
305
|
|
311
306
|
container.dependent_containers.each do |container|
|
312
307
|
recursively_deploy_container(
|
313
308
|
configuration,
|
314
309
|
deployer,
|
315
|
-
|
310
|
+
build_server_pool,
|
316
311
|
container,
|
317
312
|
containers,
|
318
313
|
skip_build,
|
@@ -327,20 +322,24 @@ class Indocker::ConfigurationDeployer
|
|
327
322
|
@progress.start_building_container(container)
|
328
323
|
|
329
324
|
if !skip_build
|
330
|
-
|
325
|
+
build_server = build_server_pool.get
|
331
326
|
|
332
|
-
|
333
|
-
compile_image(configuration, container.image,
|
334
|
-
|
327
|
+
build_server.set_busy(true)
|
328
|
+
compile_image(configuration, container.image, build_server)
|
329
|
+
build_server.set_busy(false)
|
335
330
|
end
|
336
331
|
|
337
332
|
@progress.finish_building_container(container)
|
338
333
|
|
339
334
|
if !skip_deploy
|
340
|
-
deployer
|
335
|
+
deploy_container(deployer, container, force_restart, skip_force_restart)
|
341
336
|
end
|
342
337
|
end
|
343
338
|
|
339
|
+
def deploy_container(deployer, container, force_restart, skip_force_restart)
|
340
|
+
deployer.deploy(container, force_restart, skip_force_restart, @progress)
|
341
|
+
end
|
342
|
+
|
344
343
|
class RemoteOperation
|
345
344
|
attr_reader :thread, :server, :operation, :message
|
346
345
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Indocker::ContainerRunner
|
1
|
+
class Indocker::Launchers::ContainerRunner
|
2
2
|
def initialize(logger)
|
3
3
|
@logger = logger
|
4
4
|
end
|
@@ -13,8 +13,7 @@ class Indocker::ContainerRunner
|
|
13
13
|
|
14
14
|
deploy_context = Indocker::DeployContext.new(
|
15
15
|
logger: @logger,
|
16
|
-
configuration: configuration
|
17
|
-
server: nil
|
16
|
+
configuration: configuration
|
18
17
|
)
|
19
18
|
|
20
19
|
container = configuration.containers.detect { |c| c.name == container_name }
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Indocker::ImagesCompiler
|
1
|
+
class Indocker::Launchers::ImagesCompiler
|
2
2
|
def initialize(logger)
|
3
3
|
@logger = logger
|
4
4
|
end
|
@@ -8,7 +8,6 @@ class Indocker::ImagesCompiler
|
|
8
8
|
|
9
9
|
build_context = Indocker::BuildContext.new(
|
10
10
|
configuration: configuration,
|
11
|
-
build_server: nil,
|
12
11
|
logger: @logger,
|
13
12
|
global_logger: Indocker.global_logger
|
14
13
|
)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class Indocker::ServerPools::BuildServerConnection < Indocker::ServerPools::ServerConnection
|
4
|
+
def compile_image_remotely(configuration_name:, image_name:)
|
5
|
+
result = exec!(
|
6
|
+
"cd #{Indocker::IndockerHelper.indocker_dir} && ./bin/remote/compile -C #{configuration_name} -i #{image_name} -s #{@logger.debug? ? '-d' : ''}"
|
7
|
+
)
|
8
|
+
|
9
|
+
Indocker::SshResultLogger
|
10
|
+
.new(@logger)
|
11
|
+
.log(result, "#{image_name.to_s.green} image compilation failed")
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Indocker::ServerPools::BuildServerPool
|
2
|
+
def initialize(configuration:, logger:)
|
3
|
+
@logger = logger
|
4
|
+
@configuration = configuration
|
5
|
+
|
6
|
+
@connections = configuration.build_servers.map do |build_server|
|
7
|
+
Indocker::ServerPools::BuildServerConnection.new(
|
8
|
+
logger: @logger,
|
9
|
+
configuration: configuration,
|
10
|
+
server: build_server,
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_sessions!
|
16
|
+
@connections.each(&:create_session!)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get
|
20
|
+
context = nil
|
21
|
+
|
22
|
+
loop do
|
23
|
+
context = @connections.detect {|c| !c.busy?}
|
24
|
+
sleep(0.1)
|
25
|
+
break if context
|
26
|
+
end
|
27
|
+
|
28
|
+
context
|
29
|
+
end
|
30
|
+
|
31
|
+
def each(&proc)
|
32
|
+
@connections.each(&proc)
|
33
|
+
end
|
34
|
+
|
35
|
+
def close_sessions
|
36
|
+
@connections.each(&:close_session)
|
37
|
+
rescue => e
|
38
|
+
@logger.error("error during session close: #{e.inspect}")
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Indocker::ServerPools::DeployServerConnection < Indocker::ServerPools::ServerConnection
|
2
|
+
def run_container_remotely(configuration_name:, container_name:, force_restart:)
|
3
|
+
command_output = @logger.debug? ? "" : " > /dev/null"
|
4
|
+
debug_options = @logger.debug? ? "-d" : ""
|
5
|
+
force_restart_options = force_restart ? "-f" : ""
|
6
|
+
|
7
|
+
result = exec!(
|
8
|
+
"cd #{Indocker::IndockerHelper.indocker_dir} && ./bin/remote/run -C #{configuration_name} -c #{container_name} #{debug_options} #{command_output} #{force_restart_options}"
|
9
|
+
)
|
10
|
+
|
11
|
+
Indocker::SshResultLogger
|
12
|
+
.new(@logger)
|
13
|
+
.log(result, "#{container_name.to_s.green} deployment for server #{server.name} failed")
|
14
|
+
|
15
|
+
result
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Indocker::ServerPools::DeployServerPool
|
2
|
+
def initialize(configuration:, logger:)
|
3
|
+
@logger = logger
|
4
|
+
@configuration = configuration
|
5
|
+
@connections = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_connection!(server)
|
9
|
+
connection = @connections.detect do |connection|
|
10
|
+
connection.server.host == server.host &&
|
11
|
+
connection.server.port == server.port &&
|
12
|
+
connection.server.user == server.user
|
13
|
+
end
|
14
|
+
if connection.nil?
|
15
|
+
connection = Indocker::ServerPools::DeployServerConnection.new(
|
16
|
+
logger: @logger,
|
17
|
+
configuration: @configuration,
|
18
|
+
server: server,
|
19
|
+
)
|
20
|
+
connection.create_session!
|
21
|
+
@connections.push(connection)
|
22
|
+
end
|
23
|
+
connection
|
24
|
+
end
|
25
|
+
|
26
|
+
def each(&proc)
|
27
|
+
@connections.each(&proc)
|
28
|
+
end
|
29
|
+
|
30
|
+
def close_sessions
|
31
|
+
@connections.each(&:close_session)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Indocker::ServerPools::ServerConnection
|
2
|
+
attr_reader :server, :session
|
3
|
+
|
4
|
+
def initialize(logger:, configuration:, server:)
|
5
|
+
@logger = logger
|
6
|
+
@configuration = configuration
|
7
|
+
@server = server
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_session!
|
11
|
+
return unless @server
|
12
|
+
|
13
|
+
@session = Indocker::SshSession.new(
|
14
|
+
host: @server.host,
|
15
|
+
user: @server.user,
|
16
|
+
port: @server.port,
|
17
|
+
logger: @logger
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def exec!(command)
|
22
|
+
@session.exec!(command)
|
23
|
+
end
|
24
|
+
|
25
|
+
def close_session
|
26
|
+
@session.close if @session
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_busy(flag)
|
30
|
+
@busy = !!flag
|
31
|
+
end
|
32
|
+
|
33
|
+
def busy?
|
34
|
+
!!@busy
|
35
|
+
end
|
36
|
+
end
|
data/lib/indocker/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ruslan Gatiyatov
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-08-
|
12
|
+
date: 2020-08-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-ssh
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: simplecov
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.18.5
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.18.5
|
70
84
|
description: Docker Containers Deployment
|
71
85
|
email:
|
72
86
|
- gvalmon@gmail.com
|
@@ -76,6 +90,7 @@ extra_rdoc_files: []
|
|
76
90
|
files:
|
77
91
|
- ".gitignore"
|
78
92
|
- ".rspec"
|
93
|
+
- ".ruby-version"
|
79
94
|
- ".travis.yml"
|
80
95
|
- Gemfile
|
81
96
|
- Gemfile.lock
|
@@ -95,6 +110,9 @@ files:
|
|
95
110
|
- example/indocker/bounded_contexts/shared/bad_container_start/build_context/bin/run
|
96
111
|
- example/indocker/bounded_contexts/shared/bad_container_start/container.rb
|
97
112
|
- example/indocker/bounded_contexts/shared/bad_container_start/image.rb
|
113
|
+
- example/indocker/bounded_contexts/shared/daemon_container/Dockerfile
|
114
|
+
- example/indocker/bounded_contexts/shared/daemon_container/container.rb
|
115
|
+
- example/indocker/bounded_contexts/shared/daemon_container/image.rb
|
98
116
|
- example/indocker/bounded_contexts/shared/good_container/Dockerfile
|
99
117
|
- example/indocker/bounded_contexts/shared/good_container/container.rb
|
100
118
|
- example/indocker/bounded_contexts/shared/good_container/image.rb
|
@@ -103,29 +121,25 @@ files:
|
|
103
121
|
- example/indocker/bounded_contexts/shared/ruby/image.rb
|
104
122
|
- example/indocker/configurations/dev.rb
|
105
123
|
- example/indocker/configurations/external.rb
|
124
|
+
- example/indocker/infrastructure/artifacts.rb
|
106
125
|
- example/indocker/infrastructure/build_servers.rb
|
107
126
|
- example/indocker/infrastructure/networks.rb
|
108
127
|
- example/indocker/infrastructure/registries.rb
|
109
128
|
- example/indocker/infrastructure/servers.rb
|
110
129
|
- example/indocker/setup.rb
|
111
|
-
- example/spec/indocker_spec.rb
|
112
|
-
- example/spec/spec_helper.rb
|
113
130
|
- indocker.gemspec
|
114
131
|
- lib/indocker.rb
|
115
132
|
- lib/indocker/artifacts/git.rb
|
116
133
|
- lib/indocker/build_context.rb
|
117
134
|
- lib/indocker/build_context_helper.rb
|
118
|
-
- lib/indocker/build_context_pool.rb
|
119
135
|
- lib/indocker/build_server.rb
|
120
136
|
- lib/indocker/colored_string.rb
|
121
137
|
- lib/indocker/concerns/inspectable.rb
|
122
|
-
- lib/indocker/configuration_deployer.rb
|
123
138
|
- lib/indocker/configurations/configuration.rb
|
124
139
|
- lib/indocker/configurations/configuration_builder.rb
|
125
140
|
- lib/indocker/configurations/formatters/stdout.rb
|
126
141
|
- lib/indocker/container_deployer.rb
|
127
142
|
- lib/indocker/container_helper.rb
|
128
|
-
- lib/indocker/container_runner.rb
|
129
143
|
- lib/indocker/containers/container.rb
|
130
144
|
- lib/indocker/containers/container_builder.rb
|
131
145
|
- lib/indocker/containers/restart_policy.rb
|
@@ -146,11 +160,13 @@ files:
|
|
146
160
|
- lib/indocker/images/image_compiler.rb
|
147
161
|
- lib/indocker/images/template_compiler.rb
|
148
162
|
- lib/indocker/images/templates_compiler.rb
|
149
|
-
- lib/indocker/images_compiler.rb
|
150
163
|
- lib/indocker/indocker_helper.rb
|
164
|
+
- lib/indocker/launchers/configuration_deployer.rb
|
165
|
+
- lib/indocker/launchers/container_runner.rb
|
166
|
+
- lib/indocker/launchers/images_compiler.rb
|
151
167
|
- lib/indocker/logger_factory.rb
|
152
|
-
- lib/indocker/network.rb
|
153
|
-
- lib/indocker/network_helper.rb
|
168
|
+
- lib/indocker/networks/network.rb
|
169
|
+
- lib/indocker/networks/network_helper.rb
|
154
170
|
- lib/indocker/registries/abstract.rb
|
155
171
|
- lib/indocker/registries/local.rb
|
156
172
|
- lib/indocker/registries/remote.rb
|
@@ -161,15 +177,19 @@ files:
|
|
161
177
|
- lib/indocker/repositories/no_sync.rb
|
162
178
|
- lib/indocker/rsync.rb
|
163
179
|
- lib/indocker/server.rb
|
164
|
-
- lib/indocker/
|
180
|
+
- lib/indocker/server_pools/build_server_connection.rb
|
181
|
+
- lib/indocker/server_pools/build_server_pool.rb
|
182
|
+
- lib/indocker/server_pools/deploy_server_connection.rb
|
183
|
+
- lib/indocker/server_pools/deploy_server_pool.rb
|
184
|
+
- lib/indocker/server_pools/server_connection.rb
|
165
185
|
- lib/indocker/shell.rb
|
166
186
|
- lib/indocker/ssh_result_logger.rb
|
167
187
|
- lib/indocker/ssh_session.rb
|
168
188
|
- lib/indocker/version.rb
|
169
|
-
- lib/indocker/volume_helper.rb
|
170
189
|
- lib/indocker/volumes/external.rb
|
171
190
|
- lib/indocker/volumes/local.rb
|
172
191
|
- lib/indocker/volumes/repository.rb
|
192
|
+
- lib/indocker/volumes/volume_helper.rb
|
173
193
|
homepage: https://github.com/ArtStation/indocker
|
174
194
|
licenses:
|
175
195
|
- MIT
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Indocker do
|
4
|
-
it "has a version number" do
|
5
|
-
expect(Indocker::VERSION).not_to be nil
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "successful deployment" do
|
9
|
-
it "doesn't raise any error" do
|
10
|
-
expect{
|
11
|
-
launch_deployment(containers: [:good_container])
|
12
|
-
}.to_not raise_error
|
13
|
-
end
|
14
|
-
|
15
|
-
it "shows a message about successful deploy" do
|
16
|
-
allow(Indocker.global_logger).to receive(:info).at_least(:once)
|
17
|
-
|
18
|
-
launch_deployment(containers: [:good_container])
|
19
|
-
|
20
|
-
expect(Indocker.global_logger).to have_received(:info).at_least(:once).with(/Deployment finished/)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "failed build" do
|
25
|
-
it "exits with an error" do
|
26
|
-
expect{
|
27
|
-
launch_deployment(containers: [:bad_container_build])
|
28
|
-
}.to raise_error(SystemExit)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "failed start" do
|
33
|
-
it "exits without error" do
|
34
|
-
expect{
|
35
|
-
launch_deployment(containers: [:bad_container_start])
|
36
|
-
}.to_not raise_error(SystemExit)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/example/spec/spec_helper.rb
DELETED
@@ -1,39 +0,0 @@
|
|
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
|
@@ -1,42 +0,0 @@
|
|
1
|
-
class Indocker::BuildContextPool
|
2
|
-
def initialize(configuration:, logger:, global_logger:)
|
3
|
-
@logger = logger
|
4
|
-
@configuration = configuration
|
5
|
-
@global_logger = global_logger
|
6
|
-
|
7
|
-
@contexts = configuration.build_servers.map do |build_server|
|
8
|
-
Indocker::BuildContext.new(
|
9
|
-
logger: @logger,
|
10
|
-
configuration: configuration,
|
11
|
-
build_server: build_server,
|
12
|
-
global_logger: @global_logger,
|
13
|
-
)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def create_sessions!
|
18
|
-
@contexts.each(&:create_session!)
|
19
|
-
end
|
20
|
-
|
21
|
-
def get
|
22
|
-
context = nil
|
23
|
-
|
24
|
-
loop do
|
25
|
-
context = @contexts.detect {|c| !c.busy?}
|
26
|
-
sleep(0.1)
|
27
|
-
break if context
|
28
|
-
end
|
29
|
-
|
30
|
-
context
|
31
|
-
end
|
32
|
-
|
33
|
-
def each(&proc)
|
34
|
-
@contexts.each(&proc)
|
35
|
-
end
|
36
|
-
|
37
|
-
def close_sessions
|
38
|
-
@contexts.each(&:close_session)
|
39
|
-
rescue => e
|
40
|
-
@logger.error("error during session close: #{e.inspect}")
|
41
|
-
end
|
42
|
-
end
|
data/lib/indocker/server_pool.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
class Indocker::ServerPool
|
2
|
-
def initialize(configuration:, logger:)
|
3
|
-
@logger = logger
|
4
|
-
@configuration = configuration
|
5
|
-
|
6
|
-
@contexts = configuration.servers.map do |server|
|
7
|
-
Indocker::DeployContext.new(
|
8
|
-
logger: @logger,
|
9
|
-
configuration: configuration,
|
10
|
-
server: server,
|
11
|
-
)
|
12
|
-
end
|
13
|
-
end
|
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?
|
21
|
-
def get(server)
|
22
|
-
context = Indocker::DeployContext.new(
|
23
|
-
logger: @logger,
|
24
|
-
configuration: @configuration,
|
25
|
-
server: server,
|
26
|
-
)
|
27
|
-
context.create_session!
|
28
|
-
context
|
29
|
-
end
|
30
|
-
|
31
|
-
def each(&proc)
|
32
|
-
@contexts.each(&proc)
|
33
|
-
end
|
34
|
-
|
35
|
-
def close_sessions
|
36
|
-
@contexts.each(&:close_session)
|
37
|
-
end
|
38
|
-
end
|