katello 3.18.0.rc2.1 → 3.18.2.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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/katello/katello.scss +0 -72
  3. data/app/controllers/katello/api/v2/api_controller.rb +1 -2
  4. data/app/controllers/katello/api/v2/capsule_content_controller.rb +2 -2
  5. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +98 -0
  6. data/app/controllers/katello/api/v2/content_exports_controller.rb +84 -0
  7. data/app/controllers/katello/api/v2/content_imports_controller.rb +59 -0
  8. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +1 -1
  9. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +56 -94
  10. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +2 -1
  11. data/app/controllers/katello/api/v2/repositories_controller.rb +2 -0
  12. data/app/controllers/katello/concerns/api/v2/authorization.rb +14 -1
  13. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +6 -2
  14. data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
  15. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +7 -2
  16. data/app/lib/actions/katello/content_view/promote_to_environment.rb +1 -1
  17. data/app/lib/actions/katello/content_view/publish.rb +1 -1
  18. data/app/lib/actions/katello/content_view_version/import.rb +2 -1
  19. data/app/lib/actions/katello/content_view_version/import_library.rb +17 -0
  20. data/app/lib/actions/katello/content_view_version/incremental_update.rb +19 -3
  21. data/app/lib/actions/katello/host/update_system_purpose.rb +1 -1
  22. data/app/lib/actions/katello/repository/sync.rb +5 -1
  23. data/app/lib/actions/middleware/record_smart_proxy_sync_history.rb +24 -4
  24. data/app/lib/actions/pulp3/content_migration.rb +10 -0
  25. data/app/lib/actions/pulp3/content_migration_presenter.rb +59 -0
  26. data/app/lib/actions/pulp3/content_migration_reset.rb +22 -0
  27. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
  28. data/app/lib/actions/pulp3/content_view_version/export.rb +3 -2
  29. data/app/lib/actions/pulp3/import_migration.rb +6 -1
  30. data/app/lib/actions/pulp3/orchestration/content_view_version/copy_version_units_to_library.rb +2 -1
  31. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +17 -13
  32. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +60 -0
  33. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +0 -4
  34. data/app/lib/actions/pulp3/orchestration/repository/import_upload.rb +16 -3
  35. data/app/lib/actions/pulp3/repository/copy_content.rb +1 -1
  36. data/app/lib/actions/pulp3/repository/delete.rb +1 -1
  37. data/app/lib/actions/pulp3/repository/save_version.rb +1 -1
  38. data/app/lib/actions/pulp3/repository/upload_tag.rb +18 -0
  39. data/app/lib/katello/util/pulpcore_content_filters.rb +1 -1
  40. data/app/models/katello/authorization/content_view_version.rb +25 -2
  41. data/app/models/katello/authorization/content_view_version_export_history.rb +1 -1
  42. data/app/models/katello/authorization/organization.rb +8 -0
  43. data/app/models/katello/concerns/operatingsystem_extensions.rb +2 -0
  44. data/app/models/katello/concerns/pulp_database_unit.rb +19 -0
  45. data/app/models/katello/concerns/redhat_extensions.rb +2 -2
  46. data/app/models/katello/concerns/smart_proxy_extensions.rb +7 -5
  47. data/app/models/katello/content_migration_progress.rb +4 -0
  48. data/app/models/katello/content_view.rb +5 -0
  49. data/app/models/katello/content_view_history.rb +2 -1
  50. data/app/models/katello/content_view_package_filter.rb +1 -1
  51. data/app/models/katello/content_view_version_export_history.rb +6 -1
  52. data/app/models/katello/file_unit.rb +4 -0
  53. data/app/models/katello/host/content_facet.rb +9 -31
  54. data/app/models/katello/host/subscription_facet.rb +4 -0
  55. data/app/models/katello/ping.rb +35 -15
  56. data/app/models/katello/repository.rb +7 -0
  57. data/app/models/katello/subscription_status.rb +3 -2
  58. data/app/services/katello/applicability/applicable_content_helper.rb +44 -15
  59. data/app/services/katello/pulp3/api/docker.rb +4 -0
  60. data/app/services/katello/pulp3/content_view_version/export.rb +63 -5
  61. data/app/services/katello/pulp3/content_view_version/import.rb +40 -0
  62. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +0 -16
  63. data/app/services/katello/pulp3/content_view_version/import_validator.rb +26 -49
  64. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  65. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  66. data/app/services/katello/pulp3/erratum.rb +2 -1
  67. data/app/services/katello/pulp3/migration.rb +95 -12
  68. data/app/services/katello/pulp3/migration_plan.rb +2 -2
  69. data/app/services/katello/pulp3/migration_switchover.rb +23 -5
  70. data/app/services/katello/pulp3/repository.rb +10 -5
  71. data/app/services/katello/pulp3/repository/docker.rb +5 -0
  72. data/app/services/katello/pulp3/repository/yum.rb +23 -8
  73. data/app/services/katello/pulp3/rpm.rb +5 -1
  74. data/app/services/katello/pulp3/task.rb +4 -0
  75. data/app/services/katello/pulp3/task_group.rb +4 -0
  76. data/app/views/katello/api/v2/content_views/show.json.rabl +6 -0
  77. data/app/views/katello/layouts/react.html.erb +3 -2
  78. data/app/views/katello/sync_management/_products.html.erb +1 -1
  79. data/app/views/overrides/activation_keys/_host_tab_pane.html.erb +1 -5
  80. data/config/routes/api/v2.rb +23 -3
  81. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  82. data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +5 -2
  83. data/db/migrate/20201119211133_pulp3_migration_progress.rb +9 -0
  84. data/db/migrate/20210201165835_add_migration_missing_content.rb +12 -0
  85. data/engines/bastion/app/assets/javascripts/bastion/auth/authorization.service.js +1 -1
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
  87. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-system-purpose-modal.html +35 -40
  88. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +1 -1
  89. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/deletion/content-view-version-deletion-activation-keys.controller.js +8 -3
  90. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/deletion/content-view-version-deletion-content-hosts.controller.js +9 -3
  91. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +1 -1
  92. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-publish.html +4 -0
  93. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +78 -7
  94. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +17 -20
  95. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +17 -24
  96. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +1292 -1170
  97. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +17 -20
  98. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +858 -807
  99. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +18 -19
  100. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +17 -24
  101. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +17 -18
  102. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +986 -971
  103. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +19 -20
  104. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +9 -9
  105. data/lib/katello/permission_creator.rb +23 -3
  106. data/lib/katello/tasks/delete_orphaned_content.rake +1 -3
  107. data/lib/katello/tasks/pulp3_content_switchover.rake +3 -1
  108. data/lib/katello/tasks/pulp3_migration.rake +29 -6
  109. data/lib/katello/tasks/pulp3_migration_abort.rake +7 -2
  110. data/lib/katello/tasks/pulp3_migration_approve_corrupted.rake +16 -0
  111. data/lib/katello/tasks/pulp3_migration_reset.rake +26 -0
  112. data/lib/katello/tasks/pulp3_migration_stats.rake +61 -8
  113. data/lib/katello/tasks/pulp3_post_migration_check.rake +1 -3
  114. data/lib/katello/tasks/receptor/extract_orgs.rake +1 -1
  115. data/lib/katello/tasks/reports.rake +4 -1
  116. data/lib/katello/tasks/repository.rake +3 -5
  117. data/lib/katello/version.rb +1 -1
  118. data/locale/action_names.rb +51 -51
  119. data/locale/bn/katello.po +136 -51
  120. data/locale/cs/katello.po +136 -49
  121. data/locale/de/katello.po +136 -48
  122. data/locale/en/katello.po +136 -48
  123. data/locale/es/katello.po +136 -48
  124. data/locale/fr/katello.po +136 -48
  125. data/locale/gu/katello.po +136 -51
  126. data/locale/hi/katello.po +136 -51
  127. data/locale/it/katello.po +136 -48
  128. data/locale/ja/katello.po +136 -48
  129. data/locale/katello.pot +941 -767
  130. data/locale/kn/katello.po +136 -51
  131. data/locale/ko/katello.po +136 -48
  132. data/locale/mr/katello.po +136 -51
  133. data/locale/or/katello.po +136 -51
  134. data/locale/pa/katello.po +136 -51
  135. data/locale/pt/katello.po +136 -51
  136. data/locale/pt_BR/katello.po +136 -48
  137. data/locale/ru/katello.po +136 -48
  138. data/locale/ta/katello.po +136 -51
  139. data/locale/te/katello.po +136 -51
  140. data/locale/zh_CN/katello.po +136 -48
  141. data/locale/zh_TW/katello.po +136 -48
  142. data/webpack/components/TypeAhead/TypeAhead.js +2 -1
  143. data/webpack/components/TypeAhead/pf3Search/TypeAheadSearch.js +2 -1
  144. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +7 -2
  145. data/webpack/scenes/Subscriptions/Manifest/index.js +1 -0
  146. metadata +31 -19
  147. data/lib/katello/tasks/common.rake +0 -7
