katello 3.17.0.rc2.1 → 3.17.3

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.

Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/api_controller.rb +1 -2
  3. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +9 -1
  4. data/app/controllers/katello/api/v2/host_tracer_controller.rb +16 -36
  5. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +12 -1
  6. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +23 -0
  7. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +6 -2
  8. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +6 -2
  9. data/app/lib/actions/katello/content_view/promote.rb +2 -2
  10. data/app/lib/actions/katello/content_view/promote_to_environment.rb +12 -3
  11. data/app/lib/actions/katello/content_view/publish.rb +18 -2
  12. data/app/lib/actions/katello/content_view_version/import.rb +36 -0
  13. data/app/lib/actions/katello/content_view_version/incremental_update.rb +1 -1
  14. data/app/lib/actions/katello/host/hypervisors_update.rb +18 -0
  15. data/app/lib/actions/katello/organization/create.rb +1 -1
  16. data/app/lib/actions/katello/organization/simple_content_access/disable.rb +8 -0
  17. data/app/lib/actions/katello/organization/simple_content_access/enable.rb +8 -0
  18. data/app/lib/actions/katello/organization/simple_content_access/toggle.rb +16 -2
  19. data/app/lib/actions/katello/repository/multi_clone_contents.rb +8 -6
  20. data/app/lib/actions/pulp3/abstract_async_task.rb +1 -0
  21. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
  22. data/app/lib/actions/pulp3/content_view_version/create_importer.rb +20 -0
  23. data/app/lib/actions/pulp3/content_view_version/destroy_importer.rb +16 -0
  24. data/app/lib/actions/pulp3/content_view_version/import.rb +21 -0
  25. data/app/lib/actions/pulp3/orchestration/content_view_version/copy_version_units_to_library.rb +25 -0
  26. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +9 -1
  27. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +41 -0
  28. data/app/lib/actions/pulp3/repository/copy_content.rb +6 -1
  29. data/app/lib/actions/pulp3/repository/delete.rb +1 -1
  30. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +1 -1
  31. data/app/lib/katello/resources/cdn.rb +3 -2
  32. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -7
  33. data/app/models/katello/concerns/redhat_extensions.rb +2 -2
  34. data/app/models/katello/concerns/smart_proxy_extensions.rb +3 -1
  35. data/app/models/katello/content_view.rb +6 -0
  36. data/app/models/katello/content_view_version.rb +10 -1
  37. data/app/models/katello/glue/pulp/repo.rb +1 -1
  38. data/app/models/katello/root_repository.rb +5 -1
  39. data/app/overrides/add_organization_attributes.rb +12 -0
  40. data/app/services/katello/applicability/applicable_content_helper.rb +12 -1
  41. data/app/services/katello/host_trace_manager.rb +38 -0
  42. data/app/services/katello/pulp3/content_view_version/export.rb +25 -29
  43. data/app/services/katello/pulp3/content_view_version/import.rb +87 -0
  44. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +44 -0
  45. data/app/services/katello/pulp3/erratum.rb +2 -1
  46. data/app/services/katello/pulp3/repository.rb +8 -4
  47. data/app/services/katello/pulp3/repository/yum.rb +71 -4
  48. data/app/services/katello/pulp3/task.rb +4 -4
  49. data/app/services/katello/pulp3/task_group.rb +6 -0
  50. data/app/services/katello/ui_notifications/subscriptions/sca_disable_error.rb +13 -0
  51. data/app/services/katello/ui_notifications/subscriptions/sca_disable_success.rb +13 -0
  52. data/app/services/katello/ui_notifications/subscriptions/sca_enable_error.rb +13 -0
  53. data/app/services/katello/ui_notifications/subscriptions/sca_enable_success.rb +13 -0
  54. data/app/views/overrides/organizations/_edit_override.html.erb +10 -1
  55. data/app/views/overrides/organizations/_index_header_override.html.erb +3 -0
  56. data/app/views/overrides/organizations/_index_row_override.html.erb +3 -0
  57. data/config/routes/api/v2.rb +1 -6
  58. data/config/routes/overrides.rb +4 -0
  59. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  60. data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +5 -2
  61. data/db/seeds.d/109-katello-notification-blueprints.rb +24 -0
  62. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +2 -5
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +4 -3
  64. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +2 -4
  65. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-repository-sets.html +1 -1
  66. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
  67. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-traces-modal.controller.js +3 -4
  68. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details-info.controller.js +2 -4
  69. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +4 -3
  70. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-subscriptions.controller.js +2 -4
  71. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-repository-sets.html +1 -1
  72. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +1 -1
  73. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +2 -1
  74. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +1 -1
  75. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +1 -1
  76. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -2
  77. data/lib/katello/permission_creator.rb +1 -1
  78. data/lib/katello/permissions/host_permissions.rb +1 -0
  79. data/lib/katello/tasks/pulp3_content_switchover.rake +3 -1
  80. data/lib/katello/tasks/pulp3_post_migration_check.rake +2 -1
  81. data/lib/katello/tasks/reimport.rake +1 -1
  82. data/lib/katello/tasks/reports.rake +4 -1
  83. data/lib/katello/version.rb +1 -1
  84. data/webpack/index.js +0 -1
  85. metadata +34 -14
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-traces-resolve.factory.js +0 -18
@@ -4,6 +4,7 @@ module Actions
4
4
  module SimpleContentAccess
