dockerapi 0.13.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0dac991f7f237b1df6314bae40e54a5f44175186bbbb6756184c65862bb9f652
4
- data.tar.gz: 604ea213a309219a91b6923e89e8003eb030fff51d22104e8c689872264ebd59
3
+ metadata.gz: 4117775ffcd9a7ba657bbea943fd20e52de1907fcf3174850a48b8ede27a7acf
4
+ data.tar.gz: 6d7a725d087401b8d1a2806e6deee5066ed6ad3bc8f195ffcda1321b3fc2252b
5
5
  SHA512:
6
- metadata.gz: d5f2eb58e059da1f60de416b07902e538ad707ec1a95a4efb665073d3b54a3ab74ea101144f9cea51effd50610ece9e0011061c653d848855885399bcb6b1cdd
7
- data.tar.gz: 98e253a61bd7c2ff36df30f9e3557d4c502e10e206c7b5a32d2969e9ec996151741a5bda5a46ef32426905236228caaba57485250a7f7561fb98cd2181052b86
6
+ metadata.gz: 158707ec44efb0d7ac3123e988c670af94cd9ad054bf47dfbf6d75c2ffd516f87f85296f9732a98213913e1b827dc3de582fff7fabc25f4c359c50f704b6f1ea
7
+ data.tar.gz: 62b262e3d7fcffaaa1cec28f6dd9246619abfecfcd88b85fd90e2f18fc46806135fc17c149dc26e5a5687b4e426b5a98ad60e87b8763af4949f096280d3b229c
@@ -0,0 +1,35 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ - name: Set up Ruby
24
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
25
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
26
+ # uses: ruby/setup-ruby@v1
27
+ uses: ruby/setup-ruby@21351ecc0a7c196081abca5dc55b08f085efe09a
28
+ with:
29
+ ruby-version: 2.6
30
+ - name: Install Docker
31
+ run: curl https://get.docker.com | sh
32
+ - name: Install dependencies
33
+ run: bin/setup && sudo bin/setup
34
+ - name: Run tests
35
+ run: rake spec
data/.gitignore CHANGED
@@ -9,3 +9,7 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ resources/registry_authentication/*.key
14
+ resources/registry_authentication/*.crt
15
+ resources/registry_authentication/htpasswd
@@ -1,3 +1,38 @@
1
+ # 0.18.0
2
+
3
+ Method `Docker::API::Image#distribution` now accepts authentication parameters. Feature introduced in [PR#3](https://github.com/nu12/dockerapi/pull/3)
4
+
5
+ Contributors: @zarqman
6
+
7
+ # 0.17.0
8
+
9
+ New block execution introduced in [PR#1](https://github.com/nu12/dockerapi/pull/1).
10
+
11
+ Contributors: @zarqman
12
+
13
+ # 0.16.0
14
+
15
+ `Docker::API::Task#logs` method can now receive a block to replace standard output to stdout behavior.
16
+
17
+ Add `auth_encoder` to provide standard implementation for the authentication header where needed.
18
+
19
+ # 0.15.0
20
+
21
+ `Docker::API::System#events` and `Docker::API::Exec#start` methods can now receive a block to replace standard output to stdout behavior.
22
+
23
+ General refactoring and API documentation.
24
+
25
+ # 0.14.0
26
+
27
+ Method `Docker::API::Container#archive` is splitted in `#get_archive` and `#put_archive` as per Docker API documentation.
28
+
29
+ The following `Docker::API::Container` methods that can now receive a block:
30
+ * logs (output to stdout)
31
+ * attach (output to stdout)
32
+ * stats (output to stdout)
33
+ * export (write file)
34
+ * get_archive (write file)
35
+
1
36
  # 0.13.0
2
37
 
3
38
  Add default behavior for file read, write and output to stdout. Whenever a method can receive a block, this default behavior can be replaced.
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dockerapi (0.13.0)
5
- excon (~> 0.74.0)
4
+ dockerapi (0.18.0)
5
+ excon (~> 0.76)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  diff-lcs (1.3)
11
- excon (0.74.0)
11
+ excon (0.76.0)
12
12
  rake (12.3.3)
13
13
  rspec (3.9.0)
14
14
  rspec-core (~> 3.9.0)
data/README.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # dockerapi
2
2
 
3
- Interact directly with Docker API from Ruby code.
3
+ Interact with Docker API directly from Ruby code. Comprehensive implementation (all available endpoints), no local Docker installation required, easily manipulated http responses.
4
+
5
+ * [Installation](#installation)
6
+ * [Usage](#usage)
7
+ * [Images](#images)
8
+ * [Containers](#containers)
9
+ * [Volumes](#volumes)
10
+ * [Network](#network)
11
+ * [System](#system)
12
+ * [Exec](#exec)
13
+ * [Swarm](#swarm)
14
+ * [Node](#node)
15
+ * [Service](#service)
16
+ * [Task](#task)
17
+ * [Secret](#secret)
18
+ * [Config](#config)
19
+ * [Plugin](#plugin)
20
+ * [Connection](#connection)
21
+ * [Requests](#requests)
22
+ * [Response](#response)
23
+ * [Error handling](#error-handling)
24
+ * [Blocks](#blocks)
25
+ * [Development](#development)
26
+ * [Contributing](#contributing)
27
+ * [License](#license)
4
28
 
5
29
  ## Installation
6
30
 
@@ -8,6 +32,8 @@ Add this line to your application's Gemfile:
8
32
 
9
33
  ```ruby
10
34
  gem 'dockerapi'
35
+ # or
36
+ gem 'dockerapi', github: 'nu12/dockerapi'
11
37
  ```
12
38
 
13
39
  And then execute:
@@ -20,6 +46,12 @@ Or install it yourself as:
20
46
 
21
47
  ## Usage
22
48
 
49
+ The following section will bring you up to speed in order to use most this gem resources with pratical examples.
50
+
51
+ If you need more information about the different Docker API endpoints, please see the [Docker API documentation](https://docs.docker.com/engine/api/v1.40/).
52
+
53
+ For a more detailed and comprehensive documentation about this gem's API, please see the [documentation page](https://rubydoc.info/gems/dockerapi).
54
+
23
55
  ### Images
24
56
 
25
57
  ```ruby
@@ -46,6 +78,7 @@ image.details("image")
46
78
 
47
79
  # Return image digest and platform information by contacting the registry.
48
80
  image.distribution("image")
81
+ image.distribution("image", {username: "janedoe", password: "password"}) # private repository
49
82
 
50
83
  # History
51
84
  image.history("image")
@@ -62,7 +95,7 @@ image.tag("current:tag", repo: "new", tag: "tag")
62
95
  # Push image
63
96
  image.push("repo:tag") # to dockerhub
64
97
  image.push("localhost:5000/repo:tag") # to local registry
65
- image.push("private/repo", {tag: "tag"}, {username: "janedoe", password: "password"} # to private repository
98
+ image.push("private/repo", {tag: "tag"}, {username: "janedoe", password: "password"}) # to private repository
66
99
 
67
100
  # Remove image
68
101
  image.remove("image")
@@ -151,7 +184,10 @@ container.stats("nginx", stream: true)
151
184
  container.export("nginx", "~/exported_container")
152
185
 
153
186
  # Get files from container
154
- container.archive("nginx", "~/html.tar", path: "/usr/share/nginx/html/")
187
+ container.get_archive("nginx", "~/html.tar", path: "/usr/share/nginx/html/")
188
+
189
+ # Send files to container
190
+ container.put_archive("nginx", "~/html.tar", path: "/usr/share/nginx/html/")
155
191
 
156
192
  # Stop container
157
193
  container.stop("nginx")
@@ -499,32 +535,46 @@ response.success?
499
535
 
500
536
  To completely skip the validation process, add `:skip_validation => true` in the hash to be validated.
501
537
 
538
+ ### Blocks
539
+
540
+ Some methods can receive a block to alter the default execution:
541
+ * Docker::API::Container#logs
542
+ * Docker::API::Container#attach
543
+ * Docker::API::Container#stats
544
+ * Docker::API::Container#export
545
+ * Docker::API::Container#get_archive
546
+ * Docker::API::Image#create
547
+ * Docker::API::Image#build
548
+ * Docker::API::Image#export
549
+ * Docker::API::System#event
550
+ * Docker::API::Exec#start
551
+ * Docker::API::Task#logs
552
+
553
+ Example:
554
+ ```ruby
555
+ => image = Docker::API::Image.new
556
+
557
+ => image.create(fromImage: "nginx:alpine") do | chunk, bytes_remaining, bytes_total |
558
+ p chunk.to_s
559
+ end
560
+ ```
561
+
562
+ The default blocks can be found in `Docker::API::Base`.
563
+
502
564
  ## Development
503
565
 
504
566
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
505
567
 
506
568
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
507
569
 
508
- ### Road to 1.0.0
509
-
510
- | Class | Tests | Implementation | Refactoring |
511
- |---|---|---|---|
512
- | Image | Ok | Ok | Ok |
513
- | Container | Ok | Ok | 8/14 |
514
- | Volume | Ok | Ok | 8/21 |
515
- | Network | Ok | Ok | 8/21 |
516
- | System | Ok | Ok | 8/21 |
517
- | Exec | Ok | Ok | 8/21 |
518
- | Swarm | Ok | Ok | 8/28 |
519
- | Node | Ok | Ok | 8/28 |
520
- | Service | Ok | Ok | 8/28 |
521
- | Task | Ok | Ok | 9/4 |
522
- | Secret | Ok | Ok | 9/4 |
523
- | Config | Ok | Ok | 9/4 |
524
- | Distribution | Ok | Ok | 9/4 |
525
- | Plugin | Ok | Ok | 9/4 |
526
-
527
- Add doc in these files: `base`, `connection`, `error`, `response`, `dockerapi`
570
+ ### Release nre version
571
+
572
+ * Update CHANGELOG.
573
+ * Update README as needed.
574
+ * Update version.
575
+ * Run tests.
576
+ * Commit changes.
577
+ * Release / push version to Rubygems & Github.
528
578
 
529
579
  ## Contributing
530
580
 
data/bin/setup CHANGED
@@ -18,5 +18,13 @@ then
18
18
  else
19
19
  echo "Running bundle install"
20
20
  bundle install
21
+
22
+ echo "Creating self-signed certificate to use in tests"
23
+ openssl req -newkey rsa:2048 -nodes -keyout resources/registry_authentication/registry_auth.key -x509 -days 365 -out resources/registry_authentication/registry_auth.crt -subj "/C=CL/ST=Santiago/L=Santiago/O=dockerapi/OU=dockerapi/CN=dockerapi"
24
+
25
+ echo "Creating htpasswd file to use in tests"
26
+ docker run --rm --entrypoint htpasswd registry:2.7.0 -Bbn janedoe password > resources/registry_authentication/htpasswd
27
+ docker image rm registry:2.7.0
21
28
  echo "Run this script as root for further configurations"
22
- fi
29
+ fi
30
+
@@ -6,8 +6,8 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["Alysson A. Costa"]
7
7
  spec.email = ["alysson.avila.costa@gmail.com"]
8
8
 
9
- spec.summary = "Interact directly with Docker API from Ruby code."
10
- spec.description = "Interact directly with Docker API from Ruby code."
9
+ spec.summary = "Interact with Docker API from Ruby code."
10
+ spec.description = "Interact with Docker API directly from Ruby code. Comprehensive implementation (all available endpoints), no local Docker installation required, easily manipulated http responses."
11
11
  spec.homepage = "https://github.com/nu12/dockerapi"
12
12
  spec.license = "MIT"
13
13
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
@@ -15,15 +15,16 @@ Gem::Specification.new do |spec|
15
15
  spec.metadata["homepage_uri"] = spec.homepage
16
16
  spec.metadata["source_code_uri"] = "https://github.com/nu12/dockerapi.git"
17
17
  spec.metadata["changelog_uri"] = "https://github.com/nu12/dockerapi/blob/master/CHANGELOG.md"
18
+ spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/dockerapi"
18
19
 
19
20
  # Specify which files should be added to the gem when it is released.
20
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
22
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|resources)/}) }.append("doc")
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|resources)/}) }
23
24
  end
24
25
  spec.bindir = "exe"
25
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
27
  spec.require_paths = ["lib"]
27
28
 
28
- spec.add_dependency("excon", "~> 0.74.0")
29
+ spec.add_dependency("excon", "~> 0.76")
29
30
  end
@@ -1,24 +1,21 @@
1
+ ##
2
+ # Base class to provide general methods, helpers and implementations accross classes.
1
3
  class Docker::API::Base
2
4
 
3
-
5
+ ##
6
+ # Create new object and sets the validation to happen automatically when method parameters include "params" or "body".
7
+ #
8
+ # @param connection [Docker::API::Connection]: Connection to be used.
4
9
  def initialize connection = nil
5
10
  raise Docker::API::Error.new("Expected connection to be a Docker::API::Connection class") if connection != nil && !connection.is_a?(Docker::API::Connection)
6
11
  @connection = connection || Docker::API::Connection.new
7
-
8
- (self.methods - Object.methods).each do |method|
9
- params_index = method(method).parameters.map{|ar| ar[1]}.index(:params)
10
- body_index = method(method).parameters.map{|ar| ar[1]}.index(:body)
11
-
12
- define_singleton_method(method) do |*args, &block|
13
- validate Docker::API::InvalidParameter, Docker::API::VALID_PARAMS["#{self.class.name}"]["#{method}"], (args[params_index] || {}) if params_index
14
- validate Docker::API::InvalidRequestBody, Docker::API::VALID_BODY["#{self.class.name}"]["#{method}"], (args[body_index] || {}) if body_index
15
- super(*args,&block)
16
- end
17
- end
12
+ set_automated_validation
18
13
  end
19
14
 
20
15
  private
21
16
 
17
+ ##
18
+ # Output to stdout.
22
19
  def default_streamer
23
20
  streamer = lambda do |chunk, remaining_bytes, total_bytes|
24
21
  p chunk.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?') if Docker::API::PRINT_TO_STDOUT
@@ -26,6 +23,10 @@ class Docker::API::Base
26
23
  streamer
27
24
  end
28
25
 
26
+ ##
27
+ # Write file to disk.
28
+ #
29
+ # @param path [String]: Path to the file to be writen.
29
30
  def default_writer path
30
31
  streamer = lambda do |chunk, remaining_bytes, total_bytes|
31
32
  return if "#{chunk}".match(/(No such image)/)
@@ -36,31 +37,74 @@ class Docker::API::Base
36
37
  streamer
37
38
  end
38
39
 
40
+ ##
41
+ # Read file from disk.
42
+ #
43
+ # @param path [String]: Path to the file to be read.
44
+ # @param url [String]: Endpoint URL where the file is going to be sent.
45
+ # @param header [Hash]: Header of the request.
46
+ # @param &block: Replace the default output to stdout behavior.
39
47
  def default_reader path, url, header = {"Content-Type" => "application/x-tar"}, &block
40
48
  file = File.open(File.expand_path(path), "r")
41
- response = @connection.request(method: :post, path: url , headers: header, request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s}, response_block: block_given? ? block.call : default_streamer )
49
+ response = @connection.request(method: :post, path: url , headers: header, request_block: lambda { file.read(Excon.defaults[:chunk_size]).to_s}, response_block: block_given? ? block : default_streamer )
42
50
  file.close
43
51
  response
44
52
  end
45
53
 
54
+ ##
55
+ # Encode authentication parameters.
56
+ #
57
+ # @param authentication [Hash]: Parameters to be encoded.
58
+ def auth_encoder(authentication)
59
+ Base64.urlsafe_encode64(authentication.to_json.to_s).chomp
60
+ end
61
+
62
+ ##
63
+ # Validate a Hash object comparing its keys with a given Array of permitted values. Raise an error if the validation fail.
64
+ #
65
+ # @param error [Error]: Error to be raised of the validation fail.
66
+ # @param permitted [Array]: List of permitted keys.
67
+ # @param params [Hash]: Hash object to be validated.
46
68
  def validate error, permitted, params
47
69
  return if params[:skip_validation]
48
70
  unpermitted = params.keys.map(&:to_s) - permitted.map(&:to_s)
49
71
  raise error.new(permitted, unpermitted) if unpermitted.size > 0
50
72
  end
51
73
 
52
- ## Converts Ruby Hash into query parameters
53
- ## In general, the format is key=value
54
- ## If value is another Hash, it should keep a json syntax {key:value}
55
- def hash_to_params h
74
+ ##
75
+ # Convert Ruby Hash into URL query parameters.
76
+ #
77
+ # In general, query parameters' format is "key=value", but if "value" is another Hash, it should change to a json syntax {key:value}.
78
+ #
79
+ # @param hash [Hash]: Hash object to be converted in a query parameter-like string.
80
+ def hash_to_params hash
56
81
  p = []
57
- h.delete_if{ | k, v | k.to_s == "skip_validation" }.each { |k,v| p.push( v.is_a?(Hash) ? "#{k}=#{v.to_json}" : "#{k}=#{v}") }
82
+ hash.delete_if{ | k, v | k.to_s == "skip_validation" }.each { |k,v| p.push( v.is_a?(Hash) ? "#{k}=#{v.to_json}" : "#{k}=#{v}") }
58
83
  p.join("&").gsub(" ","")
59
84
  end
60
85
 
86
+ ##
87
+ # Build an URL string using the base path and a set of parameters.
88
+ #
89
+ # @param path [String]: Base URL string.
90
+ # @param hash [Hash]: Hash object to be appended to the URL as query parameters.
61
91
  def build_path path, params = {}
62
- p = path.is_a?(Array) ? ([base_path] << path).join("/") : path # TODO: this line to be removed?
63
- params.size > 0 ? [p, hash_to_params(params)].join("?") : p
92
+ params.size > 0 ? [path, hash_to_params(params)].join("?") : path
93
+ end
94
+
95
+ ##
96
+ # Set the validation to happen automatically when method parameters include "params" or "body".
97
+ def set_automated_validation
98
+ (self.methods - Object.methods).each do |method|
99
+ params_index = method(method).parameters.map{|ar| ar[1]}.index(:params)
100
+ body_index = method(method).parameters.map{|ar| ar[1]}.index(:body)
101
+
102
+ define_singleton_method(method) do |*args, &block|
103
+ validate Docker::API::InvalidParameter, Docker::API::VALID_PARAMS["#{self.class.name}"]["#{method}"], (args[params_index] || {}) if params_index
104
+ validate Docker::API::InvalidRequestBody, Docker::API::VALID_BODY["#{self.class.name}"]["#{method}"], (args[body_index] || {}) if body_index
105
+ super(*args,&block)
106
+ end
107
+ end
64
108
  end
65
109
 
66
110
  end
@@ -1,20 +1,26 @@
1
- module Docker
2
- module API
3
- class Connection
4
- [:get, :post, :head, :delete, :put].each do | method |
5
- define_method(method) { | path | self.request(method: method, path: path) }
6
- end
7
-
8
- def request params
9
- Docker::API::Response.new(@connection.request(params).data)
10
- end
11
-
12
- def initialize url = nil, params = nil
13
- url ||= 'unix:///'
14
- params ||= url == 'unix:///' ? {socket: '/var/run/docker.sock'} : {}
15
- @connection = Excon.new(url, params)
16
- end
1
+ ##
2
+ # Connection class.
3
+ class Docker::API::Connection
4
+ [:get, :post, :head, :delete, :put].each do | method |
5
+ define_method(method) { | path | self.request(method: method, path: path) }
6
+ end
17
7
 
18
- end
8
+ ##
9
+ # Call an Excon request and returns a Docker::API::Response object.
10
+ #
11
+ # @param params [Hash]: Request parameters.
12
+ def request params
13
+ Docker::API::Response.new(@connection.request(params).data)
19
14
  end
15
+
16
+ ##
17
+ # Create an Excon connection.
18
+ #
19
+ # @param url [String]: URL for the connection.
20
+ # @param params [String]: Additional parameters.
21
+ def initialize url = nil, params = nil
22
+ return @connection = Excon.new('unix:///', {socket: '/var/run/docker.sock'}) unless url
23
+ @connection = Excon.new(url, params || {})
24
+ end
25
+
20
26
  end