katello 4.13.0.rc1 → 4.13.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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +334 -23
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +8 -0
  4. data/app/controllers/katello/api/v2/repositories_controller.rb +1 -1
  5. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +7 -2
  6. data/app/lib/actions/katello/organization/manifest_delete.rb +6 -1
  7. data/app/lib/actions/katello/repository/create.rb +17 -11
  8. data/app/lib/actions/katello/repository/create_root.rb +4 -2
  9. data/app/lib/actions/katello/repository/discover.rb +11 -4
  10. data/app/lib/actions/katello/upstream_subscriptions/bind_entitlement.rb +1 -1
  11. data/app/lib/actions/pulp3/orchestration/orphan_cleanup/remove_orphans.rb +1 -0
  12. data/app/lib/actions/pulp3/orphan_cleanup/purge_completed_tasks.rb +15 -0
  13. data/app/lib/actions/pulp3/repository/create_publication.rb +4 -0
  14. data/app/lib/katello/repo_discovery.rb +4 -190
  15. data/app/lib/katello/resources/discovery/container.rb +127 -0
  16. data/app/lib/katello/resources/discovery/yum.rb +95 -0
  17. data/app/lib/katello/util/http_helper.rb +15 -0
  18. data/app/models/732bd3db9f64c621c64d2be4f2a838727aac0845.patch +61 -0
  19. data/app/models/katello/content_view.rb +2 -0
  20. data/app/models/katello/glue/pulp/repos.rb +8 -1
  21. data/app/models/katello/repository.rb +5 -1
  22. data/app/models/katello/repository.rb.bak +978 -0
  23. data/app/models/katello/root_repository.rb +14 -2
  24. data/app/models/katello/trace_status.rb +1 -1
  25. data/app/services/katello/pulp3/api/core.rb +8 -0
  26. data/app/services/katello/pulp3/api/docker.rb +4 -0
  27. data/app/services/katello/pulp3/content_view_version/import_validator.rb.bak +166 -0
  28. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb.bak +164 -0
  29. data/app/services/katello/pulp3/repository/yum.rb +1 -6
  30. data/app/services/katello/repository_type.rb +1 -1
  31. data/app/views/foreman/smart_proxies/_content_tab.html.erb +3 -1
  32. data/config/initializers/monkeys.rb +0 -1
  33. data/db/migrate/20240520142245_add_container_push_props_to_repo.rb +7 -0
  34. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/checksum.service.js +6 -1
  35. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +3 -0
  36. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +0 -3
  37. data/lib/katello/plugin.rb +12 -0
  38. data/lib/katello/repository_types/docker.rb +1 -0
  39. data/lib/katello/repository_types/yum.rb +1 -0
  40. data/lib/katello/tasks/update_repository_expiry.rake +114 -0
  41. data/lib/katello/version.rb +1 -1
  42. data/lib/katello.rb +0 -2
  43. data/locale/bn/katello.po.time_stamp +0 -0
  44. data/locale/bn_IN/katello.po.time_stamp +0 -0
  45. data/locale/ca/katello.po.time_stamp +0 -0
  46. data/locale/cs/katello.po.time_stamp +0 -0
  47. data/locale/cs_CZ/katello.po.time_stamp +0 -0
  48. data/locale/de/katello.po.time_stamp +0 -0
  49. data/locale/de_AT/katello.po.time_stamp +0 -0
  50. data/locale/de_DE/katello.po.time_stamp +0 -0
  51. data/locale/el/katello.po.time_stamp +0 -0
  52. data/locale/en/katello.po.time_stamp +0 -0
  53. data/locale/en_GB/katello.po.time_stamp +0 -0
  54. data/locale/en_US/katello.po.time_stamp +0 -0
  55. data/locale/es/katello.po.time_stamp +0 -0
  56. data/locale/et_EE/katello.po.time_stamp +0 -0
  57. data/locale/fr/katello.po.time_stamp +0 -0
  58. data/locale/gl/katello.po.time_stamp +0 -0
  59. data/locale/gu/katello.po.time_stamp +0 -0
  60. data/locale/he_IL/katello.po.time_stamp +0 -0
  61. data/locale/hi/katello.po.time_stamp +0 -0
  62. data/locale/id/katello.po.time_stamp +0 -0
  63. data/locale/it/katello.po.time_stamp +0 -0
  64. data/locale/ja/katello.po.time_stamp +0 -0
  65. data/locale/ka/katello.po.time_stamp +0 -0
  66. data/locale/kn/katello.po.time_stamp +0 -0
  67. data/locale/ko/katello.po.time_stamp +0 -0
  68. data/locale/ml_IN/katello.po.time_stamp +0 -0
  69. data/locale/mr/katello.po.time_stamp +0 -0
  70. data/locale/nl_NL/katello.po.time_stamp +0 -0
  71. data/locale/or/katello.po.time_stamp +0 -0
  72. data/locale/pa/katello.po.time_stamp +0 -0
  73. data/locale/pl/katello.po.time_stamp +0 -0
  74. data/locale/pl_PL/katello.po.time_stamp +0 -0
  75. data/locale/pt/katello.po.time_stamp +0 -0
  76. data/locale/pt_BR/katello.po.time_stamp +0 -0
  77. data/locale/ro/katello.po.time_stamp +0 -0
  78. data/locale/ro_RO/katello.po.time_stamp +0 -0
  79. data/locale/ru/katello.po.time_stamp +0 -0
  80. data/locale/sl/katello.po.time_stamp +0 -0
  81. data/locale/sv_SE/katello.po.time_stamp +0 -0
  82. data/locale/ta/katello.po.time_stamp +0 -0
  83. data/locale/ta_IN/katello.po.time_stamp +0 -0
  84. data/locale/te/katello.po.time_stamp +0 -0
  85. data/locale/tr/katello.po.time_stamp +0 -0
  86. data/locale/vi/katello.po.time_stamp +0 -0
  87. data/locale/vi_VN/katello.po.time_stamp +0 -0
  88. data/locale/zh/katello.po.time_stamp +0 -0
  89. data/locale/zh_CN/katello.po.time_stamp +0 -0
  90. data/locale/zh_TW/katello.po.time_stamp +0 -0
  91. data/package.json +0 -1
  92. data/webpack/components/Content/ContentTable.js +0 -1
  93. data/webpack/components/Content/__tests__/__snapshots__/ContentTable.test.js.snap +0 -1
  94. data/webpack/global_test_setup.js.bak +59 -0
  95. data/webpack/scenes/ModuleStreams/ModuleStreamsPage.js +33 -39
  96. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamPage.test.js +4 -2
  97. data/webpack/scenes/ModuleStreams/__tests__/__snapshots__/ModuleStreamsTable.test.js.snap +0 -1
  98. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +4 -2
  99. metadata +87 -28
  100. data/lib/monkeys/anemone.rb +0 -33
  101. data/webpack/utils/__tests__/useParamsWithHash.test.js +0 -22
  102. data/webpack/utils/paramsFromHash.js +0 -16
  103. data/webpack/utils/useUrlParams.js +0 -14