5
5
  class Toggle < Actions::AbstractAsyncTask
6
6
  middleware.use Actions::Middleware::PropagateCandlepinErrors
7
+ include Helpers::Notifications
7
8
 
8
9
  SIMPLE_CONTENT_ACCESS_DISABLED_VALUE = "entitlement".freeze
9
10
  SIMPLE_CONTENT_ACCESS_ENABLED_VALUE = "org_environment".freeze
@@ -12,7 +13,7 @@ module Actions
12
13
 
13
14
  def plan(organization_id)
14
15
  @organization = ::Organization.find(organization_id)
15
-
16
+ action_subject organization
16
17
  ::Katello::Resources::Candlepin::UpstreamConsumer.update(
17
18
  "#{consumer['apiUrl']}#{consumer['uuid']}",
18
19
  consumer['idCert']['cert'],
@@ -24,10 +25,23 @@ module Actions
24
25
  plan_action(::Actions::Katello::Organization::ManifestRefresh, organization)
25
26
  end
26
27
 
28
+ def failure_notification(plan)
29
+ task_error_notification.deliver!(
30
+ :subject => subject_organization,
31
+ :task => get_foreman_task(plan)
32
+ )
33
+ end
34
+
35
+ def success_notification(_plan)
36
+ task_success_notification.deliver!(
37
+ subject_organization
38
+ )
39
+ end
40
+
27
41
  private
28
42
 
29
43
  def consumer
30
- @consumer ||= ::Katello::Resources::Candlepin::UpstreamCandlepinResource.upstream_consumer
44
+ @consumer ||= @organization.owner_details['upstreamConsumer']
31
45
  end
32
46
  end
33
47
  end
@@ -16,14 +16,16 @@ module Actions
16
16
  solve_dependencies: solve_dependencies)
17
17
  end
18
18
 
19
- extended_repo_mapping.each do |source_repos, dest_repo_map|
20
- if generate_metadata
21
- metadata_generate(source_repos, dest_repo_map[:dest_repo], dest_repo_map[:filters])
19
+ concurrence do
20
+ extended_repo_mapping.each do |source_repos, dest_repo_map|
21
+ if generate_metadata
22
+ metadata_generate(source_repos, dest_repo_map[:dest_repo], dest_repo_map[:filters])
23
+ end
22
24
  end
23
- end
24
25
 
25
- extended_repo_mapping.values.each do |dest_repo_map|
26
- plan_action(Katello::Repository::IndexContent, id: dest_repo_map[:dest_repo].id)
26
+ extended_repo_mapping.values.each do |dest_repo_map|
27
+ plan_action(Katello::Repository::IndexContent, id: dest_repo_map[:dest_repo].id)
28
+ end
27
29
  end
28
30
  end
29
31
  end
@@ -74,6 +74,7 @@ module Actions
74
74
 
75
75
  def cancel
76
76
  pulp_tasks.each { |task| task.cancel }
77
+ task_groups.each { |task_group| task_group.cancel }
77
78
  end
78
79
 
79
80
  def rescue_external_task(error)