@@ -267,8 +267,9 @@ module Katello
267
267
  api :POST, "/hosts/bulk/available_incremental_updates", N_("Given a set of hosts and errata, lists the content view versions" \
268
268
  " and environments that need updating.")
269
269
  param_group :bulk_params
270
- param :errata_ids, Array, :desc => N_("List of Errata ids")
270
+ param :errata_ids, Array, :desc => N_("List of Errata ids"), :required => true
271
271
  def available_incremental_updates
272
+ fail HttpErrors::BadRequest, _("errata_ids is a required parameter") if params[:errata_ids].empty?
272
273
  version_environments = {}
273
274
  content_facets = Katello::Host::ContentFacet.with_non_installable_errata(@errata, @hosts)
274
275
 
@@ -95,6 +95,7 @@ module Katello
95
95
  param :available_for, String, :desc => N_("interpret specified object to return only Repositories that can be associated with specified object. Only 'content_view' & 'content_view_version' are supported."),
96
96
  :required => false
97
97
  param :with_content, RepositoryTypeManager.enabled_content_types, :desc => N_("only repositories having at least one of the specified content type ex: rpm , erratum")
98
+ param :download_policy, ::Runcible::Models::YumImporter::DOWNLOAD_POLICIES, :desc => N_("limit to only repositories with this download policy")
98
99
  param_group :search, Api::V2::ApiController