@@ -17,7 +17,7 @@ module Katello
17
17
  DOWNLOAD_POLICIES = [DOWNLOAD_IMMEDIATE, DOWNLOAD_ON_DEMAND].freeze
18
18
 
19
19
  IGNORABLE_CONTENT_UNIT_TYPES = %w(srpm treeinfo).freeze
20
- CHECKSUM_TYPES = %w(sha1 sha256).freeze
20
+ CHECKSUM_TYPES = %w(sha256 sha384 sha512).freeze
21
21
 
22
22
  SUBSCRIBABLE_TYPES = [Repository::YUM_TYPE, Repository::OSTREE_TYPE, Repository::DEB_TYPE].freeze
23
23
  SKIPABLE_METADATA_TYPES = [Repository::YUM_TYPE, Repository::DEB_TYPE].freeze
@@ -60,6 +60,8 @@ module Katello
60
60
  has_many :repository_references, :class_name => 'Katello::Pulp3::RepositoryReference',
61
61
  :dependent => :destroy, :inverse_of => :root_repository
62
62
 
63
+ before_validation :remove_sha1_checksum_type, if: :sha1_checksum?
64
+
63
65
  validates_lengths_from_database :except => [:label]
64
66
  validates_with Validators::KatelloLabelFormatValidator, :attributes => :label
65
67
  validates_with Validators::KatelloNameFormatValidator, :attributes => :name
@@ -112,6 +114,8 @@ module Katello
112
114
  only_integer: true
113
115
  }
114
116
 
117
+ validates :container_push_name_format, inclusion: { in: ['label', 'id'].freeze, allow_nil: true}
118
+
115
119
  scope :subscribable, -> { where(content_type: RootRepository::SUBSCRIBABLE_TYPES) }
116
120
  scope :skipable_metadata_check, -> { where(content_type: RootRepository::SKIPABLE_METADATA_TYPES) }
117
121
  scope :has_url, -> { where.not(:url => nil) }
