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.
- checksums.yaml +4 -4
- data/.cane +1 -1
- data/.rspec +1 -0
- data/.travis.yml +7 -6
- data/Dockerfile +2 -0
- data/README.md +5 -5
- data/Rakefile +26 -31
- data/TESTING.md +7 -19
- data/docker-api.gemspec +0 -1
- data/lib/docker/image.rb +6 -2
- data/lib/docker/version.rb +1 -1
- data/spec/docker/container_spec.rb +72 -92
- data/spec/docker/event_spec.rb +33 -23
- data/spec/docker/exec_spec.rb +9 -24
- data/spec/docker/image_spec.rb +75 -81
- data/spec/docker_spec.rb +21 -32
- metadata +4 -200
- data/spec/support/vcr.rb +0 -14
- data/spec/vcr/Docker/_authenticate_/with_valid_credentials/logs_in_and_sets_the_creds.yml +0 -32
- data/spec/vcr/Docker/_info/returns_the_info_as_a_Hash.yml +0 -39
- data/spec/vcr/Docker/_validate_version/when_nothing_is_raised/validate_version_/.yml +0 -39
- data/spec/vcr/Docker/_version/returns_the_version_as_a_Hash.yml +0 -34
- data/spec/vcr/Docker_Container/_all/when_the_HTTP_response_is_a_200/materializes_each_Container_into_a_Docker_Container.yml +0 -125
- data/spec/vcr/Docker_Container/_attach/with_normal_sized_chunks/yields_each_chunk.yml +0 -125
- data/spec/vcr/Docker_Container/_attach/with_very_small_chunks/yields_each_chunk.yml +0 -125
- data/spec/vcr/Docker_Container/_changes/returns_the_changes_as_an_array.yml +0 -165
- data/spec/vcr/Docker_Container/_commit/creates_a_new_Image_from_the_Container_s_changes.yml +0 -165
- data/spec/vcr/Docker_Container/_copy/when_the_file_does_not_exist/raises_an_error.yml +0 -136
- data/spec/vcr/Docker_Container/_copy/when_the_input_is_a_directory/yields_each_chunk_of_the_tarred_directory.yml +0 -241
- data/spec/vcr/Docker_Container/_copy/when_the_input_is_a_file/yields_each_chunk_of_the_tarred_file.yml +0 -198
- data/spec/vcr/Docker_Container/_create/when_creating_a_container_named_bob/should_have_name_set_to_bob.yml +0 -84
- 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
- data/spec/vcr/Docker_Container/_delete/deletes_the_container.yml +0 -85
- data/spec/vcr/Docker_Container/_exec/when_detach_is_true/returns_the_Docker_Exec_object.yml +0 -180
- data/spec/vcr/Docker_Container/_exec/when_passed_a_block/streams_the_stdout/stderr_messages.yml +0 -183
- data/spec/vcr/Docker_Container/_exec/when_passed_only_a_command/returns_the_stdout/stderr_messages_and_exit_code.yml +0 -183
- data/spec/vcr/Docker_Container/_exec/when_stdin_object_is_passed/returns_the_stdout/stderr_messages.yml +0 -101
- data/spec/vcr/Docker_Container/_exec/when_tty_is_true/returns_the_raw_stdout/stderr_output.yml +0 -182
- data/spec/vcr/Docker_Container/_export/yields_each_chunk.yml +0 -333
- data/spec/vcr/Docker_Container/_get/when_the_HTTP_response_is_a_200/materializes_the_Container_into_a_Docker_Container.yml +0 -84
- data/spec/vcr/Docker_Container/_json/returns_the_description_as_a_Hash.yml +0 -84
- data/spec/vcr/Docker_Container/_kill/kills_the_container.yml +0 -164
- data/spec/vcr/Docker_Container/_kill/with_a_kill_signal/kills_the_container.yml +0 -257
- data/spec/vcr/Docker_Container/_logs/when_not_selecting_any_stream/raises_a_client_error.yml +0 -171
- data/spec/vcr/Docker_Container/_logs/when_selecting_stdout/returns_blank_logs.yml +0 -82
- data/spec/vcr/Docker_Container/_pause/pauses_the_container.yml +0 -176
- data/spec/vcr/Docker_Container/_rename/renames_the_container.yml +0 -149
- data/spec/vcr/Docker_Container/_restart/restarts_the_container.yml +0 -243
- data/spec/vcr/Docker_Container/_run/when_the_Container_s_command_does_not_return_status_code_of_0/raises_an_error.yml +0 -107
- 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
- data/spec/vcr/Docker_Container/_start/starts_the_container.yml +0 -140
- data/spec/vcr/Docker_Container/_stop/stops_the_container.yml +0 -164
- data/spec/vcr/Docker_Container/_streaming_logs/when_not_selecting_any_stream/raises_a_client_error.yml +0 -217
- data/spec/vcr/Docker_Container/_streaming_logs/when_passing_a_block/returns_hello_.yml +0 -131
- data/spec/vcr/Docker_Container/_streaming_logs/when_selecting_stdout/returns_blank_logs.yml +0 -131
- data/spec/vcr/Docker_Container/_streaming_logs/when_using_a_tty/returns_hello_.yml +0 -131
- data/spec/vcr/Docker_Container/_top/returns_the_top_commands_as_an_Array.yml +0 -194
- data/spec/vcr/Docker_Container/_unpause/unpauses_the_container.yml +0 -176
- data/spec/vcr/Docker_Container/_wait/waits_for_the_command_to_finish.yml +0 -107
- data/spec/vcr/Docker_Container/_wait/when_an_argument_is_given/sets_the_read_timeout_to_that_amount_of_time.yml +0 -107
- data/spec/vcr/Docker_Exec/_create/when_the_HTTP_request_returns_a_201/sets_the_id.yml +0 -130
- data/spec/vcr/Docker_Exec/_json/returns_the_description_as_a_Hash.yml +0 -207
- data/spec/vcr/Docker_Exec/_start_/when_detach_is_set_to_false/block_is_passed/attaches_to_the_stream.yml +0 -182
- data/spec/vcr/Docker_Exec/_start_/when_detach_is_set_to_false/returns_the_stdout_and_stderr_messages.yml +0 -182
- data/spec/vcr/Docker_Exec/_start_/when_detach_is_set_to_true/returns_empty_stdout/stderr_messages_with_exitcode.yml +0 -180
- data/spec/vcr/Docker_Exec/_start_/when_the_HTTP_request_returns_a_201/starts_the_exec_instance.yml +0 -180
- data/spec/vcr/Docker_Exec/_start_/when_the_command_has_already_run/raises_an_error.yml +0 -180
- data/spec/vcr/Docker_Exec/_start_/when_wait_set_long_time_value/returns_empty_stdout_and_stderr_messages_with_exitcode.yml +0 -189
- data/spec/vcr/Docker_Image/_all/materializes_each_Image_into_a_Docker_Image.yml +0 -111
- 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
- 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
- data/spec/vcr/Docker_Image/_build/with_a_valid_Dockerfile/without_query_parameters/builds_an_image.yml +0 -75
- data/spec/vcr/Docker_Image/_build/with_an_invalid_Dockerfile/throws_a_UnexpectedResponseError.yml +0 -79
- 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
- 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
- data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_credentials_passed/sends_X-Registry-Config_header.yml +0 -194
- data/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_no_query_parameters/builds_the_image.yml +0 -562
- 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
- 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
- data/spec/vcr/Docker_Image/_create/with_a_block_capturing_create_output/calls_the_block_and_passes_build_output.yml +0 -38
- data/spec/vcr/Docker_Image/_exist_/when_the_image_does_exist/returns_true.yml +0 -33
- data/spec/vcr/Docker_Image/_get/when_the_image_does_exist/returns_the_new_image.yml +0 -33
- data/spec/vcr/Docker_Image/_history/returns_the_history_of_the_Image.yml +0 -66
- data/spec/vcr/Docker_Image/_import/when_the_argument_is_a_URI/when_the_URI_is_invalid/raises_an_error.yml +0 -265
- data/spec/vcr/Docker_Image/_import/when_the_argument_is_a_URI/when_the_URI_is_valid/returns_an_Image.yml +0 -303
- data/spec/vcr/Docker_Image/_import/when_the_file_does_exist/creates_the_Image.yml +0 -59
- data/spec/vcr/Docker_Image/_insert_local/when_a_direcory_is_passed/inserts_the_directory.yml +0 -1469
- data/spec/vcr/Docker_Image/_insert_local/when_removing_intermediate_containers/creates_a_new_image.yml +0 -244
- data/spec/vcr/Docker_Image/_insert_local/when_removing_intermediate_containers/leave_no_intermediate_containers.yml +0 -224
- data/spec/vcr/Docker_Image/_insert_local/when_the_local_file_does_exist/creates_a_new_Image_that_has_that_file.yml +0 -289
- data/spec/vcr/Docker_Image/_insert_local/when_the_local_file_does_not_exist/raises_an_error.yml +0 -32
- data/spec/vcr/Docker_Image/_insert_local/when_there_are_multiple_files_passed/creates_a_new_Image_that_has_each_file.yml +0 -366
- data/spec/vcr/Docker_Image/_json/returns_additional_information_about_image_image.yml +0 -62
- data/spec/vcr/Docker_Image/_push/pushes_the_Image.yml +0 -246
- data/spec/vcr/Docker_Image/_push/streams_output_from_push.yml +0 -246
- 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
- data/spec/vcr/Docker_Image/_push/when_there_are_no_credentials/still_pushes.yml +0 -264
- data/spec/vcr/Docker_Image/_refresh_/updates_the_info_hash.yml +0 -141
- data/spec/vcr/Docker_Image/_refresh_/with_an_explicit_connection/updates_using_the_provided_connection.yml +0 -62
- data/spec/vcr/Docker_Image/_remove/when_no_name_is_given/removes_the_Image.yml +0 -652
- 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
- data/spec/vcr/Docker_Image/_run/when_the_argument_is_an_Array/creates_a_new_Container.yml +0 -162
- 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
- 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
- data/spec/vcr/Docker_Image/_save/calls_the_class_method.yml +0 -67
- data/spec/vcr/Docker_Image/_save/when_a_filename_is_specified/exports_tarball_of_image_to_specified_file.yml +0 -176
- data/spec/vcr/Docker_Image/_save/when_no_filename_is_specified/returns_raw_binary_data_as_string.yml +0 -176
- data/spec/vcr/Docker_Image/_search/materializes_each_Image_into_a_Docker_Image.yml +0 -79
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a6840558745f8a4830affbdc1168b007433a797
|
4
|
+
data.tar.gz: aa3fbadccdde9a27d4352eea386e7613ee2026ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af38dc7391984c580435d1180d72baa5235e28983c95b51a6e78b7401ab1818397f08a0ace2ecfaf1fd8da9a5c41966e819f104ef77e9b59743167d94d95697d
|
7
|
+
data.tar.gz: 9093e43ab34024974ebeec8b73ceb8427d14455aa49c409c0144c3f9f4030b8945af8288992a209b7504d8fdb5a0ba9a3607c7d0113292b9bade688fd8425d13
|
data/.cane
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
--abc-max
|
1
|
+
--abc-max 19
|
2
2
|
--style-measure 100
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--order rand
|
data/.travis.yml
CHANGED
data/Dockerfile
ADDED
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
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
'
|
39
|
-
|
40
|
-
|
41
|
-
'
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
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
|
34
|
-
This command will run Rspec tests normally on your local system.
|
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
|
40
|
-
|
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
|
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
|
-
|
117
|
-
|
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.
|
data/lib/docker/version.rb
CHANGED
@@ -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'
|
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'
|
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'
|
57
|
+
it 'returns blank logs' do
|
60
58
|
expect(stdout).to be_a String
|
61
|
-
expect(stdout).to
|
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`'
|
67
|
+
it 'returns `hello`' do
|
70
68
|
expect(output).to be_a(String)
|
71
|
-
expect(output).to
|
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`'
|
76
|
+
it 'returns `hello`' do
|
79
77
|
expect(output).to be_a(String)
|
80
|
-
expect(output).to
|
81
|
-
expect(lines).to
|
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'
|
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'
|
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'
|
121
|
-
expect(subject.json["Name"]).to eq
|
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'
|
136
|
+
it 'renames the container' do
|
139
137
|
subject.rename('bar')
|
140
|
-
expect(subject.json["Name"]).to eq
|
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'
|
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'
|
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'
|
193
|
-
|
194
|
-
|
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'
|
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'
|
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[
|
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'
|
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'
|
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'
|
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
|
287
|
-
|
288
|
-
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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'
|
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
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
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'
|
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'
|
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'
|
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
|
-
|
593
|
-
|
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'
|
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'
|
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'
|
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
|
}
|