docker-api 1.23.0 → 1.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +1 -1
  3. data/.rspec +1 -0
  4. data/.travis.yml +7 -6
  5. data/Dockerfile +2 -0
  6. data/README.md +5 -5
  7. data/Rakefile +26 -31
  8. data/TESTING.md +7 -19
  9. data/docker-api.gemspec +0 -1
  10. data/lib/docker/image.rb +6 -2
  11. data/lib/docker/version.rb +1 -1
  12. data/spec/docker/container_spec.rb +72 -92
  13. data/spec/docker/event_spec.rb +33 -23
  14. data/spec/docker/exec_spec.rb +9 -24
  15. data/spec/docker/image_spec.rb +75 -81
  16. data/spec/docker_spec.rb +21 -32
  17. metadata +4 -200
  18. data/spec/support/vcr.rb +0 -14
  19. data/spec/vcr/Docker/_authenticate_/with_valid_credentials/logs_in_and_sets_the_creds.yml +0 -32
  20. data/spec/vcr/Docker/_info/returns_the_info_as_a_Hash.yml +0 -39
  21. data/spec/vcr/Docker/_validate_version/when_nothing_is_raised/validate_version_/.yml +0 -39
  22. data/spec/vcr/Docker/_version/returns_the_version_as_a_Hash.yml +0 -34
  23. data/spec/vcr/Docker_Container/_all/when_the_HTTP_response_is_a_200/materializes_each_Container_into_a_Docker_Container.yml +0 -125
  24. data/spec/vcr/Docker_Container/_attach/with_normal_sized_chunks/yields_each_chunk.yml +0 -125
  25. data/spec/vcr/Docker_Container/_attach/with_very_small_chunks/yields_each_chunk.yml +0 -125
  26. data/spec/vcr/Docker_Container/_changes/returns_the_changes_as_an_array.yml +0 -165
  27. data/spec/vcr/Docker_Container/_commit/creates_a_new_Image_from_the_Container_s_changes.yml +0 -165
  28. data/spec/vcr/Docker_Container/_copy/when_the_file_does_not_exist/raises_an_error.yml +0 -136
  29. data/spec/vcr/Docker_Container/_copy/when_the_input_is_a_directory/yields_each_chunk_of_the_tarred_directory.yml +0 -241
  30. data/spec/vcr/Docker_Container/_copy/when_the_input_is_a_file/yields_each_chunk_of_the_tarred_file.yml +0 -198
  31. data/spec/vcr/Docker_Container/_create/when_creating_a_container_named_bob/should_have_name_set_to_bob.yml +0 -84
  32. data/spec/vcr/Docker_Container/_create/when_the_Container_does_not_yet_exist/when_the_HTTP_request_returns_a_200/sets_the_id.yml +0 -55
  33. data/spec/vcr/Docker_Container/_delete/deletes_the_container.yml +0 -85
  34. data/spec/vcr/Docker_Container/_exec/when_detach_is_true/returns_the_Docker_Exec_object.yml +0 -180
  35. data/spec/vcr/Docker_Container/_exec/when_passed_a_block/streams_the_stdout/stderr_messages.yml +0 -183
  36. data/spec/vcr/Docker_Container/_exec/when_passed_only_a_command/returns_the_stdout/stderr_messages_and_exit_code.yml +0 -183
  37. data/spec/vcr/Docker_Container/_exec/when_stdin_object_is_passed/returns_the_stdout/stderr_messages.yml +0 -101
  38. data/spec/vcr/Docker_Container/_exec/when_tty_is_true/returns_the_raw_stdout/stderr_output.yml +0 -182
  39. data/spec/vcr/Docker_Container/_export/yields_each_chunk.yml +0 -333
  40. data/spec/vcr/Docker_Container/_get/when_the_HTTP_response_is_a_200/materializes_the_Container_into_a_Docker_Container.yml +0 -84
  41. data/spec/vcr/Docker_Container/_json/returns_the_description_as_a_Hash.yml +0 -84
  42. data/spec/vcr/Docker_Container/_kill/kills_the_container.yml +0 -164
  43. data/spec/vcr/Docker_Container/_kill/with_a_kill_signal/kills_the_container.yml +0 -257
  44. data/spec/vcr/Docker_Container/_logs/when_not_selecting_any_stream/raises_a_client_error.yml +0 -171
  45. data/spec/vcr/Docker_Container/_logs/when_selecting_stdout/returns_blank_logs.yml +0 -82
  46. data/spec/vcr/Docker_Container/_pause/pauses_the_container.yml +0 -176
  47. data/spec/vcr/Docker_Container/_rename/renames_the_container.yml +0 -149
  48. data/spec/vcr/Docker_Container/_restart/restarts_the_container.yml +0 -243
  49. data/spec/vcr/Docker_Container/_run/when_the_Container_s_command_does_not_return_status_code_of_0/raises_an_error.yml +0 -107
  50. data/spec/vcr/Docker_Container/_run/when_the_Container_s_command_returns_a_status_code_of_0/creates_a_new_container_to_run_the_specified_command.yml +0 -392
  51. data/spec/vcr/Docker_Container/_start/starts_the_container.yml +0 -140
  52. data/spec/vcr/Docker_Container/_stop/stops_the_container.yml +0 -164
  53. data/spec/vcr/Docker_Container/_streaming_logs/when_not_selecting_any_stream/raises_a_client_error.yml +0 -217
  54. data/spec/vcr/Docker_Container/_streaming_logs/when_passing_a_block/returns_hello_.yml +0 -131
  55. data/spec/vcr/Docker_Container/_streaming_logs/when_selecting_stdout/returns_blank_logs.yml +0 -131
  56. data/spec/vcr/Docker_Container/_streaming_logs/when_using_a_tty/returns_hello_.yml +0 -131
  57. data/spec/vcr/Docker_Container/_top/returns_the_top_commands_as_an_Array.yml +0 -194
  58. data/spec/vcr/Docker_Container/_unpause/unpauses_the_container.yml +0 -176
  59. data/spec/vcr/Docker_Container/_wait/waits_for_the_command_to_finish.yml +0 -107
  60. data/spec/vcr/Docker_Container/_wait/when_an_argument_is_given/sets_the_read_timeout_to_that_amount_of_time.yml +0 -107
  61. data/spec/vcr/Docker_Exec/_create/when_the_HTTP_request_returns_a_201/sets_the_id.yml +0 -130
  62. data/spec/vcr/Docker_Exec/_json/returns_the_description_as_a_Hash.yml +0 -207
  63. data/spec/vcr/Docker_Exec/_start_/when_detach_is_set_to_false/block_is_passed/attaches_to_the_stream.yml +0 -182
  64. data/spec/vcr/Docker_Exec/_start_/when_detach_is_set_to_false/returns_the_stdout_and_stderr_messages.yml +0 -182
  65. data/spec/vcr/Docker_Exec/_start_/when_detach_is_set_to_true/returns_empty_stdout/stderr_messages_with_exitcode.yml +0 -180
  66. data/spec/vcr/Docker_Exec/_start_/when_the_HTTP_request_returns_a_201/starts_the_exec_instance.yml +0 -180
  67. data/spec/vcr/Docker_Exec/_start_/when_the_command_has_already_run/raises_an_error.yml +0 -180
  68. data/spec/vcr/Docker_Exec/_start_/when_wait_set_long_time_value/returns_empty_stdout_and_stderr_messages_with_exitcode.yml +0 -189
  69. data/spec/vcr/Docker_Image/_all/materializes_each_Image_into_a_Docker_Image.yml +0 -111
  70. data/spec/vcr/Docker_Image/_build/with_a_valid_Dockerfile/with_a_block_capturing_build_output/calls_the_block_and_passes_build_output.yml +0 -75
  71. data/spec/vcr/Docker_Image/_build/with_a_valid_Dockerfile/with_specifying_a_repo_in_the_query_parameters/builds_an_image_and_tags_it.yml +0 -219
  72. data/spec/vcr/Docker_Image/_build/with_a_valid_Dockerfile/without_query_parameters/builds_an_image.yml +0 -75
  73. data/spec/vcr/Docker_Image/_build/with_an_invalid_Dockerfile/throws_a_UnexpectedResponseError.yml +0 -79
  74. data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_a_block_capturing_build_output/calls_the_block_and_passes_build_output.yml +0 -194
  75. data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_a_block_capturing_build_output/uses_a_cached_version_the_second_time/calls_the_block_and_passes_build_output.yml +0 -96
  76. data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_credentials_passed/sends_X-Registry-Config_header.yml +0 -194
  77. data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_no_query_parameters/builds_the_image.yml +0 -562
  78. data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_specifying_a_repo_in_the_query_parameters/builds_the_image_and_tags_it.yml +0 -601
  79. data/spec/vcr/Docker_Image/_create/when_the_Image_does_not_yet_exist_and_the_body_is_a_Hash/sets_the_id_and_sends_Docker_creds.yml +0 -65
  80. data/spec/vcr/Docker_Image/_create/with_a_block_capturing_create_output/calls_the_block_and_passes_build_output.yml +0 -38
  81. data/spec/vcr/Docker_Image/_exist_/when_the_image_does_exist/returns_true.yml +0 -33
  82. data/spec/vcr/Docker_Image/_get/when_the_image_does_exist/returns_the_new_image.yml +0 -33
  83. data/spec/vcr/Docker_Image/_history/returns_the_history_of_the_Image.yml +0 -66
  84. data/spec/vcr/Docker_Image/_import/when_the_argument_is_a_URI/when_the_URI_is_invalid/raises_an_error.yml +0 -265
  85. data/spec/vcr/Docker_Image/_import/when_the_argument_is_a_URI/when_the_URI_is_valid/returns_an_Image.yml +0 -303
  86. data/spec/vcr/Docker_Image/_import/when_the_file_does_exist/creates_the_Image.yml +0 -59
  87. data/spec/vcr/Docker_Image/_insert_local/when_a_direcory_is_passed/inserts_the_directory.yml +0 -1469
  88. data/spec/vcr/Docker_Image/_insert_local/when_removing_intermediate_containers/creates_a_new_image.yml +0 -244
  89. data/spec/vcr/Docker_Image/_insert_local/when_removing_intermediate_containers/leave_no_intermediate_containers.yml +0 -224
  90. data/spec/vcr/Docker_Image/_insert_local/when_the_local_file_does_exist/creates_a_new_Image_that_has_that_file.yml +0 -289
  91. data/spec/vcr/Docker_Image/_insert_local/when_the_local_file_does_not_exist/raises_an_error.yml +0 -32
  92. data/spec/vcr/Docker_Image/_insert_local/when_there_are_multiple_files_passed/creates_a_new_Image_that_has_each_file.yml +0 -366
  93. data/spec/vcr/Docker_Image/_json/returns_additional_information_about_image_image.yml +0 -62
  94. data/spec/vcr/Docker_Image/_push/pushes_the_Image.yml +0 -246
  95. data/spec/vcr/Docker_Image/_push/streams_output_from_push.yml +0 -246
  96. data/spec/vcr/Docker_Image/_push/when_the_image_was_retrived_by_get/when_no_tag_is_specified/looks_up_the_first_repo_tag.yml +0 -382
  97. data/spec/vcr/Docker_Image/_push/when_there_are_no_credentials/still_pushes.yml +0 -264
  98. data/spec/vcr/Docker_Image/_refresh_/updates_the_info_hash.yml +0 -141
  99. data/spec/vcr/Docker_Image/_refresh_/with_an_explicit_connection/updates_using_the_provided_connection.yml +0 -62
  100. data/spec/vcr/Docker_Image/_remove/when_no_name_is_given/removes_the_Image.yml +0 -652
  101. data/spec/vcr/Docker_Image/_run/when_the_argument_is_a_String/splits_the_String_by_spaces_and_creates_a_new_Container.yml +0 -162
  102. data/spec/vcr/Docker_Image/_run/when_the_argument_is_an_Array/creates_a_new_Container.yml +0 -162
  103. data/spec/vcr/Docker_Image/_run/when_the_argument_is_nil/command_configured_in_image/should_normally_show_result_if_image_has_Cmd_configured.yml +0 -162
  104. data/spec/vcr/Docker_Image/_run/when_the_argument_is_nil/no_command_configured_in_image/should_raise_an_error_if_no_command_is_specified.yml +0 -63
  105. data/spec/vcr/Docker_Image/_save/calls_the_class_method.yml +0 -67
  106. data/spec/vcr/Docker_Image/_save/when_a_filename_is_specified/exports_tarball_of_image_to_specified_file.yml +0 -176
  107. data/spec/vcr/Docker_Image/_save/when_no_filename_is_specified/returns_raw_binary_data_as_string.yml +0 -176
  108. data/spec/vcr/Docker_Image/_search/materializes_each_Image_into_a_Docker_Image.yml +0 -79
  109. data/spec/vcr/Docker_Image/_tag/tags_the_image_with_the_repo_name.yml +0 -88
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fab8042f6b472f3aee3283d18c822fe3b9e7e35d
4
- data.tar.gz: df6af05cba4552155fc735acd2d1754f8c088ac9
3
+ metadata.gz: 7a6840558745f8a4830affbdc1168b007433a797
4
+ data.tar.gz: aa3fbadccdde9a27d4352eea386e7613ee2026ae
5
5
  SHA512:
