From 6b4f4ad85ed79dbff6f6a4cf3c62f5bf2cde613c Mon Sep 17 00:00:00 2001 From: Jeremy Lenz Date: Mon, 11 Dec 2023 16:02:24 -0500 Subject: [PATCH] Fixes #36960 - Assign default content view environment during migration when no existing CVE found (#10817) --- app/lib/katello/util/cvecf_migrator.rb | 34 +++++++++++++++ ..._content_view_environment_content_facet.rb | 41 +++++++++++++++++-- 2 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 app/lib/katello/util/cvecf_migrator.rb diff --git a/app/lib/katello/util/cvecf_migrator.rb b/app/lib/katello/util/cvecf_migrator.rb new file mode 100644 index 00000000000..917e60918a3 --- /dev/null +++ b/app/lib/katello/util/cvecf_migrator.rb @@ -0,0 +1,34 @@ +module Katello + module Util + class CVECFMigrator # used in db/migrate/20220929204746_add_content_view_environment_content_facet.rb + def execute! + hosts_with_no_cve = [] + hosts_with_missing_cve = [] + + ::Host::Managed.all.each do |host| + next if host.content_facet.blank? + if ::Katello::ContentView.exists?(id: host.content_facet.content_view_id) && ::Katello::KTEnvironment.exists?(host.content_facet.lifecycle_environment_id) + cve = ::Katello::ContentViewEnvironment.find_by(content_view_id: host.content_facet.content_view_id, environment_id: host.content_facet.lifecycle_environment_id) + if cve.blank? + hosts_with_no_cve << host + end + else + hosts_with_missing_cve << host + end + end + + if hosts_with_missing_cve.present? || hosts_with_no_cve.present? + Rails.logger.warn "Found #{hosts_with_no_cve.count} hosts whose lifecycle environment does not have a corresponding ContentViewEnvironment" + Rails.logger.warn "Found #{hosts_with_missing_cve.count} hosts whose content facet is missing either content_view_id or lifecycle_environment_id" + Rails.logger.info "You may want to change the content view / lifecycle environment for these hosts manually." + end + (hosts_with_no_cve + hosts_with_missing_cve).each do |host| + default_content_view = host.organization.default_content_view + library = host.organization.library + Rails.logger.info "Updating host #{host.name} with default content_view_id and lifecycle_environment_id" + host.content_facet&.update_columns(content_view_id: default_content_view&.id, lifecycle_environment_id: library&.id) + end + end + end + end +end diff --git a/db/migrate/20220929204746_add_content_view_environment_content_facet.rb b/db/migrate/20220929204746_add_content_view_environment_content_facet.rb index 76aa39300a4..5eb74dcdf73 100644 --- a/db/migrate/20220929204746_add_content_view_environment_content_facet.rb +++ b/db/migrate/20220929204746_add_content_view_environment_content_facet.rb @@ -8,12 +8,13 @@ def up t.references :content_view_environment, :null => false, :index => false, :foreign_key => { :to_table => 'katello_content_view_environments' } t.references :content_facet, :null => false, :index => false, :foreign_key => { :to_table => 'katello_content_facets' } end + ::Katello::Util::CVECFMigrator.new.execute! FakeContentFacet.all.each do |content_facet| cve_id = ::Katello::KTEnvironment.find(content_facet.lifecycle_environment_id) .content_view_environments .find_by(content_view_id: content_facet.content_view_id) - .id - unless ::Katello::ContentViewEnvironmentContentFacet.create( + &.id + unless cve_id.present? && ::Katello::ContentViewEnvironmentContentFacet.create( content_facet_id: content_facet.id, content_view_environment_id: cve_id ) @@ -39,14 +40,46 @@ def down ::Katello::ContentViewEnvironmentContentFacet.all.each do |cvecf| content_facet = cvecf.content_facet - content_facet.content_view_id = cvecf.content_view_environment.content_view_id - content_facet.lifecycle_environment_id = cvecf.content_view_environment.environment_id + cve = cvecf.content_view_environment + default_org = cve.environment&.organization + default_cv_id = default_org&.default_content_view&.id + default_lce_id = default_org&.library&.id + cv_id = cvecf.content_view_environment.content_view_id || default_cv_id + lce_id = cvecf.content_view_environment.environment_id || default_lce_id + say "Updating content_facet #{content_facet.id} with cv_id #{cv_id} and lce_id #{lce_id}" + content_facet.content_view_id = cv_id + content_facet.lifecycle_environment_id = lce_id content_facet.save(validate: false) end + ensure_no_null_cv_lce change_column :katello_content_facets, :content_view_id, :integer, :null => false change_column :katello_content_facets, :lifecycle_environment_id, :integer, :null => false drop_table :katello_content_view_environment_content_facets end + + def ensure_no_null_cv_lce + # The following is to try to prevent PG::NotNullViolation: ERROR: column "content_view_id" contains null values + # since we add null constraints to the columns in the next step + content_facets_without_cv = ::Katello::Host::ContentFacet.where(content_view_id: nil) + if content_facets_without_cv.any? + say "Found #{content_facets_without_cv.count} content_facets with nil content_view_id" + content_facets_without_cv.each do |content_facet| + say "reassigning bad content_facet #{content_facet.id} to default content view" + content_facet.content_view_id = content_facet.host&.organization&.default_content_view&.id + content_facet.save(validate: false) + end + end + + content_facets_without_lce = ::Katello::Host::ContentFacet.where(lifecycle_environment_id: nil) + if content_facets_without_lce.any? + say "Found #{content_facets_without_lce.count} content_facets with nil lifecycle_environment_id" + content_facets_without_lce.each do |content_facet| + say "reassigning bad content_facet #{content_facet.id} to default lifecycle environment" + content_facet.lifecycle_environment_id = content_facet.host&.organization&.library&.id + content_facet.save(validate: false) + end + end + end end