katello 3.15.0.rc1.3 → 3.15.1.1

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/api_controller.rb +5 -0
  3. data/app/controllers/katello/api/v2/docker_tags_controller.rb +17 -0
  4. data/app/controllers/katello/api/v2/host_packages_controller.rb +1 -0
  5. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
  6. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +4 -0
  7. data/app/lib/actions/katello/content_view/destroy.rb +1 -0
  8. data/app/lib/actions/katello/host/erratum/applicable_errata_install.rb +1 -1
  9. data/app/lib/actions/katello/host/upload_profiles.rb +36 -5
  10. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +13 -0
  11. data/app/lib/actions/katello/pulp_selector.rb +1 -0
  12. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +26 -0
  13. data/app/lib/actions/pulp3/orchestration/repository/delete.rb +8 -1
  14. data/app/lib/actions/pulp3/repository/delete_version.rb +20 -0
  15. data/app/lib/katello/concerns/base_template_scope_extensions.rb +23 -1
  16. data/app/lib/katello/errors.rb +8 -0
  17. data/app/lib/katello/util/package.rb +0 -1
  18. data/app/models/katello/concerns/host_managed_extensions.rb +8 -3
  19. data/app/models/katello/concerns/smart_proxy_extensions.rb +13 -0
  20. data/app/models/katello/docker_meta_tag.rb +3 -6
  21. data/app/models/katello/installed_package.rb +1 -1
  22. data/app/models/katello/repository.rb +50 -11
  23. data/app/models/setting/content.rb +8 -2
  24. data/app/services/katello/pulp/simple_package.rb +2 -2
  25. data/app/services/katello/pulp3/migration.rb +19 -4
  26. data/app/services/katello/pulp3/migration_switchover.rb +94 -0
  27. data/app/services/katello/pulp3/repository.rb +4 -0
  28. data/app/views/foreman/job_templates/install_errata_-_katello_ansible_default.erb +1 -1
  29. data/app/views/foreman/job_templates/install_group_-_katello_ansible_default.erb +1 -1
  30. data/app/views/foreman/job_templates/remove_group_-_katello_ansible_default.erb +1 -1
  31. data/app/views/foreman/job_templates/update_group_-_katello_ansible_default.erb +1 -1
  32. data/app/views/foreman/job_templates/update_package_-_katello_ansible_default.erb +1 -1
  33. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +1 -1
  34. data/app/views/katello/api/v2/repositories/base.json.rabl +8 -0
  35. data/config/routes/api/v2.rb +3 -0
  36. data/db/migrate/20200402130013_add_repsoitory_docker_meta_tag_f_key.rb +44 -0
  37. data/db/migrate/20200429153103_installed_package_bad_nvrea.rb +14 -0
  38. data/db/migrate/20200501155054_installed_package_unique_nvrea.rb +64 -0
  39. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  40. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details.controller.js +13 -0
  41. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +4 -2
  42. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-subscriptions.html +11 -8
  43. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +8 -0
  44. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +2 -0
  45. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +2 -0
  46. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +2 -0
  47. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -0
  48. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +2 -1
  49. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-installed.html +4 -2
  50. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +10 -1
  51. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +6 -3
  52. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions.html +4 -2
  53. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +9 -1
  54. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-environments.controller.js +10 -22
  55. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/views/docker-tag-environments.html +6 -6
  56. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.controller.js +8 -0
  57. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.factory.js +1 -1
  58. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/views/docker-tags.html +1 -1
  59. data/lib/katello/permission_creator.rb +6 -1
  60. data/lib/katello/tasks/pulp3_content_switchover.rake +7 -12
  61. data/lib/katello/tasks/pulp3_post_migration_check.rake +27 -11
  62. data/lib/katello/tasks/upgrades/3.16/update_applicable_el8_hosts.rake +29 -0
  63. data/lib/katello/version.rb +1 -1
  64. data/webpack/__mocks__/foremanReact/redux/API.js +6 -0
  65. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors.js +6 -0
  66. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware/index.js +11 -0
  67. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +0 -12
  68. data/webpack/scenes/Subscriptions/Manifest/index.js +0 -1
  69. data/webpack/scenes/Subscriptions/SubscriptionActions.js +49 -10
  70. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +10 -5
  71. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +37 -43
  72. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +55 -131
  73. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +2 -5
  74. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +1 -1
  75. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +75 -8
  76. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +35 -8
  77. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +58 -46
  78. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsSelectors.test.js +3 -5
  79. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +85 -9
  80. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +0 -2
  81. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +111 -124
  82. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsSelectors.test.js.snap +2 -12
  83. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +2 -8
  84. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +1 -16
  85. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +1 -6
  86. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/UpdateDialog.js +0 -25
  87. data/webpack/scenes/Subscriptions/index.js +2 -5
  88. data/webpack/scenes/Tasks/TaskActions.js +34 -104
  89. data/webpack/scenes/Tasks/TaskSelectors.js +7 -0
  90. data/webpack/scenes/Tasks/__tests__/TaskActions.test.js +17 -154
  91. data/webpack/scenes/Tasks/__tests__/TaskSelectors.test.js +21 -0
  92. data/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap +57 -0
  93. data/webpack/scenes/Tasks/__tests__/__snapshots__/TaskSelectors.test.js.snap +9 -0
  94. data/webpack/scenes/Tasks/__tests__/task.fixtures.js +0 -82
  95. data/webpack/scenes/Tasks/helpers.js +13 -6
  96. metadata +19 -5
  97. data/webpack/scenes/Tasks/TaskConstants.js +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a6bd47c5fa7163ee343c23d652b46abc14fdba414c1630b3b56335196aa6941
