Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify Docker API version #9

Merged
merged 4 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: CD
on:
push:
branches: [ main ]
tags:
- 'v*.*.*'

jobs:
release:
Expand All @@ -12,9 +13,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@21351ecc0a7c196081abca5dc55b08f085efe09a
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
ruby-version: 3.3
- name: Setup to RubyGems
run: |
mkdir -p $HOME/.gem
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@21351ecc0a7c196081abca5dc55b08f085efe09a
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
ruby-version: 3.3
- name: Install Docker
run: curl https://get.docker.com | sh
- name: Install dependencies
Expand Down
31 changes: 16 additions & 15 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
PATH
remote: .
specs:
dockerapi (0.19.0)
dockerapi (0.20.0)
excon (~> 0.79)

GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.3)
excon (0.79.0)
diff-lcs (1.5.1)
excon (0.112.0)
rake (12.3.3)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.2)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.2)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.2)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.3)
rspec-support (~> 3.13.0)
rspec-support (3.13.1)

PLATFORMS
arm64-darwin-23
ruby

DEPENDENCIES
Expand All @@ -33,4 +34,4 @@ DEPENDENCIES
rspec (~> 3.0)

BUNDLED WITH
2.1.4
2.5.11
1 change: 1 addition & 0 deletions lib/docker/api/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def hash_to_params hash
# @param path [String]: Base URL string.
# @param hash [Hash]: Hash object to be appended to the URL as query parameters.
def build_path path, params = {}
path = "/v#{Docker::API::API_VERSION}#{path}"
params.size > 0 ? [path, hash_to_params(params)].join("?") : path
end

Expand Down
8 changes: 4 additions & 4 deletions lib/docker/api/network.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def details name, params = {}
#
# @param body [Hash]: Request body to be sent as json.
def create body = {}
@connection.request(method: :post, path: "/networks/create", headers: {"Content-Type": "application/json"}, body: body.to_json)
@connection.request(method: :post, path: build_path("/networks/create"), headers: {"Content-Type": "application/json"}, body: body.to_json)
end

##
Expand All @@ -45,7 +45,7 @@ def create body = {}
#
# @param name [String]: The ID or name of the network.
def remove name
@connection.delete("/networks/#{name}")
@connection.delete(build_path("/networks/#{name}"))
end

##
Expand All @@ -68,7 +68,7 @@ def prune params = {}
# @param name [String]: The ID or name of the network.
# @param body [Hash]: Request body to be sent as json.
def connect name, body = {}
@connection.request(method: :post, path: "/networks/#{name}/connect", headers: {"Content-Type": "application/json"}, body: body.to_json)
@connection.request(method: :post, path: build_path("/networks/#{name}/connect"), headers: {"Content-Type": "application/json"}, body: body.to_json)
end

##
Expand All @@ -80,7 +80,7 @@ def connect name, body = {}
# @param name [String]: The ID or name of the network.
# @param body [Hash]: Request body to be sent as json.
def disconnect name, body = {}
@connection.request(method: :post, path: "/networks/#{name}/disconnect", headers: {"Content-Type": "application/json"}, body: body.to_json)
@connection.request(method: :post, path: build_path("/networks/#{name}/disconnect"), headers: {"Content-Type": "application/json"}, body: body.to_json)
end

end
2 changes: 1 addition & 1 deletion lib/docker/api/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def list params = {}
# @param params [Hash]: Parameters that are appended to the URL.
# @param body [Hash]: Request body to be sent as json.
def update name, params = {}, body = {}
@connection.request(method: :post, path: build_path("nodes/#{name}/update", params), headers: {"Content-Type": "application/json"}, body: body.to_json)
@connection.request(method: :post, path: build_path("/nodes/#{name}/update", params), headers: {"Content-Type": "application/json"}, body: body.to_json)
end

##
Expand Down
6 changes: 3 additions & 3 deletions lib/docker/api/system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def events params = {}, &block
# Docker API: GET /_ping
# @see https://docs.docker.com/engine/api/v1.40/#operation/SystemPing
def ping
@connection.get("/_ping")
@connection.get(build_path("/_ping"))
end

##
Expand All @@ -41,7 +41,7 @@ def ping
# Docker API: GET /info
# @see https://docs.docker.com/engine/api/v1.40/#operation/SystemInfo
def info
@connection.get("/info")
@connection.get(build_path("/info"))
end

##
Expand All @@ -50,7 +50,7 @@ def info
# Docker API: GET /version
# @see https://docs.docker.com/engine/api/v1.40/#operation/SystemVersion
def version
@connection.get("/version")
@connection.get(build_path("/version"))
end