@@ -155,6 +159,14 @@ module Katello
155
159
  joins(:product).where("#{Katello::Product.table_name}.organization_id" => org)
156
160
  end
157
161
 
162
+ def sha1_checksum?
163
+ checksum_type == 'sha1'
164
+ end
165
+
166
+ def remove_sha1_checksum_type
167
+ self.checksum_type = nil
168
+ end
169
+
158
170
  def ensure_content_attribute_restrictions
159
171
  CONTENT_ATTRIBUTE_RESTRICTIONS.each do |attribute, value|
160
172
  if self.send(attribute).present? && !value.include?(self.content_type)
@@ -195,7 +207,7 @@ module Katello
195
207
  def ensure_docker_repo_unprotected
196
208
  unless unprotected
197
209
  errors.add(:base, _("Container Image Repositories are not protected at this time. " \
198
- "They need to be published via http to be available to containers."))
210
+ "They need to be published via http to be available to containers."))
199
211
  end
200
212
  end
201
213
 
@@ -36,7 +36,7 @@ module Katello
36
36
  end
37
37
 
38
38
  def to_status(_options = {})
39
- traces = host.host_traces.pluck(:app_type)
39
+ traces = host.host_traces.reload.pluck(:app_type)
40
40
  traces.delete(Katello::HostTracer::TRACE_APP_TYPE_SESSION)
41
41
 
42
42
  if traces.include?(Katello::HostTracer::TRACE_APP_TYPE_STATIC)
@@ -176,6 +176,14 @@ module Katello
176
176
  nil
177
177
  end
178
178
 
179
+ def purge_class
180
+ PulpcoreClient::Purge
181
+ end
182
+
183
+ def purge_completed_tasks
184
+ tasks_api.purge(purge_class.new(finished_before: DateTime.now - Setting[:completed_pulp_task_protection_days]))
185
+ end
186
+
179
187
  def delete_orphans
180
188
  [orphans_api.cleanup(PulpcoreClient::OrphansCleanup.new(orphan_protection_time: (smart_proxy.pulp_mirror? ? 0 : Setting[:orphan_protection_time])))]
181
189
  end
@@ -15,6 +15,10 @@ module Katello
15
15
  def recursive_add_api
16
16
  PulpContainerClient::ContainerRecursiveAddApi.new(api_client)
17
17
  end