4
- data.tar.gz: 18829650fef9ffdad3cea5d73a30a7bb31eca9305db9bbbda85d922b3ca93d90
3
+ metadata.gz: 198db45b1663ec5e4dd73cb999c9ef4860660fe9ca3428293d0c82ea45ff78a2
4
+ data.tar.gz: c541eaa6a075bf545ba668d2b80197375428a55047852ca7a4a8fddd2ac7f0cb
5
5
  SHA512:
6
- metadata.gz: 7ab1ee973db81ec2f17436659b364cf1e7529aac79616bc7e8f6b7cf4fecad4b0821abafaeaf90077bcbaccaba6882731050719586d05239f6204ecadd506968
7
- data.tar.gz: 3583ab23ec2bdb236ec056f79dd789d2d8455f2e071b93b200f4836845371f6c5aee7616077cb6d7f34b8ed9cd08ee5ec30fdabbaac97f6b6d27f4b7b96c4dd0
6
+ metadata.gz: 54851ee1cbf1de239a68264f377b4b96e58b310e656b67daed646927aa56bfbc6f6bdf307dc6f4a1240982675a98d2a05bf4d2991b9dae8dc5b829f0d897a4c2
7
+ data.tar.gz: e8466a953f3bedaa7f761f353fdddf8c858dbe9b09b72dcd338c5a2a132745f9b923e2ba1afdd6e4c2a4fd71fafc2bcb1bc88332866c0d6b08930b9c37246d69
@@ -35,6 +35,11 @@ module Katello
35
35
  @resource_class ||= "Katello::#{resource_name.classify}".constantize
36
36
  end
37
37
 
38
+ def deprecate_katello_agent
39
+ ::Foreman::Deprecation.api_deprecation_warning("Remote actions using katello-agent are deprecated and will be removed in Katello 4.0. " \
40
+ "You may consider switching to Remote Execution.")
41
+ end
42
+
38
43
  def full_result_response(collection)
