docker-api 1.4.0 → 1.5.0

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: cfc50f47e7b014bac994dd4077a3fd77abf38a3b
4
- data.tar.gz: 6ccc92a4b1be40bef5628a7800a4870e408e027e
3
+ metadata.gz: 649da0fe1cfd65917ce9975d649ba38846ce728c
4
+ data.tar.gz: 17a7e5506eccab710826b563b8fa74961f3d31ff
5
5
  SHA512:
6
- metadata.gz: 6bf902fd4852f9662dbf942f929be54a8d84416bd9ddbd4d2acbb822f5e3f7a7e6ec09ef73f14485598c5d90261256e362b32cdfa65734286b6356398b805a07
7
- data.tar.gz: 748c6151a34ce6aeae730af14e339bff538f3d637def12ebdc24db30e3185912cd61b37f4e73bfe95e9391ee31ac7fcdbacd82c6de25f40f8e6ee2e1a572747c
6
+ metadata.gz: 0884b950410fc3d3d8b169dbc6561efd26e08640cf9d5a0439e36ef743eb2decdb880378639b090da4f9e0a1380cf9fe5aef5829a9eb7b169112c33df893b6e6
7
+ data.tar.gz: 26c0b55692549c0f77f6a946967c228f5f86c005fdb555b2366dd1e015fcccab157b77fae1c31dc7a3ed2ab2346cba9295299b29fb617632ca16fa036f146015
data/README.md CHANGED
@@ -2,7 +2,7 @@ docker-api
2
2
  ==========