18
+
19
+ def container_push_api
20
+ PulpContainerClient::RepositoriesContainerPushApi.new(api_client)
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -0,0 +1,166 @@
1
+ module Katello
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class ImportValidator
5
+ def initialize(import:)
6
+ @content_view = import.content_view
7
+ @path = import.path
8
+ @smart_proxy = import.smart_proxy
9
+ @organization = import.organization
10
+ @metadata_map = import.metadata_map
11
+ @interested_repos = import.intersecting_repos_library_and_metadata
12
+ @redhat_library_products = redhat_library_products
13
+ end
14
+
15
+ def check!
16
+ if @metadata_map.content_view.blank? && !metadata_map.syncable_format?
17
+ fail _("Content view not provided in the metadata")
18
+ end
19
+
20
+ ensure_non_syncable_path_valid! unless @metadata_map.syncable_format?
21
+ ensure_pulp_importable!
22
+ if @content_view && !@content_view.default?
23
+ ensure_non_composite!
24
+ ensure_importing_cvv_does_not_exist!
25
+ ensure_from_cvv_exists!
26
+ end
27
+ ensure_manifest_imported!
28
+ ensure_metadata_matches_repos_in_library!
29
+ ensure_redhat_products_metadata_are_in_the_library!
30
+ end
31
+
32
+ def ensure_non_syncable_path_valid!
33
+ uri = URI(@path)
34
+ unless uri.scheme.blank? || uri.scheme == "file"
35
+ fail _("Invalid path provided. Content can be only imported from file system. ")
36
+ end
37
+ end
38
+
39
+ def ensure_non_composite!
40
+ return if @content_view.blank?
41
+ fail _("Content cannot be imported into a Composite Content View. ") if @content_view.composite?
42
+ end
43
+
44
+ def ensure_pulp_importable!
45
+ return if @metadata_map.syncable_format?
46
+ api = ::Katello::Pulp3::Api::Core.new(@smart_proxy).importer_check_api
47
+ response = api.pulp_import_check_post(toc: "#{@path}/#{@metadata_map.toc}")
48
+ unless response.toc.is_valid
49
+ fail response.toc.messages.join("\n")
50
+ end
51
+ end
52
+
53
+ def ensure_importing_cvv_does_not_exist!
54
+ major = @metadata_map.content_view_version.major
55
+ minor = @metadata_map.content_view_version.minor
56
+
57
+ if ::Katello::ContentViewVersion.where(major: major, minor: minor, content_view: @content_view).exists?
58
+ fail _("Content View Version specified in the metadata - '%{name}' already exists. "\
59
+ "If you wish to replace the existing version, delete %{name} and try again. " % { name: "#{@content_view.name} #{major}.#{minor}" })
60
+ end
61
+ end
62
+
63
+ def ensure_from_cvv_exists!
64
+ major = @metadata_map.content_view_version.major
65
+ minor = @metadata_map.content_view_version.minor
66
+
67
+ if @metadata_map.from_content_view_version
68
+ from_major = @metadata_map.from_content_view_version.major
69
+ from_minor = @metadata_map.from_content_view_version.minor
70
+
71
+ unless ::Katello::ContentViewVersion.where(major: from_major, minor: from_minor, content_view: @content_view).exists?
72
+ fail _("Prior Content View Version specified in the metadata - '%{name}' does not exist. "\
73
+ "Please import the metadata for '%{name}' before importing '%{current}' " % { name: "#{@content_view.name} #{from_major}.#{from_minor}",
74
+ current: "#{@content_view.name} #{major}.#{minor}"})
75
+ end
76
+ end
77
+ end
78
+
79
+ def ensure_manifest_imported!
80
+ any_rh_repos = @metadata_map.repositories.any?(&:redhat)
81
+ if any_rh_repos && !@organization.manifest_imported?
82
+ fail _("No manifest found. Import a manifest with the appropriate subscriptions "\
83
+ "before importing content.")
84
+ end
85
+ end
86
+
87
+ def ensure_metadata_matches_repos_in_library!
88
+ bad_repos = @interested_repos.select do |katello_repo|
89
+ metadata_repo = metadata_repo_for_katello_repo(katello_repo)
90
+
91
+ next unless metadata_repo
92
+
93
+ !(katello_repo.content_type == metadata_repo.content_type &&
94
+ katello_repo.redhat? == metadata_repo.redhat)
95
+ end
96
+
97
+ if bad_repos.any?
98
+ fail _("The following repositories provided in the import metadata have an incorrect content type or provider type. "\
99
+ "Make sure the export and import repositories are of the same type before importing\n "\
100
+ "%{repos}" % { repos: generate_product_repo_i18n_string(bad_repos).join("")}
101
+ )
102
+ end
103
+ end
104
+
105
+ def ensure_redhat_products_metadata_are_in_the_library!
106
+ missing = @metadata_map.repositories.select do |repo|
107
+ repo.redhat && katello_product_for_metadata_repo(repo).nil?
108
+ end
109
+
110
+ if missing.any?
111
+ repos_in_import = generate_product_repo_i18n_string(missing)
112
+ fail _("The organization's manifest does not contain the subscriptions required to enable the following repositories.\n "\
113
+ "%{repos}" % { repos: repos_in_import.join("")}
114
+ )
115
+ end
116
+ end
117
+
118
+ def ensure_no_missing_rh_repos!
119
+ rh_repos = @metadata_map.repositories.select { |r| r.redhat }
120
+ helper = ::Katello::Pulp3::ContentViewVersion::ImportableRepositories.new(
121
+ organization: @organization,
122
+ metadata_repositories: rh_repos,
123
+ syncable_format: @metadata_map.syncable_format?,
124
+ path: path
125
+ )
126
+ helper.generate!
127
+ rh_repos = rh_repos.select do |repo|
128
+ end
129
+ end
130
+
131
+
132
+ private
133
+
134
+ def katello_product_for_metadata_repo(metadata_repo)
135
+ @redhat_library_products.find do |product|
136
+ if metadata_repo.redhat && metadata_repo.product.cp_id
137
+ product.cp_id == metadata_repo.product.cp_id
138
+ else
139
+ product.label == metadata_repo.product.label
140
+ end
141
+ end
142
+ end
143
+
144
+ def metadata_repo_for_katello_repo(repo)
145
+ @metadata_map.repositories.find do |metadata_repo|
146
+ if repo.redhat? && metadata_repo.product.cp_id
147
+ repo.label == metadata_repo.label && repo.product.cp_id == metadata_repo.product.cp_id
148
+ else
149
+ repo.label == metadata_repo.label && repo.product.label == metadata_repo.product.label
150
+ end
151
+ end
152
+ end
153
+
154
+ def redhat_library_products
155
+ ::Katello::Product.in_org(@organization).redhat
156
+ end
157
+
158
+ def generate_product_repo_i18n_string(metadata_repos)
159
+ metadata_repos.map do |repo|
160
+ _("\n* Product = '%{product}', Repository = '%{repository}'" % { product: repo.product.name, repository: repo.name })
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,164 @@
1
+ module Katello
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class ImportableRepositories
5
+ attr_reader :creatable, :updatable
6
+
7
+ def initialize(organization:,
8
+ metadata_repositories:,
9
+ syncable_format: false,
10
+ path: nil)
11
+ @organization = organization
12
+ @metadata_repositories = metadata_repositories
13
+ @creatable = []
14
+ @updatable = []
15
+ @syncable_format = syncable_format
16
+ @path = path
17
+ end
18
+
19
+ def find_root_repo(metadata_repo:, product:)
20
+ product.root_repositories.find do |r|
21
+ if metadata_repo.content&.id && metadata_repo.redhat
22
+ next if (r.content.cp_content_id != metadata_repo.content.id)
23
+ next if metadata_repo.arch_substituted? && r.arch != metadata_repo.arch
24
+ next if metadata_repo.release_version_substituted? && (r.major != metadata_repo.major ||
25
+ r.minor != metadata_repo.minor)
26
+ true
27
+ else
28
+ r.label == metadata_repo.label
29
+ end
30
+ end
31
+ end
32
+
33
+ def generate!
34
+ # For Red Hat repositories or Custom Repositories in the metadata exclusively
35
+ # Set up a 2 different list of importable root repositories
36
+ # creatable: repos that are part of the metadata but not in the library.
37
+ # They are ready to be created
38
+ # updatable: repo that are both in the metadata and library.
39
+ # These may contain updates to the repo and hence ready to be updated.
40
+ @metadata_repositories.each do |repo|
41
+ product = product_for_metadata_repo(repo)
42
+ fail _("Unable to find product '%s' in organization '%s'" % [repo.product.label, @organization.name]) if product.blank?
43
+
44
+ root = find_root_repo(product: product, metadata_repo: repo)
45
+ if root
46
+ updatable << { repository: root, options: update_repo_params(repo) }
47
+ elsif repo.redhat
48
+ product_content = fetch_product_content(repo.content, product)
49
+ substitutions = {}
50
+ substitutions[:basearch] = repo.arch if repo.content.arch_substituted?
51
+ substitutions[:releasever] = repo.minor if repo.content.release_version_substituted?
52
+ create_options = {
53
+ product: product,
54
+ content: product_content,
55
+ substitutions: substitutions,
56
+ override_url: fetch_feed_url(repo)
57
+ }
58
+ create_options[:override_arch] = repo.arch
59
+ creatable << create_options
60
+ else
61
+ creatable << { repository: product.add_repo(create_repo_params(repo, product)) }
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def find_unique_name(metadata_repo, product)
69
+ name = metadata_repo.name
70
+ i = 1
71
+ while product.root_repositories.where(name: name).exists?
72
+ name = "#{metadata_repo.name} #{i}"
73
+ i += 1
74
+ end
75
+ name
76
+ end
77
+
78
+ def product_for_metadata_repo(repo)
79
+ if repo.redhat && repo.product.cp_id
80
+ @organization.products.includes(:root_repositories).find_by(cp_id: repo.product.cp_id)
81
+ else
82
+ @organization.products.includes(:root_repositories).find_by(label: repo.product.label)
83
+ end
84
+ end
85
+
86
+ def fetch_product_content(content_metadata, product)
87
+ query = ::Katello::Content.joins(:product_contents).where("#{Katello::ProductContent.table_name}.product_id": product.id)
88
+ table_name = Katello::Content.table_name
89
+ if content_metadata&.id
90
+ query.find_by("#{table_name}.cp_content_id": content_metadata.id)
91
+ else
92
+ query.find_by("#{table_name}.label": content_metadata.label)
93
+ end
94
+ end
95
+
96
+ def gpg_key_id(metadata_repo)
97
+ if metadata_repo.gpg_key
98
+ @organization.gpg_keys.find_by(name: metadata_repo.gpg_key.name).id
99
+ end
100
+ end
101
+
102
+ def create_repo_params(metadata_repo, product)
103
+ keys = [
104
+ :label,
105
+ :description,
106
+ :arch,
107
+ :unprotected,
108
+ :content_type,
109
+ :checksum_type,
110
+ :os_versions,
111
+ :major,
112
+ :minor,
113
+ :download_policy,
114
+ :mirroring_policy
115
+ ]
116
+
117
+ params = { name: find_unique_name(metadata_repo, product) }
118
+ params[:gpg_key_id] = gpg_key_id(metadata_repo)
119
+ keys.each do |key|
120
+ params[key] = metadata_repo.send(key)
121
+ end
122
+ url = fetch_feed_url(metadata_repo)
123
+ params[:url] = url if url
124
+ params
125
+ end
126
+
127
+ def fetch_feed_url(metadata_repo)
128
+ return unless @syncable_format
129
+ uri = URI(@path)
130
+ if uri.scheme.blank? || uri.scheme == "file"
131
+ "file://#{uri.path.chomp('/')}#{metadata_repo.content.url}"
132
+ else
133
+ "#{@path.chomp('/')}#{metadata_repo.content.url}"
134
+ end
135
+ end
136
+
137
+ def update_repo_params(metadata_repo)
138
+ keys = [
139
+ :description,
140
+ :arch,
141
+ :unprotected,
142
+ :checksum_type,
143
+ :os_versions,
144
+ :major,
145
+ :minor,
146
+ :download_policy,
147
+ :mirroring_policy
148
+ ]
149
+ params = {}
150
+ url = fetch_feed_url(metadata_repo)
151
+ params[:url] = url if url
152
+ params[:gpg_key_id] = gpg_key_id(metadata_repo)
153
+
154
+ keys.each do |key|
155
+ value = metadata_repo.send(key)
156
+ params[key] = value if value
157
+ end
158
+
159
+ params
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -22,12 +22,7 @@ module Katello
22
22
 