##
Expand Down
12 changes: 6 additions & 6 deletions spec/endpoints/container_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
end

describe "request path" do
it { expect(subject.list( { all: true, filters: {name: {"#{name}": true}} } ).path).to eq("/containers/json?all=true&filters={\"name\":{\"#{name}\":true}}") }
it { expect(subject.list( { all: true, filters: {exited: {"0": true} } } ).path).to eq("/containers/json?all=true&filters={\"exited\":{\"0\":true}}") }
it { expect(subject.list( { all: true, filters: {status: ["running"] } } ).path).to eq("/containers/json?all=true&filters={\"status\":[\"running\"]}") }
it { expect(subject.list( { all: true, filters: {name: {"#{name}": true}} } ).path).to eq("/v#{Docker::API::API_VERSION}/containers/json?all=true&filters={\"name\":{\"#{name}\":true}}") }
it { expect(subject.list( { all: true, filters: {exited: {"0": true} } } ).path).to eq("/v#{Docker::API::API_VERSION}/containers/json?all=true&filters={\"exited\":{\"0\":true}}") }
it { expect(subject.list( { all: true, filters: {status: ["running"] } } ).path).to eq("/v#{Docker::API::API_VERSION}/containers/json?all=true&filters={\"status\":[\"running\"]}") }
end
end

Expand Down Expand Up @@ -98,7 +98,7 @@
it { expect(subject.start(name).status).to eq(204 )}
it { expect(subject.start("doesn-exist").status).to eq(404 )}
it { expect(subject.start(name, {detachKeys: "ctrl-c"}).status).to eq(204 )}
it { expect(subject.start(name, {detachKeys: "ctrl-c"}).path).to eq("/containers/#{name}/start?detachKeys=ctrl-c" )}
it { expect(subject.start(name, {detachKeys: "ctrl-c"}).path).to eq("/v#{Docker::API::API_VERSION}/containers/#{name}/start?detachKeys=ctrl-c" )}
it { expect{subject.start(name, {invalid_value: "invalid"})}.to raise_error(Docker::API::InvalidParameter )}
it do
subject.start(name)
Expand Down Expand Up @@ -126,7 +126,7 @@
it { expect(subject.kill(name).status).to be(204) }
it { expect(subject.kill("doesn-exist").status).to be(404) }
it { expect(subject.kill(name, {signal: "SIGKILL"}).status).to eq(204) }
it { expect(subject.kill(name, {signal: "SIGKILL"}).path).to eq("/containers/#{name}/kill?signal=SIGKILL") }
it { expect(subject.kill(name, {signal: "SIGKILL"}).path).to eq("/v#{Docker::API::API_VERSION}/containers/#{name}/kill?signal=SIGKILL") }
it { expect{subject.kill(name, {invalid_value: "invalid"})}.to raise_error(Docker::API::InvalidParameter) }
it do
subject.stop(name)
Expand All @@ -139,7 +139,7 @@
it { expect(subject.restart("doesn-exist").status).to be(404) }
it { expect(subject.restart(name, {t: 2}).status).to eq(204) }
it { expect(subject.restart(name, {signal: "SIGINT"}).status).to eq(204) }
it { expect(subject.restart(name, {t: 2}).path).to eq("/containers/#{name}/restart?t=2") }
it { expect(subject.restart(name, {t: 2}).path).to eq("/v#{Docker::API::API_VERSION}/containers/#{name}/restart?t=2") }
it { expect{subject.restart(name, {invalid_value: "invalid"})}.to raise_error(Docker::API::InvalidParameter) }
end