99
100
  add_scoped_search_description_for(Repository)
100
101
  def index
@@ -138,6 +139,7 @@ module Katello
138
139
  def index_relation_product(query)
139
140
  query = query.joins(:root => :product).where("#{Product.table_name}.organization_id" => @organization) if @organization
140
141
  query = query.joins(:root).where("#{RootRepository.table_name}.product_id" => @product.id) if @product
142
+ query = query.joins(:root).where("#{RootRepository.table_name}.download_policy" => params[:download_policy]) if params[:download_policy]
141
143
  query
142
144
  end
143
145
 
@@ -39,7 +39,20 @@ module Katello
39
39
  end
40
40
 
41
41
  def throw_resource_not_found(name: resource_name, id: params[:id])
42
- fail HttpErrors::NotFound, _("Could not find %{name} resource with id %{id}") % {id: id, name: name}
42
+ perms_message = "Potential missing permissions: " +
43
+ missing_permissions.map(&:name).join(', ')
44
+ fail HttpErrors::NotFound, _("Could not find %{name} resource with id %{id}. %{perms_message}") % {id: id, name: name, perms_message: perms_message}
45
+ end
46
+
47
+ def missing_permissions
48
+ missing_perms = ::Foreman::AccessControl.permissions_for_controller_action(path_to_authenticate)
49
+
50
+ # promote_or_remove_content_views_to_environments has a special relationship to promote_or_remove_content_views
51
+ if path_to_authenticate["controller"] == "katello/api/v2/content_view_versions" &&
52
+ path_to_authenticate["action"].in?(["promote", "remove_from_environment", "remove", "republish_repositories"])
53
+ missing_perms << ::Permission.find_by(name: "promote_or_remove_content_views_to_environments")
54
+ end
55
+ missing_perms
43
56
  end
44
57
 
45
58
  def throw_resources_not_found(name:, expected_ids: [])
@@ -9,8 +9,12 @@ module Actions
9
9
 
10
10
  def run
11
11
  input[:host_ids].each do |host_id|
12
- content_facet = ::Host.find(host_id).content_facet
13
- content_facet.calculate_and_import_applicability
12
+ content_facet = ::Katello::Host::ContentFacet.find_by_host_id(host_id)
13
+ if content_facet.present?
14
+ content_facet.calculate_and_import_applicability
15
+ else
16
+ Rails.logger.warn(_("Content Facet for host with id %s is non-existent. Skipping applicability calculation.") % host_id)
17
+ end
14
18
  end