6
- metadata.gz: aa04e4b157cd1a0e8b2cc881dfd59f4e754cb95dfb89b0cd304b33d3082359982d4131b1e7136edde559351452267c93992fa18dd64664f3daec485556d5fefe
7
- data.tar.gz: c7414e392a8a770888a5c3a44908a732dec432603c0466482b6d07ca4e1935f156ea200f912f75652397625439b4dbc348309444f834db0a39f6f6069c873883
6
+ metadata.gz: af38dc7391984c580435d1180d72baa5235e28983c95b51a6e78b7401ab1818397f08a0ace2ecfaf1fd8da9a5c41966e819f104ef77e9b59743167d94d95697d
7
+ data.tar.gz: 9093e43ab34024974ebeec8b73ceb8427d14455aa49c409c0144c3f9f4030b8945af8288992a209b7504d8fdb5a0ba9a3607c7d0113292b9bade688fd8425d13
data/.cane CHANGED
@@ -1,2 +1,2 @@
1
- --abc-max 17
1
+ --abc-max 19
2
2
  --style-measure 100
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --order rand
data/.travis.yml CHANGED
@@ -1,9 +1,10 @@
1
- sudo: false
1
+ sudo: required
2
+ services:
3
+ - docker
2
4
  cache: bundler
3
5
  language: ruby
