foreman_docker 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +22 -22
- data/app/assets/javascripts/foreman_docker/image_step.js +36 -6
- data/app/controllers/api/v2/containers_controller.rb +13 -11
- data/app/controllers/containers/steps_controller.rb +8 -2
- data/app/controllers/containers_controller.rb +4 -3
- data/app/controllers/image_search_controller.rb +36 -79
- data/app/helpers/container_steps_helper.rb +21 -0
- data/app/models/concerns/foreman_docker/parameter_validators.rb +27 -4
- data/app/models/container.rb +9 -10
- data/app/models/docker_container_wizard_state.rb +2 -0
- data/app/models/docker_container_wizard_states/dns.rb +2 -8
- data/app/models/docker_container_wizard_states/environment.rb +4 -14
- data/app/models/docker_container_wizard_states/environment_variable.rb +2 -2
- data/app/models/docker_container_wizard_states/exposed_port.rb +2 -8
- data/app/models/docker_container_wizard_states/image.rb +30 -0
- data/app/models/docker_container_wizard_states/preliminary.rb +1 -1
- data/app/models/docker_parameter.rb +20 -0
- data/app/models/docker_registry.rb +6 -4
- data/app/models/environment_variable.rb +3 -3
- data/app/models/exposed_port.rb +4 -10
- data/app/models/foreman_docker/compute_resource_extensions.rb +11 -0
- data/app/models/foreman_docker/dns.rb +3 -9
- data/app/models/foreman_docker/docker.rb +1 -5
- data/app/models/service/containers.rb +15 -11
- data/app/models/service/registry_api.rb +87 -15
- data/app/services/foreman_docker/image_search.rb +92 -0
- data/app/views/containers/index.html.erb +1 -3
- data/app/views/containers/show.html.erb +1 -1
- data/app/views/containers/steps/_image_hub_tab.html.erb +39 -29
- data/app/views/containers/steps/_title.html.erb +1 -1
- data/app/views/containers/steps/preliminary.html.erb +1 -1
- data/app/views/foreman_docker/common_parameters/_dns_entry.html.erb +1 -1
- data/app/views/foreman_docker/common_parameters/_environment_variable.html.erb +1 -1
- data/app/views/foreman_docker/common_parameters/_exposed_port.html.erb +1 -1
- data/app/views/image_search/_repository_search_results.html.erb +1 -1
- data/app/views/registries/index.html.erb +1 -3
- data/app/views/registries/new.html.erb +1 -1
- data/db/migrate/20160605133025_create_docker_parameters.rb +13 -0
- data/db/migrate/20160605134652_move_parameters_to_docker_parameters.rb +27 -0
- data/lib/foreman_docker/engine.rb +6 -7
- data/lib/foreman_docker/version.rb +1 -1
- data/lib/tasks/test.rake +35 -0
- data/test/functionals/api/v2/containers_controller_test.rb +21 -0
- data/test/functionals/api/v2/registries_controller_test.rb +4 -3
- data/test/functionals/containers_controller_test.rb +5 -0
- data/test/functionals/containers_steps_controller_test.rb +74 -36
- data/test/functionals/image_search_controller_test.rb +166 -12
- data/test/integration/container_test.rb +1 -1
- data/test/test_plugin_helper.rb +10 -0
- data/test/units/container_test.rb +1 -1
- data/test/units/containers_service_test.rb +31 -9
- data/test/units/docker_container_wizard_states/image_test.rb +84 -0
- data/test/units/docker_registry_test.rb +27 -10
- data/test/units/foreman_docker/compute_resource_extensions_test.rb +10 -0
- data/test/units/image_search_service_test.rb +188 -0
- data/test/units/registry_api_test.rb +206 -12
- metadata +55 -36
- data/lib/foreman_docker/tasks/test.rake +0 -45
- data/locale/de/foreman_docker.edit.po +0 -631
- data/locale/de/foreman_docker.po.time_stamp +0 -0
- data/locale/es/foreman_docker.edit.po +0 -631
- data/locale/es/foreman_docker.po.time_stamp +0 -0
- data/locale/fr/foreman_docker.edit.po +0 -632
- data/locale/fr/foreman_docker.po.time_stamp +0 -0
- data/locale/it/foreman_docker.edit.po +0 -630
- data/locale/it/foreman_docker.po.time_stamp +0 -0
- data/locale/ja/foreman_docker.edit.po +0 -634
- data/locale/ja/foreman_docker.po.time_stamp +0 -0
- data/locale/ko/foreman_docker.edit.po +0 -629
- data/locale/ko/foreman_docker.po.time_stamp +0 -0
- data/locale/pt_BR/foreman_docker.edit.po +0 -631
- data/locale/pt_BR/foreman_docker.po.time_stamp +0 -0
- data/locale/ru/foreman_docker.edit.po +0 -630
- data/locale/ru/foreman_docker.po.time_stamp +0 -0
- data/locale/zh_CN/foreman_docker.edit.po +0 -628
- data/locale/zh_CN/foreman_docker.po.time_stamp +0 -0
- data/locale/zh_TW/foreman_docker.edit.po +0 -628
- data/locale/zh_TW/foreman_docker.po.time_stamp +0 -0
data/app/models/container.rb
CHANGED
@@ -6,20 +6,19 @@ class Container < ActiveRecord::Base
|
|
6
6
|
belongs_to :registry, :class_name => "DockerRegistry", :foreign_key => :registry_id
|
7
7
|
has_many :environment_variables, :dependent => :destroy, :foreign_key => :reference_id,
|
8
8
|
:inverse_of => :container,
|
9
|
-
:class_name => 'EnvironmentVariable'
|
10
|
-
|
9
|
+
:class_name => 'EnvironmentVariable'
|
10
|
+
|
11
11
|
accepts_nested_attributes_for :environment_variables, :allow_destroy => true
|
12
|
-
include ForemanDocker::ParameterValidators
|
13
12
|
|
14
13
|
has_many :exposed_ports, :dependent => :destroy, :foreign_key => :reference_id,
|
15
14
|
:inverse_of => :container,
|
16
|
-
:class_name => 'ExposedPort'
|
17
|
-
:validate => true
|
15
|
+
:class_name => 'ExposedPort'
|
18
16
|
|
19
17
|
has_many :dns, :dependent => :destroy, :foreign_key => :reference_id,
|
20
18
|
:inverse_of => :container,
|
21
|
-
:class_name => 'ForemanDocker::Dns'
|
22
|
-
|
19
|
+
:class_name => 'ForemanDocker::Dns'
|
20
|
+
|
21
|
+
include ForemanDocker::ParameterValidators
|
23
22
|
|
24
23
|
accepts_nested_attributes_for :exposed_ports, :allow_destroy => true
|
25
24
|
scoped_search :on => :name
|
@@ -41,10 +40,10 @@ class Container < ActiveRecord::Base
|
|
41
40
|
'AttachStdout' => attach_stdout, 'AttachStdin' => attach_stdin,
|
42
41
|
'AttachStderr' => attach_stderr, 'CpuShares' => cpu_shares,
|
43
42
|
'Cpuset' => cpu_set,
|
44
|
-
'Env' => environment_variables.map { |env| "#{env.
|
45
|
-
'ExposedPorts' => Hash[*exposed_ports.map { |v| [v.
|
43
|
+
'Env' => environment_variables.map { |env| "#{env.key}=#{env.value}" },
|
44
|
+
'ExposedPorts' => Hash[*exposed_ports.map { |v| [v.key + "/" + v.value, {}] }.flatten],
|
46
45
|
'HostConfig' => {
|
47
|
-
'Dns' => dns.map { |env| "#{env.
|
46
|
+
'Dns' => dns.map { |env| "#{env.key}" }
|
48
47
|
} }
|
49
48
|
end
|
50
49
|
|
@@ -9,6 +9,8 @@ class DockerContainerWizardState < ActiveRecord::Base
|
|
9
9
|
:dependent => :destroy, :validate => true, :autosave => true
|
10
10
|
|
11
11
|
delegate :compute_resource_id, :to => :preliminary
|
12
|
+
delegate :compute_resource, :to => :preliminary
|
13
|
+
|
12
14
|
delegate :environment_variables, :to => :environment
|
13
15
|
delegate :exposed_ports, :to => :environment
|
14
16
|
delegate :dns, :to => :environment
|
@@ -1,17 +1,11 @@
|
|
1
1
|
require 'resolv'
|
2
2
|
|
3
3
|
module DockerContainerWizardStates
|
4
|
-
class Dns <
|
5
|
-
# The Parameter class from which this Dns class inherits,validates for the
|
6
|
-
# presence of an associated domain, operating system, host or host group.
|
7
|
-
# We will have to reset those validations for the Dns class as they do not
|
8
|
-
# make any sense for the context in which this class is being used here.
|
9
|
-
Dns.reset_callbacks(:validate)
|
10
|
-
|
4
|
+
class Dns < DockerParameter
|
11
5
|
belongs_to :environment, :foreign_key => :reference_id,
|
12
6
|
:inverse_of => :dns,
|
13
7
|
:class_name => 'DockerContainerWizardStates::Environment'
|
14
|
-
validates :
|
8
|
+
validates :key, :uniqueness => { :scope => :reference_id },
|
15
9
|
:format => {
|
16
10
|
:with => Regexp.union(Resolv::IPv4::Regex,
|
17
11
|
Resolv::IPv6::Regex,
|
@@ -3,32 +3,22 @@ module DockerContainerWizardStates
|
|
3
3
|
self.table_name_prefix = 'docker_container_wizard_states_'
|
4
4
|
belongs_to :wizard_state, :class_name => DockerContainerWizardState
|
5
5
|
|
6
|
-
# Fix me:
|
7
|
-
# Validations are off on this association as there's a bug in ::Parameter
|
8
|
-
# that forces validation of reference_id. This will fail on new records as
|
9
|
-
# validations are executed before parent and children records have been persisted.
|
10
6
|
has_many :environment_variables, :dependent => :destroy, :foreign_key => :reference_id,
|
11
7
|
:inverse_of => :environment,
|
12
8
|
:class_name =>
|
13
|
-
'DockerContainerWizardStates::EnvironmentVariable'
|
14
|
-
:validate => false
|
15
|
-
include ::ParameterValidators
|
9
|
+
'DockerContainerWizardStates::EnvironmentVariable'
|
16
10
|
|
17
11
|
has_many :exposed_ports, :dependent => :destroy, :foreign_key => :reference_id,
|
18
12
|
:inverse_of => :environment,
|
19
|
-
:class_name => 'DockerContainerWizardStates::ExposedPort'
|
20
|
-
:validate => true
|
13
|
+
:class_name => 'DockerContainerWizardStates::ExposedPort'
|
21
14
|
has_many :dns, :dependent => :destroy, :foreign_key => :reference_id,
|
22
15
|
:inverse_of => :environment,
|
23
|
-
:class_name => 'DockerContainerWizardStates::Dns'
|
24
|
-
:validate => true
|
16
|
+
:class_name => 'DockerContainerWizardStates::Dns'
|
25
17
|
|
18
|
+
include ForemanDocker::ParameterValidators
|
26
19
|
accepts_nested_attributes_for :environment_variables, :allow_destroy => true
|
27
20
|
accepts_nested_attributes_for :exposed_ports, :allow_destroy => true
|
28
21
|
accepts_nested_attributes_for :dns, :allow_destroy => true
|
29
22
|
|
30
|
-
def parameters_symbol
|
31
|
-
:environment_variables
|
32
|
-
end
|
33
23
|
end
|
34
24
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module DockerContainerWizardStates
|
2
|
-
class EnvironmentVariable <
|
2
|
+
class EnvironmentVariable < DockerParameter
|
3
3
|
belongs_to :environment, :foreign_key => :reference_id, :inverse_of => :environment_variables,
|
4
4
|
:class_name => 'DockerContainerWizardStates::Environment'
|
5
|
-
validates :
|
5
|
+
validates :key, :uniqueness => { :scope => :reference_id }
|
6
6
|
end
|
7
7
|
end
|
@@ -1,14 +1,8 @@
|
|
1
1
|
module DockerContainerWizardStates
|
2
|
-
class ExposedPort <
|
3
|
-
# The Parameter class from which ExposedPort class inherits,validates for the
|
4
|
-
# presence of an associated domain, operating system, host or host group. We
|
5
|
-
# will have to reset those validations for the ExposedPort class as they do
|
6
|
-
# not make any sense for the context in which this class is being used here.
|
7
|
-
ExposedPort.reset_callbacks(:validate)
|
8
|
-
|
2
|
+
class ExposedPort < DockerParameter
|
9
3
|
belongs_to :environment, :foreign_key => :reference_id, :inverse_of => :exposed_ports,
|
10
4
|
:class_name => 'DockerContainerWizardStates::Environment'
|
11
|
-
validates :
|
5
|
+
validates :key, :uniqueness => { :scope => :reference_id },
|
12
6
|
:numericality => { :only_integer => true,
|
13
7
|
:greater_than => 0,
|
14
8
|
:less_than_or_equal_to => 655_35 }
|
@@ -4,8 +4,38 @@ module DockerContainerWizardStates
|
|
4
4
|
belongs_to :wizard_state, :class_name => DockerContainerWizardState,
|
5
5
|
:foreign_key => :docker_container_wizard_state_id
|
6
6
|
delegate :compute_resource_id, :to => :wizard_state
|
7
|
+
delegate :compute_resource, :to => :wizard_state
|
7
8
|
|
8
9
|
validates :tag, :presence => true
|
9
10
|
validates :repository_name, :presence => true
|
11
|
+
validate :image_exists
|
12
|
+
|
13
|
+
def name
|
14
|
+
"#{repository_name}:#{tag}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def registry_api
|
18
|
+
if registry_id
|
19
|
+
DockerRegistry.find(registry_id).api
|
20
|
+
else
|
21
|
+
Service::RegistryApi.docker_hub
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def sources
|
26
|
+
[compute_resource, registry_api]
|
27
|
+
end
|
28
|
+
|
29
|
+
def image_search_service
|
30
|
+
ForemanDocker::ImageSearch.new(*sources)
|
31
|
+
end
|
32
|
+
|
33
|
+
def image_exists
|
34
|
+
return true if image_search_service.available?(name)
|
35
|
+
error_msg = _("Container image %{image_name} is not available.") % {
|
36
|
+
image_name: "#{name}",
|
37
|
+
}
|
38
|
+
errors.add(:image, error_msg)
|
39
|
+
end
|
10
40
|
end
|
11
41
|
end
|
@@ -6,7 +6,7 @@ module DockerContainerWizardStates
|
|
6
6
|
belongs_to :wizard_state, :class_name => DockerContainerWizardState,
|
7
7
|
:foreign_key => :docker_container_wizard_state_id
|
8
8
|
|
9
|
-
|
9
|
+
belongs_to :compute_resource, :required => true
|
10
10
|
|
11
11
|
def used_location_ids
|
12
12
|
Location.joins(:taxable_taxonomies).where(
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class DockerParameter < ActiveRecord::Base
|
2
|
+
extend FriendlyId
|
3
|
+
friendly_id :key
|
4
|
+
include Parameterizable::ByIdName
|
5
|
+
|
6
|
+
validates_lengths_from_database
|
7
|
+
|
8
|
+
include Authorizable
|
9
|
+
validates :key, :presence => true, :no_whitespace => true
|
10
|
+
|
11
|
+
scoped_search :on => :key, :complete_value => true
|
12
|
+
|
13
|
+
default_scope -> { order("docker_parameters.key") }
|
14
|
+
|
15
|
+
before_validation :strip_whitespaces
|
16
|
+
|
17
|
+
def strip_whitespaces
|
18
|
+
self.value.strip! unless value.blank?
|
19
|
+
end
|
20
|
+
end
|
@@ -42,13 +42,15 @@ class DockerRegistry < ActiveRecord::Base
|
|
42
42
|
_("Docker/Registry")
|
43
43
|
end
|
44
44
|
|
45
|
+
def api
|
46
|
+
@api ||= Service::RegistryApi.new(url: url, user: username,
|
47
|
+
password: password)
|
48
|
+
end
|
49
|
+
|
45
50
|
private
|
46
51
|
|
47
52
|
def attempt_login
|
48
|
-
|
49
|
-
:user => username,
|
50
|
-
:password => password)
|
51
|
-
login_endpoint.get == "\"OK\""
|
53
|
+
api.ok?
|
52
54
|
rescue => e
|
53
55
|
errors.add(:base, _('Unable to log in to this Docker Registry - %s') % e)
|
54
56
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
class EnvironmentVariable <
|
1
|
+
class EnvironmentVariable < DockerParameter
|
2
2
|
belongs_to :container, :foreign_key => :reference_id, :inverse_of => :environment_variables
|
3
|
-
audited :
|
4
|
-
validates :
|
3
|
+
audited :associated_with => :container, :allow_mass_assignment => true
|
4
|
+
validates :key, :uniqueness => { :scope => :reference_id }
|
5
5
|
end
|
data/app/models/exposed_port.rb
CHANGED
@@ -1,14 +1,8 @@
|
|
1
|
-
class ExposedPort <
|
2
|
-
# The Parameter class from which ExposedPort class inherits,validates for the
|
3
|
-
# presence of an associated domain, operating system, host or host group. We
|
4
|
-
# will have to reset those validations for the ExposedPort class as they do
|
5
|
-
# not make any sense for the context in which this class is being used here.
|
6
|
-
ExposedPort.reset_callbacks(:validate)
|
7
|
-
|
1
|
+
class ExposedPort < DockerParameter
|
8
2
|
belongs_to :container, :foreign_key => :reference_id, :inverse_of => :exposed_ports
|
9
|
-
audited :
|
10
|
-
validates :
|
11
|
-
validates :
|
3
|
+
audited :associated_with => :container, :allow_mass_assignment => true
|
4
|
+
validates :key, :uniqueness => { :scope => :reference_id }
|
5
|
+
validates :key, :numericality => { :only_integer => true,
|
12
6
|
:greater_than => 0,
|
13
7
|
:less_than_or_equal_to => 655_35,
|
14
8
|
:message => "%{value} is not a valid port number" }
|
@@ -1,19 +1,13 @@
|
|
1
1
|
require 'resolv'
|
2
2
|
|
3
3
|
module ForemanDocker
|
4
|
-
class Dns <
|
5
|
-
# The Parameter class from which this Dns class inherits,validates for the
|
6
|
-
# presence of an associated domain, operating system, host or host group.
|
7
|
-
# We will have to reset those validations for the Dns class as they do not
|
8
|
-
# make any sense for the context in which this class is being used here.
|
9
|
-
ForemanDocker::Dns.reset_callbacks(:validate)
|
10
|
-
|
4
|
+
class Dns < DockerParameter
|
11
5
|
belongs_to :container, :foreign_key => :reference_id,
|
12
6
|
:inverse_of => :dns,
|
13
7
|
:class_name => "Container"
|
14
8
|
|
15
|
-
audited :
|
16
|
-
validates :
|
9
|
+
audited :associated_with => :container, :allow_mass_assignment => true
|
10
|
+
validates :key, :uniqueness => { :scope => :reference_id },
|
17
11
|
:format => {
|
18
12
|
:with => Regexp.union(Resolv::IPv4::Regex,
|
19
13
|
Resolv::IPv6::Regex,
|
@@ -61,11 +61,7 @@ module ForemanDocker
|
|
61
61
|
if exist?(image_name)
|
62
62
|
tags_for_local_image(image(image_name))
|
63
63
|
else
|
64
|
-
|
65
|
-
hub_api_url = "https://index.docker.io/v1/repositories/#{image_name}/tags"
|
66
|
-
JSON.parse(URI.parse(hub_api_url).read).map do |tag|
|
67
|
-
tag['name']
|
68
|
-
end
|
64
|
+
Service::RegistryApi.docker_hub.tags(image_name).map { |tag| tag['name'] }
|
69
65
|
end
|
70
66
|
end
|
71
67
|
|
@@ -41,9 +41,14 @@ module Service
|
|
41
41
|
|
42
42
|
pull_image(container)
|
43
43
|
start_container(container)
|
44
|
-
|
44
|
+
unless container.valid?
|
45
|
+
@errors = errors + container.errors.full_messages
|
46
|
+
end
|
45
47
|
|
46
|
-
|
48
|
+
if @errors.present?
|
49
|
+
@errors = @errors.flatten.uniq
|
50
|
+
fail ActiveRecord::Rollback
|
51
|
+
end
|
47
52
|
|
48
53
|
container.name = container.in_fog.name[1..-1] unless container.name.present?
|
49
54
|
|
@@ -53,7 +58,8 @@ module Service
|
|
53
58
|
def pull_image(container)
|
54
59
|
success = container.compute_resource.
|
55
60
|
create_image(:fromImage => container.repository_pull_url)
|
56
|
-
|
61
|
+
return true if success
|
62
|
+
@errors = errors + container.compute_resource.errors.full_messages
|
57
63
|
end
|
58
64
|
|
59
65
|
def start_container(container)
|
@@ -61,7 +67,7 @@ module Service
|
|
61
67
|
if started
|
62
68
|
container.uuid = started.id
|
63
69
|
else
|
64
|
-
errors
|
70
|
+
@errors = errors + container.compute_resource.errors.full_messages
|
65
71
|
end
|
66
72
|
started
|
67
73
|
end
|
@@ -74,31 +80,29 @@ module Service
|
|
74
80
|
def load_environment_variables(state, r)
|
75
81
|
state.environment_variables.each do |environment_variable|
|
76
82
|
var = r.environment_variables.build
|
77
|
-
var.
|
83
|
+
var.key = environment_variable.key
|
78
84
|
var.value = environment_variable.value
|
79
|
-
var.priority = environment_variable.priority
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
83
88
|
def load_exposed_ports(state, r)
|
84
89
|
state.exposed_ports.each do |e|
|
85
90
|
port = r.exposed_ports.build
|
86
|
-
port.
|
91
|
+
port.key = e.key
|
87
92
|
port.value = e.value
|
88
|
-
port.priority = e.priority
|
89
93
|
end
|
90
94
|
end
|
91
95
|
|
92
96
|
def load_dns(state, r)
|
93
97
|
state.dns.each do |e|
|
94
98
|
dns = r.dns.build
|
95
|
-
dns.
|
96
|
-
dns.priority = e.priority
|
99
|
+
dns.key = e.key
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
100
103
|
def full_messages
|
101
|
-
errors.respond_to?(:full_messages)
|
104
|
+
return errors.full_messages if errors.respond_to?(:full_messages)
|
105
|
+
@errors
|
102
106
|
end
|
103
107
|
|
104
108
|
def run_container(container)
|
@@ -1,26 +1,98 @@
|
|
1
1
|
module Service
|
2
2
|
class RegistryApi
|
3
|
-
|
4
|
-
|
3
|
+
DOCKER_HUB = 'https://registry.hub.docker.com/'.freeze
|
4
|
+
DEFAULTS = {
|
5
|
+
url: 'http://localhost:5000'.freeze,
|
6
|
+
connection: { omit_default_port: true }
|
7
|
+
}
|
8
|
+
|
9
|
+
attr_accessor :config, :url
|
10
|
+
delegate :logger, :to => Rails
|
5
11
|
|
6
12
|
def initialize(params = {})
|
7
|
-
config = DEFAULTS.merge(params)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
13
|
+
self.config = DEFAULTS.merge(params)
|
14
|
+
self.url = config[:url]
|
15
|
+
@user = config[:user] unless config[:user].blank?
|
16
|
+
@password = config[:password] unless config[:password].blank?
|
17
|
+
|
18
|
+
Docker.logger = logger if Rails.env.development? || Rails.env.test?
|
19
|
+
end
|
20
|
+
|
21
|
+
def connection
|
22
|
+
@connection ||= ::Docker::Connection.new(url, credentials)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(path, params = nil)
|
26
|
+
response = connection.get('/'.freeze, params,
|
27
|
+
DEFAULTS[:connection].merge({ path: "#{path}" }))
|
28
|
+
response = parse_json(response)
|
29
|
+
response
|
30
|
+
end
|
31
|
+
|
32
|
+
# Since the Registry API v2 does not support a search the v1 endpoint is used
|
33
|
+
# Newer registries will fail, the v2 catalog endpoint is used
|
34
|
+
def search(query)
|
35
|
+
get('/v1/search'.freeze, { q: query })
|
36
|
+
rescue => e
|
37
|
+
logger.warn "API v1 - Search failed #{e.backtrace}"
|
38
|
+
{ 'results' => catalog(query) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Some Registries might have this endpoint not implemented/enabled
|
42
|
+
def catalog(query)
|
43
|
+
get('/v2/_catalog'.freeze)['repositories'].select do |image|
|
44
|
+
image =~ /^#{query}/
|
45
|
+
end.map { |image_name| { 'name' => image_name } }
|
46
|
+
end
|
47
|
+
|
48
|
+
def tags(image_name, query = nil)
|
49
|
+
result = get_tags(image_name)
|
50
|
+
result = result.keys.map { |t| {'name' => t.to_s } } if result.is_a? Hash
|
51
|
+
result = filter_tags(result, query) if query
|
52
|
+
result
|
53
|
+
end
|
54
|
+
|
55
|
+
def ok?
|
56
|
+
get('/v1/'.freeze).match("Docker Registry API")
|
57
|
+
rescue => e
|
58
|
+
logger.warn "API v1 - Ping failed #{e.backtrace}"
|
59
|
+
get('/v2/'.freeze).is_a? Hash
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.docker_hub
|
63
|
+
@@docker_hub ||= new(url: DOCKER_HUB)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def parse_json(string)
|
69
|
+
JSON.parse(string)
|
70
|
+
rescue => e
|
71
|
+
logger.warn "JSON parsing failed: #{e.backtrace}"
|
72
|
+
string
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_tags(image_name)
|
76
|
+
get("/v1/repositories/#{image_name}/tags")
|
77
|
+
rescue => e
|
78
|
+
logger.warn "API v1 - Repository images request failed #{e.backtrace}"
|
79
|
+
tags_v2(image_name)
|
80
|
+
end
|
81
|
+
|
82
|
+
def tags_v2(image_name)
|
83
|
+
get("/v2/#{image_name}/tags/list")['tags'].map { |tag| { 'name' => tag } }
|
84
|
+
rescue Docker::Error::NotFoundError
|
85
|
+
[]
|
12
86
|
end
|
13
87
|
|
14
|
-
def
|
15
|
-
|
16
|
-
:params => { :q => aquery }, :accept => :json)
|
17
|
-
JSON.parse(response.body)
|
88
|
+
def credentials
|
89
|
+
{ user: @user, password: @password }
|
18
90
|
end
|
19
91
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
92
|
+
def filter_tags(result, query)
|
93
|
+
result.select do |tag_name|
|
94
|
+
tag_name['name'] =~ /^#{query}/
|
95
|
+
end
|
24
96
|
end
|
25
97
|
end
|
26
98
|
end
|