@@ -14,7 +14,7 @@ module Actions
14
14
  content_view.repository_references.each do |repository_reference|
15
15
  repo = repository_reference.root_repository.library_instance
16
16
  #force pulp3 in case we've done migrations, but haven't switched over yet
17
- tasks << repo.backend_service(smart_proxy, true).delete(repository_reference.repository_href)
17
+ tasks << repo.backend_service(smart_proxy, true).delete_repository(repository_reference)
18
18
  end
19
19
  content_view.repository_references.destroy_all
20
20
 
@@ -0,0 +1,20 @@
1
+ module Actions
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class CreateImporter < Pulp3::Abstract
5
+ input_format do
6
+ param :smart_proxy_id, Integer
7
+ param :content_view_version_id, Integer
8
+ param :path, String
9
+ end
10
+
11
+ def run
12
+ cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
13
+ output[:importer_data] = ::Katello::Pulp3::ContentViewVersion::Import.new(smart_proxy: smart_proxy,
14
+ content_view_version: cvv,
15
+ path: input[:path]).create_importer
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module Actions
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class DestroyImporter < Pulp3::Abstract
5
+ input_format do
6
+ param :smart_proxy_id, Integer
7
+ param :importer_data, Hash
8
+ end
9
+
10
+ def run
11
+ ::Katello::Pulp3::ContentViewVersion::Import.new(smart_proxy: smart_proxy).destroy_importer(input[:importer_data][:pulp_href])
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Actions
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class Import < Pulp3::AbstractAsyncTask
5
+ input_format do
6
+ param :content_view_version_id, Integer
7
+ param :smart_proxy_id, Integer
8
+ param :importer_data, Hash
9
+ param :path, String
10
+ end
11
+
12
+ def invoke_external_task
13
+ cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
14
+ output[:pulp_tasks] = ::Katello::Pulp3::ContentViewVersion::Import.new(smart_proxy: smart_proxy,
15
+ content_view_version: cvv,
16
+ path: input[:path]).create_import(input[:importer_data][:pulp_href])
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Orchestration
4
+ module ContentViewVersion
5
+ class CopyVersionUnitsToLibrary < Actions::EntryAction
6
+ def plan(content_view_version)
7
+ concurrence do
8
+ content_view_version.importable_repositories.each do |repo|
9
+ sequence do
10
+ copy_action = plan_action(Actions::Pulp3::Repository::CopyContent, repo, SmartProxy.pulp_primary!,
11
+ repo.library_instance,
12
+ copy_all: true)
13
+ plan_action(Actions::Pulp3::Repository::SaveVersion, repo.library_instance,
14
+ tasks: copy_action.output[:pulp_tasks])
15
+ plan_action(Katello::Repository::IndexContent, id: repo.library_instance_id)
16
+ plan_action(Katello::Repository::MetadataGenerate, repo.library_instance, :force => true)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -50,9 +50,17 @@ module Actions
50
50
  api = ::Katello::Pulp3::Api::Core.new(smart_proxy)
51
51
  export_data = api.export_api.list(input[:exporter_data][:pulp_href]).results.first
52
52
  output[:exported_file_name], output[:exported_file_checksum] = export_data.output_file_info.first
53
+ path = File.dirname(output[:exported_file_name].to_s)
53
54
  ::Katello::ContentViewVersionExportHistory.create!(content_view_version_id: input[:content_view_version_id],
54
55
  destination_server: input[:destination_server],
55
- path: File.dirname(output[:exported_file_name].to_s))
56
+ path: path)
57
+ cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
58
+
59
+ export_metadata = ::Katello::Pulp3::ContentViewVersion::Export.new(:content_view_version => cvv,
60
+ :smart_proxy => smart_proxy).generate_metadata
61
+ toc = Dir.glob("#{path}/*toc.json").first
62
+ export_metadata[:toc] = File.basename(toc) if toc
63
+ File.write("#{path}/#{::Katello::Pulp3::ContentViewVersion::Export::METADATA_FILE}", export_metadata.to_json)
56
64
  end
57
65
 
58
66
  def humanized_name