4
6
  rvm:
5
- - 1.9.2
6
- - 1.9.3
7
- - 2.0
8
- - 2.1
9
- - 2.2
7
+ - 1.9.3
8
+ - 2.0
9
+ - 2.1
10
+ - 2.2
data/Dockerfile ADDED
@@ -0,0 +1,2 @@
1
+ FROM scratch
2
+ ADD Dockerfile /Dockerfile
data/README.md CHANGED
@@ -387,24 +387,24 @@ container.run('pwd', 10)
387
387
  # => Docker::Image { :id => 4427be4199ac, :connection => Docker::Connection { :url => tcp://localhost, :options => {:port=>2375} } }
388
388
 
389
389
  # Run an Exec instance inside the container and capture its output and exit status
390
- container.exec('date')
390
+ container.exec(['date'])
391
391
  # => [["Wed Nov 26 11:10:30 CST 2014\n"], [], 0]
392
392
 
393
393
  # Launch an Exec instance without capturing its output or status
394
- container.exec('./my_service', detach: true)
394
+ container.exec(['./my_service'], detach: true)
395
395
  # => Docker::Exec { :id => be4eaeb8d28a, :connection => Docker::Connection { :url => tcp://localhost, :options => {:port=>2375} } }
396
396
 
397
397
  # Parse the output of an Exec instance
398
- container.exec('find / -name *') { |stream, chunk| puts "#{stream}: #{chunk}" }
398
+ container.exec(['find', '/', '-name *']) { |stream, chunk| puts "#{stream}: #{chunk}" }
399
399
  stderr: 2013/10/30 17:16:24 Unable to locate find / -name *
400
400
  # => [[], ["2013/10/30 17:16:24 Unable to locate find / -name *\n"], 1]
401
401
 
402
402
  # Run an Exec instance by grab only the STDOUT output
403
- container.exec('date', stderr: false)
403
+ container.exec(['date'], stderr: false)
404
404
  # => [["Wed Nov 26 11:10:30 CST 2014\n"], [], 0]
