centurion 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -15,14 +15,19 @@ tools directly so you can use anything they currently support via the normal
15
15
  registry mechanism.
16
16
 
17
17
  If you haven't been using a registry, you should read up on how to do that
18
- before trying to deploy anything with Centurion. Docker, Inc [provide
19
- repositories](https://index.docker.io/), including the main public repository.
20
- Alternatively, you can [host your
21
- own](https://github.com/dotcloud/docker-registry), or
22
- [Quay.io](https://quay.io) is another commercial option.
18
+ before trying to deploy anything with Centurion.
23
19
 
24
- Centurion also now supports [Dogestry](https://github.com/newrelic-forks/dogestry)!
25
- See details below for more information.
20
+ Commercial Docker Registry Providers:
21
+ - Docker, Inc. [provides repositories](https://index.docker.io/), and hosts the
22
+ main public Docker repository.
23
+ - [Quay.io](https://quay.io) from the CoreOS team
24
+
25
+ Open-source:
26
+ - The [Docker registry](https://github.com/dotcloud/docker-registry) project,
27
+ built and maintained by Docker. You host this yourself.
28
+ - (*NEW!*) [Dogestry](https://github.com/newrelic-forks/dogestry) is an
29
+ s3-backed Docker registry alternative that removes the requirement to set up
30
+ a centralized registry service or host anything yourself.
26
31
 
27
32
  Status
28
33
  ------
@@ -89,7 +94,7 @@ will have the following effects:
89
94
  Any time you add a new project you can scaffold it in the same manner even
90
95
  in the same repo.
91
96
 
92
- ###Writing configs
97
+ ### Writing configs
93
98
 
94
99
  If you used `centurionize` you will have a base config scaffolded for you.
95
100
  But you'll still need to specify all of your configuration.
@@ -139,12 +144,22 @@ Most of the DSL items (`host_port`, `host_volume`, `env_vars`, `host`) can be
139
144
  specified more than once and will append to the configuration. However, there
140
145
  can only be one `command`; the last one will take priority.
141
146
 
142
- ###Interpolation
147
+ You can cause your container to be started with a specific DNS server
148
+ IP address (the equivalent of `docker run --dns 172.17.42.1 ...`) like this:
149
+ ```ruby
150
+ task :production => :common do
151
+ set :custom_dns, '172.17.42.1'
152
+ # ...
153
+ end
154
+ ```
155
+
156
+ ### Interpolation
143
157
 
144
158
  Currently there is one special string for interpolation that can be added to
145
- any `env_var` value in the DSL. `%DOCKER_HOST%` will be replaced with the
159
+ any `env_var` value in the DSL. `%DOCKER_HOSTNAME%` will be replaced with the
146
160
  current server's hostname in the environment variable at deployment time.
147
161
 
162
+
148
163
  Deploying
149
164
  ---------
150
165
 
@@ -182,6 +197,11 @@ are the same everywhere. Settings are per-project.
182
197
  `rolling_deployment_wait_time` is the total time Centurion will wait for
183
198
  an individual container to come up before giving up as a failure. Defaults
184
199
  to 24 attempts.
200
+ * `rolling_deploy_skip_ports` => Either a single port, or an array of ports
201
+ that should be skipped for status checks. Status checking assumes an HTTP
202
+ server is on the other end and if you are deploying a container where some
203
+ ports are not HTTP services, this allows you to only health check the ports
204
+ that are. The default is an empty array.
185
205
 
186
206
  ###Deploy a project to a fleet of Docker servers
187
207
 
@@ -231,15 +251,45 @@ Returns a list of all the images for this project in the registry.
231
251
  $ bundle exec centurion -p radio-radio -e staging -a list
232
252
  ````
233
253
 
234
- ###Alternative Docker Registry
254
+ ### Registry
255
+
256
+ Centurion needs to have access to some registry in order to pull images to
257
+ remote Docker servers. This needs to be either a hosted registry (public or
258
+ private), or [Dogestry](https://github.com/newrelic-forks/dogestry).
259
+
260
+ #### Access to the registry
261
+
262
+ If you are not using either Dogestry, or the public registry, you may need to
263
+ provide authentication credentials. Centurion needs to access the Docker
264
+ registry hosting your images directly to retrive image ids and tags.This is
265
+ supported in both the config file and also as command line arguments.
266
+
267
+ The command line arguments are:
268
+ * `--registry-user` => The username to pass to the registry
269
+ * `--registry-password` => The password
270
+
271
+ These correspond to the following settings:
272
+
273
+ * `registry_user`
274
+ * `registry_password`
275
+
276
+ #### Alternative Docker Registry
235
277
 
236
- Centurion normally uses the built-in registry support in the Docker daemon to handle pushing and pulling images.But Centurion also has the ability to use external tooling to support hosting your registry on Amazon S3. That tooling is from a project called [Dogestry](https://github.com/newrelic-forks/dogestry). We have recently improved that tooling
237
- substantially in coordination with the Centurion support.
278
+ Centurion normally uses the built-in registry support in the Docker daemon to
279
+ handle pushing and pulling images.But Centurion also has the ability to use
280
+ external tooling to support hosting your registry on Amazon S3. That tooling is
281
+ from a project called [Dogestry](https://github.com/newrelic-forks/dogestry).
282
+ We have recently improved that tooling substantially in coordination with the
283
+ Centurion support.
238
284
 
239
- Dogestry uses the Docker daemon's import/export functionality in combination with Amazon S3 to provide reliable hosting of images. Setting Centurion up to use Dogestry is pretty trivial:
285
+ Dogestry uses the Docker daemon's import/export functionality in combination
286
+ with Amazon S3 to provide reliable hosting of images. Setting Centurion up to
287
+ use Dogestry is pretty trivial:
240
288
 
241
- 1. Install Dogestry binaries on the client from which Dogestry is run. Binaries are provided in the GitHub release.
242
- 1. Add the settings necessary to get Centurion to pull from Dogestry. A config example is provided below:
289
+ 1. Install Dogestry binaries on the client from which Dogestry is run.
290
+ Binaries are provided in the GitHub release.
291
+ 1. Add the settings necessary to get Centurion to pull from Dogestry. A config
292
+ example is provided below:
243
293
 
244
294
  See example below to use `dogestry`:
245
295
 
data/bin/centurion CHANGED
@@ -22,14 +22,16 @@ Dir.glob(File.join(task_dir, '*.rake')).each { |file| load file }
22
22
  require 'trollop'
23
23
 
24
24
  opts = Trollop::options do
25
- opt :project, 'project (blog, forums...)', type: String, required: true, short: '-p'
26
- opt :environment, "environment (production, staging...)", type: String, required: true, short: '-e'
27
- opt :action, 'action (deploy, list...)', type: String, default: 'list', short: '-a'
28
- opt :image, 'image (yourco/project...)', type: String, required: false, short: '-i'
29
- opt :tag, 'tag (latest...)', type: String, required: false, short: '-t'
30
- opt :hosts, 'hosts, comma separated', type: String, required: false, short: '-h'
31
- opt :docker_path, 'path to docker executable (default: docker)', type: String, default: 'docker', short: '-d'
32
- opt :nopull, 'Skip the pull_image step', type: :flag, default: false, long: '--no-pull'
25
+ opt :project, 'project (blog, forums...)', type: String, required: true, short: '-p'
26
+ opt :environment, "environment (production, staging...)", type: String, required: true, short: '-e'
27
+ opt :action, 'action (deploy, list...)', type: String, default: 'list', short: '-a'
28
+ opt :image, 'image (yourco/project...)', type: String, required: false, short: '-i'
29
+ opt :tag, 'tag (latest...)', type: String, required: false, short: '-t'
30
+ opt :hosts, 'hosts, comma separated', type: String, required: false, short: '-h'
31
+ opt :docker_path, 'path to docker executable (default: docker)', type: String, default: 'docker', short: '-d'
32
+ opt :nopull, 'Skip the pull_image step', type: :flag, default: false, long: '--no-pull'
33
+ opt :registry_user, 'user for registry auth (default: nil)', type: String, default: nil, short: :none
34
+ opt :registry_password,'password for registry auth (default: nil)', type: String, default: nil, short: :none
33
35
  end
34
36
 
35
37
  set_current_environment(opts[:environment].to_sym)
@@ -60,6 +62,8 @@ set :docker_registry, Centurion::DockerRegistry::OFFICIAL_URL unless any?(:docke
60
62
  # Specify a path to docker executable
61
63
  set :docker_path, opts[:docker_path]
62
64
 
63
- set :no_pull, opts[:nopull]
65
+ set :no_pull, opts[:registry_user]
66
+ set :registry_user, opts[:registry_user] if opts[:registry_user]
67
+ set :registry_password, opts[:registry_password] if opts[:registry_password]
64
68
 
65
69
  invoke(opts[:action])
data/centurion.gemspec CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
39
39
 
40
40
  spec.add_development_dependency 'bundler'
41
41
  spec.add_development_dependency 'rake'
42
- spec.add_development_dependency 'rspec', '~> 2.14.0'
42
+ spec.add_development_dependency 'rspec', '~> 3.1.0'
43
43
  spec.add_development_dependency 'pry'
44
44
  spec.add_development_dependency 'simplecov'
45
45
 
@@ -58,7 +58,7 @@ module Centurion::Deploy
58
58
  def http_status_ok?(target_server, port, endpoint)
59
59
  url = "http://#{target_server.hostname}:#{port}#{endpoint}"
60
60
  response = begin
61
- Excon.get(url)
61
+ Excon.get(url, :headers => {'Accept' => '*/*'})
62
62
  rescue Excon::Errors::SocketError
63
63
  warn "Failed to connect to #{url}, no socket open."
64
64
  nil
@@ -67,7 +67,7 @@ module Centurion::Deploy
67
67
  return false unless response
68
68
  return true if response.status >= 200 && response.status < 300
69
69
 
70
- warn "Got HTTP status: #{response.status}"
70
+ warn "Got HTTP status: #{response.status}"
71
71
  false
72
72
  end
73
73
 
@@ -137,7 +137,7 @@ module Centurion::Deploy
137
137
  end
138
138
 
139
139
  private
140
-
140
+
141
141
  def start_container_with_config(target_server, volumes, port_bindings, container_config)
142
142
  info "Creating new container for #{container_config['Image'][0..7]}"
143
143
  new_container = target_server.create_container(container_config)
@@ -146,7 +146,10 @@ module Centurion::Deploy
146
146
  # Map some host volumes if needed
147
147
  host_config['Binds'] = volumes if volumes && !volumes.empty?
148
148
  # Bind the ports
149
- host_config['PortBindings'] = port_bindings
149
+ host_config['PortBindings'] = port_bindings
150
+ # DNS if specified
151
+ dns = fetch(:custom_dns)
152
+ host_config['Dns'] = dns if dns
150
153
 
151
154
  info "Starting new container #{new_container['Id'][0..7]}"
152
155
  target_server.start_container(new_container['Id'], host_config)
@@ -72,7 +72,7 @@ module Centurion::DeployDSL
72
72
  end
73
73
 
74
74
  def registry(type)
75
- set(:registry, type)
75
+ set(:registry, type.to_s)
76
76
  end
77
77
 
78
78
  private
@@ -7,17 +7,24 @@ module Centurion; end
7
7
  class Centurion::DockerRegistry
8
8
  OFFICIAL_URL = 'https://registry.hub.docker.com'
9
9
 
10
- def initialize(base_uri)
10
+ def initialize(base_uri, registry_user=nil, registry_password=nil)
11
11
  @base_uri = base_uri
12
+ @user = registry_user
13
+ @password = registry_password
12
14
  end
13
15
 
14
16
  def digest_for_tag(repository, tag)
15
17
  path = "/v1/repositories/#{repository}/tags/#{tag}"
16
18
  uri = uri_for_repository_path(repository, path)
17
19
  $stderr.puts "GET: #{uri}"
20
+ options = { :headers => { "Content-Type" => "application/json" } }
21
+ if @user
22
+ options[:user] = @user
23
+ options[:password] = @password
24
+ end
18
25
  response = Excon.get(
19
26
  uri,
20
- :headers => { "Content-Type" => "application/json" }
27
+ options
21
28
  )
22
29
  raise response.inspect unless response.status == 200
23
30
 
@@ -30,8 +37,18 @@ class Centurion::DockerRegistry
30
37
  def repository_tags(repository)
31
38
  path = "/v1/repositories/#{repository}/tags"
32
39
  uri = uri_for_repository_path(repository, path)
40
+
33
41
  $stderr.puts "GET: #{uri.inspect}"
34
- response = Excon.get(uri)
42
+
43
+ # Need to workaround a bug in Docker Hub to now pass port in Host header
44
+ options = { omit_default_port: true }
45
+
46
+ if @user
47
+ options[:user] = @user
48
+ options[:password] = @password
49
+ end
50
+
51
+ response = Excon.get(uri, options)
35
52
  raise response.inspect unless response.status == 200
36
53
 
37
54
  tags = JSON.load(response.body)
@@ -46,10 +63,8 @@ class Centurion::DockerRegistry
46
63
  # [1]: https://docs.docker.com/v1.1/reference/api/registry_api/
47
64
 
48
65
  if is_official_registry?(repository)
49
- {}.tap do |hash|
50
- tags.each do |tag|
51
- hash[tag['name']] = tag['layer']
52
- end
66
+ tags.each_with_object({}) do |tag, hash|
67
+ hash[tag['name']] = tag['layer']
53
68
  end
54
69
  else
55
70
  tags
@@ -59,10 +74,7 @@ class Centurion::DockerRegistry
59
74
  private
60
75
 
61
76
  def is_official_registry?(repository)
62
- if @base_uri == OFFICIAL_URL
63
- return !repository.match(/^[a-z0-9]+[a-z0-9\-\.]+(?::[1-9][0-9]*)?\//)
64
- end
65
- false
77
+ return @base_uri == OFFICIAL_URL
66
78
  end
67
79
 
68
80
  def uri_for_repository_path(repository, path)
@@ -1,9 +1,11 @@
1
1
  require_relative 'logging'
2
+ require 'fileutils'
2
3
 
3
4
  module Centurion; end
4
5
 
5
6
  class Centurion::Dogestry
6
7
  include Centurion::Logging
8
+ attr_accessor :options
7
9
 
8
10
  def initialize(options = {})
9
11
  @options = options
@@ -54,7 +56,7 @@ class Centurion::Dogestry
54
56
  @options[:docker_host] || 'tcp://localhost:2375'
55
57
  end
56
58
 
57
- def set_envs
59
+ def set_envs(docker_host)
58
60
  ENV['DOCKER_HOST'] = docker_host
59
61
  ENV['AWS_ACCESS_KEY'] = aws_access_key_id
60
62
  ENV['AWS_SECRET_KEY'] = aws_secret_key
@@ -62,23 +64,28 @@ class Centurion::Dogestry
62
64
  info "Dogestry ENV: #{ENV.inspect}"
63
65
  end
64
66
 
65
- def exec_command(command, repo)
66
- command = "dogestry #{command} #{s3_url} #{repo}"
67
+ def exec_command(command, repo, flags="")
68
+ command = "dogestry #{flags} #{command} #{s3_url} #{repo}"
67
69
  info "Executing: #{command}"
68
70
  command
69
71
  end
70
72
 
71
- def pull(repo)
73
+ def download_image_to_temp_dir(repo, local_dir)
72
74
  validate_before_exec
73
- set_envs
75
+ set_envs("")
74
76
 
75
- echo(exec_command('pull', repo))
77
+ flags = "-tempdir #{File.expand_path(local_dir)}"
78
+
79
+ echo(exec_command('download', repo, flags=flags))
76
80
  end
77
81
 
78
- def push(repo)
82
+ def upload_temp_dir_image_to_docker(repo, local_dir, docker_host)
79
83
  validate_before_exec
80
- set_envs
84
+ set_envs(docker_host)
85
+
86
+ command = "dogestry upload #{local_dir} #{repo}"
87
+ info "Executing: #{command}"
81
88
 
82
- echo(exec_command('push', repo))
89
+ echo(command)
83
90
  end
84
91
  end
@@ -1,3 +1,3 @@
1
1
  module Centurion
2
- VERSION = '1.2.0'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require 'thread'
2
2
  require 'excon'
3
3
  require 'centurion/deploy'
4
+ require 'tmpdir'
4
5
 
5
6
  task :deploy do
6
7
  invoke 'deploy:get_image'
@@ -31,7 +32,7 @@ namespace :deploy do
31
32
  task :validate_pull_image do
32
33
  ['aws_access_key_id', 'aws_secret_key', 's3_bucket'].each do |env_var|
33
34
  unless fetch(env_var.to_sym)
34
- $stderr.puts "\n\n#{env_var} is not defined."
35
+ error "\n\n#{env_var} is not defined."
35
36
  exit(1)
36
37
  end
37
38
  end
@@ -40,21 +41,32 @@ namespace :deploy do
40
41
  task :pull_image do
41
42
  invoke 'deploy:dogestry:validate_pull_image'
42
43
 
43
- target_servers = Centurion::DockerServerGroup.new(fetch(:hosts), fetch(:docker_path))
44
- target_servers.each_in_parallel do |target_server|
45
- dogestry_options = {
46
- aws_access_key_id: fetch(:aws_access_key_id),
47
- aws_secret_key: fetch(:aws_secret_key),
48
- s3_bucket: fetch(:s3_bucket),
49
- s3_region: fetch(:s3_region) || 'us-east-1',
50
- docker_host: "tcp://#{target_server.hostname}:#{target_server.port}"
51
- }
44
+ # Create Centurion::Dogestry instance
45
+ registry = Centurion::Dogestry.new(
46
+ aws_access_key_id: fetch(:aws_access_key_id),
47
+ aws_secret_key: fetch(:aws_secret_key),
48
+ s3_bucket: fetch(:s3_bucket),
49
+ s3_region: fetch(:s3_region) || 'us-east-1',
50
+ )
51
+
52
+ # Download image from S3 to local /tmp/directory
53
+ Dir.mktmpdir("dogestry") do |local_dir|
54
+
55
+ info "** Downloading image(#{fetch(:image)}:#{fetch(:tag)}) from S3 to local directory"
56
+ registry.download_image_to_temp_dir("#{fetch(:image)}:#{fetch(:tag)}", local_dir)
57
+
58
+ # Upload image from local /tmp/directory to specified Docker hosts
59
+ target_servers = Centurion::DockerServerGroup.new(fetch(:hosts), fetch(:docker_path))
60
+ target_servers.each_in_parallel do |target_server|
52
61
 
53
- $stdout.puts "** Pulling image(#{fetch(:image)}:#{fetch(:tag)}) from Dogestry: #{dogestry_options.inspect}"
62
+ docker_host = "tcp://#{target_server.hostname}:#{target_server.port}"
54
63
 
55
- registry = Centurion::Dogestry.new(dogestry_options)
64
+ image_and_tag = "#{fetch(:image)}:#{fetch(:tag)}"
56
65
 
57
- registry.pull("#{fetch(:image)}:#{fetch(:tag)}")
66
+ info "** Pushing image(#{image_and_tag}) from #{local_dir} to Docker: #{docker_host}"
67
+
68
+ registry.upload_temp_dir_image_to_docker(image_and_tag, local_dir, docker_host)
69
+ end
58
70
  end
59
71
  end
60
72
  end
@@ -85,7 +97,8 @@ namespace :deploy do
85
97
  fetch(:image_id),
86
98
  fetch(:port_bindings),
87
99
  fetch(:binds),
88
- fetch(:env_vars)
100
+ fetch(:env_vars),
101
+ fetch(:command)
89
102
  )
90
103
  end
91
104
  end
@@ -111,13 +124,19 @@ namespace :deploy do
111
124
  fetch(:image_id),
112
125
  fetch(:port_bindings),
113
126
  fetch(:binds),
114
- fetch(:env_vars)
127
+ fetch(:env_vars),
128
+ fetch(:command)
115
129
  )
116
130
 
131
+ skip_ports = Array(fetch(:rolling_deploy_skip_ports, [])).map(&:to_s)
132
+
117
133
  fetch(:port_bindings).each_pair do |container_port, host_ports|
134
+ port = host_ports.first['HostPort']
135
+ next if skip_ports.include?(port)
136
+
118
137
  wait_for_http_status_ok(
119
138
  server,
120
- host_ports.first['HostPort'],
139
+ port,
121
140
  fetch(:status_endpoint, '/'),
122
141
  fetch(:image),
123
142
  fetch(:tag),
@@ -137,10 +156,14 @@ namespace :deploy do
137
156
  end
138
157
 
139
158
  task :determine_image_id do
140
- registry = Centurion::DockerRegistry.new(fetch(:docker_registry))
159
+ registry = Centurion::DockerRegistry.new(
160
+ fetch(:docker_registry),
161
+ fetch(:registry_user),
162
+ fetch(:registry_password)
163
+ )
141
164
  exact_image = registry.digest_for_tag(fetch(:image), fetch(:tag))
142
165
  set :image_id, exact_image
143
- $stderr.puts "RESOLVED #{fetch(:image)}:#{fetch(:tag)} => #{exact_image[0..11]}"
166
+ info "RESOLVED #{fetch(:image)}:#{fetch(:tag)} => #{exact_image[0..11]}"
144
167
  end
145
168
 
146
169
  task :determine_image_id_from_first_server do
@@ -148,7 +171,7 @@ namespace :deploy do
148
171
  image_detail = target_server.inspect_image(fetch(:image), fetch(:tag))
149
172
  exact_image = image_detail["id"]
150
173
  set :image_id, exact_image
151
- $stderr.puts "RESOLVED #{fetch(:image)}:#{fetch(:tag)} => #{exact_image[0..11]}"
174
+ info "RESOLVED #{fetch(:image)}:#{fetch(:tag)} => #{exact_image[0..11]}"
152
175
  break
153
176
  end
154
177
  end
@@ -159,7 +182,7 @@ namespace :deploy do
159
182
  next
160
183
  end
161
184
 
162
- $stderr.puts "Fetching image #{fetch(:image)}:#{fetch(:tag)} IN PARALLEL\n"
185
+ info "Fetching image #{fetch(:image)}:#{fetch(:tag)} IN PARALLEL\n"
163
186
 
164
187
  if fetch(:registry) == 'dogestry'
165
188
  invoke 'deploy:dogestry:pull_image'
@@ -177,21 +200,21 @@ namespace :deploy do
177
200
  found_image_id = image_detail["id"]
178
201
 
179
202
  if found_image_id == fetch(:image_id)
180
- $stderr.puts "Image #{found_image_id[0..7]} found on #{target_server.hostname}"
203
+ info "Image #{found_image_id[0..7]} found on #{target_server.hostname}"
181
204
  else
182
205
  raise "Did not find image #{fetch(:image_id)} on host #{target_server.hostname}!"
183
206
  end
184
207
 
185
208
  # Print the container config
186
209
  image_detail["container_config"].each_pair do |key,value|
187
- $stderr.puts "\t#{key} => #{value.inspect}"
210
+ info "\t#{key} => #{value.inspect}"
188
211
  end
189
212
  end
190
213
  end
191
214
 
192
215
  task :promote_from_staging do
193
216
  if fetch(:environment) == 'staging'
194
- $stderr.puts "\n\nYour target environment needs to not be 'staging' to promote from staging."
217
+ error "\n\nYour target environment needs to not be 'staging' to promote from staging."
195
218
  exit(1)
196
219
  end
197
220
 
@@ -203,17 +226,17 @@ namespace :deploy do
203
226
  staging_tags = get_current_tags_for(fetch(:image)).map { |t| t[:tags] }.flatten.uniq
204
227
 
205
228
  if staging_tags.size != 1
206
- $stderr.puts "\n\nUh, oh: Not sure which staging tag to deploy! Found:(#{staging_tags.join(', ')})"
229
+ error "\n\nUh, oh: Not sure which staging tag to deploy! Found:(#{staging_tags.join(', ')})"
207
230
  exit(1)
208
231
  end
209
232
 
210
- $stderr.puts "Staging environment has #{staging_tags.first} deployed."
233
+ info "Staging environment has #{staging_tags.first} deployed."
211
234
 
212
235
  # Make sure that we set our env back to production, then update the tag.
213
236
  set_current_environment(starting_environment)
214
237
  set :tag, staging_tags.first
215
238
 
216
- $stderr.puts "Deploying #{fetch(:tag)} to the #{starting_environment} environment"
239
+ info "Deploying #{fetch(:tag)} to the #{starting_environment} environment"
217
240
 
218
241
  invoke 'deploy'
219
242
  end
data/lib/tasks/list.rake CHANGED
@@ -24,7 +24,11 @@ namespace :list do
24
24
 
25
25
  task :tags do
26
26
  begin
27
- registry = Centurion::DockerRegistry.new(fetch(:docker_registry))
27
+ registry = Centurion::DockerRegistry.new(
28
+ fetch(:docker_registry),
29
+ fetch(:registry_user),
30
+ fetch(:registry_password)
31
+ )
28
32
  tags = registry.repository_tags(fetch(:image))
29
33
  tags.each do |tag|
30
34
  puts "\t#{tag[0]}\t-> #{tag[1][0..11]}"
data/spec/deploy_spec.rb CHANGED
@@ -226,10 +226,13 @@ describe Centurion::Deploy do
226
226
 
227
227
  server.stub(:inspect_container)
228
228
 
229
+ allow(test_deploy).to receive(:fetch).with(:custom_dns).and_return('8.8.8.8')
230
+
229
231
  expect(server).to receive(:start_container).with(
230
232
  'abc123456',
231
233
  {
232
- 'PortBindings' => bindings
234
+ 'PortBindings' => bindings,
235
+ 'Dns' => '8.8.8.8'
233
236
  }
234
237
  ).once
235
238
 
@@ -258,6 +261,8 @@ describe Centurion::Deploy do
258
261
  end
259
262
 
260
263
  it 'ultimately asks the server object to do the work' do
264
+ allow(test_deploy).to receive(:fetch).with(:custom_dns).and_return(nil)
265
+
261
266
  server.should_receive(:create_container).with(
262
267
  hash_including(
263
268
  'Image'=>'image_id',
@@ -46,7 +46,7 @@ describe Centurion::DockerRegistry do
46
46
  let(:registry_url) { Centurion::DockerRegistry::OFFICIAL_URL }
47
47
  let(:repository) { 'docker-reg.example.com/foobar' }
48
48
  let(:response) { <<-JSON.strip }
49
- {"#{tag_name}": "#{image_id}"}
49
+ [{"layer": "#{image_id}", "name": "#{tag_name}"}]
50
50
  JSON
51
51
 
52
52
  it 'fetches from the image-referenced registry' do
@@ -77,4 +77,29 @@ describe Centurion::DockerRegistry do
77
77
  end
78
78
  end
79
79
  end
80
+
81
+ describe '#repository_auth' do
82
+ let(:tag_name) { 'arbitrary_tag' }
83
+ let(:image_id) { 'deadbeef0000' }
84
+ let(:user) { 'user_foo' }
85
+ let(:password) { 'pass_bar' }
86
+ let(:registry) { Centurion::DockerRegistry.new(registry_url, user, password) }
87
+
88
+ context 'when authentication data is provided to the DockerRegistry object' do
89
+ let(:registry_url) { Centurion::DockerRegistry::OFFICIAL_URL }
90
+ let(:repository) { 'docker-reg.example.com/foobar' }
91
+ let(:response) { <<-JSON.strip }
92
+ [{"layer": "#{image_id}", "name": "#{tag_name}"}]
93
+ JSON
94
+
95
+ before do
96
+ expect(Excon).to receive(:get).with(kind_of(String), hash_including(:user => user, :password => password)).and_return(
97
+ double(status: 200, body: response)
98
+ )
99
+ end
100
+ it 'uses it to connect to the registry' do
101
+ registry.repository_tags(repository)
102
+ end
103
+ end
104
+ end
80
105
  end
@@ -50,6 +50,7 @@ describe Centurion::Dogestry do
50
50
 
51
51
  describe '#which' do
52
52
  it 'finds dogestry command line' do
53
+ allow(File).to receive(:executable?).and_return(true)
53
54
  registry.which('dogestry').should_not == nil
54
55
  end
55
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: centurion
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -21,7 +21,7 @@ authors:
21
21
  autorequire:
22
22
  bindir: bin
23
23
  cert_chain: []
24
- date: 2014-10-29 00:00:00.000000000 Z
24
+ date: 2014-11-20 00:00:00.000000000 Z
25
25
  dependencies:
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: trollop
@@ -110,7 +110,7 @@ dependencies:
110
110
  requirements:
111
111
  - - ~>
112
112
  - !ruby/object:Gem::Version
113
- version: 2.14.0
113
+ version: 3.1.0
114
114
  type: :development
115
115
  prerelease: false
116
116
  version_requirements: !ruby/object:Gem::Requirement
@@ -118,7 +118,7 @@ dependencies:
118
118
  requirements:
119
119
  - - ~>
120
120
  - !ruby/object:Gem::Version
121
- version: 2.14.0
121
+ version: 3.1.0
122
122
  - !ruby/object:Gem::Dependency
123
123
  name: pry
124
124
  requirement: !ruby/object:Gem::Requirement