@@ -0,0 +1,41 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Orchestration
4
+ module ContentViewVersion
5
+ class Import < Actions::EntryAction
6
+ def plan(content_view_version, path:)
7
+ action_subject(content_view_version)
8
+ sequence do
9
+ smart_proxy = SmartProxy.pulp_primary!
10
+ importer_output = plan_action(::Actions::Pulp3::ContentViewVersion::CreateImporter,
11
+ content_view_version_id: content_view_version.id,
12
+ smart_proxy_id: smart_proxy.id,
13
+ path: path).output
14
+
15
+ import_output = plan_action(::Actions::Pulp3::ContentViewVersion::Import,
16
+ content_view_version_id: content_view_version.id,
17
+ smart_proxy_id: smart_proxy.id,
18
+ importer_data: importer_output[:importer_data],
19
+ path: path).output
20
+
21
+ plan_action(Actions::Pulp3::Repository::SaveVersions, content_view_version.importable_repositories.pluck(:id),
22
+ tasks: import_output[:pulp_tasks])
23
+
24
+ plan_action(::Actions::Pulp3::ContentViewVersion::DestroyImporter,
25
+ smart_proxy_id: smart_proxy.id,
26
+ importer_data: importer_output[:importer_data])
27
+ end
28
+ end
29
+
30
+ def humanized_name
31
+ _("Import")
32
+ end
33
+
34
+ def rescue_strategy
35
+ Dynflow::Action::Rescue::Skip
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -11,7 +11,12 @@ module Actions
11
11
  def invoke_external_task
12
12
  source = ::Katello::Repository.find(input[:source_repository_id])
13
13
  target = ::Katello::Repository.find(input[:target_repository_id] || input[:target_repository])
14
- output[:pulp_tasks] = target.backend_service(smart_proxy).copy_content_for_source(source, input)
14
+ service = target.backend_service(smart_proxy)
15
+ output[:pulp_tasks] = if input[:copy_all]
16
+ service.copy_all(source)
17
+ else
18
+ service.copy_content_for_source(source, input)
19
+ end
15
20
  end
16
21
  end
17
22
  end
@@ -8,7 +8,7 @@ module Actions
8
8
 
9
9
  def invoke_external_task
10
10
  repo = ::Katello::Repository.find(input[:repository_id])
11
- output[:response] = repo.backend_service(smart_proxy).delete
11
+ output[:response] = repo.backend_service(smart_proxy).delete_repository
12
12
  end
13
13
  end
14
14
  end
@@ -17,7 +17,7 @@ module Actions
17
17
  repo_id_map = {}
18
18
 
19
19
  input[:repo_id_map].each do |source_repo_ids, dest_repo_map|
20
- repo_id_map[JSON.parse(source_repo_ids)] = dest_repo_map
20
+ repo_id_map[JSON.parse(source_repo_ids)] = dest_repo_map.deep_dup
21
21
  end
22
22
 
23
23
  output[:pulp_tasks] = ::Katello::Repository.find(repo_id_map.values.first[:dest_repo]).backend_service(smart_proxy).copy_content_from_mapping(repo_id_map, input)
@@ -18,7 +18,7 @@ module Katello
18
18
  class CdnResource
19
19
  CDN_DOCKER_CONTAINER_LISTING = "CONTAINER_REGISTRY_LISTING".freeze
20
20
 
21
- attr_reader :url, :product, :options
21
+ attr_reader :url, :product, :options, :proxy
22
22
 
23
23
  def substitutor(logger = nil)
24
24
  @logger = logger
@@ -26,6 +26,7 @@ module Katello
26
26
  end
27
27
 
28
28
  def initialize(url, options = {})
29
+ @proxy = ::HttpProxy.default_global_content_proxy
29
30
  @ssl_version = Setting[:cdn_ssl_version]
30
31
  if @ssl_version && !SUPPORTED_SSL_VERSIONS.include?(@ssl_version)
31
32
  fail("Invalid SSL version specified. Check the 'CDN SSL Version' setting")
@@ -140,7 +141,7 @@ module Katello
140
141
  end
141
142
 
142
143
  def net_http_class
143
- if (proxy = ::HttpProxy.default_global_content_proxy)
144
+ if self.proxy
144
145
  uri = URI(proxy.url) #Net::HTTP::Proxy ignores port as part of the url