405
405
 
406
406
  # Pass input to an Exec instance command via Stdin
407
- container.exec('cat', stdin: StringIO.new("foo\nbar\n"))
407
+ container.exec(['cat'], stdin: StringIO.new("foo\nbar\n"))
408
408
  # => [["foo\nbar\n"], [], 0]
409
409
 
410
410
  # Get the raw stream of data from an Exec instance
data/Rakefile CHANGED
@@ -5,7 +5,9 @@ require 'docker'
5
5
  require 'rspec/core/rake_task'
6
6
  require 'cane/rake_task'
7
7
 
8
- task :default => [:spec, :quality]
8
+
9
+ desc 'Run the full test suite from scratch'
10
+ task :default => [:unpack, :rspec, :quality]
9
11
 
10
12
  RSpec::Core::RakeTask.new do |t|
11
13
  t.pattern = 'spec/**/*_spec.rb'
@@ -15,38 +17,31 @@ Cane::RakeTask.new(:quality) do |cane|
15
17
  cane.canefile = '.cane'
16
18
  end
17
19
 
18
- dir = File.expand_path(File.dirname(__FILE__))
19
- namespace :vcr do
20
- desc 'Run the full test suite from scratch'
21
- task :spec => [:unpack, :record]
22
-
23
- desc 'Download the necessary base images'
24
- task :unpack do
25
- %w( registry busybox tianon/true scratch debian:wheezy ).each do |image|
26
- system "docker pull #{image}"
27
- end
20
+ desc 'Download the necessary base images'
21
+ task :unpack do
22
+ %w( swipely/base registry busybox tianon/true debian:wheezy ).each do |image|
23
+ system "docker pull #{image}"
28
24
  end
25
+ end
29
26
 
30
- desc 'Run spec tests and record VCR cassettes'
31
- task :record do
32
- begin
33
- FileUtils.remove_dir("#{dir}/spec/vcr", true)
34
- registry = Docker::Container.create(
35
- 'name' => 'registry',
36
- 'Image' => 'registry',
37
- 'Env' => ["GUNICORN_OPTS=[--preload]"],
38
- 'ExposedPorts' => {
39
- '5000/tcp' => {}
40
- },
41
- 'HostConfig' => {
42
- 'PortBindings' => { '5000/tcp' => [{ 'HostPort' => '5000' }] }
43
- }
44
- )
45
- registry.start
46
- Rake::Task["spec"].invoke
47
- ensure
48
- registry.kill!.remove unless registry.nil?
49
- end
27
+ desc 'Run spec tests with a registry'
28
+ task :rspec do
29
+ begin
30
+ registry = Docker::Container.create(
31
+ 'name' => 'registry',
32
+ 'Image' => 'registry',
33
+ 'Env' => ["GUNICORN_OPTS=[--preload]"],
34
+ 'ExposedPorts' => {
35
+ '5000/tcp' => {}
36
+ },
37
+ 'HostConfig' => {
38
+ 'PortBindings' => { '5000/tcp' => [{ 'HostPort' => '5000' }] }
39
+ }
40
+ )
41
+ registry.start
42
+ Rake::Task["spec"].invoke
43
+ ensure
44
+ registry.kill!.remove unless registry.nil?
50
45
  end
51
46
  end
52
47
 
data/TESTING.md CHANGED
@@ -22,40 +22,28 @@ $ bundle install
22
22
  $ git checkout -b my_bug_fix
23
23
  ```
24
24
  4. Make any changes
25
- 5. Write tests to support those changes.
25
+ 5. Write tests to support those changes.
26
26
  6. Run the tests:
27
- * `bundle exec rake vcr:spec`
27
+ * `bundle exec rake`
28
28
  7. Assuming the tests pass, open a Pull Request on Github.
29
29
 
30
30
  # Using Rakefile Commands
31
31
  This repository comes with five Rake commands to assist in your testing of the code.
32
32
 
33
- ## `rake spec`
34
- This command will run Rspec tests normally on your local system. Be careful that VCR will behave "weirdly" if you currently have the Docker daemon running.
33
+ ## `rake rspec`
34
+ This command will run Rspec tests normally on your local system. You must have all the required base images pulled.
35
35
 
36
36
  ## `rake quality`
37
37
  This command runs a code quality threshold checker to hinder bad code.
38
38
 
39
- ## `rake vcr`
40
- This gem uses [VCR](https://relishapp.com/vcr/vcr) to record and replay HTTP requests made to the Docker API. The `vcr` namespace is used to record and replay spec tests inside of a Docker container. This will allow each developer to run and rerecord VCR cassettes in a consistent environment.
39
+ ## `rake unpack`
40
+ Pulls down all the required base images for testing.
41
41
 
42
42
  ### Setting Up Environment Variables
43
- Certain Rspec tests will require your credentials to the Docker Hub. If you do not have a Docker Hub account, you can sign up for one [here](https://hub.docker.com/account/signup/). To avoid hard-coding credentials into the code the test suite leverages three Environment Variables: `DOCKER_API_USER`, `DOCKER_API_PASS`, and `DOCKER_API_EMAIL`. You will need to configure your work environment (shell profile, IDE, etc) with these values in order to successfully re-record VCR cassettes.
43
+ Certain Rspec tests will require your credentials to the Docker Hub. If you do not have a Docker Hub account, you can sign up for one [here](https://hub.docker.com/account/signup/). To avoid hard-coding credentials into the code the test suite leverages three Environment Variables: `DOCKER_API_USER`, `DOCKER_API_PASS`, and `DOCKER_API_EMAIL`. You will need to configure your work environment (shell profile, IDE, etc) with these values in order to successfully run certain tests.
44
44
 
45
45
  ```shell