15
19
  end
16
20
 
@@ -39,7 +39,7 @@ module Actions
39
39
  environment: environment,
40
40
  repository: repository)
41
41
  sequence do
42
- plan_action(Actions::Pulp::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options)
42
+ plan_action(Actions::Pulp::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options) if smart_proxy.has_feature?(SmartProxy::PULP_NODE_FEATURE)
43
43
  plan_action(Actions::Pulp3::CapsuleContent::RefreshContentGuard, smart_proxy) if repositories.any? { |repo| smart_proxy.pulp3_support?(repo) }
44
44
  plan_action(Actions::Pulp3::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options) if smart_proxy.pulp3_enabled?
45
45
  plan_action(SyncCapsule, smart_proxy, refresh_options)
@@ -19,9 +19,14 @@ module Actions
19
19
  Actions::Pulp3::CapsuleContent::Sync],
20
20
  repo, smart_proxy,
21
21
  skip_metadata_check: skip_metadata_check)
22
+ end
23
+ end
24
+
25
+ concurrence do
26
+ repo_batch.each do |repo|
22
27
  if repo.is_a?(::Katello::Repository) &&
23
- repo.distribution_bootable? &&
24
- repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
28
+ repo.distribution_bootable? &&
29
+ repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
25
30
  plan_action(Katello::Repository::FetchPxeFiles,
26
31
  id: repo.id,
27
32
  capsule_id: smart_proxy.id)
@@ -71,7 +71,7 @@ module Actions
71
71
  private
72
72
 
73
73
  def sync_proxies?(environment)
74
- Setting[:foreman_proxy_content_auto_sync] && ::SmartProxy.sync_needed?(environment)
74
+ ::SmartProxy.sync_needed?(environment)
75
75
  end
76
76
 
77
77
  def repos_to_delete(version, environment)
@@ -137,7 +137,7 @@ module Actions
137
137
  history.save!
138
138
  environment = ::Katello::KTEnvironment.find(input[:environment_id])
139
139
  view = ::Katello::ContentView.find(input[:content_view_id])
140
- if SmartProxy.sync_needed?(environment) && Setting[:foreman_proxy_content_auto_sync] && !input[:skip_promotion]
140
+ if SmartProxy.sync_needed?(environment) && !input[:skip_promotion]
141
141
  ForemanTasks.async_task(ContentView::CapsuleSync,
142
142
  view,
143
143
  environment)
@@ -5,10 +5,11 @@ module Actions
5
5
  def plan(content_view, path:, metadata:)
6
6
  content_view.check_ready_to_import!
7
7
  unless SmartProxy.pulp_primary.pulp3_repository_type_support?(::Katello::Repository::YUM_TYPE)
8
- fail ::Katello::HttpErrors::BadRequest, _("This API endpoint is only valid for Pulp 3 repositories.")
8
+ fail _("This action will become available after the Pulp 3 content migration")
9
9
  end
10
10
 
11
11
  ::Katello::Pulp3::ContentViewVersion::Import.check!(content_view: content_view, metadata: metadata, path: path)
12
+ ::Katello::Pulp3::ContentViewVersion::Import.reset_content_view_repositories_from_metadata!(content_view: content_view, metadata: metadata)
12
13
 
13
14
  major = metadata[:content_view_version][:major]
14
15
  minor = metadata[:content_view_version][:minor]
@@ -0,0 +1,17 @@
1
+ module Actions
2
+ module Katello
3
+ module ContentViewVersion
4
+ class ImportLibrary < Actions::EntryAction
5
+ def plan(organization, path:, metadata:)
6
+ action_subject(organization)
7
+ library_view = ::Katello::Pulp3::ContentViewVersion::Import.find_or_create_library_import_view(organization)
8
+ plan_action(::Actions::Katello::ContentViewVersion::Import, library_view, path: path, metadata: metadata)
9
+ end
10
+
11
+ def humanized_name
12
+ _("Import Default Content View")
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -352,20 +352,36 @@ module Actions
352
352
  end
353
353
 
354
354
  def copy_yum_content(new_repo, dep_solve, package_ids, errata_ids)