3
3
  [![Gem Version](https://badge.fury.io/rb/docker-api.png)](http://badge.fury.io/rb/docker-api) [![travis-ci](https://travis-ci.org/swipely/docker-api.png?branch=master)](https://travis-ci.org/swipely/docker-api) [![Code Climate](https://codeclimate.com/github/swipely/docker-api.png)](https://codeclimate.com/github/swipely/docker-api) [![Dependency Status](https://gemnasium.com/swipely/docker-api.png)](https://gemnasium.com/swipely/docker-api)
4
4
 
5
- This gem provides an object-oriented interface to the [Docker Remote API](http://docs.docker.io/en/latest/api/docker_remote_api_v1.4/). Every method listed there is implemented, with the exception of attaching to the STDIN of a Container. At the time of this writing, docker-api is meant to interface with Docker version 0.5.1.
5
+ This gem provides an object-oriented interface to the [Docker Remote API](http://docs.docker.io/en/latest/api/docker_remote_api_v1.4/). Every method listed there is implemented, with the exception of attaching to the STDIN of a Container. At the time of this writing, docker-api is meant to interface with Docker version 0.5.*.
6
6
 
7
7
  Installation
8
8
  ------------
@@ -74,7 +74,7 @@ require 'docker'
74
74
  # => true
75
75
 
76
76
  Docker.version
77
- # => { 'Version' => '0.4.0', 'GoVersion' => 'go1.0.3' }
77
+ # => { 'Version' => '0.5.2', 'GoVersion' => 'go1.1' }
78
78
 
79
79
  Docker.info
80
80
  # => { "Debug" => false, "Containers" => 187, "Images" => 196, "NFd" => 10, "NGoroutines" => 9, "MemoryLimit" => true }
@@ -160,19 +160,19 @@ container.json
160
160
 
161
161
  # Start running the Container.
162
162
  container.start
163
- # => nil
163
+ # => Docker::Container { :id => 492510dd38e4, :connection => Docker::Connection { :url => http://localhost, :options => {:port=>4243} } }
164
164
 
165
165
  # Stop running the Container.
166
166
  container.stop
167
- # => nil
167
+ # => Docker::Container { :id => 492510dd38e4, :connection => Docker::Connection { :url => http://localhost, :options => {:port=>4243} } }
168
168
 
169
169
  # Restart the Container.
170
170
  container.restart
171
- # => nil
171
+ # => Docker::Container { :id => 492510dd38e4, :connection => Docker::Connection { :url => http://localhost, :options => {:port=>4243} } }
172
172
 
173
173
  # Kill the command running in the Container.
174
174
  container.kill
175
- # => nil
175
+ # => Docker::Container { :id => 492510dd38e4, :connection => Docker::Connection { :url => http://localhost, :options => {:port=>4243} } }
176
176
 
177
177
  # Return the currently executing processes in a Container.
178
178
  container.top
data/lib/docker.rb CHANGED
@@ -8,8 +8,6 @@ require 'archive/tar/minitar'
8
8
  # The top-level module for this gem. It's purpose is to hold global
9
9
  # configuration variables that are used as defaults in other classes.
10
10
  module Docker
11
- extend self
12
-
13
11
  attr_reader :creds
14
12
 
15
13
  def url
@@ -64,12 +62,15 @@ module Docker
64
62
  rescue Docker::Error::DockerError
65
63
  raise Docker::Error::VersionError, "Expected API Version: #{API_VERSION}"
66
64
  end
65
+
66
+ module_function :url, :url=, :options, :options=, :connection,
67
+ :reset_connection!, :version, :info, :authenticate!,
68
+ :validate_version!
67
69
  end
68
70
 
69
71
  require 'docker/version'
70
72
  require 'docker/error'
71
73
  require 'docker/util'
72
74
  require 'docker/connection'
73
- require 'docker/model'
74
75
  require 'docker/container'
75
76
  require 'docker/image'
@@ -53,12 +53,13 @@ private
53
53
  query ||= {}
54
54
  opts ||= {}
55
55
  headers = opts.delete(:headers) || {}
56
+ content_type = opts[:body].nil? ? 'text/plain' : 'application/json'
56
57
  user_agent = "Swipely/Docker-API #{Docker::VERSION}"
57
58
  {
58
59
  :method => http_method,
59
60
  :path => "/v#{Docker::API_VERSION}#{path}",
60
61
  :query => query,
61
- :headers => { 'Content-Type' => 'text/plain',
62
+ :headers => { 'Content-Type' => content_type,
62
63
  'User-Agent' => user_agent,
63
64
  }.merge(headers),
64
65
  :expects => (200..204),
@@ -1,48 +1,32 @@
1
1
  # This class represents a Docker Container. It's important to note that nothing
2
2
  # is cached so that the information is always up to date.
3
3
  class Docker::Container
4
- include Docker::Model
5
4
  include Docker::Error
6
5
 
7
- set_resource_prefix '/containers'
6
+ attr_accessor :id, :connection
8
7
 
9
- set_create_request do |body|
10
- response = connection.post('/containers/create', nil, :body => body.to_json)
11
- @id = Docker::Util.parse_json(response)['Id']
12
- self
8
+ # The private new method accepts a connection and optional id.
9
+ def initialize(connection, id = nil)
10
+ if connection.is_a?(Docker::Connection)
11
+ @connection, @id = connection, id
12
+ else
13
+ raise ArgumentError, "Expected a Docker::Connection, got: #{connection}."
14
+ end
13
15
  end
14
16
 
15
- # Get more information about the Container.
16
- request :get, :json
17
- # Start the Container.
18
- request :post, :start
19
- # Inspect the Container's changes to the filesysetem
20
- request :get, :changes
21
- # Stop the Container.
22
- request :post, :stop
23
- # Kill the Container.
24
- request :post, :kill
25
- # Restart the Container
26
- request :post, :restart
27
-
28
17
  # Return a List of Hashes that represents the top running processes.
29
18
  def top(opts = {})
30
- resp = connection.get("/containers/#{id}/top", opts)
31
- hash = Docker::Util.parse_json(resp)
32
- hash['Processes'].map { |ary| Hash[hash['Titles'].zip(ary)] }
33
- end
34
-
35
- # For each method, `m`, define a method called `m?` that attempts the method,
36
- # but catches all Server errors.
37
- [:stop, :start, :kill, :restart].each do |method|
38
- define_method :"#{method}?" do |*args|
39
- begin; public_send(method, *args); rescue ServerError; end
19
+ resp = Docker::Util.parse_json(connection.get(path_for(:top), opts))
20
+ if resp['Processes'].nil?
21
+ []
22
+ else
23
+ resp['Processes'].map { |ary| Hash[resp['Titles'].zip(ary)] }
40
24
  end
41
25
  end
42
26
 
43
27
  # Wait for the current command to finish executing.
44
28
  def wait(time = 60)
45
- resp = connection.post("/containers/#{id}/wait", nil, :read_timeout => time)
29
+ resp = connection.post(path_for(:wait), nil, :read_timeout => time)
46
30
  Docker::Util.parse_json(resp)
47
31
  end
48
32
 
@@ -51,8 +35,8 @@ class Docker::Container
51
35
  # the command that is currently executing does not return a 0 status code, an
52
36
  # UnexpectedResponseError is raised.
53
37
  def run(cmd, time = 1000)
54
- if (code = tap(&:start?).wait(time)['StatusCode']).zero?
55
- commit.run(cmd).tap(&:start?)
38
+ if (code = tap(&:start).wait(time)['StatusCode']).zero?
39
+ commit.run(cmd).tap(&:start)
56
40
  else
57
41
  raise UnexpectedResponseError, "Command returned status code #{code}."
58
42
  end
@@ -60,21 +44,72 @@ class Docker::Container
60
44
 
61
45
  # Export the Container as a tar.
62
46
  def export(&block)
63
- connection.get("/containers/#{id}/export", nil, :response_block => block)
64
- true
47
+ connection.get(path_for(:export), {}, :response_block => block)
48
+ self
65
49
  end
66
50
 
67
51
  # Attach to a container's standard streams / logs.
68
52
  def attach(options = {}, &block)
69
- options = { :stream => true, :stdout => true }.merge(options)
70
- connection.post("/containers/#{id}/attach", options,
71
- :response_block => block)
53
+ opts = { :stream => true, :stdout => true }.merge(options)
54
+ connection.post(path_for(:attach), opts, :response_block => block)
72
55
  end
73
56
 
74
57
  # Create an Image from a Container's change.s
75
58
  def commit(options = {})
76
59
  options.merge!('container' => self.id[0..7])
77
60
  hash = Docker::Util.parse_json(connection.post('/commit', options))
78
- Docker::Image.send(:new, :id => hash['Id'], :connection => self.connection)
61
+ Docker::Image.send(:new, self.connection, hash['Id'])
62
+ end
63
+
64
+ # Return a String represntation of the Container.
65
+ def to_s
66
+ "Docker::Container { :id => #{self.id}, :connection => #{self.connection} }"
79
67
  end
68
+
69
+ # #json returns information about the Container, #changes returns a list of
70
+ # the changes the Container has made to the filesystem.
71
+ [:json, :changes].each do |method|
72
+ define_method(method) do |opts = {}|
73
+ Docker::Util.parse_json(connection.get(path_for(method), opts))
74
+ end
75
+ end
76
+
77
+ # #start!, #stop!, #kill!, and #restart! all perform the associated action and
78
+ # return the Container. #start, #stop, #kill, and #restart all do the same,
79
+ # but rescue from ServerErrors.
80
+ [:start, :stop, :kill, :restart].each do |method|
81
+ define_method(:"#{method}!") do |opts = {}|
82
+ connection.post(path_for(method), {}, :body => opts.to_json)
83
+ self
84
+ end
85
+
86
+ define_method(method) do |*args|
87
+ begin; public_send(:"#{method}!", *args); rescue ServerError; self end
88
+ end
89
+ end
90
+
91
+ # Create a new Container.
92
+ def self.create(opts = {}, conn = Docker.connection)
93
+ instance = new(conn)
94
+ resp = conn.post('/containers/create', {}, :body => opts.to_json)
95
+ if (instance.id = Docker::Util.parse_json(resp)['Id']).nil?
96
+ raise UnexpectedResponseError, 'Create response did not contain an Id'
97
+ else
98
+ instance
99
+ end
100
+ end
101
+
102
+ # Return all of the Containers.
103
+ def self.all(opts = {}, conn = Docker.connection)
104
+ hashes = Docker::Util.parse_json(conn.get('/containers/json', opts)) || []
105
+ hashes.map { |hash| new(conn, hash['Id']) }
106
+ end
107
+
108
+ # Convenience method to return the path for a particular resource.
109
+ def path_for(resource)
110
+ "/containers/#{self.id}/#{resource}"
111
+ end
112
+
113
+ private :path_for
114
+ private_class_method :new
80
115
  end
data/lib/docker/image.rb CHANGED
@@ -1,47 +1,45 @@
1
1
  # This class represents a Docker Image.
2
2
  class Docker::Image
3
- include Docker::Model
4
3
  include Docker::Error
5
4
 
6
- set_resource_prefix '/images'
5
+ attr_accessor :id, :connection
7
6
 
8
- set_create_request do |options|
9
- body = connection.post('/images/create', options)
10
- @id = Docker::Util.parse_json(body)['status'] rescue nil
11
- @id ||= options['fromImage']
12
- @id ||= "#{options['repo']}/#{options['tag']}"
13
- self
7
+ # The private new method accepts a connection and optional id.
8
+ def initialize(connection, id = nil)
9
+ if connection.is_a?(Docker::Connection)
10
+ @connection, @id = connection, id
11
+ else
12
+ raise ArgumentError, "Expected a Docker::Connection, got: #{connection}."
13
+ end
14
14
  end
15
15
 
16
- # Tag the Image.
17
- request :post, :tag
18
- # Get more information about the Image.
19
- request :get, :json
20
- # Get the history of the Image.
21
- request :get, :history
22
-
23
16
  # Given a command and optional list of streams to attach to, run a command on
24
17
  # an Image. This will not modify the Image, but rather create a new Container
25
18
  # to run the Image.
26
19
  def run(cmd)
27
20
  cmd = cmd.split(/\s+/) if cmd.is_a?(String)
28
21
  Docker::Container.create({ 'Image' => self.id, 'Cmd' => cmd }, connection)
29
- .tap(&:start)
22
+ .tap(&:start!)
30
23
  end
31
24
 
32
25
  # Push the Image to the Docker registry.
33
26
  def push(options = {})
34
- connection.post("/images/#{self.id}/push", options, :body => Docker.creds)
35
- true
27
+ connection.post(path_for(:push), options, :body => Docker.creds)
28
+ self
29
+ end
30
+
31
+ # Tag the Image.
32
+ def tag(opts = {})
33
+ Docker::Util.parse_json(connection.post(path_for(:tag), opts))
36
34
  end
37
35
 
38
36
  # Insert a file into the Image, returns a new Image that has that file.
39
37
  def insert(query = {})
40
- body = connection.post("/images/#{self.id}/insert", query)
38
+ body = connection.post(path_for(:insert), query)
41
39
  if (id = body.match(/{"Id":"([a-f0-9]+)"}\z/)).nil? || id[1].empty?
42
40
  raise UnexpectedResponseError, "Could not find Id in '#{body}'"
43
41
  else
44
- self.class.send(:new, :id => id[1], :connection => self.connection)
42
+ self.class.send(:new, connection, id[1])
45
43
  end
46
44
  end
47
45
 
@@ -50,15 +48,46 @@ class Docker::Image
50
48
  connection.delete("/images/#{self.id}")
51
49
  end
52
50
 
51
+ # Return a String representation of the Image.
52
+ def to_s
53
+ "Docker::Image { :id => #{self.id}, :connection => #{self.connection} }"
54
+ end
55
+
56
+ # #json returns extra information about an Image, #history returns its
57
+ # history.
58
+ [:json, :history].each do |method|
59
+ define_method(method) do |opts = {}|
60
+ Docker::Util.parse_json(connection.get(path_for(method), opts))
61
+ end
62
+ end
63
+
53
64
  class << self
54
65
  include Docker::Error
55
66
 
67
+ # Create a new Image.
68
+ def create(opts = {}, conn = Docker.connection)
69
+ instance = new(conn)
70
+ conn.post('/images/create', opts)
71
+ id = opts['repo'] ? "#{opts['repo']}/#{opts['tag']}" : opts['fromImage']
72
+ if (instance.id = id).nil?
73
+ raise UnexpectedResponseError, 'Create response did not contain an Id'
74
+ else
75
+ instance
76
+ end
77
+ end
78
+
79
+ # Return every Image.
80
+ def all(opts = {}, conn = Docker.connection)
81
+ hashes = Docker::Util.parse_json(conn.get('/images/json', opts)) || []
82
+ hashes.map { |hash| new(conn, hash['Id']) }
83
+ end
84
+
56
85
  # Given a query like `{ :term => 'sshd' }`, queries the Docker Registry for
57
- # a corresponiding Image.
86
+ # a corresponding Image.
58
87
  def search(query = {}, connection = Docker.connection)
59
88
  body = connection.get('/images/search', query)
60
89
  hashes = Docker::Util.parse_json(body) || []
61
- hashes.map { |hash| new(:id => hash['Name'], :connection => connection) }
90
+ hashes.map { |hash| new(connection, hash['Name']) }
62
91
  end
63
92
 
64
93
  # Import an Image from the output of Docker::Container#export.
@@ -67,17 +96,17 @@ class Docker::Image
67
96
  body = connection.post(
68
97
  '/images/create',
69
98
  options.merge('fromSrc' => '-'),
70
- :headers => { 'Transfer-Encoding' => 'chunked' }
99
+ :headers => { 'Content-Type' => 'application/tar',
100
+ 'Transfer-Encoding' => 'chunked' }
71
101
  ) { io.read(Excon.defaults[:chunk_size]).to_s }
72
- new(:id => Docker::Util.parse_json(body)['status'],
73
- :connection => connection)
102
+ new(connection, Docker::Util.parse_json(body)['status'])
74
103
  end
75
104
  end
76
105
 
77
106
  # Given a Dockerfile as a string, builds an Image.
78
107
  def build(commands, connection = Docker.connection)
79
108
  body = connection.post('/build', {}, :body => create_tar(commands))
80
- new(:id => extract_id(body), :connection => connection)
109
+ new(connection, extract_id(body))
81
110
  end
82
111
 
83
112
  # Given a directory that contains a Dockerfile, builds an Image.
@@ -88,7 +117,7 @@ class Docker::Image
88
117
  :headers => { 'Content-Type' => 'application/tar',
89
118
  'Transfer-Encoding' => 'chunked' }
90
119
  ) { tar.read(Excon.defaults[:chunk_size]).to_s }
91
- new(:id => extract_id(body), :connection => connection)
120
+ new(connection, extract_id(body))
92
121
  ensure
93
122
  tar.close unless tar.nil?
94
123
  end
@@ -121,4 +150,11 @@ class Docker::Image
121
150
  FileUtils.cd(cwd)
122
151
  end
123
152
  end
153
+
154
+ # Convenience method to return the path for a particular resource.
155
+ def path_for(resource)
156
+ "/images/#{self.id}/#{resource}"
157
+ end
158
+
159
+ private :path_for
124
160
  end
data/lib/docker/util.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # This module holds shared logic that doesn't really belong anywhere else in the
2
2
  # gem.
3
3
  module Docker::Util
4
- extend self
5
4
  include Docker::Error
6
5
 
7
6
  def parse_json(body)
@@ -9,4 +8,6 @@ module Docker::Util
9
8
  rescue JSON::ParserError => ex
10
9
  raise UnexpectedResponseError, ex.message
11
10
  end
11
+
12
+ module_function :parse_json
12
13
  end
@@ -1,6 +1,6 @@
1
1
  module Docker
2
2
  # The version of the docker-api gem.
3
- VERSION = '1.4.0'
3
+ VERSION = '1.5.0'
4
4
 
5
5
  # The version of the compatible Docker remote API.
6
6
  API_VERSION = '1.4'
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  # Docker daemon and have the base Image pulled.
5
5
  describe Docker::Container do
6
6
  describe '#to_s' do
7
- subject { described_class.send(:new, :id => rand(10000).to_s) }
7
+ subject { described_class.send(:new, Docker.connection, rand(10000).to_s) }
8
8
 
9
9
  let(:id) { 'bf119e2' }
10
10
  let(:connection) { Docker.connection }
@@ -91,13 +91,20 @@ describe Docker::Container do
91
91
  end
92
92
 
93
93
  describe '#start' do
94
- subject { described_class.create('Cmd' => %w[true], 'Image' => 'base') }
94
+ subject {
95
+ described_class.create(
96
+ 'Cmd' => %w[test -d /foo],
97
+ 'Image' => 'base',
98
+ 'Volumes' => {'/foo' => {}}
99
+ )
100
+ }
101
+ let(:all) { Docker::Container.all }
102
+
103
+ before { subject.start('Binds' => ["/tmp:/foo"]) }
95
104
 
96
105
  it 'starts the container', :vcr do
97
- subject.start
98
- described_class.all.map(&:id).should be_any { |id|
99
- id.start_with?(subject.id)
100
- }
106
+ all.map(&:id).should be_any { |id| id.start_with?(subject.id) }
107
+ subject.wait(10)['StatusCode'].should be_zero
101
108
  end
102
109
  end
103
110
 
@@ -214,14 +221,7 @@ describe Docker::Container do
214
221
  describe '.create' do
215
222
  subject { described_class }
216
223
 
217
- context 'when the body is not a Hash' do
218
- it 'raises an error' do
219
- expect { subject.create(:not_a_hash) }
220
- .to raise_error(Docker::Error::ArgumentError)
221
- end
222
- end
223
-
224
- context 'when the Container does not yet exist and the body is a Hash' do
224
+ context 'when the Container does not yet exist' do
225
225
  context 'when the HTTP request does not return a 200' do
226
226
  before { Excon.stub({ :method => :post }, { :status => 400 }) }
227
227
  after { Excon.stubs.shift }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Docker::Image do
4
4
  describe '#to_s' do
5
- subject { described_class.send(:new, :id => rand(10000).to_s) }
5
+ subject { described_class.send(:new, Docker.connection, id) }
6
6
 
7
7
  let(:id) { 'bf119e2' }
8
8
  let(:connection) { Docker.connection }
@@ -102,13 +102,6 @@ describe Docker::Image do
102
102
  describe '.create' do
103
103
  subject { described_class }
104
104
 
105
- context 'when the body is not a Hash' do
106
- it 'raises an error' do
107
- expect { subject.create(:not_a_hash) }
108
- .to raise_error(Docker::Error::ArgumentError)
109
- end
110
- end
111
-
112
105
  context 'when the Image does not yet exist and the body is a Hash' do
113
106
  let(:image) { subject.create('fromImage' => 'base') }
114
107
 
@@ -0,0 +1,30 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://localhost:4243/v1.4/containers/create
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"Hostname":"","User":"","Memory":0,"MemorySwap":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["date"],"Dns":null,"Image":"base","Volumes":{},"VolumesFrom":""}'
9
+ headers:
10
+ Content-Type:
11
+ - text/plain
12
+ User-Agent:
13
+ - Swipely/Docker-API 1.4.0
14
+ response:
15
+ status:
16
+ code: 201
17
+ message: ''
18
+ headers:
19
+ Content-Type:
20
+ - text/plain; charset=utf-8
21
+ Content-Length:
22
+ - '21'
23
+ Date:
24
+ - Thu, 08 Aug 2013 14:47:05 GMT
25
+ body:
26
+ encoding: UTF-8
27
+ string: '{"Id":"3e4587069eb0"}'
28
+ http_version:
29
+ recorded_at: Thu, 08 Aug 2013 14:47:05 GMT
30
+ recorded_with: VCR 2.4.0
@@ -5,55 +5,61 @@ http_interactions:
5
5
  uri: http://localhost:4243/v1.4/containers/create
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"Cmd":["true"],"Image":"base"}'
8
+ string: ! '{"Cmd":["test","-d","/foo"],"Image":"base","Volumes":{"/foo":{}}}'
9
9
  headers:
10
10
  Content-Type:
11
11
  - text/plain
12
12
  User-Agent:
13
- - Swipely/Docker-API 1.3.1
13
+ - Swipely/Docker-API 1.4.0
14
14
  response:
15
15
  status:
16
16
  code: 201
17
17
  message: ''
18
18
  headers:
19
- Content-Type:
20
- - text/plain; charset=utf-8
21
- Content-Length:
22
- - '21'
23
- Date:
24
- - Wed, 07 Aug 2013 16:51:14 GMT
19
+ !binary "Q29udGVudC1UeXBl":
20
+ - !binary |-
21
+ dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOA==
22
+ !binary "Q29udGVudC1MZW5ndGg=":
23
+ - !binary |-
24
+ MjE=
25
+ !binary "RGF0ZQ==":
26
+ - !binary |-
27
+ RnJpLCAwOSBBdWcgMjAxMyAwODo1MDowNSBHTVQ=
25
28
  body:
26
- encoding: UTF-8
27
- string: '{"Id":"006a81e3a9ef"}'
29
+ encoding: US-ASCII
30
+ string: ! '{"Id":"3632688f5774"}'
28
31
  http_version:
29
- recorded_at: Wed, 07 Aug 2013 16:51:14 GMT
32
+ recorded_at: Fri, 09 Aug 2013 08:50:06 GMT
30
33
  - request:
31
34
  method: post
32
- uri: http://localhost:4243/v1.4/containers/006a81e3a9ef/start
35
+ uri: http://localhost:4243/v1.4/containers/3632688f5774/start
33
36
  body:
34
- encoding: US-ASCII
35
- string: ''
37
+ encoding: UTF-8
38
+ string: ! '{"Binds":["/tmp:/foo"]}'
36
39
  headers:
37
40
  Content-Type:
38
- - text/plain
41
+ - application/json
39
42
  User-Agent:
40
- - Swipely/Docker-API 1.3.1
43
+ - Swipely/Docker-API 1.4.0
41
44
  response:
42
45
  status:
43
46
  code: 204
44
47
  message: ''
45
48
  headers:
46
- Content-Type:
47
- - text/plain; charset=utf-8
48
- Content-Length:
49
- - '0'
50
- Date:
51
- - Wed, 07 Aug 2013 16:51:14 GMT
49
+ !binary "Q29udGVudC1UeXBl":
50
+ - !binary |-
51
+ dGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOA==
52
+ !binary "Q29udGVudC1MZW5ndGg=":
53
+ - !binary |-
54
+ MA==
55
+ !binary "RGF0ZQ==":
56
+ - !binary |-
57
+ RnJpLCAwOSBBdWcgMjAxMyAwODo1MDowNiBHTVQ=
52
58
  body:
53
- encoding: UTF-8
59
+ encoding: US-ASCII
54
60
  string: ''
55
61
  http_version:
56
- recorded_at: Wed, 07 Aug 2013 16:51:14 GMT
62
+ recorded_at: Fri, 09 Aug 2013 08:50:06 GMT
57
63
  - request:
58
64
  method: get
59
65
  uri: http://localhost:4243/v1.4/containers/json
@@ -64,22 +70,84 @@ http_interactions:
64
70
  Content-Type:
65
71
  - text/plain
66
72
  User-Agent:
67
- - Swipely/Docker-API 1.3.1
73
+ - Swipely/Docker-API 1.4.0
68
74
  response:
69
75
  status:
70
76
  code: 200
71
77
  message: ''
78
+ headers:
79
+ !binary "Q29udGVudC1UeXBl":
80
+ - !binary |-
81
+ YXBwbGljYXRpb24vanNvbg==
82
+ !binary "Q29udGVudC1MZW5ndGg=":
83
+ - !binary |-
84
+ OTQ2
85
+ !binary "RGF0ZQ==":
86
+ - !binary |-
87
+ RnJpLCAwOSBBdWcgMjAxMyAwODo1MDowNiBHTVQ=
88
+ body:
89
+ encoding: US-ASCII
90
+ string: ! '[{"Id":"3632688f5774a1a5077e0b29e4410458ae43ec9dbaa400b10e68b385206e0cff","Image":"base:latest","Command":"test
91
+ -d /foo","Created":1376038205,"Status":"Up Less than a second","Ports":"","SizeRw":0,"SizeRootFs":0},{"Id":"965d1be64f580f590fa712f6e34b1186cd937f1448b6d5feeeb02174dd562cba","Image":"c401009f3872","Command":"/bin/bash
92
+ --login -c cd /app && bundle exec rackup -p $PORT","Created":1376001906,"Status":"Up
93
+ 10 hours","Ports":"","SizeRw":0,"SizeRootFs":0},{"Id":"371a31ee0515e231b53331827e2169a781d605259ca75f0d1b1593095fee6924","Image":"69e523818a5f","Command":"/bin/bash
94
+ --login -c cd /app && bundle exec rackup config.ru -p 80","Created":1375967943,"Status":"Up
95
+ 19 hours","Ports":"","SizeRw":0,"SizeRootFs":0},{"Id":"c7a4fe69a7249d6db5f24106891e1c28ee4bfe538ece09a53574c0b91850f165","Image":"samalba/hipache:latest","Command":"supervisord
96
+ -n","Created":1375657256,"Status":"Up 19 hours","Ports":"80-\u003e80","SizeRw":0,"SizeRootFs":0}]'
97
+ http_version:
98
+ recorded_at: Fri, 09 Aug 2013 08:50:06 GMT
99
+ - request:
100
+ method: post
101
+ uri: http://localhost:4243/v1.4/containers/3632688f5774/wait
102
+ body:
103
+ encoding: US-ASCII
104
+ string: ''
72
105
  headers:
73
106
  Content-Type:
74
- - application/json
75
- Content-Length:
76
- - '207'
77
- Date:
78
- - Wed, 07 Aug 2013 16:51:14 GMT
107
+ - text/plain
108
+ User-Agent:
109
+ - Swipely/Docker-API 1.4.0
110
+ response:
111
+ status:
112
+ code: 200
113
+ message: ''
114
+ headers:
115
+ !binary "Q29udGVudC1UeXBl":
116
+ - !binary |-
117
+ YXBwbGljYXRpb24vanNvbg==
118
+ !binary "Q29udGVudC1MZW5ndGg=":
119
+ - !binary |-
120
+ MTY=
121
+ !binary "RGF0ZQ==":
122
+ - !binary |-
123
+ RnJpLCAwOSBBdWcgMjAxMyAwODo1MDowNiBHTVQ=
79
124
  body:
80
- encoding: UTF-8
81
- string: '[{"Id":"006a81e3a9efb2d6b6b1bf7b25031f7c0ca972e731c4efeaaab30b75997d5804","Image":"base2:latest","Command":"true
82
- ","Created":1375894274,"Status":"Up Less than a second","Ports":"","SizeRw":0,"SizeRootFs":0}]'
125
+ encoding: US-ASCII
126
+ string: ! '{"StatusCode":0}'
127
+ http_version:
128
+ recorded_at: Fri, 09 Aug 2013 08:50:06 GMT
129
+ - request:
130
+ method: post
131
+ uri: http://localhost:4243/v1.4/containers/3632688f5774/attach?logs=true&stderr=true&stdout=true&stream=false
132
+ body:
133
+ encoding: US-ASCII
134
+ string: ''
135
+ headers:
136
+ Content-Type:
137
+ - text/plain
138
+ User-Agent:
139
+ - Swipely/Docker-API 1.4.0
140
+ response:
141
+ status:
142
+ code: 200
143
+ message: ''
144
+ headers:
145
+ !binary "Q29udGVudC1UeXBl":
146
+ - !binary |-
147
+ YXBwbGljYXRpb24vdm5kLmRvY2tlci5yYXctc3RyZWFt
148
+ body:
149
+ encoding: US-ASCII
150
+ string: ''
83
151
  http_version:
84
- recorded_at: Wed, 07 Aug 2013 16:51:14 GMT
85
- recorded_with: VCR 2.4.0
152
+ recorded_at: Fri, 09 Aug 2013 08:50:06 GMT
153
+ recorded_with: VCR 2.5.0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Swipely, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-07 00:00:00.000000000 Z
11
+ date: 2013-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: excon
@@ -171,7 +171,6 @@ files:
171
171
  - lib/docker/container.rb
172
172
  - lib/docker/error.rb
173
173
  - lib/docker/image.rb
174
- - lib/docker/model.rb
175
174
  - lib/docker/util.rb
176
175
  - lib/docker/version.rb
177
176
  - spec/docker/connection_spec.rb
@@ -189,6 +188,7 @@ files:
189
188
  - spec/vcr/Docker_Container/_attach/yields_each_chunk.yml
190
189
  - spec/vcr/Docker_Container/_changes/returns_the_changes_as_an_array.yml
191
190
  - spec/vcr/Docker_Container/_commit/creates_a_new_Image_from_the_Container_s_changes.yml
191
+ - spec/vcr/Docker_Container/_create/when_the_Container_does_not_yet_exist/when_the_HTTP_request_returns_a_200/sets_the_id.yml
192
192
  - spec/vcr/Docker_Container/_create/when_the_Container_does_not_yet_exist_and_the_body_is_a_Hash/when_the_HTTP_request_returns_a_200/sets_the_id.yml
193
193
  - spec/vcr/Docker_Container/_export/yields_each_chunk.yml
194
194
  - spec/vcr/Docker_Container/_json/returns_the_description_as_a_Hash.yml
@@ -254,6 +254,7 @@ test_files:
254
254
  - spec/vcr/Docker_Container/_attach/yields_each_chunk.yml
255
255
  - spec/vcr/Docker_Container/_changes/returns_the_changes_as_an_array.yml
256
256
  - spec/vcr/Docker_Container/_commit/creates_a_new_Image_from_the_Container_s_changes.yml
257
+ - spec/vcr/Docker_Container/_create/when_the_Container_does_not_yet_exist/when_the_HTTP_request_returns_a_200/sets_the_id.yml
257
258
  - spec/vcr/Docker_Container/_create/when_the_Container_does_not_yet_exist_and_the_body_is_a_Hash/when_the_HTTP_request_returns_a_200/sets_the_id.yml
258
259
  - spec/vcr/Docker_Container/_export/yields_each_chunk.yml
259
260
  - spec/vcr/Docker_Container/_json/returns_the_description_as_a_Hash.yml
data/lib/docker/model.rb DELETED
@@ -1,77 +0,0 @@
1
- # This module is intended to be used as a Mixin for all objects exposed by the
2
- # Remote API. Currently, these are limited to Containers and Images.
3
- module Docker::Model
4
- include Docker::Error
5
-
6
- attr_reader :id, :connection
7
-
8
- def self.included(base)
9
- base.class_eval do
10
- extend ClassMethods
11
- private_class_method :new, :request, :set_create_request,
12
- :set_resource_prefix
13
- end
14
- end
15
-
16
- # Creates a new Model with the specified id and Connection. If a Connection
17
- # is specified and it is not a Docker::Connection, a
18
- # Docker::Error::ArgumentError is raised.
19
- def initialize(options = {})
20
- if (options[:connection] ||= Docker.connection).is_a?(Docker::Connection)
21
- @id, @connection = options[:id], options[:connection]
22
- else
23
- raise ArgumentError, 'Expected a Docker::Connection.'
24
- end
25
- end
26
-
27
- def to_s
28
- "#{self.class.name} { :id => #{id}, :connection => #{connection} }"
29
- end
30
-
31
- # This defines the DSL for the including Classes.
32
- module ClassMethods
33
- include Docker::Error
34
- attr_reader :resource_prefix, :create_request
35
-
36
- # Define the Model's prefix for all requests.
37
- def set_resource_prefix(val)
38
- @resource_prefix = val
39
- end
40
-
41
- # Define how the Model should send a create request to the server.
42
- def set_create_request(&block)
43
- @create_request = block
44
- end
45
-
46
- # Define a method named `action` that sends an http `method` request to the
47
- # Docker Server.
48
- def request(method, action, opts = {}, &outer_block)
49
- define_method(action) do |query = nil, &block|
50
- new_opts = {
51
- :path => "#{self.class.resource_prefix}/#{self.id}/#{action}",
52
- :json => true
53
- }.merge(opts)
54
- body = connection.request(method, new_opts[:path], query,
55
- new_opts[:excon], &block)
56
- body = Docker::Util.parse_json(body) if new_opts[:json]
57
- outer_block.nil? ? body : instance_exec(body, &outer_block)
58
- end
59
- end
60
-
61
- # Create a Model with the specified body. Raises a
62
- # Docker::Error::ArgumentError if the argument is not a Hash. Otherwise,
63
- # instances execs the Class's #create_request method with the single
64
- # argument.
65
- def create(opts = {}, conn = Docker.connection)
66
- raise Docker::Error::ArgumentError, 'Expected a Hash' if !opts.is_a?(Hash)
67
- new(:connection => conn).instance_exec(opts, &create_request)
68
- end
69
-
70
- # Retrieve every Instance of a model for the given server.
71
- def all(options = {}, connection = Docker.connection)
72
- path = "#{resource_prefix}/json"
73
- hashes = Docker::Util.parse_json(connection.get(path, options)) || []
74
- hashes.map { |hash| new(:id => hash['Id'], :connection => connection) }
75
- end
76
- end
77
- end