145
146
  Net::HTTP::Proxy("#{uri.host}#{uri.path}", uri.port, proxy.username, proxy.password)
146
147
  else
@@ -59,15 +59,17 @@ module Katello
59
59
 
60
60
  return resolved if to_resolve.empty?
61
61
 
62
- futures = to_resolve.map do |path_with_substitution|
63
- Concurrent::Promises.future do
64
- path_with_substitution.resolve_substitutions(@resource)
62
+ to_resolve.in_groups_of(8) do |group|
63
+ futures = group.map do |path_with_substitution|
64
+ Concurrent::Promises.future do
65
+ path_with_substitution.resolve_substitutions(@resource)
66
+ end
65
67
  end
66
- end
67
68
 
68
- futures.each do |future|
69
- resolved << future.value
70
- Rails.logger.error("Failed at scanning for repository: #{future.reason}") if future.rejected?
69
+ futures.each do |future|
70
+ resolved << future.value
71
+ Rails.logger.error("Failed at scanning for repository: #{future.reason}") if future.rejected?
72
+ end
71
73
  end
72
74
 
73
75
  find_substitutions(resolved.compact.flatten)
@@ -44,8 +44,8 @@ module Katello
44
44
 
45
45
  def kickstart_repos(host)
46
46
  distros = distribution_repositories(host).where(distribution_bootable: true)
47
- if distros && host.content_source
48
- distros.map { |distro| distro.to_hash(host.content_source) }
47
+ if distros && host&.content_facet&.content_source
48
+ distros.map { |distro| distro.to_hash(host.content_facet.content_source) }
49
49
  else
50
50
  []
51
51
  end
@@ -177,7 +177,9 @@ module Katello
177
177
  end
178
178
 
179
179
  def fix_pulp3_capabilities(type)
180
- if missing_pulp3_capabilities? && !pulp2_preferred_for_type?(type)
180
+ repository_type_obj = type.is_a?(String) || type.is_a?(Symbol) ? Katello::RepositoryTypeManager.repository_types[type] : type
181
+
182
+ if missing_pulp3_capabilities? && repository_type_obj.pulp3_plugin && !pulp2_preferred_for_type?(repository_type_obj.id)
181
183
  self.refresh
182
184
  if self.capabilities(::SmartProxy::PULP3_FEATURE).empty?
183
185
  fail Katello::Errors::PulpcoreMissingCapabilities
@@ -579,6 +579,12 @@ module Katello
579
579
  PuppetModule.group_by_repoid(puppet_modules.flatten)
580
580
  end
581
581
 
582
+ def check_ready_to_import!
583
+ fail _("User must be logged in.") if ::User.current.nil?
584
+ fail _("Cannot import a composite content view") if composite?
585
+ true
586
+ end
587
+
582
588
  def check_ready_to_publish!
583
589
  fail _("User must be logged in.") if ::User.current.nil?
584
590
  fail _("Cannot publish default content view") if default?
@@ -1,4 +1,5 @@
1
1
  module Katello
2
+ # rubocop:disable Metrics/ClassLength
2
3
  class ContentViewVersion < Katello::Model
3
4
  include Authorization::ContentViewVersion
4
5
  include ForemanTasks::Concerns::ActionSubject
@@ -25,7 +26,7 @@ module Katello
25
26
  has_many :export_histories, :class_name => "Katello::ContentViewVersionExportHistory", :dependent => :destroy,
26
27
  :inverse_of => :content_view_version, :foreign_key => :content_view_version_id
27
28
 
28
- has_many :repositories, :class_name => "Katello::Repository", :dependent => :destroy
29
+ has_many :repositories, :class_name => "::Katello::Repository", :dependent => :destroy
29
30
  has_many :content_view_puppet_environments, :class_name => "Katello::ContentViewPuppetEnvironment",
30
31
  :dependent => :destroy
31
32
  has_one :task_status, :class_name => "Katello::TaskStatus", :as => :task_owner, :dependent => :destroy
@@ -357,6 +358,14 @@ module Katello
357
358
  true
358
359
  end
359
360
 
361
+ def importable_repositories
362
+ if default?
363
+ repositories.yum_type
364
+ else
365
+ archived_repos.yum_type
366
+ end
367
+ end
368
+
360
369
  def before_promote_hooks
