freighter 0.2.0 → 0.2.1

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
  SHA1:
3
- metadata.gz: 9739746b3edb3b6a5501f9a06527001ba44bde9a
4
- data.tar.gz: 2286c47c829338ab1517f253d91e708015e054ae
3
+ metadata.gz: f46424de56a54174c0feeb60213a0802bbd2f1d9
4
+ data.tar.gz: 884308db7063d5319f0bf5e34c63b9abb629cb83
5
5
  SHA512:
6
- metadata.gz: 346ef0d893e55776c1b350ea8365a7111c1cd04c51de5e4581eb27fd298d60780cba18fd2a2d4ac2af5a80a3a4828cb2642a5ff64f636c1a11a170c4044ccdb7
7
- data.tar.gz: 63d2046ad8739b5bf6d3bffb2cfbe24226c5b3dcf80c342ebb6370787da1ca8e72e8c8297b5eb09e54de852a8ceb65df2055c51618615510ecfab98adce2ffdb
6
+ metadata.gz: e658a0d63238b37b3ee9bc1bed406e6a075a533f819cde405c3ddfbc8ca912ce4fc2345f65f416c407e22e92c9531b1dcc00dff5c712f5180b2384015e8ce4a4
7
+ data.tar.gz: 6b3d156462bcf74cca7ba5ab9ee1830bacec6816571f0ad572880beed8d39d198210b4e8c4eaab459c6db9088341dd9d8b069a5330f9d50ab4e746948e3be0ac
@@ -1,8 +1,10 @@
1
1
  require 'docker'
2
+ require 'thread'
3
+ require 'thwait'
2
4
 
3
5
  module Freighter
4
6
  class Deploy
5
- attr_reader :logger, :config
7
+ attr_reader :logger, :config
6
8
 
7
9
  def initialize
8
10
  @parser = Parser.new OPTIONS.config_path
@@ -28,6 +30,7 @@ module Freighter
28
30
 
29
31
  @environment.fetch('hosts').each_with_index do |host, i|
30
32
  host_name = host.fetch('host')
33
+ @current_host_name = host_name
31
34
  images = @parser.images(host_name)
32
35
 
33
36
  ssh = SSH.new(host_name, ssh_options)
@@ -35,9 +38,8 @@ module Freighter
35
38
  # docker_api = DockerRestAPI.new("http://localhost:#{local_port}")
36
39
 
37
40
  ssh.tunneled_proxy(local_port) do |session|
38
- msg = ->(m) { "#{host_name}: #{m}" }
39
41
 
40
- logger.debug msg["Connected"]
42
+ logger.debug msg "Connected"
41
43
  begin
42
44
  # The timeout is needed in the case that we are unable to communicate with the docker REST API
43
45
  Timeout::timeout(5) do
@@ -45,7 +47,7 @@ module Freighter
45
47
  end
46
48
  rescue Timeout::Error
47
49
  ssh.thread.exit
48
- logger.error msg["Could not reach the docker REST API"]
50
+ logger.error msg "Could not reach the docker REST API"
49
51
  end
50
52
 
51
53
 
@@ -53,11 +55,11 @@ module Freighter
53
55
  image_name = image['name']
54
56
  # pull image
55
57
  if OPTIONS.pull_image
56
- logger.info msg["Pulling image: #{image_name}"]
58
+ logger.info msg "Pulling image: #{image_name}"
57
59
  pull_response = Docker::Image.create 'fromImage' => image_name
58
60
  else
59
- logger.info msg["Skip pull image"]
60
- logger.error msg["Skipping is not yet implemented. Please run again without the --no-pull option"]
61
+ logger.info msg "Skip pull image"
62
+ logger.error msg "Skipping is not yet implemented. Please run again without the --no-pull option"
61
63
  end
62
64
 
63
65
  # find existing images on the machine
@@ -65,7 +67,7 @@ module Freighter
65
67
  img.info['RepoTags'].member?(image_name)
66
68
  end.map { |img| img.id[0...12] }
67
69
 
68
- logger.info msg["Existing image(s) found #{image_ids.join(', ')}"]
70
+ logger.info msg "Existing image(s) found #{image_ids.join(', ')}"
69
71
 
70
72
  # determine if a the latest version of the image is currently running
71
73
  matching_containers = containers_matching_port_map(Docker::Container.all, image['containers'].map { |c| c['port_mapping'] })
@@ -82,14 +84,19 @@ module Freighter
82
84
  end
83
85
  end
84
86
  if !current_running_containers.empty? and stopped_containers.empty?
85
- logger.info msg["Container already running with the latest image: #{pull_response.id}"]
87
+ logger.info msg "Container already running with the latest image: #{pull_response.id}"
86
88
  else