39
44
  { :results => collection,
40
45
  :total => collection.count,
@@ -25,6 +25,23 @@ module Katello
25
25
  end
26
26
  end
27
27
 
28
+ api :GET, "/docker_tags/:id/repositories", N_("List of repositories for a docker meta tag")
29
+ def repositories
30
+ tag = DockerMetaTag.find(params[:id])
31
+
32
+ if tag.repositories.size > 1 #pulp3
33
+ repos = tag.repositories.non_archived
34
+ else
35
+ repos = []
36
+ tag.related_tags.each do |related|
37
+ repos << related.repositories.non_archived
38
+ end
39
+ repos.flatten!
40
+ end
41
+
42
+ respond_with_template_collection('index', 'repositories', collection: full_result_response(repos))
43
+ end
44
+
28
45
  private
29
46
 
30
47
  def find_repositories
@@ -6,6 +6,7 @@ module Katello
6
6
  before_action :require_packages_only, :only => [:upgrade]
7
7
  before_action :find_editable_host_with_facet, :except => :index
8
8
  before_action :find_host, :only => :index
9
+ before_action :deprecate_katello_agent, :only => [:install, :remove, :upgrade, :upgrade_all]
9
10
 
10
11
  resource_description do
11
12
  api_version 'v2'
@@ -10,6 +10,7 @@ module Katello
10
10
  before_action :find_deletable_hosts, :only => [:destroy_hosts]
11
11
  before_action :find_readable_hosts, :only => [:applicable_errata, :installable_errata, :available_incremental_updates]
12
12
  before_action :find_errata, :only => [:available_incremental_updates]
13
+ before_action :deprecate_katello_agent, :only => [:install_content, :update_content, :remove_content]
13
14
 
14
15
  before_action :validate_content_action, :only => [:install_content, :update_content, :remove_content]
15
16
 
@@ -118,7 +119,6 @@ module Katello
118
119
  :desc => N_("The type of content. The following types are supported: 'package', 'package_group' and 'errata'."),
119
120
  :required => true
120
121
  param :content, Array, :desc => N_("List of content (e.g. package names, package group names or errata ids)")
121
- param :install_all, :bool, :desc => N_("Only used for errata, but will install all installable errata.")
122
122
  def install_content
123
123
  content_action
124
124
  end
@@ -31,6 +31,10 @@ module Actions
31
31
  end
32
32
  end
33
33
 
34
+ def resource_locks
35
+ :link
36
+ end
37
+
34
38
  def rescue_strategy
35
39
  Dynflow::Action::Rescue::Skip
36
40
  end
@@ -17,6 +17,7 @@ module Actions
17
17
  end
18
18
  end
19
19
 
20
+ plan_action(Actions::Pulp3::ContentView::DeleteRepositoryReferences, content_view, SmartProxy.pulp_master)
20
21
  plan_self
21
22
  end
22
23
  end
@@ -11,7 +11,7 @@ module Actions
11
11
  errata_ids = options.fetch(:errata_ids, nil)
12
12
 
13
13
  applicable_errata = host.content_facet.applicable_errata
14
- applicable_errata = applicable_errata.with_identifiers(errata_ids) if errata_ids
14
+ applicable_errata = applicable_errata.with_identifiers(errata_ids) unless options[:update_all]
15
15
  plan_action(Actions::Katello::Host::Erratum::Install, host, applicable_errata.pluck(:errata_id))
16
16
  plan_self(:hostname => host.name)
17
17
  end
@@ -33,16 +33,42 @@ module Actions
33
33
  Dynflow::Action::Rescue::Skip
34
34
  end
35
35
 
36
+ def self.upload_modules_to_pulp(available_streams, host)
37
+ query_name_streams = available_streams.map do |profile|
38
+ ::Katello::ModuleStream.where(profile.slice(:name, :stream))
39
+ end
40
+
41
+ query_name_streams = query_name_streams.inject(&:or)
42
+
43
+ bound_library_instances = host.content_facet.bound_repositories.map(&:library_instance_or_self)
44
+ query = ::Katello::ModuleStream.in_repositories(bound_library_instances).
45
+ select(:name, :stream, :version, :context, :arch).
46
+ merge(query_name_streams)
47
+
48
+ updated_profiles = query.map do |module_stream|
49
+ module_stream.slice(:name, :stream, :version, :context, :arch)
50
+ end
51
+
52
+ # We also need to pass module streams that are not found in the ModuleStream table
53
+ # but are present on the content host
54
+ unassociated_profiles = available_streams.select do |profile|
55
+ updated_profiles.none? { |p| p[:name] == profile[:name] && p[:stream] == profile[:stream] }
56
+ end
57
+
58
+ ::Katello::Pulp::Consumer.new(host.content_facet.uuid).
59
+ upload_module_stream_profile(updated_profiles + unassociated_profiles)
60
+ rescue RestClient::ResourceNotFound
61
+ Rails.logger.warn("Host with ID %s was not known to Pulp, continuing" % host.id)
62
+ end
63
+
36
64
  def import_module_streams(payload, host)
37
65
  enabled_payload = payload.map do |profile|
38
- profile.slice("name", "stream", "version", "context", "arch") if profile["status"] == "enabled"
66
+ profile.slice("name", "stream", "version", "context", "arch").with_indifferent_access if profile["status"] == "enabled"
39
67
  end
40
68
  enabled_payload.compact!
41
69
 
42
- ::Katello::Pulp::Consumer.new(host.content_facet.uuid).upload_module_stream_profile(enabled_payload)
70
+ UploadProfiles.upload_modules_to_pulp(enabled_payload, host)
43
71
  host.import_module_streams(payload)
44
- rescue RestClient::ResourceNotFound
45
- Rails.logger.warn("Host with ID %s was not known to Pulp, continuing" % input[:host_id])
46
72
  end
47
73
 
48
74
  def import_deb_package_profile(host, profile)
@@ -69,6 +95,7 @@ module Actions
69
95
  payload = profiles.dig("deb_package_profile", "deb_packages") || []
70
96
  import_deb_package_profile(host, payload)
71
97
  else
98
+ module_streams = []
72
99
  profiles.each do |profile|
73
100
  payload = profile["profile"]
74
101
  case profile["content_type"]
@@ -79,9 +106,13 @@ module Actions
79
106
  when "enabled_repos"
80
107
  host.import_enabled_repositories(payload)
81
108
  else
82
- import_module_streams(payload, host)
109
+ module_streams << payload
83
110
  end
84
111
  end
112
+
113
+ module_streams.each do |module_stream_payload|
114
+ import_module_streams(module_stream_payload, host)
115
+ end
85
116
  end
86
117
  end
87
118
  end
@@ -13,6 +13,19 @@ module Actions
13
13
  Actions::Pulp3::Orchestration::OrphanCleanup::RemoveOrphans,
14
14
  proxy)