23
23
  def publication_options(repository_version)
24
24
  options = super(repository_version)
25
- options.merge(
26
- {
27
- metadata_checksum_type: root.checksum_type,
28
- package_checksum_type: root.checksum_type
29
- }
30
- )
25
+ options.merge(checksum_type: root.checksum_type)
31
26
  end
32
27
 
33
28
  def specific_create_options
@@ -17,7 +17,7 @@ module Katello
17
17
  :repositories_api_class, :api_class, :remotes_api_class, :repository_versions_api_class,
18
18
  :distributions_api_class, :remote_class, :repo_sync_url_class, :client_module_class,
19
19
  :distribution_class, :publication_class, :publications_api_class, :url_description,
20
- :test_url, :test_url_root_options
20
+ :test_url, :test_url_root_options, :repo_discovery_class
21
21
 
22
22
  attr_accessor :metadata_publish_matching_check, :index_additional_data_proc
23
23
  attr_reader :id, :unique_content_per_repo
@@ -1,3 +1,5 @@
1
- <%= javascript_include_tag *webpack_asset_paths('katello', extension: 'js') %>
1
+ <% content_for(:javascripts) do %>
2
+ <%= webpacked_plugins_js_for :katello %>
3
+ <% end %>
2
4
  <% @smartProxyId= @smart_proxy.id %>