87
- logger.info msg["Stopped containers: #{stopped_containers.map(&:info).map(&:to_json)}"]
89
+ logger.info msg "Stopped containers: #{stopped_containers.map(&:info).map(&:to_json)}"
88
90
  results = update_containers matching_containers, image
89
- logger.info msg["Finished:"]
90
- logger.info msg[" started: #{results[:started]}"]
91
- logger.info msg[" stopped: #{results[:stopped]}"]
92
- logger.info msg[" started container ids: #{results[:container_ids_started]}"]
91
+ logger.info msg "Finished:"
92
+ logger.info msg " started: #{results[:started]}"
93
+ logger.info msg " stopped: #{results[:stopped]}"
94
+ logger.info msg " started container ids: #{results[:container_ids_started]}"
95
+
96
+ # cleanup old containers
97
+ cleanup_old_containers
98
+ # cleanup unused/outdated images
99
+ cleanup_dangling_images
93
100
  end
94
101
  end
95
102
  end
@@ -98,6 +105,11 @@ module Freighter
98
105
 
99
106
  private
100
107
 
108
+ # Used for logging to prefix log messages with the current host
109
+ def msg(message)
110
+ "#{@current_host_name}: #{message}"
111
+ end
112
+
101
113
  # Sets up the Docker gem by setting the local URL and authenticating to the host's REST API
102
114
  def setup_docker_client(local_port)
103
115
  Docker.url = "http://localhost:#{local_port}"
@@ -135,16 +147,16 @@ module Freighter
135
147
  end
136
148
  end
137
149
 
138
- def update_containers existing_containers=[], image
150
+ def update_containers(existing_containers=[], image)
139
151
  totals = { stopped: 0, started: 0, container_ids_started: [] }
140
152
  # stop the existing matching containers
141
153
  existing_containers.map do |container|
142
154
  Thread.new do
143
155
  existing_container = Docker::Container.get(container.id)
144
- logger.info "Stopping container: #{contianer.id}"
156
+ logger.info msg "Stopping container: #{contianer.id}"
145
157
  existing_container.stop
146
158
  existing_container.wait()
147
- logger.info "Container stopped (#{container.id}"
159
+ logger.info msg "Container stopped (#{container.id}"
148
160
  totals[:stopped] += 1
149
161
  end
150
162
  end.join
@@ -162,17 +174,46 @@ module Freighter
162
174
  }
163
175
 
164
176
  new_container = Docker::Container.create container_options
165
- logger.info "Starting container with port_mapping: host #{[port_map.ip, port_map.host].join(':')}, container #{port_map.container}"
177
+ logger.info msg "Starting container with port_mapping: host #{[port_map.ip, port_map.host].join(':')}, container #{port_map.container}"
166
178
  new_container.start(
167
179
  "PortBindings" => { "#{port_map.container}/tcp" => [{ "HostPort" => port_map.host.to_s, "HostIp" => port_map.ip }] }
168
180
  )
169
181
  totals[:container_ids_started] << new_container.id
170
- logger.info "New container started with id: #{new_container.id}"
182
+ logger.info msg "New container started with id: #{new_container.id}"
171
183
  totals[:started] += 1
172
184
  end
173
185
 
174
186
  totals
175
187
  end
176
188
 
189
+ # cleans up all exited containers
190
+ def cleanup_old_containers
191
+ thread_pool = []
192
+ Docker::Container.all(all: true).select { |c| c.info['Status'] =~ /^Exited/ }.each do |container|
193
+ thread_pool << Thread.new do
194
+ logger.info msg "Removing container: #{container.info.to_json}"
195
+ container.remove
196
+ end
197
+ end
198
+ if thread_pool.empty?
199
+ logger.info msg "No containers need to be cleaned up"
200
+ else
201
+ logger.info msg "Waiting for old containers to be cleaned up"
202
+ ThreadsWait.all_waits(*thread_pool)
203
+ end
204
+ end
205
+
206
+ def cleanup_dangling_images
207
+ thread_pool = []
208
+ Docker::Image.all(filters: '{"dangling":["true"]}').each do |image|
209
+ thread_pool << Thread.new do
210
+ image.remove
211
+ logger.info msg "Removed image: #{image.info.to_json}"
212
+ end
213
+ end
214
+ logger.info msg "Waiting for dangling images to be cleaned up"
215
+ ThreadsWait.all_waits(*thread_pool)
216
+ end
217
+
177
218
  end
178
219
  end
@@ -1,3 +1,3 @@
1
1
  module Freighter
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freighter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean McCleary