15
15
  end
16
+ plan_self
17
+ end
18
+ end
19
+
20
+ def run
21
+ models = []
22
+ ::Katello::RepositoryTypeManager.repository_types.each_value do |repo_type|
23
+ indexable_types = repo_type.content_types_to_index
24
+ models += indexable_types&.map(&:model_class)
25
+ models.select! { |model| model.many_repository_associations }
26
+ end
27
+ models.each do |model|
28
+ model.joins("left join katello_#{model.repository_association} on #{model.table_name}.id = katello_#{model.repository_association}.#{model.unit_id_field}").where("katello_#{model.repository_association}.#{model.unit_id_field} IS NULL").destroy_all
16
29
  end
17
30
  end
18
31
  end
@@ -3,6 +3,7 @@ module Actions
3
3
  module PulpSelector
4
4
  def plan_pulp_action(backend_actions, repository, smart_proxy, *args)
5
5
  fail "nil smart_proxy passed to PulpSelector" if smart_proxy.nil?
6
+ smart_proxy.fix_pulp3_capabilities(repository.content_type)
6
7
  planned = plan_optional_pulp_action(backend_actions, repository, smart_proxy, *args)
7
8
  fail "Could not locate an action for type #{smart_proxy.backend_service_type(repository)}" unless planned
8
9
  planned
@@ -0,0 +1,26 @@
1
+ module Actions
2
+ module Pulp3
3
+ module ContentView
4
+ class DeleteRepositoryReferences < Pulp3::AbstractAsyncTask
5
+ def plan(content_view, smart_proxy)
6
+ if content_view.repository_references.any?
7
+ plan_self(:content_view_id => content_view.id, :smart_proxy_id => smart_proxy.id)
8
+ end
9
+ end
10
+
11
+ def invoke_external_task
12
+ tasks = []
13
+ content_view = ::Katello::ContentView.find(input[:content_view_id])
14
+ content_view.repository_references.each do |repository_reference|
15
+ repo = repository_reference.root_repository.library_instance
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)
18
+ end
19
+ content_view.repository_references.destroy_all
20
+
21
+ output[:pulp_tasks] = tasks
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -7,7 +7,14 @@ module Actions
7
7
  sequence do
8
8
  plan_action(Actions::Pulp3::Repository::DeleteRemote, repository.id, smart_proxy) if repository.remote_href
9
9
  plan_action(Actions::Pulp3::Repository::DeleteDistributions, repository.id, smart_proxy)
10
- plan_action(Actions::Pulp3::Repository::Delete, repository.id, smart_proxy)
10
+
11
+ if repository.content_view.default?
12
+ #we're deleting the library instance, so just delete the whole pulp3 repo
13
+ plan_action(Actions::Pulp3::Repository::Delete, repository.id, smart_proxy)
14
+ elsif repository.environment.nil?
15
+ #we're deleting the archived instance, so delete the version
16
+ plan_action(Actions::Pulp3::Repository::DeleteVersion, repository, smart_proxy)
17
+ end
11
18
  end