Expand Down
34 changes: 17 additions & 17 deletions spec/endpoints/image_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@
it { expect(subject.list(all: true, filters: {since: {"#{image}": true}}).status).to eq(200) }
end
describe "request path" do
it { expect(subject.list(all: true).path).to eq("/images/json?all=true") }
it { expect(subject.list(all: true, "shared-size": true).path).to eq("/images/json?all=true&shared-size=true") }
it { expect(subject.list(digests: true).path).to eq("/images/json?digests=true") }
it { expect(subject.list(all: true, digests: true).path).to eq("/images/json?all=true&digests=true") }
it { expect(subject.list(all: true, filters: {dangling: {"true": true}}).path).to eq("/images/json?all=true&filters={\"dangling\":{\"true\":true}}") }
it { expect(subject.list(all: true, filters: {label: {"label-here": true}}).path).to eq("/images/json?all=true&filters={\"label\":{\"label-here\":true}}") }
it { expect(subject.list(all: true, filters: {reference: {"#{image}": true}}).path).to eq("/images/json?all=true&filters={\"reference\":{\"#{image}\":true}}") }
it { expect(subject.list(all: true, filters: {before: {"#{image}": true}}).path).to eq("/images/json?all=true&filters={\"before\":{\"#{image}\":true}}") }
it { expect(subject.list(all: true, filters: {since: {"#{image}": true}}).path).to eq("/images/json?all=true&filters={\"since\":{\"#{image}\":true}}") }
it { expect(subject.list(all: true, invalid: true, skip_validation: true).path).to eq("/images/json?all=true&invalid=true") }
it { expect(subject.list(all: true).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true") }
it { expect(subject.list(all: true, "shared-size": true).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&shared-size=true") }
it { expect(subject.list(digests: true).path).to eq("/v#{Docker::API::API_VERSION}/images/json?digests=true") }
it { expect(subject.list(all: true, digests: true).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&digests=true") }
it { expect(subject.list(all: true, filters: {dangling: {"true": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&filters={\"dangling\":{\"true\":true}}") }
it { expect(subject.list(all: true, filters: {label: {"label-here": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&filters={\"label\":{\"label-here\":true}}") }
it { expect(subject.list(all: true, filters: {reference: {"#{image}": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&filters={\"reference\":{\"#{image}\":true}}") }
it { expect(subject.list(all: true, filters: {before: {"#{image}": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&filters={\"before\":{\"#{image}\":true}}") }
it { expect(subject.list(all: true, filters: {since: {"#{image}": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&filters={\"since\":{\"#{image}\":true}}") }
it { expect(subject.list(all: true, invalid: true, skip_validation: true).path).to eq("/v#{Docker::API::API_VERSION}/images/json?all=true&invalid=true") }
end
it { expect{subject.list(invalid: "invalid")}.to raise_error(Docker::API::InvalidParameter) }
end
Expand Down Expand Up @@ -159,11 +159,11 @@
it { expect(subject.prune(filters: {label: {"LABEL": true}, dangling: {"1": true}}).status).to eq(200) }
end
describe "request path" do
it { expect(subject.prune(filters: {dangling: {"true": true}}).path).to eq("/images/prune?filters={\"dangling\":{\"true\":true}}") }
it { expect(subject.prune(filters: {dangling: {"1": true}}).path).to eq("/images/prune?filters={\"dangling\":{\"1\":true}}") }
it { expect(subject.prune(filters: {until: {"10m": true}}).path).to eq("/images/prune?filters={\"until\":{\"10m\":true}}") }
it { expect(subject.prune(filters: {label: {"LABEL": true}}).path).to eq("/images/prune?filters={\"label\":{\"LABEL\":true}}") }
it { expect(subject.prune(filters: {label: {"LABEL": true}, dangling: {"1": true}}).path).to eq("/images/prune?filters={\"label\":{\"LABEL\":true},\"dangling\":{\"1\":true}}") }
it { expect(subject.prune(filters: {dangling: {"true": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/prune?filters={\"dangling\":{\"true\":true}}") }
it { expect(subject.prune(filters: {dangling: {"1": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/prune?filters={\"dangling\":{\"1\":true}}") }
it { expect(subject.prune(filters: {until: {"10m": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/prune?filters={\"until\":{\"10m\":true}}") }
it { expect(subject.prune(filters: {label: {"LABEL": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/prune?filters={\"label\":{\"LABEL\":true}}") }
it { expect(subject.prune(filters: {label: {"LABEL": true}, dangling: {"1": true}}).path).to eq("/v#{Docker::API::API_VERSION}/images/prune?filters={\"label\":{\"LABEL\":true},\"dangling\":{\"1\":true}}") }
end
it { expect{subject.prune( invalid: "invalid")}.to raise_error(Docker::API::InvalidParameter) }
end
Expand All @@ -174,10 +174,10 @@
it { expect(subject.build("resources/build.tar.xz", q: true, rm: false).status).to eq(200) }
it { expect(subject.build("resources/build.tar.xz", memory: 4000000, rm: true, forcerm:true).status).to eq(200) }
it { expect(subject.build("resources/build.tar.xz", memory: 4000000, rm: true, forcerm:true, pull:true).status).to eq(200) }
it { expect(subject.build(nil, remote: "https://github.com/nu12/dockerapi/blob/master/resources/build.tar.xz?raw=true").status).to eq(200) }
it { expect(subject.build(nil, remote: "https://github.com/nu12/dockerapi/raw/refs/heads/main/resources/build.tar.xz").status).to eq(200) }
it { expect(subject.build(nil, remote: "https://raw.githubusercontent.com/nu12/dockerapi/master/resources/Dockerfile").status).to eq(200) }
it { expect{subject.build("resources/build.tar.xz", invalid: "invalid")}.to raise_error(Docker::API::InvalidParameter) }
it { expect{subject.build(nil, remote: "https://github.com/nu12/dockerapi/blob/master/resources/build.tar.xz?raw=true", invalid: "invalid")}.to raise_error(Docker::API::InvalidParameter) }
it { expect{subject.build(nil, remote: "https://github.com/nu12/dockerapi/raw/refs/heads/main/resources/build.tar.xz", invalid: "invalid")}.to raise_error(Docker::API::InvalidParameter) }
it { expect{subject.build(nil, invalid: "invalid", skip_validation: true)}.to raise_error(Docker::API::Error) }
end

Expand Down
2 changes: 1 addition & 1 deletion spec/endpoints/network_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
end

describe ".create" do
it { expect(subject.create.status).to eq(500) }
it { expect(subject.create.status).to eq(400) }
it do
expect(subject.create(
Name: "rspec-network",
Expand Down
2 changes: 1 addition & 1 deletion spec/endpoints/node_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
RSpec.describe Docker::API::Node do
ip_address = Socket.ip_address_list[2].ip_address
ip_address = get_api_ip_address
subject { described_class.new }
it { is_expected.to respond_to(:list) }
it { is_expected.to respond_to(:details) }
Expand Down
4 changes: 2 additions & 2 deletions spec/endpoints/swarm_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'socket'

RSpec.describe Docker::API::Swarm do
ip_address = Socket.ip_address_list[2].ip_address
ip_address = get_api_ip_address

subject { described_class.new }
describe ".init" do
Expand Down
12 changes: 6 additions & 6 deletions spec/endpoints/system_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@
describe ".ping" do
it { expect(subject).to respond_to(:ping) }
it { expect(subject.ping.status).to eq(200) }
it { expect(subject.ping.path).to eq("/_ping") }
it { expect(subject.ping.path).to eq("/v#{Docker::API::API_VERSION}/_ping") }
end

describe ".info" do
it { expect(subject).to respond_to(:info) }
it { expect(subject.info.status).to eq(200) }
it { expect(subject.info.success?).to eq(true) }
it { expect(subject.info.json).to be_kind_of(Hash) }
it { expect(subject.info.path).to eq("/info") }
it { expect(subject.info.path).to eq("/v#{Docker::API::API_VERSION}/info") }
end

describe ".version" do
it { expect(subject).to respond_to(:version) }
it { expect(subject.version.status).to eq(200) }
it { expect(subject.version.success?).to eq(true) }
it { expect(subject.version.json).to be_kind_of(Hash) }
it { expect(subject.version.path).to eq("/version") }
it { expect(subject.version.path).to eq("/v#{Docker::API::API_VERSION}/version") }
end

describe ".events" do
Expand All @@ -35,7 +35,7 @@
it { expect(described_class.new).to respond_to(:events) }
it { expect(subject.status).to eq(200) }
it { expect(subject.success?).to eq(true) }
it { expect(subject.path).to eq("/events?until=#{now}") }
it { expect(subject.path).to eq("/v#{Docker::API::API_VERSION}/events?until=#{now}") }
it { expect{described_class.new.events(invalid: true)}.to raise_error(Docker::API::InvalidParameter) }
it { expect{described_class.new.events(invalid: true, skip_validation: false)}.to raise_error(Docker::API::InvalidParameter) }
end
Expand All @@ -45,9 +45,9 @@
it { expect(subject.df.status).to eq(200) }
it { expect(subject.df.success?).to eq(true) }
it { expect(subject.df.json).to be_kind_of(Hash) }
it { expect(subject.df.path).to eq("/system/df") }
it { expect(subject.df.path).to eq("/v#{Docker::API::API_VERSION}/system/df") }
it { expect{subject.df(invalid: "true")}.to raise_error(Docker::API::InvalidParameter) }
it { expect{subject.df(type: "container")}.not_to raise_error }
it { expect(subject.df(type: "container").path).to eq("/system/df?type=container" )}
it { expect(subject.df(type: "container").path).to eq("/v#{Docker::API::API_VERSION}/system/df?type=container" )}
end
end
8 changes: 8 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,11 @@
c.syntax = :expect
end
end

def get_api_ip_address

Socket.ip_address_list.each do |addr|
return addr.ip_address if addr.ipv4? && !addr.ipv4_loopback? && addr.ip_address =~ /\A\d{1,3}(\.\d{1,3}){3}\z/
end

end
Loading