361
370
  run_callbacks :sync do
362
371
  logger.debug "custom hook before_promote on #{name} will be executed if defined."
@@ -369,7 +369,7 @@ module Katello
369
369
  pulp_uri = URI.parse(smart_proxy ? smart_proxy.url : SETTINGS[:katello][:pulp][:url])
370
370
  scheme = (self.unprotected && !force_https) ? 'http' : 'https'
371
371
  if docker?
372
- "#{pulp_uri.host.downcase}:#{Setting['pulp_docker_registry_port']}/#{container_repository_name}"
372
+ "#{pulp_uri.host.downcase}/#{container_repository_name}"
373
373
  elsif file?
374
374
  "#{scheme}://#{pulp_uri.host.downcase}/pulp/isos/#{relative_path}/"
375
375
  elsif puppet?
@@ -321,7 +321,11 @@ module Katello
321
321
 
322
322
  def format_arches
323
323
  if content_type == ::Katello::Repository::DEB_TYPE
324
- self.deb_architectures
324
+ # FIXME: This should be set to self.deb_architectures but it needs to have the
325
+ # subscription-manager PR https://github.com/candlepin/subscription-manager/pull/2213
326
+ # merged. Otherwise subscription-manager returns _NO_ debian repository as described in
327
+ # https://community.theforeman.org/t/katello-3-16-1-1-el7-subscription-manager-doesnt-create-rhsm-repos-for-ubuntu/20928/38
328
+ nil
325
329
  else
326
330
  self.arch == "noarch" ? nil : self.arch
327
331
  end
@@ -22,3 +22,15 @@ Deface::Override.new(:virtual_path => "taxonomies/_form",
22
22
  :name => "add_organization_attributes_on_edit",
23
23
  :insert_after => 'erb[loud]:contains("text_f"):contains(":name")',
24
24
  :partial => 'overrides/organizations/edit_override')
25
+
26
+ # Add Simple Content Access column to org table
27
+ Deface::Override.new(:virtual_path => "taxonomies/index",
28
+ :name => "add_sca_column_on_index",
29
+ :insert_before => 'table th:last-child', # make it the second-to-last column
30
+ :partial => 'overrides/organizations/index_header_override')
31
+
32
+ # Add Simple Content Access cells to org table
33
+ Deface::Override.new(:virtual_path => "taxonomies/index",
34
+ :name => "add_sca_attributes_on_index",
35
+ :insert_before => 'tbody td:last-child',
36
+ :partial => 'overrides/organizations/index_row_override')
@@ -78,7 +78,8 @@ module Katello
78
78
  joins("INNER JOIN katello_installed_packages ON
79
79
  katello_rpms.name = katello_installed_packages.name AND
80
80
  katello_rpms.arch = katello_installed_packages.arch AND
81
- katello_rpms.evr > katello_installed_packages.evr").
81
+ katello_rpms.evr > katello_installed_packages.evr AND
82
+ katello_installed_packages.id in (#{newest_distinct_installed_packages_query})").
82
83
  joins("LEFT JOIN katello_module_stream_rpms ON
83
84
  katello_rpms.id = katello_module_stream_rpms.rpm_id").
84
85
  joins("INNER JOIN katello_host_installed_packages ON
@@ -92,6 +93,16 @@ module Katello
92
93
  :enabled_module_streams => enabled_module_stream_ids).pluck(:id).uniq
93
94
  end
94
95
 
96
+ def newest_distinct_installed_packages_query
97
+ "SELECT DISTINCT ON (katello_installed_packages.name) katello_installed_packages.id " \
98
+ "FROM katello_installed_packages INNER JOIN " \
99
+ "katello_host_installed_packages ON " \
100
+ "katello_installed_packages.id = " \
101
+ "katello_host_installed_packages.installed_package_id " \
102
+ "WHERE katello_host_installed_packages.host_id = " \
103
+ "#{content_facet.host.id} ORDER BY katello_installed_packages.name, katello_installed_packages.evr DESC"
104
+ end
105
+
95
106
  def applicable_differences
96
107
  consumer_ids = content_facet.send(applicable_units).pluck("#{content_unit_class.table_name}.id")
97
108
  content_ids = fetch_content_ids