12
19
  end
13
20
  end
@@ -0,0 +1,20 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class DeleteVersion < Pulp3::AbstractAsyncTask
5
+ def plan(repository, smart_proxy)
6
+ #A version from library might be reused in a composite, or could have been copied
7
+ # from a library repository, so only delete the version if its the last
8
+ if ::Katello::Repository.where(:version_href => repository.version_href).count == 1
9
+ plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id)
10
+ end
11
+ end
12
+
13
+ def invoke_external_task
14
+ repo = ::Katello::Repository.find(input[:repository_id])
15
+ output[:response] = repo.backend_service(smart_proxy).delete_version
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -7,7 +7,8 @@ module Katello
7
7
  def allowed_helpers
8
8
  super + [:errata, :host_subscriptions, :host_applicable_errata_ids, :host_applicable_errata_filtered,
9
9
  :host_latest_applicable_rpm_version, :load_pools, :load_errata_applications, :host_content_facet,
10
- :host_sla, :host_products, :sub_name, :sub_sku, :registered_through, :last_checkin]
10
+ :host_sla, :host_products, :sub_name, :sub_sku, :registered_through, :last_checkin, :host_collections,
11
+ :host_subscriptions_names, :host_subscriptions, :host_products_names, :host_collections_names]
11
12
  end
12
13
  end
13
14
 
@@ -23,6 +24,10 @@ module Katello
23
24
  host.subscriptions
24
25
  end
25
26
 
27
+ def host_subscriptions_names(host)
28
+ host.subscriptions.map(&:name)
29
+ end
30
+
26
31
  def host_content_facet(host)
27
32
  host.content_facet
28
33
  end
@@ -35,6 +40,23 @@ module Katello
35
40
  host_subscription_facet(host)&.installed_products
36
41
  end
37
42
 
43
+ def host_products_names(host)
44
+ products = host_products(host)
45
+ if products
46
+ products.map(&:name)
47
+ else
48
+ []
49
+ end
50
+ end
51
+
52
+ def host_collections(host)
53
+ host.host_collections
54
+ end
55
+
56
+ def host_collections_names(host)
57
+ host.host_collections.map(&:name)
58
+ end
59
+
38
60
  def sub_name(pool)
39
61
  return unless pool
40
62
  pool.subscription&.name
@@ -45,6 +45,12 @@ module Katello
45
45
  end
46
46
  end
47
47
 
48
+ class PulpcoreMissingCapabilities < StandardError
49
+ def message
50
+ _("A smart proxy seems to have been refreshed without pulpcore being running. You may want to ")
51
+ end
52
+ end
53
+
48
54
  class ConnectionRefusedException < StandardError; end
49
55
 
50
56
  class MaxHostsReachedException < StandardError; end
@@ -115,6 +121,8 @@ module Katello
115
121
  end
116
122
  end
117
123
 
124
+ class Pulp3MigrationError < StandardError; end
125
+
118
126
  class PulpError < StandardError
119
127
  def self.from_task(task)
120
128
  if %w(error canceled).include?(task[:state])
@@ -22,7 +22,6 @@ module Katello
22
22
  def self.parse_nvrea(name)
23
23
  name, suffix = extract_suffix(name)
24
24
  name, arch = extract_arch(name)
25
- return unless arch
26
25
 
27
26
  if (nvre = parse_nvre(name))
28
27
  nvre.merge(:suffix => suffix, :arch => arch).delete_if { |_k, v| v.nil? }
@@ -106,7 +106,7 @@ module Katello
106
106
 
107
107
  def import_package_profile(simple_packages)
108
108
  found = import_package_profile_in_bulk(simple_packages)
109
- sync_package_associations(found.map(&:id))
109
+ sync_package_associations(found.map(&:id).uniq)
110
110
  end
111
111
 
112
112
  def import_package_profile_in_bulk(simple_packages)
@@ -127,9 +127,14 @@ module Katello
127
127
  :arch => simple_package.arch)
128
128
  end
129
129
  InstalledPackage.import(installed_packages, validate: false, on_duplicate_key_ignore: true)