46
46
  export DOCKER_API_USER='your_docker_hub_user'
47
47
  export DOCKER_API_PASS='your_docker_hub_password'
48
48
  export DOCKER_API_EMAIL='your_docker_hub_email_address'
49
49
  ```
50
-
51
- ### `rake vcr:spec`
52
- This command will download the necessary Docker images and then run the Rspec tests while recording your VCR cassettes.
53
-
54
- ### `rake vcr:unpack`
55
- This command will download the necessary Docker image.
56
-
57
- ### `rake vcr:record`
58
- This is the command you will use to record a new set of VCR cassettes. This command runs the following procedures:
59
- 1. Delete the existing `spec/vcr` directory.
60
- 2. Launch a temporary local Docker registry
61
- 3. Record new VCR cassettes by running the Rspec test suite against a live Docker daemon.
data/docker-api.gemspec CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |gem|
21
21
  gem.add_development_dependency 'rspec-its'
22
22
  gem.add_development_dependency 'cane'
23
23
  gem.add_development_dependency 'pry'
24
- gem.add_development_dependency 'vcr', '>= 2.7.0'
25
24
  gem.add_development_dependency 'simplecov'
26
25
  gem.add_development_dependency 'webmock'
27
26
  # > 1.3.4 doesn't support ruby 1.9.2
data/lib/docker/image.rb CHANGED
@@ -113,8 +113,12 @@ class Docker::Image
113
113
  :response_block => response_block(body, &block)
114
114
  )
115
115
  json = Docker::Util.fix_json(body)
116
- image = json.reverse_each.find { |el| el && el.key?('id') }
117
- new(conn, 'id' => image && image.fetch('id'), :headers => headers)
116
+ completions = json.compact.select { |j| j['status'] && j['status'].include?('complete') }
117
+ if image = completions.reverse_each.find { |j| j['id'] }
118
+ get(image['id'], {}, conn)
119
+ elsif image = opts['fromImage']
120
+ get(image, {}, conn)
121
+ end
118
122
  end
119
123
 
120
124
  # Return a specific image.
@@ -1,6 +1,6 @@
1
1
  module Docker
2
2
  # The version of the docker-api gem.
3
- VERSION = '1.23.0'
3
+ VERSION = '1.24.0'
4
4
 
5
5
  # The version of the compatible Docker remote API.
6
6
  API_VERSION = '1.16'
@@ -1,7 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- # WARNING if you're re-recording any of these VCRs, you must be running the
4
- # Docker daemon and have the base Image pulled.
5
3
  describe Docker::Container do
6
4
  describe '#to_s' do
7
5
  subject {
@@ -30,7 +28,7 @@ describe Docker::Container do
30
28
  let(:description) { subject.json }
31
29
  after(:each) { subject.remove }
32
30
 
33
- it 'returns the description as a Hash', :vcr do
31
+ it 'returns the description as a Hash' do
34
32
  expect(description).to be_a Hash
35
33
  expect(description['Id']).to start_with(subject.id)
36
34
  end
@@ -49,16 +47,16 @@ describe Docker::Container do
49
47
 
50
48
  context 'when not selecting any stream' do
51
49
  let(:non_destination) { subject.streaming_logs }
52
- it 'raises a client error', :vcr do
50
+ it 'raises a client error' do
53
51
  expect { non_destination }.to raise_error(Docker::Error::ClientError)
54
52
  end
55
53
  end
56
54
 
57
55
  context 'when selecting stdout' do
58
56
  let(:stdout) { subject.streaming_logs(stdout: 1) }
59
- it 'returns blank logs', :vcr do
57
+ it 'returns blank logs' do
60
58
  expect(stdout).to be_a String
61
- expect(stdout).to eq "hello\n"
59
+ expect(stdout).to match("hello")
62
60
  end
63
61
  end
64
62
 
@@ -66,19 +64,19 @@ describe Docker::Container do
66
64
  let(:options) { { 'Tty' => true } }
67
65
 
68
66
  let(:output) { subject.streaming_logs(stdout: 1, tty: 1) }
69
- it 'returns `hello`', :vcr do
67
+ it 'returns `hello`' do
70
68
  expect(output).to be_a(String)
71
- expect(output).to eq("hello\n")
69
+ expect(output).to match("hello")
72
70
  end
73
71
  end
74
72
 
75
73
  context 'when passing a block' do
76
74
  let(:lines) { [] }
77
75
  let(:output) { subject.streaming_logs(stdout: 1, follow: 1) { |s,c| lines << c } }
78
- it 'returns `hello`', :vcr do
76
+ it 'returns `hello`' do
79
77
  expect(output).to be_a(String)
80
- expect(output).to eq("hello\n")
81
- expect(lines).to eq(["hello\n"])
78
+ expect(output).to match("hello")
79
+ expect(lines.join).to match("hello")
82
80
  end
83
81
  end
84
82
  end
@@ -91,14 +89,14 @@ describe Docker::Container do
91
89
 
92
90
  context "when not selecting any stream" do
93
91
  let(:non_destination) { subject.logs }
94
- it 'raises a client error', :vcr do
92
+ it 'raises a client error' do
95
93
  expect { non_destination }.to raise_error(Docker::Error::ClientError)
96
94
  end
97
95
  end
98
96
 
99
97
  context "when selecting stdout" do
100
98
  let(:stdout) { subject.logs(stdout: 1) }
101
- it 'returns blank logs', :vcr do
99
+ it 'returns blank logs' do
102
100
  expect(stdout).to be_a String
103
101
  expect(stdout).to eq ""
104
102
  end
@@ -117,8 +115,8 @@ describe Docker::Container do
117
115
  let(:opts) { {"name" => "bob"} }
118
116
  after(:each) { subject.remove }
119
117
 
120
- it 'should have name set to bob', :vcr do
121
- expect(subject.json["Name"]).to eq "/bob"
118
+ it 'should have name set to bob' do
119
+ expect(subject.json["Name"]).to eq("/bob")
122
120
  end
123
121
  end
124
122
  end
@@ -135,9 +133,9 @@ describe Docker::Container do
135
133
  before { subject.start }
136
134
  after(:each) { subject.kill!.remove }
137
135
 
138
- it 'renames the container', :vcr do
136
+ it 'renames the container' do
139
137
  subject.rename('bar')
140
- expect(subject.json["Name"]).to eq "bar"
138
+ expect(subject.json["Name"]).to eq("/bar")
141
139
  end
142
140
  end
143
141
 
@@ -153,7 +151,7 @@ describe Docker::Container do
153
151
  before { subject.tap(&:start).tap(&:wait) }
154
152
  after(:each) { subject.tap(&:wait).remove }
155
153
 
156
- it 'returns the changes as an array', :vcr do
154
+ it 'returns the changes as an array' do
157
155
  expect(changes).to eq [
158
156
  {
159
157
  "Path" => "/root",
@@ -175,7 +173,7 @@ describe Docker::Container do
175
173
  image.remove
176
174
  end
177
175
 
178
- it 'returns the top commands as an Array', :vcr do
176
+ it 'returns the top commands as an Array' do
179
177
  expect(top).to be_a Array
180
178
  expect(top).to_not be_empty
181
179
  expect(top.first.keys).to include('PID')
@@ -189,15 +187,14 @@ describe Docker::Container do
189
187
  after(:each) { subject.remove }
190
188
 
191
189
  context 'when the file does not exist' do
192
- it 'raises an error', :vcr do
193
- skip 'Docker no longer returns a 500 when the file does not exist'
194
- # expect { subject.copy('/lol/not/a/real/file') { |chunk| puts chunk } }
195
- # .to raise_error
190
+ it 'raises an error' do
191
+ expect { subject.copy('/lol/not/a/real/file') { |chunk| puts chunk } }
192
+ .to raise_error
196
193
  end
197
194
  end
198
195
 
199
196
  context 'when the input is a file' do
200
- it 'yields each chunk of the tarred file', :vcr do
197
+ it 'yields each chunk of the tarred file' do
201
198
  chunks = []
202
199
  subject.copy('/test') { |chunk| chunks << chunk }
203
200
  chunks = chunks.join("\n")
@@ -206,7 +203,7 @@ describe Docker::Container do
206
203
  end
207
204
 
208
205
  context 'when the input is a directory' do
209
- it 'yields each chunk of the tarred directory', :vcr do
206
+ it 'yields each chunk of the tarred directory' do
210
207
  chunks = []
211
208
  subject.copy('/etc/logrotate.d') { |chunk| chunks << chunk }
212
209
  chunks = chunks.join("\n")
@@ -216,12 +213,12 @@ describe Docker::Container do
216
213
  end
217
214
 
218
215
  describe '#export' do
219
- subject { described_class.create('Cmd' => %w[rm -rf / --no-preserve-root],
216
+ subject { described_class.create('Cmd' => %w[/true],
220
217
  'Image' => 'tianon/true') }
221
218
  before { subject.start }
222
219
  after { subject.tap(&:wait).remove }
223
220
 
224
- it 'yields each chunk', :vcr do
221
+ it 'yields each chunk' do
225
222
  first = nil
226
223
  subject.export do |chunk|
227
224
  first ||= chunk
@@ -242,7 +239,7 @@ describe Docker::Container do
242
239
  after(:each) { subject.stop.remove }
243
240
 
244
241
  context 'with normal sized chunks' do
245
- it 'yields each chunk', :vcr do
242
+ it 'yields each chunk' do
246
243
  chunk = nil
247
244
  subject.attach do |stream, c|
248
245
  chunk ||= c
@@ -260,7 +257,7 @@ describe Docker::Container do
260
257
  Docker.options = {}
261
258
  end
262
259
 
263
- it 'yields each chunk', :vcr do
260
+ it 'yields each chunk' do
264
261
  chunk = nil
265
262
  subject.attach do |stream, c|
266
263
  chunk ||= c
@@ -271,11 +268,7 @@ describe Docker::Container do
271
268
  end
272
269
 
273
270
  describe '#attach with stdin' do
274
- # Because this uses HTTP socket hijacking, it is not compatible with
275
- # VCR, so it is currently pending until a good way to test it without
276
- # a running Docker daemon is discovered
277
271
  it 'yields the output' do
278
- skip 'HTTP socket hijacking not compatible with VCR'
279
272
  container = described_class.create(
280
273
  'Cmd' => %w[cat],
281
274
  'Image' => 'debian:wheezy',
@@ -283,9 +276,13 @@ describe Docker::Container do
283
276
  'StdinOnce' => true
284
277
  )
285
278
  chunk = nil
286
- container.attach(stdin: StringIO.new("foo\nbar\n")) do |stream, c|
287
- chunk ||= c
288
- end
279
+ container
280
+ .tap(&:start)
281
+ .attach(stdin: StringIO.new("foo\nbar\n")) do |stream, c|
282
+ chunk ||= c
283
+ end
284
+ container.tap(&:wait).remove
285
+
289
286
  expect(chunk).to eq("foo\nbar\n")
290
287
  end
291
288
  end
@@ -298,12 +295,12 @@ describe Docker::Container do
298
295
  'Volumes' => {'/foo' => {}}
299
296
  )
300
297
  }
301
- let(:all) { Docker::Container.all }
298
+ let(:all) { Docker::Container.all(all: true) }
302
299
 
303
300
  before { subject.start('Binds' => ["/tmp:/foo"]) }
304
301
  after(:each) { subject.remove }
305
302
 
306
- it 'starts the container', :vcr do
303
+ it 'starts the container' do
307
304
  expect(all.map(&:id)).to be_any { |id| id.start_with?(subject.id) }
308
305
  expect(subject.wait(10)['StatusCode']).to be_zero
309
306
  end
@@ -317,7 +314,7 @@ describe Docker::Container do
317
314
  before { subject.tap(&:start).stop('timeout' => '10') }
318
315
  after { subject.remove }
319
316
 
320
- it 'stops the container', :vcr do
317
+ it 'stops the container' do
321
318
  expect(described_class.all(:all => true).map(&:id)).to be_any { |id|
322
319
  id.start_with?(subject.id)
323
320
  }
@@ -339,22 +336,22 @@ describe Docker::Container do
339
336
  context 'when passed only a command' do
340
337
  let(:output) { subject.exec(['bash','-c','sleep 2; echo hello']) }
341
338
 
342
- it 'returns the stdout/stderr messages and exit code', :vcr do
339
+ it 'returns the stdout/stderr messages and exit code' do
343
340
  expect(output).to eq([["hello\n"], [], 0])
344
341
  end
345
342
  end
346
343
 
347
344
  context 'when detach is true' do
348
- let(:output) { subject.exec('date', detach: true) }
345
+ let(:output) { subject.exec(['date'], detach: true) }
349
346
 
350
- it 'returns the Docker::Exec object', :vcr do
347
+ it 'returns the Docker::Exec object' do
351
348
  expect(output).to be_a Docker::Exec
352
349
  expect(output.id).to_not be_nil
353
350
  end
354
351
  end
355
352
 
356
353
  context 'when passed a block' do
357
- it 'streams the stdout/stderr messages', :vcr do
354
+ it 'streams the stdout/stderr messages' do
358
355
  chunk = nil
359
356
  subject.exec(['bash','-c','sleep 2; echo hello']) do |stream, c|
360
357
  chunk ||= c
@@ -364,10 +361,9 @@ describe Docker::Container do
364
361
  end
365
362
 
366
363
  context 'when stdin object is passed' do
367
- let(:output) { subject.exec('cat', stdin: StringIO.new("hello")) }
364
+ let(:output) { subject.exec(['cat'], stdin: StringIO.new("hello")) }
368
365
 
369
- it 'returns the stdout/stderr messages', :vcr do
370
- skip 'HTTP socket hijacking not compatible with VCR'
366
+ it 'returns the stdout/stderr messages' do
371
367
  expect(output).to eq([["hello"],[],0])
372
368
  end
373
369
  end
@@ -379,7 +375,7 @@ describe Docker::Container do
379
375
  ] }
380
376
  let(:output) { subject.exec(command, tty: true) }
381
377
 
382
- it 'returns the raw stdout/stderr output', :vcr do
378
+ it 'returns the raw stdout/stderr output' do
383
379
  expect(output).to eq([["I'm a TTY!"], [], 0])
384
380
  end
385
381
  end
@@ -394,7 +390,7 @@ describe Docker::Container do
394
390
  before { subject.start }
395
391
  after(:each) {subject.remove }
396
392
 
397
- it 'kills the container', :vcr do
393
+ it 'kills the container' do
398
394
  subject.kill
399
395
  expect(described_class.all.map(&:id)).to be_none { |id|
400
396
  id.start_with?(subject.id)
@@ -412,7 +408,7 @@ describe Docker::Container do
412
408
  'trap echo SIGTERM; while [ 1 ]; do echo hello; done'
413
409
  ]
414
410
  }
415
- it 'kills the container', :vcr do
411
+ it 'kills the container' do
416
412
  subject.kill(:signal => "SIGTERM")
417
413
  expect(described_class.all.map(&:id)).to be_any { |id|
418
414
  id.start_with?(subject.id)
@@ -437,7 +433,7 @@ describe Docker::Container do
437
433
  described_class.create('Cmd' => ['ls'], 'Image' => 'debian:wheezy')
438
434
  }
439
435
 
440
- it 'deletes the container', :vcr do
436
+ it 'deletes the container' do
441
437
  subject.delete(:force => true)
442
438
  expect(described_class.all.map(&:id)).to be_none { |id|
443
439
  id.start_with?(subject.id)
@@ -453,7 +449,7 @@ describe Docker::Container do
453
449
  before { subject.start }
454
450
  after { subject.kill!.remove }
455
451
 
456
- it 'restarts the container', :vcr do
452
+ it 'restarts the container' do
457
453
  expect(described_class.all.map(&:id)).to be_any { |id|
458
454
  id.start_with?(subject.id)
459
455
  }
@@ -477,7 +473,7 @@ describe Docker::Container do
477
473
  }
478
474
  after { subject.unpause.kill!.remove }
479
475
 
480
- it 'pauses the container', :vcr do
476
+ it 'pauses the container' do
481
477
  subject.pause
482
478
  expect(described_class.get(subject.id).info['State']['Paused']).to be true
483
479
  end
@@ -493,7 +489,7 @@ describe Docker::Container do
493
489
  before { subject.pause }
494
490
  after { subject.kill!.remove }
495
491
 
496
- it 'unpauses the container', :vcr do
492
+ it 'unpauses the container' do
497
493
  subject.unpause
498
494
  expect(
499
495
  described_class.get(subject.id).info['State']['Paused']
@@ -512,7 +508,7 @@ describe Docker::Container do
512
508
  before { subject.start }
513
509
  after(:each) { subject.remove }
514
510
 
515
- it 'waits for the command to finish', :vcr do
511
+ it 'waits for the command to finish' do
516
512
  expect(subject.wait['StatusCode']).to_not be_zero
517
513
  end
518
514
 
@@ -520,18 +516,16 @@ describe Docker::Container do
520
516
  subject { described_class.create('Cmd' => %w[sleep 5],
521
517
  'Image' => 'debian:wheezy') }
522
518
 
523
- it 'sets the :read_timeout to that amount of time', :vcr do
519
+ it 'sets the :read_timeout to that amount of time' do
524
520
  expect(subject.wait(6)['StatusCode']).to be_zero
525
521
  end
526
522
 
527
- # context 'and a command runs for too long' do
528
- # after(:each) { subject.remove }
529
- #
530
- # it 'raises a ServerError', :vcr do
531
- # skip "VCR doesn't like to record errors"
532
- # expect{subject.wait(4)}.to raise_error(Docker::Error::TimeoutError)
533
- # end
534
- # end
523
+ context 'and a command runs for too long' do
524
+ it 'raises a ServerError' do
525
+ expect{subject.wait(4)}.to raise_error(Docker::Error::TimeoutError)
526
+ subject.tap(&:wait)
527
+ end
528
+ end
535
529
  end
536
530
  end
537
531
 
@@ -546,7 +540,7 @@ describe Docker::Container do
546
540
  subject.remove
547
541
  end
548
542
 
549
- it 'raises an error', :vcr do
543
+ it 'raises an error' do
550
544
  expect { run_command }
551
545
  .to raise_error(Docker::Error::UnexpectedResponseError)
552
546
  end
@@ -565,7 +559,7 @@ describe Docker::Container do
565
559
  end
566
560
  end
567
561
 
568
- it 'creates a new container to run the specified command', :vcr do
562
+ it 'creates a new container to run the specified command' do
569
563
  expect(run_command.wait['StatusCode']).to be_zero
570
564
  end
571
565
  end
@@ -582,22 +576,23 @@ describe Docker::Container do
582
576
  image.remove
583
577
  end
584
578
 
585
- it 'creates a new Image from the Container\'s changes', :vcr do
579
+ it 'creates a new Image from the Container\'s changes' do
586
580
  subject.tap(&:start).wait
587
581
 
588
582
  expect(image).to be_a Docker::Image
589
583
  expect(image.id).to_not be_nil
590
584
  end
591
585
 
592
- # context 'if run is passed, it saves the command in the image', :vcr do
593
- # let(:image) { subject.commit }
594
- #
595
- # it 'saves the command' do
596
- # skip 'This is no longer working in v0.8'
597
- # expect(image.run('pwd').attach).to eql [["/\n"],[]]
598
- # end
599
- # end
586
+ context 'if run is passed, it saves the command in the image' do
587
+ let(:image) { subject.commit }
588
+ let(:container) { image.run('pwd') }
600
589
 
590
+ it 'saves the command' do
591
+ container.wait
592
+ expect(container.attach(logs: true, stream: false)).to eql [["/\n"],[]]
593
+ container.remove
594
+ end
595
+ end
601
596
  end
602
597
 
603
598
  describe '.create' do
@@ -622,29 +617,14 @@ describe Docker::Container do
622
617
  context 'when the HTTP request returns a 200' do
623
618
  let(:options) do
624
619
  {
625
- "Hostname" => "",
626
- "User" => "",
627
- "Memory" => 0,
628
- "MemorySwap" => 0,
629
- "AttachStdin" => false,
630
- "AttachStdout" => false,
631
- "AttachStderr" => false,
632
- "PortSpecs" => nil,
633
- "Tty" => false,
634
- "OpenStdin" => false,
635
- "StdinOnce" => false,
636
- "Env" => nil,
637
620
  "Cmd" => ["date"],
638
- "Dns" => nil,
639
621
  "Image" => "debian:wheezy",
640
- "Volumes" => {},
641
- "VolumesFrom" => ""
642
622
  }
643
623
  end
644
624
  let(:container) { subject.create(options) }
645
625
  after { container.remove }
646
626
 
647
- it 'sets the id', :vcr do
627
+ it 'sets the id' do
648
628
  expect(container).to be_a Docker::Container
649
629
  expect(container.id).to_not be_nil
650
630
  expect(container.connection).to_not be_nil
@@ -678,7 +658,7 @@ describe Docker::Container do
678
658
  }
679
659
  after { container.remove }
680
660
 
681
- it 'materializes the Container into a Docker::Container', :vcr do
661
+ it 'materializes the Container into a Docker::Container' do
682
662
  expect(subject.get(container.id)).to be_a Docker::Container
683
663
  end
684
664
  end
@@ -711,7 +691,7 @@ describe Docker::Container do
711
691
  before { container }
712
692
  after { container.remove }
713
693
 
714
- it 'materializes each Container into a Docker::Container', :vcr do
694
+ it 'materializes each Container into a Docker::Container' do
715
695
  expect(subject.all(:all => true)).to be_all { |container|
716
696
  container.is_a?(Docker::Container)
717
697
  }