katello 4.0.0.rc1 → 4.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/katello/katello.scss +0 -72
- data/app/controllers/katello/api/v2/host_errata_controller.rb +1 -1
- data/app/controllers/katello/api/v2/host_packages_controller.rb +6 -6
- data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
- data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +1 -1
- data/app/lib/actions/katello/agent/dispatch_history_presenter.rb +64 -0
- data/app/lib/actions/katello/agent_action.rb +107 -0
- data/app/lib/actions/katello/bulk_agent_action.rb +21 -0
- data/app/lib/actions/katello/host/erratum/applicable_errata_install.rb +1 -1
- data/app/lib/actions/katello/host/erratum/install.rb +8 -26
- data/app/lib/actions/katello/host/package/install.rb +8 -21
- data/app/lib/actions/katello/host/package/remove.rb +8 -20
- data/app/lib/actions/katello/host/package/update.rb +9 -22
- data/app/lib/actions/katello/host/package_group/install.rb +8 -21
- data/app/lib/actions/katello/host/package_group/remove.rb +8 -20
- data/app/lib/actions/pulp/consumer.rb +0 -11
- data/app/lib/katello/agent/base_message.rb +38 -0
- data/app/lib/katello/agent/client_message_handler.rb +60 -0
- data/app/lib/katello/agent/connection.rb +24 -0
- data/app/lib/katello/agent/install_errata_message.rb +25 -0
- data/app/lib/katello/agent/install_package_group_message.rb +25 -0
- data/app/lib/katello/agent/install_package_message.rb +28 -0
- data/app/lib/katello/agent/remove_package_group_message.rb +25 -0
- data/app/lib/katello/agent/remove_package_message.rb +28 -0
- data/app/lib/katello/agent/update_package_message.rb +25 -0
- data/app/lib/katello/event_daemon/services/agent_event_receiver.rb +62 -0
- data/app/lib/katello/messaging/received_message.rb +1 -1
- data/app/lib/katello/qpid/connection.rb +130 -0
- data/app/models/katello/agent/dispatch_history.rb +17 -0
- data/app/models/katello/concerns/host_managed_extensions.rb +3 -0
- data/app/models/katello/events/delete_host_agent_queue.rb +19 -0
- data/app/models/katello/ping.rb +9 -1
- data/app/models/setting/content.rb +0 -2
- data/app/services/katello/agent/dispatcher.rb +66 -0
- data/app/services/katello/candlepin_event_listener.rb +1 -0
- data/app/services/katello/event_monitor/poller_thread.rb +1 -0
- data/app/services/katello/registration_manager.rb +10 -0
- data/app/views/katello/sync_management/_products.html.erb +1 -1
- data/db/migrate/20210122200618_create_katello_agent_dispatch_history.rb +11 -0
- data/db/migrate/20210125161911_delete_erratum_install_batch_size_setting.rb +5 -0
- data/db/migrate/20210208213920_add_available_module_stream_context.rb +8 -0
- data/engines/bastion/app/assets/javascripts/bastion/auth/authorization.service.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscription-start-date.directive.js +21 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/subscription-type.directive.js +16 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/subscription-start-date.html +2 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/subscription-type.html +18 -0
- data/lib/katello/engine.rb +7 -0
- data/lib/katello/plugin.rb +1 -0
- data/lib/katello/tasks/reset.rake +0 -15
- data/lib/katello/version.rb +1 -1
- data/locale/bn/katello.edit.po +8538 -0
- data/locale/bn/katello.po.time_stamp +0 -0
- data/locale/cs/katello.edit.po +8440 -0
- data/locale/cs/katello.po.time_stamp +0 -0
- data/locale/de/katello.edit.po +8344 -0
- data/locale/de/katello.po.time_stamp +0 -0
- data/locale/en/katello.edit.po +8161 -0
- data/locale/en/katello.po.time_stamp +0 -0
- data/locale/es/katello.edit.po +8306 -0
- data/locale/es/katello.po.time_stamp +0 -0
- data/locale/fr/katello.edit.po +8356 -0
- data/locale/fr/katello.po.time_stamp +0 -0
- data/locale/gu/katello.edit.po +8540 -0
- data/locale/gu/katello.po.time_stamp +0 -0
- data/locale/hi/katello.edit.po +8537 -0
- data/locale/hi/katello.po.time_stamp +0 -0
- data/locale/it/katello.edit.po +8293 -0
- data/locale/it/katello.po.time_stamp +0 -0
- data/locale/ja/katello.edit.po +8322 -0
- data/locale/ja/katello.po.time_stamp +0 -0
- data/locale/kn/katello.edit.po +8538 -0
- data/locale/kn/katello.po.time_stamp +0 -0
- data/locale/ko/katello.edit.po +8289 -0
- data/locale/ko/katello.po.time_stamp +0 -0
- data/locale/mr/katello.edit.po +8502 -0
- data/locale/mr/katello.po.time_stamp +0 -0
- data/locale/or/katello.edit.po +8538 -0
- data/locale/or/katello.po.time_stamp +0 -0
- data/locale/pa/katello.edit.po +8524 -0
- data/locale/pa/katello.po.time_stamp +0 -0
- data/locale/pt/katello.edit.po +8255 -0
- data/locale/pt/katello.po.time_stamp +0 -0
- data/locale/pt_BR/katello.edit.po +8289 -0
- data/locale/pt_BR/katello.po.time_stamp +0 -0
- data/locale/ru/katello.edit.po +8309 -0
- data/locale/ru/katello.po.time_stamp +0 -0
- data/locale/ta/katello.edit.po +8536 -0
- data/locale/ta/katello.po.time_stamp +0 -0
- data/locale/te/katello.edit.po +8536 -0
- data/locale/te/katello.po.time_stamp +0 -0
- data/locale/zh_CN/katello.edit.po +8288 -0
- data/locale/zh_CN/katello.po.time_stamp +0 -0
- data/locale/zh_TW/katello.edit.po +8420 -0
- data/locale/zh_TW/katello.po.time_stamp +0 -0
- metadata +62 -12
- data/app/lib/actions/pulp/consumer/abstract_content_action.rb +0 -71
- data/app/lib/actions/pulp/consumer/content_install.rb +0 -43
- data/app/lib/actions/pulp/consumer/content_uninstall.rb +0 -26
- data/app/lib/actions/pulp/consumer/content_update.rb +0 -32
- data/db/functions/empty_v01.sql +0 -7
- data/db/functions/evr_trigger_v01.sql +0 -9
- data/db/functions/isalpha_v01.sql +0 -11
- data/db/functions/isalphanum_v01.sql +0 -12
- data/db/functions/isdigit_v01.sql +0 -10
- data/db/functions/rpmver_array_v01.sql +0 -60
@@ -2,16 +2,13 @@ module Actions
|
|
2
2
|
module Katello
|
3
3
|
module Host
|
4
4
|
module Package
|
5
|
-
class Remove < Actions::
|
6
|
-
|
5
|
+
class Remove < Actions::Katello::AgentAction
|
6
|
+
def self.agent_message
|
7
|
+
:remove_package
|
8
|
+
end
|
7
9
|
|
8
|
-
def
|
9
|
-
|
10
|
-
plan_action(Pulp::Consumer::ContentUninstall,
|
11
|
-
consumer_uuid: host.content_facet.uuid,
|
12
|
-
type: 'rpm',
|
13
|
-
args: packages)
|
14
|
-
plan_self(:host_id => host.id)
|
10
|
+
def agent_action_type
|
11
|
+
:content_uninstall
|
15
12
|
end
|
16
13
|
|
17
14
|
def humanized_name
|
@@ -27,7 +24,7 @@ module Actions
|
|
27
24
|
end
|
28
25
|
|
29
26
|
def humanized_package_names
|
30
|
-
input[:
|
27
|
+
input[:content].inject([]) do |result, package|
|
31
28
|
if package.is_a?(Hash)
|
32
29
|
new_name = package.include?(:name) ? package[:name] : ""
|
33
30
|
new_name += '-' + package[:version] if package.include?(:version)
|
@@ -40,18 +37,9 @@ module Actions
|
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
43
|
-
def presenter
|
44
|
-
Helpers::Presenter::Delegated.new(
|
45
|
-
self, planned_actions(Pulp::Consumer::ContentUninstall))
|
46
|
-
end
|
47
|
-
|
48
|
-
def rescue_strategy
|
49
|
-
Dynflow::Action::Rescue::Skip
|
50
|
-
end
|
51
|
-
|
52
40
|
def finalize
|
53
41
|
host = ::Host.find_by(:id => input[:host_id])
|
54
|
-
host.update(audit_comment: (_("Removal of package(s) requested: %{packages}") % {packages: input[:
|
42
|
+
host.update(audit_comment: (_("Removal of package(s) requested: %{packages}") % {packages: input[:content].join(", ")}).truncate(255))
|
55
43
|
end
|
56
44
|
end
|
57
45
|
end
|
@@ -2,18 +2,13 @@ module Actions
|
|
2
2
|
module Katello
|
3
3
|
module Host
|
4
4
|
module Package
|
5
|
-
class Update < Actions::
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
Type! host, ::Host::Managed
|
5
|
+
class Update < Actions::Katello::AgentAction
|
6
|
+
def self.agent_message
|
7
|
+
:update_package
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
consumer_uuid: host.content_facet.uuid,
|
14
|
-
type: 'rpm',
|
15
|
-
args: packages)
|
16
|
-
plan_self(:host_id => host.id)
|
10
|
+
def agent_action_type
|
11
|
+
:content_install
|
17
12
|
end
|
18
13
|
|
19
14
|
def humanized_name
|
@@ -25,15 +20,7 @@ module Actions
|
|
25
20
|
end
|
26
21
|
|
27
22
|
def humanized_input
|
28
|
-
[(input[:
|
29
|
-
end
|
30
|
-
|
31
|
-
def presenter
|
32
|
-
Helpers::Presenter::Delegated.new(self, planned_actions(Pulp::Consumer::ContentUpdate))
|
33
|
-
end
|
34
|
-
|
35
|
-
def rescue_strategy
|
36
|
-
Dynflow::Action::Rescue::Skip
|
23
|
+
[(input[:content].present? && input[:content].join(", ") || "all packages")] + super
|
37
24
|
end
|
38
25
|
|
39
26
|
def finalize
|
@@ -42,8 +29,8 @@ module Actions
|
|
42
29
|
end
|
43
30
|
|
44
31
|
def audit_comment
|
45
|
-
if input[:
|
46
|
-
(_("Update of package(s) requested: %{packages}") % {packages: input[:
|
32
|
+
if input[:content].present?
|
33
|
+
(_("Update of package(s) requested: %{packages}") % {packages: input[:content].join(", ")}).truncate(255)
|
47
34
|
else
|
48
35
|
_("Update of all packages requested")
|
49
36
|
end
|
@@ -2,18 +2,13 @@ module Actions
|
|
2
2
|
module Katello
|
3
3
|
module Host
|
4
4
|
module PackageGroup
|
5
|
-
class Install < Actions::
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
Type! host, ::Host::Managed
|
5
|
+
class Install < Actions::Katello::AgentAction
|
6
|
+
def self.agent_message
|
7
|
+
:install_package_group
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
consumer_uuid: host.content_facet.uuid,
|
14
|
-
type: 'package_group',
|
15
|
-
args: groups)
|
16
|
-
plan_self(:host_id => host.id)
|
10
|
+
def agent_action_type
|
11
|
+
:content_install
|
17
12
|
end
|
18
13
|
|
19
14
|
def humanized_name
|
@@ -21,20 +16,12 @@ module Actions
|
|
21
16
|
end
|
22
17
|
|
23
18
|
def humanized_input
|
24
|
-
[input[:
|
25
|
-
end
|
26
|
-
|
27
|
-
def presenter
|
28
|
-
Helpers::Presenter::Delegated.new(self, planned_actions(Pulp::Consumer::ContentInstall))
|
29
|
-
end
|
30
|
-
|
31
|
-
def rescue_strategy
|
32
|
-
Dynflow::Action::Rescue::Skip
|
19
|
+
[input[:content].join(", ")] + super
|
33
20
|
end
|
34
21
|
|
35
22
|
def finalize
|
36
23
|
host = ::Host.find_by(:id => input[:host_id])
|
37
|
-
host.update(audit_comment: (_("Installation of package group(s) requested: %{groups}") % {groups: input[:
|
24
|
+
host.update(audit_comment: (_("Installation of package group(s) requested: %{groups}") % {groups: input[:content].join(", ")}).truncate(255))
|
38
25
|
end
|
39
26
|
end
|
40
27
|
end
|
@@ -2,16 +2,13 @@ module Actions
|
|
2
2
|
module Katello
|
3
3
|
module Host
|
4
4
|
module PackageGroup
|
5
|
-
class Remove < Actions::
|
6
|
-
|
5
|
+
class Remove < Actions::Katello::AgentAction
|
6
|
+
def self.agent_message
|
7
|
+
:remove_package_group
|
8
|
+
end
|
7
9
|
|
8
|
-
def
|
9
|
-
|
10
|
-
plan_action(Pulp::Consumer::ContentUninstall,
|
11
|
-
consumer_uuid: host.content_facet.uuid,
|
12
|
-
type: 'package_group',
|
13
|
-
args: groups)
|
14
|
-
plan_self(:host_id => host.id)
|
10
|
+
def agent_action_type
|
11
|
+
:content_uninstall
|
15
12
|
end
|
16
13
|
|
17
14
|
def humanized_name
|
@@ -19,21 +16,12 @@ module Actions
|
|
19
16
|
end
|
20
17
|
|
21
18
|
def humanized_input
|
22
|
-
[input[:
|
23
|
-
end
|
24
|
-
|
25
|
-
def presenter
|
26
|
-
Helpers::Presenter::Delegated.new(
|
27
|
-
self, planned_actions(Pulp::Consumer::ContentUninstall))
|
28
|
-
end
|
29
|
-
|
30
|
-
def rescue_strategy
|
31
|
-
Dynflow::Action::Rescue::Skip
|
19
|
+
[input[:content].join(', ')] + super
|
32
20
|
end
|
33
21
|
|
34
22
|
def finalize
|
35
23
|
host = ::Host.find_by(:id => input[:host_id])
|
36
|
-
host.update(audit_comment: (_("Removal of package group(s) requested: %{groups}") % {groups: input[:
|
24
|
+
host.update(audit_comment: (_("Removal of package group(s) requested: %{groups}") % {groups: input[:content].join(", ")}).truncate(255))
|
37
25
|
end
|
38
26
|
end
|
39
27
|
end
|
@@ -9,8 +9,6 @@ module Actions
|
|
9
9
|
ret << task_result_packages
|
10
10
|
elsif task_result_packages.any?
|
11
11
|
ret.concat(task_result_packages.map { |package| package[:qname] })
|
12
|
-
else
|
13
|
-
ret << humanized_no_package
|
14
12
|
end
|
15
13
|
if humanized_errors
|
16
14
|
ret.concat(humanized_errors)
|
@@ -96,15 +94,6 @@ module Actions
|
|
96
94
|
def humanized_errors
|
97
95
|
task_errors&.map { |k, v| "#{k}: #{v}" }
|
98
96
|
end
|
99
|
-
|
100
|
-
def humanized_no_package
|
101
|
-
case action
|
102
|
-
when Consumer::ContentInstall
|
103
|
-
_("No new packages installed")
|
104
|
-
when Consumer::ContentUninstall
|
105
|
-
_("No packages removed")
|
106
|
-
end
|
107
|
-
end
|
108
97
|
end
|
109
98
|
end
|
110
99
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class BaseMessage
|
4
|
+
attr_accessor :dispatch_history_id, :recipient_address, :reply_to
|
5
|
+
|
6
|
+
def json
|
7
|
+
{
|
8
|
+
data: {
|
9
|
+
consumer_id: @consumer_id,
|
10
|
+
dispatch_history_id: dispatch_history_id
|
11
|
+
},
|
12
|
+
replyto: reply_to,
|
13
|
+
request: {
|
14
|
+
args: [
|
15
|
+
units,
|
16
|
+
{
|
17
|
+
importkeys: true
|
18
|
+
}
|
19
|
+
],
|
20
|
+
classname: "Content",
|
21
|
+
cntr: [[], {}],
|
22
|
+
kws: {},
|
23
|
+
method: @method
|
24
|
+
},
|
25
|
+
routing: [
|
26
|
+
nil,
|
27
|
+
recipient_address
|
28
|
+
],
|
29
|
+
version: "2.0"
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
json.to_json
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class ClientMessageHandler
|
4
|
+
def initialize(message)
|
5
|
+
logger.debug("client message: #{message.body}")
|
6
|
+
@json = parse_message_json(message)
|
7
|
+
dispatch_history_id = @json&.dig(:data, :dispatch_history_id)
|
8
|
+
@dispatch_history = Katello::Agent::DispatchHistory.find_by_id(dispatch_history_id)
|
9
|
+
|
10
|
+
unless @dispatch_history
|
11
|
+
fail("No valid dispatch history in client message")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def accepted?
|
16
|
+
@json[:status] == 'accepted'
|
17
|
+
end
|
18
|
+
|
19
|
+
def result
|
20
|
+
@json.dig(:result, :retval, :details)
|
21
|
+
end
|
22
|
+
|
23
|
+
def handle
|
24
|
+
@dispatch_history.accepted_at = DateTime.now if accepted?
|
25
|
+
@dispatch_history.result = result if result
|
26
|
+
@dispatch_history.save!
|
27
|
+
|
28
|
+
if @dispatch_history.dynflow_execution_plan_id && @dispatch_history.dynflow_step_id
|
29
|
+
handle_dynflow_event
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def handle_dynflow_event
|
36
|
+
task_exists = ForemanTasks::Task.exists?(external_id: @dispatch_history.dynflow_execution_plan_id, result: 'pending')
|
37
|
+
unless task_exists
|
38
|
+
logger.warn("Couldn't find pending task with external_id=#{@dispatch_history.dynflow_execution_plan_id} dispatch_history_id=#{@dispatch_history.id}")
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
42
|
+
if accepted?
|
43
|
+
ForemanTasks.dynflow.world.event(@dispatch_history.dynflow_execution_plan_id, @dispatch_history.dynflow_step_id, 'accepted')
|
44
|
+
elsif result
|
45
|
+
ForemanTasks.dynflow.world.event(@dispatch_history.dynflow_execution_plan_id, @dispatch_history.dynflow_step_id, 'finished')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_message_json(message)
|
50
|
+
JSON.parse(message.body).with_indifferent_access
|
51
|
+
rescue
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def logger
|
56
|
+
::Foreman::Logging.logger('katello/agent')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class Connection
|
4
|
+
def send_messages(messages)
|
5
|
+
connection = ::Katello::Qpid::Connection.new(settings[:broker_url])
|
6
|
+
connection.send_messages(messages)
|
7
|
+
end
|
8
|
+
|
9
|
+
def fetch_agent_messages(handler = ClientMessageHandler)
|
10
|
+
connection = ::Katello::Qpid::Connection.new(settings[:broker_url])
|
11
|
+
connection.receive_messages(address: settings[:event_queue_name], handler: handler)
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete_client_queue(queue_name)
|
15
|
+
connection = ::Katello::Qpid::Connection.new(settings[:broker_url])
|
16
|
+
connection.delete_queue(queue_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def settings
|
20
|
+
SETTINGS[:katello][:agent]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class InstallErrataMessage < BaseMessage
|
4
|
+
def initialize(content:, consumer_id:)
|
5
|
+
@errata_ids = content
|
6
|
+
@consumer_id = consumer_id
|
7
|
+
@content_type = 'erratum'
|
8
|
+
@method = 'install'
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def units
|
14
|
+
@errata_ids.map do |id|
|
15
|
+
{
|
16
|
+
type_id: @content_type,
|
17
|
+
unit_key: {
|
18
|
+
id: id
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class InstallPackageGroupMessage < BaseMessage
|
4
|
+
def initialize(content:, consumer_id:)
|
5
|
+
@groups = content
|
6
|
+
@consumer_id = consumer_id
|
7
|
+
@content_type = 'package_group'
|
8
|
+
@method = 'install'
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def units
|
14
|
+
@groups.map do |group|
|
15
|
+
{
|
16
|
+
type_id: @content_type,
|
17
|
+
unit_key: {
|
18
|
+
name: group
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class InstallPackageMessage < BaseMessage
|
4
|
+
def initialize(content:, consumer_id:)
|
5
|
+
@packages = content
|
6
|
+
@consumer_id = consumer_id
|
7
|
+
@content_type = 'rpm'
|
8
|
+
@method = 'install'
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def units
|
14
|
+
@packages.map do |package|
|
15
|
+
nvra = ::Katello::Util::Package.parse_nvrea_nvre(package)
|
16
|
+
unit_key = nvra || {
|
17
|
+
name: package
|
18
|
+
}
|
19
|
+
|
20
|
+
{
|
21
|
+
type_id: @content_type,
|
22
|
+
unit_key: unit_key
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Katello
|
2
|
+
module Agent
|
3
|
+
class RemovePackageGroupMessage < BaseMessage
|
4
|
+
def initialize(content:, consumer_id:)
|
5
|
+
@groups = content
|
6
|
+
@consumer_id = consumer_id
|
7
|
+
@content_type = 'package_group'
|
8
|
+
@method = 'uninstall'
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def units
|
14
|
+
@groups.map do |group|
|
15
|
+
{
|
16
|
+
type_id: @content_type,
|
17
|
+
unit_key: {
|
18
|
+
name: group
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|