130
+ #re-lookup all imported to pickup any duplicates/conflicts
131
+ imported = InstalledPackage.where(:nvrea => installed_packages.map(&:nvrea)).select(:id).to_a
130
132
 
131
- found << installed_packages
132
- found.flatten
133
+ if imported.count != installed_packages.count
134
+ Rails.logger.warn("Mismatch found in installed package insertion, expected #{installed_packages.count} but only could find #{imported.count}. This is most likley a bug.")
135
+ end
136
+
137
+ (found + imported).flatten
133
138
  end
134
139
 
135
140
  def import_enabled_repositories(repos)
@@ -152,6 +152,19 @@ module Katello
152
152
  end
153
153
  end
154
154
 
155
+ def missing_pulp3_capabilities?
156
+ pulp3_enabled? && self.capabilities(PULP3_FEATURE).empty?
157
+ end
158
+
159
+ def fix_pulp3_capabilities(type)
160
+ if missing_pulp3_capabilities? && !pulp2_preferred_for_type?(type)
161
+ self.refresh
162
+ if self.capabilities(::SmartProxy::PULP3_FEATURE).empty?
163
+ fail Katello::Errors::PulpcoreMissingCapabilities
164
+ end
165
+ end
166
+ end
167
+
155
168
  def pulp3_repository_type_support?(repository_type, check_pulp2_preferred = true)
156
169
  repository_type_obj = repository_type.is_a?(String) ? Katello::RepositoryTypeManager.repository_types[repository_type] : repository_type
157
170
  fail "Cannot find repository type #{repository_type}, is it enabled?" unless repository_type_obj
@@ -107,7 +107,7 @@ module Katello
107
107
  if grouped
108
108
  grouped_fields = "#{table_name}.name, katello_repositories.root_id"
109
109
  ids = distinct.select("ON (#{grouped_fields}) #{table_name}.id").joins(:repositories)
110
- where(:id => ids).where("#{self.table_name}.schema1_id in (#{sql}) or #{self.table_name}.schema2_id in (#{sql})")
110
+ self.where(:id => ids)
111
111
  else
112
112
  self.where("#{self.table_name}.schema1_id in (#{sql}) or #{self.table_name}.schema2_id in (#{sql})")
113
113
  end
@@ -153,17 +153,14 @@ module Katello
153
153
  end
154
154
 
155
155
  unless params_to_query_for_delete.empty?
156
- DockerMetaTag.where(:id => repository_association_class.
157
- where(:repository_id => repo.id).
158
- select(:docker_meta_tag_id)).
159
- where(params_to_query_for_delete.join(" OR ")).delete_all
156
+ RepositoryDockerMetaTag.where(:docker_meta_tag => DockerMetaTag.where(params_to_query_for_delete.join(" OR "))).delete_all
160
157
  end
161
158
 
162
159
  metatags = []
163
160
  (tag_table_values - meta_tag_table_values).each do |schema1, schema2, name|
164
161
  metatags << DockerMetaTag.where(:schema1_id => schema1,
165
162
  :schema2_id => schema2,
166
- :name => name).create!
163
+ :name => name).first_or_create
167
164
  end
168
165
  repo.docker_meta_tags += metatags
169
166
  end
@@ -4,8 +4,8 @@ module Katello
4
4
  allow :nvra, :nvrea, :name
5
5
  end
6
6
 
7
- has_many :hosts, :through => :host_installed_packages, :class_name => "::Host"
8
7
  has_many :host_installed_packages, :class_name => "Katello::HostInstalledPackage", :dependent => :destroy, :inverse_of => :installed_package
8
+ has_many :hosts, :through => :host_installed_packages, :class_name => "::Host"
9
9
 
10
10
  scoped_search :on => :name, :complete_value => true
11
11
  scoped_search :on => :nvrea
@@ -171,8 +171,8 @@ module Katello
171
171
  joins(:root).where("#{RootRepository.table_name}.content_type" => content_type)
172
172
  end
173
173
 
174
- def backend_service(smart_proxy)
175
- if smart_proxy.pulp3_support?(self)
174
+ def backend_service(smart_proxy, force_pulp3 = false)
175
+ if force_pulp3 || smart_proxy.pulp3_support?(self)
176
176
  @service ||= Katello::Pulp3::Repository.instance_for_type(self, smart_proxy)
177
177
  else
178
178
  @service ||= Katello::Pulp::Repository.instance_for_type(self, smart_proxy)