355
+ return [] unless new_repo.content_type == ::Katello::Repository::YUM_TYPE
356
+
355
357
  copy_outputs = []
356
- if new_repo.content_type == ::Katello::Repository::YUM_TYPE
357
- unless errata_ids.blank?
358
+
359
+ unless errata_ids.blank?
360
+ content_present_in_this_repo = new_repo
361
+ .library_instance
362
+ .errata
363
+ .with_identifiers(errata_ids)
364
+ .exists?
365
+ if content_present_in_this_repo
358
366
  copy_outputs << plan_action(Pulp::Repository::CopyUnits, new_repo.library_instance, new_repo,
359
367
  ::Katello::Erratum.with_identifiers(errata_ids),
360
368
  incremental_update: dep_solve).output
361
369
  end
370
+ end
362
371
 
363
- unless package_ids.blank?
372
+ unless package_ids.blank?
373
+ content_present_in_this_repo = new_repo
374
+ .library_instance
375
+ .rpms
376
+ .with_identifiers(package_ids)
377
+ .exists?
378
+ if content_present_in_this_repo
364
379
  copy_outputs << plan_action(Pulp::Repository::CopyUnits, new_repo.library_instance, new_repo,
365
380
  ::Katello::Rpm.with_identifiers(package_ids),
366
381
  incremental_update: dep_solve).output
367
382
  end
368
383
  end
384
+
369
385
  copy_outputs
370
386
  end
371
387
 
@@ -14,7 +14,7 @@ module Actions
14
14
  host.subscription_facet.purpose_addons = purpose_addon_objects
15
15
  end
16
16
 
17
- host.subscription_facet.save!
17
+ host.save!
18
18
  plan_self(:hostname => host.name)
19
19
  end
20
20
 
@@ -72,7 +72,11 @@ module Actions
72
72
  end
73
73
  plan_self(:id => repo.id, :sync_result => output, :skip_metadata_check => skip_metadata_check, :validate_contents => validate_contents,
74
74
  :contents_changed => contents_changed)
75
- plan_action(Katello::Repository::ImportApplicability, :repo_id => repo.id, :contents_changed => contents_changed) if generate_applicability
75
+
76
+ if generate_applicability && !SETTINGS[:katello][:katello_applicability]
77
+ plan_action(Katello::Repository::ImportApplicability, :repo_id => repo.id, :contents_changed => contents_changed)
78
+ end
79
+
76
80
  plan_action(Katello::Repository::SyncHook, :id => repo.id)
77
81
  end
78
82
  end
@@ -1,12 +1,32 @@
1
1
  module Actions
2
2
  module Middleware
3
3
  class RecordSmartProxySyncHistory < Dynflow::Middleware
4
- def run(*args)
4
+ def save_smart_proxy_sync_history
5
5
  if (action.input[:repository_id] && (action.input[:smart_proxy_id] || action.input[:capsule_id]) && !self.action.output[:smart_proxy_history_id])
6
- repo = ::Katello::Repository.find(action.input[:repository_id])
6
+ repo_id = action.input[:repository_id]
7
+ repo = ::Katello::Repository.find_by(id: repo_id)
7
8
  smart_proxy_id = action.input[:smart_proxy_id] || action.input[:capsule_id]
8
- smart_proxy = ::SmartProxy.find(smart_proxy_id)
9
- self.action.output[:smart_proxy_history_id] = repo.create_smart_proxy_sync_history(smart_proxy)
9
+ smart_proxy = ::SmartProxy.find_by(id: smart_proxy_id)
10
+
11
+ #skip pulp2 puppet syncs
12
+ if (repo_pulp_id = action.input[:repo_pulp_id])
13
+ return if ::Katello::ContentViewPuppetEnvironment.find_by(pulp_id: repo_pulp_id)
14
+ end
15
+
16
+ if repo && smart_proxy
17
+ self.action.output[:smart_proxy_history_id] = repo.create_smart_proxy_sync_history(smart_proxy)
18
+ else
19
+ fail "Smart Proxy could not be found with id #{smart_proxy_id}" if smart_proxy.nil?
20
+ fail "Repository could not be found with id #{repo_id}" if repo.nil?
21
+ end
22
+ end
23
+ end
24
+
25
+ def run(*args)
26
+ begin
27
+ save_smart_proxy_sync_history
28
+ rescue => error
29
+ Rails.logger.error("Error saving smart proxy history: #{error.message}")
10
30
  end
