diff --git a/lib/docker/image.rb b/lib/docker/image.rb index dc923138f..f9ef3830a 100644 --- a/lib/docker/image.rb +++ b/lib/docker/image.rb @@ -192,15 +192,15 @@ def build_from_dir(dir, opts = {}, connection = Docker.connection, private - # A method to build auth headers and merge them into headers sent - # by build_from_dir. + # A method to build the config header and merge it into the + # headers sent by build_from_dir. def self.build_headers(creds) credentials = creds || Docker.creds || {} - auth_header = Docker::Util.build_auth_header(credentials.to_json) + config_header = Docker::Util.build_config_header(credentials) headers = { 'Content-Type' => 'application/tar', 'Transfer-Encoding' => 'chunked' } - headers = headers.merge(auth_header) if auth_header + headers = headers.merge(config_header) if config_header headers end diff --git a/lib/docker/util.rb b/lib/docker/util.rb index 5c127708b..78ac137a1 100644 --- a/lib/docker/util.rb +++ b/lib/docker/util.rb @@ -77,8 +77,28 @@ def build_auth_header(credentials) credentials = credentials.to_json if credentials.is_a?(Hash) encoded_creds = Base64.encode64(credentials).gsub(/\n/, '') { - 'X-Registry-Auth' => encoded_creds, - 'X-Registry-Config' => encoded_creds, + 'X-Registry-Auth' => encoded_creds + } + end + + def build_config_header(credentials) + if credentials.is_a?(String) + credentials = JSON.parse(credentials, symbolize_names: true) + end + header = { + "configs" => { + credentials[:serveraddress].to_s => { + "username" => credentials[:username].to_s, + "password" => credentials[:password].to_s, + "email" => credentials[:email].to_s + } + } + }.to_json + + encoded_header = Base64.encode64(header).gsub(/\n/, '') + + { + 'X-Registry-Config' => encoded_header } end end diff --git a/spec/docker/image_spec.rb b/spec/docker/image_spec.rb index 6ba224715..82d93f665 100644 --- a/spec/docker/image_spec.rb +++ b/spec/docker/image_spec.rb @@ -455,14 +455,15 @@ { :username => 'nahiluhmot', :password => '*********', - :email => 'hulihan.tom159@gmail.com' + :email => 'hulihan.tom159@gmail.com', + :serveraddress => 'https://index.docker.io/v1' } } before { Docker.creds = creds } - it 'sends Docker.creds', :vcr do - expect(image.info[:headers].keys).to include('X-Registry-Auth') + it 'sends X-Registry-Config header', :vcr do + expect(image.info[:headers].keys).to include('X-Registry-Config') end end end diff --git a/spec/docker/util_spec.rb b/spec/docker/util_spec.rb index 6c3e87c35..4fa2e77ae 100644 --- a/spec/docker/util_spec.rb +++ b/spec/docker/util_spec.rb @@ -86,17 +86,16 @@ } let(:credential_string) { credentials.to_json } let(:encoded_creds) { Base64.encode64(credential_string).gsub(/\n/, '') } - let(:expected_headers) { + let(:expected_header) { { - 'X-Registry-Auth' => encoded_creds, - 'X-Registry-Config' => encoded_creds + 'X-Registry-Auth' => encoded_creds } } context 'given credentials as a Hash' do it 'returns an X-Registry-Auth header encoded' do - expect(subject.build_auth_header(credentials)).to eq(expected_headers) + expect(subject.build_auth_header(credentials)).to eq(expected_header) end end @@ -104,7 +103,53 @@ it 'returns an X-Registry-Auth header encoded' do expect( subject.build_auth_header(credential_string) - ).to eq(expected_headers) + ).to eq(expected_header) + end + end + end + + describe '.build_config_header' do + subject { described_class } + + let(:credentials) { + { + :username => 'test', + :password => 'password', + :email => 'test@example.com', + :serveraddress => 'https://registry.com/' + } + } + + let(:credentials_object) { + { + :configs => { + :'https://registry.com/' => { + :username => 'test', + :password => 'password', + :email => 'test@example.com', + } + } + }.to_json + } + + let(:encoded_creds) { Base64.encode64(credentials_object).gsub(/\n/, '') } + let(:expected_header) { + { + 'X-Registry-Config' => encoded_creds + } + } + + context 'given credentials as a Hash' do + it 'returns an X-Registry-Config header encoded' do + expect(subject.build_config_header(credentials)).to eq(expected_header) + end + end + + context 'given credentials as a String' do + it 'returns an X-Registry-Config header encoded' do + expect( + subject.build_config_header(credentials.to_json) + ).to eq(expected_header) end end end diff --git a/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_credentials_passed/sends_X-Registry-Config_header.yml b/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_credentials_passed/sends_X-Registry-Config_header.yml new file mode 100644 index 000000000..91a878552 --- /dev/null +++ b/spec/vcr/Docker_Image/_build_from_dir/with_a_valid_Dockerfile/with_credentials_passed/sends_X-Registry-Config_header.yml @@ -0,0 +1,39 @@ +--- +http_interactions: +- request: + method: post + uri: unix:///var/run/docker.sock/v1.12/build + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Swipely/Docker-API 1.13.1 + Content-Type: + - application/tar + Transfer-Encoding: + - chunked + X-Registry-Config: + - eyJjb25maWdzIjp7Imh0dHBzOi8vaW5kZXguZG9ja2VyLmlvL3YxIjp7InVzZXJuYW1lIjoibmFoaWx1aG1vdCIsInBhc3N3b3JkIjoiKioqKioqKioqIiwiZW1haWwiOiJodWxpaGFuLnRvbTE1OUBnbWFpbC5jb20ifX19 + response: + status: + code: 200 + message: + headers: + Content-Type: + - application/json + Date: + - Mon, 21 Jul 2014 17:07:50 GMT + Connection: + - close + Transfer-Encoding: + - '' + body: + encoding: US-ASCII + string: ! "{\"stream\":\"Step 0 : from base\\n\"}\r\n{\"stream\":\" ---\\u003e + b750fe79269d\\n\"}\r\n{\"stream\":\"Step 1 : add / /\\n\"}\r\n{\"stream\":\" + ---\\u003e 282d877698a4\\n\"}\r\n{\"stream\":\"Removing intermediate container + f76554ba0d24\\n\"}\r\n{\"stream\":\"Successfully built 282d877698a4\\n\"}\r\n" + http_version: + recorded_at: Mon, 21 Jul 2014 17:07:53 GMT +recorded_with: VCR 2.9.2