@@ -301,17 +301,52 @@ module Katello
301
301
  group("#{errata}.id").count
302
302
  end
303
303
 
304
+ def self.errata_with_module_stream_counts(repo)
305
+ repository_errata = Katello::RepositoryErratum.table_name
306
+ errata = Katello::Erratum.table_name
307
+ erratum_package = Katello::ErratumPackage.table_name
308
+ repository_module_stream = Katello::RepositoryModuleStream.table_name
309
+ msep = ::Katello::ModuleStreamErratumPackage.table_name
310
+ ::Katello::Erratum.joins(
311
+ "INNER JOIN #{erratum_package} on #{erratum_package}.erratum_id = #{errata}.id",
312
+ "INNER JOIN #{msep} on #{msep}.erratum_package_id = #{erratum_package}.id",
313
+ "INNER JOIN #{repository_errata} on #{repository_errata}.erratum_id = #{errata}.id",
314
+ "INNER JOIN #{repository_module_stream} on #{repository_module_stream}.module_stream_id = #{msep}.module_stream_id").
315
+ where("#{repository_module_stream}.repository_id" => repo.id).
316
+ where("#{repository_errata}.repository_id" => repo.id).
317
+ group("#{errata}.id").count
318
+ end
319
+
320
+ def fetch_package_errata_to_keep
321
+ errata_counts = ::Katello::Repository.errata_with_package_counts(self)
322
+ if errata_counts.any?
323
+ errata_counts_in_library = ::Katello::Repository.errata_with_package_counts(library_instance)
324
+ errata_counts.keep_if { |id| errata_counts[id] == errata_counts_in_library[id] }
325
+ errata_counts.keys
326
+ else
327
+ []
328
+ end
329
+ end
330
+
331
+ def fetch_module_errata_to_filter
332
+ errata_counts = ::Katello::Repository.errata_with_module_stream_counts(self)
333
+ errata_counts_in_library = ::Katello::Repository.errata_with_module_stream_counts(library_instance)
334
+ if errata_counts_in_library.any?
335
+ errata_counts_in_library.keep_if { |id| errata_counts[id] != errata_counts_in_library[id] }
336
+ errata_counts_in_library.keys
337
+ else
338
+ []
339
+ end
340
+ end
341
+
304
342
  def partial_errata
305
343
  return [] if library_instance?
306
344
 
307
- errata_with_package_counts = ::Katello::Repository.errata_with_package_counts(self)
308
345
  partial_errata = self.errata
309
- if errata_with_package_counts.any?
310
- errata_with_packages_in_library = ::Katello::Repository.errata_with_package_counts(library_instance)
311
- errata_with_package_counts.keep_if { |id| errata_with_package_counts[id] == errata_with_packages_in_library[id] }
312
- unless errata_with_package_counts.empty?
313
- partial_errata = self.errata.where("#{Katello::Erratum.table_name}.id NOT IN (?)", errata_with_package_counts.keys)
314
- end
346
+ errata_to_keep = fetch_package_errata_to_keep - fetch_module_errata_to_filter
347
+
348
+ if errata_to_keep.any?
349
+ partial_errata = self.errata.where("#{Katello::Erratum.table_name}.id NOT IN (?)", errata_to_keep)
315
350
  end
316
351
 
317
352
  partial_errata
@@ -387,8 +422,12 @@ module Katello
387
422
  path
388
423
  end
389
424
 
425
+ def library_instance_or_self
426
+ self.library_instance || self
427
+ end
428
+
390
429
  def generate_repo_path(content_path = nil)
391
- _org, _content, content_path = (self.library_instance || self).relative_path.split("/", 3) if content_path.blank?
430
+ _org, _content, content_path = library_instance_or_self.relative_path.split("/", 3) if content_path.blank?
392
431
  content_path = content_path.sub(%r|^/|, '')
393
432
  if self.environment
394
433
  cve = ContentViewEnvironment.where(:environment_id => self.environment,
@@ -461,7 +500,7 @@ module Katello
461
500
  end
462
501
  end
463
502
  clone = Repository.new(:environment => to_env,
464
- :library_instance => self.library_instance || self,
503
+ :library_instance => library_instance_or_self,
465
504
  :root => self.root,
466
505
  :content_view_version => to_version,
467
506
  :saved_checksum_type => checksum_type)