11
31
  pass(*args)
12
32
  end
@@ -1,6 +1,8 @@
1
1
  module Actions
2
2
  module Pulp3
3
3
  class ContentMigration < Pulp3::AbstractAsyncTask
4
+ include Helpers::Presenter
5
+
4
6
  def plan(smart_proxy, options)
5
7
  sequence do
6
8
  action = plan_self(smart_proxy_id: smart_proxy.id)
@@ -13,6 +15,14 @@ module Actions
13
15
  migration_service.create_and_run_migrations
14
16
  end
15
17
 
18
+ def humanized_name
19
+ _("Content Migration")
20
+ end
21
+
22
+ def presenter
23
+ Actions::Pulp3::ContentMigrationPresenter.new(self)
24
+ end
25
+
16
26
  def rescue_strategy
17
27
  Dynflow::Action::Rescue::Skip
18
28
  end
@@ -0,0 +1,59 @@
1
+ require 'katello/content_migration_progress'
2
+
3
+ module Actions
4
+ module Pulp3
5
+ class ContentMigrationPresenter < Helpers::Presenter::Base
6
+ def initialize(migration_action)
7
+ @migration_action = migration_action
8
+ end
9
+
10
+ def humanized_output
11
+ if !@migration_action.done?
12
+ ContentMigrationTaskPresenter.new(@migration_action).humanized_output
13
+ else
14
+ task = ForemanTasks::Task.find_by(:external_id => @migration_action.execution_plan_id)
15
+ ::Katello::ContentMigrationProgress.find_by(:task_id => task.id)&.progress_message
16
+ end
17
+ end
18
+
19
+ class ContentMigrationTaskPresenter
20
+ def initialize(action)
21
+ @action = action
22
+ end
23
+
24
+ def task_progress_reports
25
+ if @action.pulp_tasks.empty?
26
+ []
27
+ else
28
+ @action.pulp_tasks[0].progress_reports
29
+ end
30
+ end
31
+
32
+ def task_group_progress_reports
33
+ if @action.task_groups.empty?
34
+ []
35
+ else
36
+ @action.task_groups[0].group_progress_reports
37
+ end
38
+ end
39
+
40
+ def humanized_output
41
+ report = task_progress_reports.find { |current| current['state'] == 'running' && current['total'] != 0 }
42
+ report ||= task_group_progress_reports.find { |current| current['total'] != 0 && current['done'] != current['total'] }
43
+
44
+ if !report.blank? && report['total'] != 0
45
+ "#{report['message']} #{report['done']}/#{report['total']}"
46
+ elsif report
47
+ report['message']
48
+ elsif task_progress_reports.empty?
49
+ "Content migration starting. "
50
+ else
51
+ "Initial Migration steps complete."
52
+ end
53
+ rescue
54
+ ""
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,22 @@
1
+ module Actions
2
+ module Pulp3
3
+ class ContentMigrationReset < Pulp3::AbstractAsyncTask
4
+ def plan(smart_proxy)
5
+ plan_self(smart_proxy_id: smart_proxy.id)
6
+ end
7
+
8
+ def invoke_external_task
9
+ migration_service = ::Katello::Pulp3::Migration.new(smart_proxy)
10
+ migration_service.reset
11
+ end
12
+
13
+ def humanized_name
14
+ _("Content Migration Reset")
15
+ end
16
+
17
+ def rescue_strategy
18
+ Dynflow::Action::Rescue::Skip
19
+ end
20
+ end
21
+ end
22
+ end
@@ -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
 
@@ -15,8 +15,9 @@ module Actions
15
15
  from_cvv = ::Katello::ContentViewVersion.find(input[:from_content_view_version_id]) unless input[:from_content_view_version_id].blank?
16
16
  ::Katello::Pulp3::ContentViewVersion::Export.new(smart_proxy: smart_proxy,
17
17
  content_view_version: cvv,
18
- from_content_view_version: from_cvv).create_export(input[:exporter_data][:pulp_href],
19
- chunk_size: input[:chunk_size])
18
+ from_content_view_version: from_cvv)
19
+ .create_export(input[:exporter_data][:pulp_href],
20
+ chunk_size: input[:chunk_size])
20
21
  end