3
5
  <%= react_component('Content', smartProxyId: @smartProxyId, organizationId: Organization.current&.id,) %>
@@ -1,5 +1,4 @@
1
1
  #place where monkey patches are required
2
- require 'monkeys/anemone'
3
2
  require 'monkeys/ar_postgres_evr_t'
4
3
  require 'monkeys/fx_sqlite_skip'
5
4
  require 'monkeys/remove_hidden_distribution'
@@ -0,0 +1,7 @@
1
+ class AddContainerPushPropsToRepo < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :katello_root_repositories, :is_container_push, :boolean, default: false
4
+ add_column :katello_root_repositories, :container_push_name, :string, default: nil
5
+ add_column :katello_root_repositories, :container_push_name_format, :string, default: nil
6
+ end
7
+ end
@@ -10,7 +10,12 @@
10
10
  angular.module('Bastion.repositories').service('Checksum',
11
11
  ['translate', function (translate) {
12
12
 
13
- this.checksums = [{name: translate('Default'), id: null}, {id: 'sha256', name: 'sha256'}, {id: 'sha1', name: 'sha1'}];
13
+ this.checksums = [
14
+ {name: translate('Default'), id: null},
15
+ {id: 'sha256', name: 'sha256'},
16
+ {id: 'sha384', name: 'sha384'},
17
+ {id: 'sha512', name: 'sha512'}
18
+ ];
14
19
 
15
20
  this.checksumType = function (checksum) {
16
21
  if (checksum === null) {
@@ -208,6 +208,9 @@
208
208
  options="checksums"
209
209
  on-save="save(repository)">
210
210
  </dd>
211
+ <p ng-hide="repository.checksum_type !== 'sha1'" class="help-block" translate>
212
+ The sha1 checksum type is no longer supported. The checksum type will reset to 'Default' at the next edit or change in content.
213
+ </p>
211
214
  </span>
212
215
 
213
216
  <span ng-show="repository.content_type === 'yum' && repository.mirroring_policy === 'additive'">
@@ -371,9 +371,6 @@
371
371
  ng-model="repository.checksum_type"
372
372
  ng-options="type.id as type.name for type in checksums">
373
373
  </select>
374
- <p class="help-block" translate>
375
- For older operating systems such as Red Hat Enterprise Linux 5 or CentOS 5 it is recommended to use sha1.
376
- </p>
377
374
  </div>
378
375
 
379
376
  <div class="checkbox" ng-hide="repository.content_type === 'docker' || repository.content_type === 'ansible_collection'">
@@ -634,6 +634,12 @@ Foreman::Plugin.register :katello do
634
634
  full_name: N_('Orphaned Content Protection Time'),
635
635
  description: N_('Time in minutes before content that is not contained within a repository and has not been accessed is considered orphaned.')
636
636
 
637
+ setting 'completed_pulp_task_protection_days',
638
+ type: :integer,
639
+ default: 30,
640
+ full_name: N_('Completed pulp task protection days'),
641
+ description: N_('How many days before a completed Pulp task is purged by Orphan Cleanup.')
642
+
637
643
  setting 'remote_execution_prefer_registered_through_proxy',
638
644
  type: :boolean,
639
645
  default: false,
@@ -651,6 +657,12 @@ Foreman::Plugin.register :katello do
651
657
  default: true,
652
658
  full_name: N_('Distribute archived content view versions'),
653
659
  description: N_("If this is enabled, repositories of content view versions without environments (\"archived\") will be distributed at '/pulp/content/<organization>/content_views/<content view>/X.Y/...'.")
660
+
661
+ setting 'automatic_content_count_updates',
662
+ type: :boolean,
663
+ default: true,
664
+ full_name: N_('Calculate content counts on smart proxies automatically'),
665
+ description: N_("If this is enabled, content counts on smart proxies will be updated automatically after content sync.")
654
666
  end
655
667
  end
656
668
 
@@ -2,6 +2,7 @@ Katello::RepositoryTypeManager.register(::Katello::Repository::DOCKER_TYPE) do
2
2
  default_managed_content_type Katello::DockerManifest::CONTENT_TYPE
3
3
  pulp3_service_class Katello::Pulp3::Repository::Docker
4
4
  pulp3_api_class Katello::Pulp3::Api::Docker
5
+ repo_discovery_class ::Katello::Resources::Discovery::Container
5
6
  pulp3_skip_publication true
6
7
  pulp3_plugin 'container'
7
8
 
@@ -1,6 +1,7 @@
1
1
  Katello::RepositoryTypeManager.register(::Katello::Repository::YUM_TYPE) do
2
2
  pulp3_service_class Katello::Pulp3::Repository::Yum
3
3
  pulp3_api_class Katello::Pulp3::Api::Yum
4
+ repo_discovery_class ::Katello::Resources::Discovery::Yum
4
5
  pulp3_plugin 'rpm'
5
6
  prevent_unneeded_metadata_publish
6
7
 
@@ -0,0 +1,114 @@
1
+ namespace :katello do
2
+ def commit?
3
+ ENV['COMMIT'] == 'true' || ENV['FOREMAN_UPGRADE'] == '1'
4
+ end
5
+
6
+ desc "Regnerate metadata for all repositories. Specify CONTENT_VIEW=name and LIFECYCLE_ENVIRONMENT=name to narrow repositories."
7
+ task :regenerate_repo_metadata => ["dynflow:client", "check_ping"] do
8
+ User.current = User.anonymous_api_admin
9
+ repos = lookup_repositories
10
+
11
+ if repos.any?
12
+ task = ForemanTasks.async_task(Actions::Katello::Repository::BulkMetadataGenerate, repos.all.order_by_root(:name))
13
+ puts "Regenerating #{repos.count} repositories. You can monitor these on task id #{task.id}\n"
14
+ else
15
+ puts "No repositories found for regeneration."
16
+ end
17
+ end
18
+
19
+ desc "Refresh repository metadata for all repositories. Specify CONTENT_VIEW=name and LIFECYCLE_ENVIRONMENT=name to narrow repositories."
20
+ task :refresh_pulp_repo_details => ["dynflow:client", "check_ping"] do
21
+ User.current = User.anonymous_api_admin
22
+ repos = lookup_repositories
23
+
24
+ if repos.any?
25
+ task = ForemanTasks.async_task(::Actions::BulkAction, Actions::Katello::Repository::RefreshRepository, repos.all.order_by_root(:name))
26
+ puts "Refreshing #{repos.count} repositories. You can monitor these on task id #{task.id}\n"
27
+ else
28
+ puts "No repositories found for regeneration."
29
+ end
30
+ end
31
+
32
+ desc "Correct missing pulp repositories. Specify CONTENT_VIEW=name and LIFECYCLE_ENVIRONMENT=name to narrow repositories. COMMIT=true to perform operation."
33
+ task :correct_repositories => ["environment", "check_ping"] do
34
+ puts "All operations will be skipped. Re-run with COMMIT=true to perform corrections." unless commit?
35
+
36
+ User.current = User.anonymous_api_admin
37
+ repos = lookup_repositories
38
+
39
+ repos.find_each.with_index do |repo, index|
40
+ puts "Processing Repository #{index + 1}/#{repos.count}: #{repo.name} (#{repo.id})"
41
+ unless repo_exists?(repo)
42
+ handle_missing_repo(repo)
43
+ end
44
+ end
45
+
46
+ ::Katello::RootRepository.orphaned.each do |root_repo|
47
+ handle_missing_root_repo(root_repo)
48
+ end
49
+ end
50
+
51
+ desc "Change the download policy of all repos. Specify DOWNLOAD_POLICY=policy. Options are immediate or on_demand."
52
+ task :change_download_policy => ["environment", "check_ping"] do
53
+ policy = ENV['DOWNLOAD_POLICY']
54
+ unless ::Katello::RootRepository::DOWNLOAD_POLICIES.include?(policy)
55
+ puts "Invalid download policy specified: '#{policy}'. "
56
+ puts "Options are immediate or on_demand."
57
+ next
58
+ end
59
+
60
+ User.current = User.anonymous_api_admin
61
+ repos = Katello::Repository.yum_type.where(library_instance_id: nil)
62
+
63
+ repos.find_each.with_index do |repo, index|
64
+ puts "Processing Repository #{index + 1}/#{repos.count}: #{repo.name} (#{repo.id})"
65
+ begin
66
+ ForemanTasks.sync_task(::Actions::Katello::Repository::Update, repo.root,
67
+ download_policy: policy)
68
+ rescue => e
69
+ puts "Failed to update repository #{repo.name} (#{repo.id}): #{e.message}"
70
+ end
71
+ end
72
+ end
73
+
74
+ def lookup_repositories
75
+ lifecycle_envs = Katello::KTEnvironment.where(:name => ENV['LIFECYCLE_ENVIRONMENT']) if ENV['LIFECYCLE_ENVIRONMENT']
76
+ content_views = Katello::ContentView.where(:name => ENV['CONTENT_VIEW']) if ENV['CONTENT_VIEW']
77
+
78
+ repos = ::Katello::Repository
79
+ repos = repos.in_environment(lifecycle_envs) if lifecycle_envs
80
+ repos = repos.in_content_views(content_views) if content_views
81
+ repos
82
+ end
83
+
84
+ def repo_exists?(repo)
85
+ if SmartProxy.pulp_primary!.pulp3_support?(repo)
86
+ backend_service = repo.backend_service(SmartProxy.pulp_primary!)
87
+ return false unless backend_service&.repository_reference&.repository_href
88
+ backend_service.api.repositories_api.read(backend_service.repository_reference.repository_href)
89
+ else
90
+ false
91
+ end
92
+ true
93
+ rescue StandardError => e
94
+ return false if e.code == 404
95
+ end
96
+
97
+ def handle_missing_repo(repo)
98
+ puts "Repository #{repo.id} Missing"
99
+ if repo.content_view.default?
100
+ puts "Recreating #{repo.id}"
101
+ if commit?
102
+ ForemanTasks.sync_task(::Actions::Katello::Repository::Create, repo, force_repo_create: true)
103
+ repo.reload.index_content
104
+ end
105
+ else
106
+ puts "Deleting #{repo.id}"
107
+ ForemanTasks.sync_task(::Actions::Katello::Repository::Destroy, repo) if commit?
108
+ end
109
+ end
110
+
111
+ def handle_missing_root_repo(root_repo)
112
+ root_repo.destroy! if commit?
113
+ end
114
+ end
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "4.13.0.rc1".freeze
2
+ VERSION = "4.13.1".freeze
3
3
  end