21
22
  end
22
23
  end
@@ -6,9 +6,14 @@ module Actions
6
6
  end
7
7
 
8
8
  def run
9
- migration_service = ::Katello::Pulp3::Migration.new(SmartProxy.pulp_primary)
9
+ task_id = ForemanTasks::Task.find_by(external_id: self.execution_plan_id)&.id
10
+ migration_service = ::Katello::Pulp3::Migration.new(SmartProxy.pulp_primary, input.merge(task_id: task_id))
10
11
  migration_service.import_pulp3_content
11
12
  end
13
+
14
+ def humanized_output
15
+ output[:status]
16
+ end
12
17
  end
13
18
  end
14
19
  end
@@ -9,7 +9,8 @@ module Actions
9
9
  sequence do
10
10
  copy_action = plan_action(Actions::Pulp3::Repository::CopyContent, repo, SmartProxy.pulp_primary!,
11
11
  repo.library_instance,
12
- copy_all: true)
12
+ copy_all: true,
13
+ mirror: content_view_version.content_view.library_import?)
13
14
  plan_action(Actions::Pulp3::Repository::SaveVersion, repo.library_instance,
14
15
  tasks: copy_action.output[:pulp_tasks])
15
16
  plan_action(Katello::Repository::IndexContent, id: repo.library_instance_id)
@@ -18,7 +18,10 @@ module Actions
18
18
  end
19
19
 
20
20
  # rubocop:disable Metrics/MethodLength
21
- def plan(content_view_version, destination_server:, chunk_size: nil, from_history: nil)
21
+ def plan(content_view_version:, destination_server: nil,
22
+ chunk_size: nil, from_history: nil,
23
+ validate_incremental: true,
24
+ fail_on_missing_content: false)
22
25
  action_subject(content_view_version)
23
26
  unless File.directory?(Setting['pulpcore_export_destination'])
24
27
  fail ::Foreman::Exception, N_("Unable to export. 'pulpcore_export_destination' setting is not set to a valid directory.")
@@ -27,14 +30,13 @@ module Actions
27
30
  sequence do
28
31
  smart_proxy = SmartProxy.pulp_primary!
29
32
  from_content_view_version = from_history&.content_view_version
30
- if from_content_view_version.present?
31
- export_service = ::Katello::Pulp3::ContentViewVersion::Export.new(
32
- smart_proxy: smart_proxy,
33
- content_view_version: content_view_version,
34
- destination_server: destination_server,
35
- from_content_view_version: from_content_view_version)
36
- export_service.validate_incremental_export!
37
- end
33
+ export_service = ::Katello::Pulp3::ContentViewVersion::Export.new(
34
+ smart_proxy: smart_proxy,
35
+ content_view_version: content_view_version,
36
+ destination_server: destination_server,
37
+ from_content_view_version: from_content_view_version)
38
+ export_service.validate!(fail_on_missing_content: fail_on_missing_content,
39
+ validate_incremental: validate_incremental)
38
40
 
39
41
  action_output = plan_action(::Actions::Pulp3::ContentViewVersion::CreateExporter,
40
42
  content_view_version_id: content_view_version.id,
@@ -74,15 +76,17 @@ module Actions
74
76
  content_view_version: cvv,
75
77
  smart_proxy: smart_proxy,
76
78
  from_content_view_version: from_cvv).generate_metadata
77
- export_metadata[:incremental] = from_cvv.present?
78
- toc = Dir.glob("#{path}/*toc.json").first
79
- export_metadata[:toc] = File.basename(toc) if toc
80
- ::Katello::ContentViewVersionExportHistory.create!(
79
+
80
+ toc_path_info = output[:exported_file_checksum].find { |item| item.first.end_with?("toc.json") }
81
+ export_metadata[:toc] = File.basename(toc_path_info.first)
82
+
83
+ history = ::Katello::ContentViewVersionExportHistory.create!(
81
84
  content_view_version_id: input[:content_view_version_id],
82
85
  destination_server: input[:destination_server],
83
86
  path: path,
84
87
  metadata: export_metadata
85
88
  )
89
+ output[:export_history_id] = history.id
86
90
  end
87
91
 
88
92
  def humanized_name