Class: Katello::Repository
- Inherits:
-
Model
- Object
- Model
- Katello::Repository
- Includes:
- ERB::Util, ForemanTasks::Concerns::ActionSubject, Authorization::Repository, Glue, Glue::Candlepin::Repository, ScopedSearchExtensions
- Defined in:
- app/models/katello/repository.rb
Overview
rubocop:disable Metrics/ClassLength
Defined Under Namespace
Classes: Jail
Constant Summary collapse
- PULP_ID_MAX_LENGTH =
pulp uses pulp id to sync with 'yum_distributor' on the end
220- AUDIT_SYNC_ACTION =
'sync'.freeze
- DEB_TYPE =
'deb'.freeze
- YUM_TYPE =
'yum'.freeze
- FILE_TYPE =
'file'.freeze
- DOCKER_TYPE =
'docker'.freeze
- OSTREE_TYPE =
'ostree'.freeze
- ANSIBLE_COLLECTION_TYPE =
'ansible_collection'.freeze
- GENERIC_TYPE =
'generic'.freeze
- EXPORTABLE_TYPES =
[YUM_TYPE, FILE_TYPE, ANSIBLE_COLLECTION_TYPE, DOCKER_TYPE, DEB_TYPE].freeze
- ALLOWED_UPDATE_FIELDS =
['version_href', 'last_indexed'].freeze
Constants included from Glue::Candlepin::Repository
Glue::Candlepin::Repository::CANDLEPIN_DOCKER_TYPE, Glue::Candlepin::Repository::CANDLEPIN_OSTREE_TYPE
Class Method Summary collapse
- .attribute_name ⇒ Object
- .clean_container_name(name) ⇒ Object
- .errata_with_module_stream_counts(repo) ⇒ Object
- .errata_with_package_counts(repo) ⇒ Object
- .exportable(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE) ⇒ Object
- .exportable_types(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE) ⇒ Object
- .feed_ca_cert(url) ⇒ Object
- .feed_ca_file(url) ⇒ Object
- .for_products(products) ⇒ Object
- .import_distributions ⇒ Object
- .in_content_views(views) ⇒ Object
- .in_environment(env_id) ⇒ Object
- .in_organization(org) ⇒ Object
- .in_product(prod) ⇒ Object
- .linked_repositories ⇒ Object
- .repo_path_from_content_path(environment, content_path) ⇒ Object
- .safe_render_container_name(repository, pattern = nil) ⇒ Object
- .search_by_content_label(_key, operator, value) ⇒ Object
- .search_by_redhat(_key, operator, value) ⇒ Object
- .smart_proxy_syncable ⇒ Object
- .synced_on_capsule(smart_proxy) ⇒ Object
- .undisplayable_types ⇒ Object
- .with_errata(errata) ⇒ Object
- .with_type(content_type) ⇒ Object
Instance Method Summary collapse
- #all_instances ⇒ Object
- #archive? ⇒ Boolean
- #archived_instance ⇒ Object
- #assert_deletable ⇒ Object
- #audit_sync ⇒ Object
- #backend_content_service(smart_proxy) ⇒ Object
- #backend_content_unit_service(smart_proxy, content_unit_type) ⇒ Object
- #backend_service(smart_proxy) ⇒ Object
- #blocking_task ⇒ Object
-
#build_clone(options) ⇒ Object
TODO: break up method.
- #cancel_dynflow_sync ⇒ Object
- #check_ready_to_act! ⇒ Object
- #clear_smart_proxy_sync_histories(smart_proxy = nil) ⇒ Object
-
#cloned_in?(env) ⇒ Boolean
is the repo cloned in the specified environment.
- #clones ⇒ Object
- #component_source_repositories ⇒ Object
- #content ⇒ Object
- #content_counts ⇒ Object
- #content_id ⇒ Object
- #content_view ⇒ Object
- #content_view_environment ⇒ Object
- #content_views_all(include_composite: false) ⇒ Object
- #copy_indexed_data(source_repository) ⇒ Object
- #create_smart_proxy_sync_history(smart_proxy) ⇒ Object
- #custom_docker_repo_path ⇒ Object
- #custom_repo_path ⇒ Object
- #deb_content_url_options ⇒ Object
-
#destroyable?(remove_from_content_view_versions = false) ⇒ Boolean
deleteable? is already taken by the authorization mixin.
- #distribution_information ⇒ Object
- #docker_meta_tag_count ⇒ Object
-
#dynflow_handled_last_sync?(pulp_task_id) ⇒ Boolean
Returns true if the pulp_task_id was triggered by the last synchronization action for the repository.
-
#environmental_instances(view) ⇒ Object
returns other instances of this repo with the same library equivalent of repo.
- #errata_filenames ⇒ Object
- #exist_for_environment?(environment, content_view, attribute = nil) ⇒ Boolean
- #fetch_module_errata_to_filter ⇒ Object
- #fetch_package_errata_to_keep ⇒ Object
- #flatpak_dependencies? ⇒ Boolean
- #full_gpg_key_path(smart_proxy = nil, force_http = false) ⇒ Object
- #full_path(smart_proxy = nil, force_http = false) ⇒ Object
- #generate_content_path ⇒ Object
- #generate_docker_repo_path ⇒ Object
- #generate_repo_path(content_path = nil) ⇒ Object
- #get_clone(env) ⇒ Object
- #group ⇒ Object
- #immediate? ⇒ Boolean
- #import_distribution_data(target_repo = nil) ⇒ Object
- #in_content_view?(content_view) ⇒ Boolean
- #in_default_view? ⇒ Boolean
- #index_content(options = {}) ⇒ Object
- #index_linked_repo ⇒ Object
- #latest_dynflow_sync ⇒ Object
- #latest_sync_audit ⇒ Object
- #library_instance? ⇒ Boolean
- #library_instance_or_self ⇒ Object
-
#link? ⇒ Boolean
a link repository has no content in the pulp repository and serves as a shell.
- #module_streams_without_errata ⇒ Object
- #node_syncable? ⇒ Boolean
- #on_demand? ⇒ Boolean
- #organization ⇒ Object
- #organization_id ⇒ Object
- #packages_without_errata ⇒ Object
- #partial_errata ⇒ Object
-
#primary? ⇒ Boolean
a primary repository actually has content (rpms, errata, etc) in the pulp repository.
- #product_type ⇒ Object
- #promoted? ⇒ Boolean
- #published_in_versions ⇒ Object
- #rabl_path ⇒ Object
- #related_resources ⇒ Object
- #remove_partial_errata! {|found| ... } ⇒ Object
- #requires_yum_clone_distributor? ⇒ Boolean
- #set_container_repository_name ⇒ Object
- #set_pulp_id ⇒ Object
- #siblings ⇒ Object
-
#skip_container_name? ⇒ Boolean
Skip setting container name if the repository is not container type or if it's a library instance of a container-push repo, indicating that the container name is set by the user.
- #soft_copy_of_library? ⇒ Boolean
- #sync_hook ⇒ Object
- #sync_status ⇒ Object
-
#target_repository ⇒ Object
A link (empty repo) points to a target (a repository that actually has units in pulp).
- #to_hash(content_source = nil, force_http = false) ⇒ Object
- #to_label ⇒ Object
- #units_for_removal(ids, type_class = nil) ⇒ Object
- #url? ⇒ Boolean
- #using_mirrored_metadata? ⇒ Boolean
- #yum_gpg_key_url ⇒ Object
Methods included from Authorization::Repository
#deletable?, #readable?, #redhat_deletable?
Methods included from Glue
Methods included from Glue::Candlepin::Repository
Class Method Details
.attribute_name ⇒ Object
270 271 272 |
# File 'app/models/katello/repository.rb', line 270 def self.attribute_name :name end |
.clean_container_name(name) ⇒ Object
991 992 993 |
# File 'app/models/katello/repository.rb', line 991 def self.clean_container_name(name) name.gsub(/[^-\/\w]/, "_").gsub(/_{3,}/, "_").gsub(/-_|^_+|_+$/, "").downcase.strip end |
.errata_with_module_stream_counts(repo) ⇒ Object
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'app/models/katello/repository.rb', line 407 def self.errata_with_module_stream_counts(repo) repository_errata = Katello::RepositoryErratum.table_name errata = Katello::Erratum.table_name erratum_package = Katello::ErratumPackage.table_name repository_module_stream = Katello::RepositoryModuleStream.table_name msep = ::Katello::ModuleStreamErratumPackage.table_name ::Katello::Erratum.joins( "INNER JOIN #{erratum_package} on #{erratum_package}.erratum_id = #{errata}.id", "INNER JOIN #{msep} on #{msep}.erratum_package_id = #{erratum_package}.id", "INNER JOIN #{repository_errata} on #{repository_errata}.erratum_id = #{errata}.id", "INNER JOIN #{repository_module_stream} on #{repository_module_stream}.module_stream_id = #{msep}.module_stream_id"). where("#{repository_module_stream}.repository_id" => repo.id). where("#{repository_errata}.repository_id" => repo.id). group("#{errata}.id").count end |
.errata_with_package_counts(repo) ⇒ Object
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'app/models/katello/repository.rb', line 391 def self.errata_with_package_counts(repo) repository_rpm = Katello::RepositoryRpm.table_name repository_errata = Katello::RepositoryErratum.table_name rpm = Katello::Rpm.table_name errata = Katello::Erratum.table_name erratum_package = Katello::ErratumPackage.table_name ::Katello::Erratum.joins( "INNER JOIN #{erratum_package} on #{erratum_package}.erratum_id = #{errata}.id", "INNER JOIN #{repository_errata} on #{repository_errata}.erratum_id = #{errata}.id", "INNER JOIN #{rpm} on #{rpm}.filename = #{erratum_package}.filename", "INNER JOIN #{repository_rpm} on #{repository_rpm}.rpm_id = #{rpm}.id"). where("#{repository_rpm}.repository_id" => repo.id). where("#{repository_errata}.repository_id" => repo.id). group("#{errata}.id").count end |
.exportable(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE) ⇒ Object
193 194 195 |
# File 'app/models/katello/repository.rb', line 193 def self.exportable(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE) with_type(exportable_types(format: format)) end |
.exportable_types(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE) ⇒ Object
188 189 190 191 |
# File 'app/models/katello/repository.rb', line 188 def self.exportable_types(format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE) return [YUM_TYPE, FILE_TYPE] if format == ::Katello::Pulp3::ContentViewVersion::Export::SYNCABLE EXPORTABLE_TYPES end |
.feed_ca_cert(url) ⇒ Object
317 318 319 320 |
# File 'app/models/katello/repository.rb', line 317 def self.feed_ca_cert(url) file = feed_ca_file(url) File.read(file) if file end |
.feed_ca_file(url) ⇒ Object
322 323 324 |
# File 'app/models/katello/repository.rb', line 322 def self.feed_ca_file(url) ::Katello::Resources::CDN::CdnResource.ca_file if ::Katello::Resources::CDN::CdnResource.redhat_cdn?(url) end |
.for_products(products) ⇒ Object
201 202 203 |
# File 'app/models/katello/repository.rb', line 201 def self.for_products(products) joins(:root).where("#{Katello::RootRepository.table_name}.product_id" => products) end |
.import_distributions ⇒ Object
793 794 795 796 797 |
# File 'app/models/katello/repository.rb', line 793 def self.import_distributions self.all.each do |repo| repo.import_distribution_data end end |
.in_content_views(views) ⇒ Object
312 313 314 315 |
# File 'app/models/katello/repository.rb', line 312 def self.in_content_views(views) joins(:content_view_version) .where("#{Katello::ContentViewVersion.table_name}.content_view_id" => views.map(&:id)) end |
.in_environment(env_id) ⇒ Object
304 305 306 |
# File 'app/models/katello/repository.rb', line 304 def self.in_environment(env_id) where(environment_id: env_id) end |
.in_organization(org) ⇒ Object
300 301 302 |
# File 'app/models/katello/repository.rb', line 300 def self.in_organization(org) where("#{Repository.table_name}.environment_id" => org.kt_environments.pluck("#{KTEnvironment.table_name}.id")) end |
.in_product(prod) ⇒ Object
308 309 310 |
# File 'app/models/katello/repository.rb', line 308 def self.in_product(prod) where(:root_id => RootRepository.where(product_id: prod)) end |
.linked_repositories ⇒ Object
911 912 913 914 915 916 917 |
# File 'app/models/katello/repository.rb', line 911 def self.linked_repositories to_return = [] Katello::Repository.yum_type.in_non_default_view.find_each do |repo| to_return << repo if repo.link? end to_return end |
.repo_path_from_content_path(environment, content_path) ⇒ Object
205 206 207 208 209 |
# File 'app/models/katello/repository.rb', line 205 def self.repo_path_from_content_path(environment, content_path) path = content_path.sub(%r|^/|, '') path_prefix = [environment.organization.label, environment.label].join('/') "#{path_prefix}/#{path}" end |
.safe_render_container_name(repository, pattern = nil) ⇒ Object
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 |
# File 'app/models/katello/repository.rb', line 944 def self.safe_render_container_name(repository, pattern = nil) # pattern provided / env pattern provided # | 00 | 01 | 11 | 10 # ----------------+-----+-----+-----+------ # env exists / 00| 4 | n/a | n/a | 4 # is cv default 01| 2 | n/a | n/a | 4 # 11| 2 | 1 | 1 | 1 # 10| 3 | 1 | 1 | 1 # # This table shows the name to render given the properties of # the container provided. Branches numbered as ordered below. # # 1 - Render promotion pattern (or env pattern if no promo pattern) # 2 - <org label>/<product label>/<repo label> # 3 - <org label>/<env label>/<cv label>/<product label>/<repo label> # 4 - <org label>/<cv label>/<cvv label>/<product label>/<repo label> is_pattern_provided = pattern.present? env_exists = repository.environment.present? is_env_pattern_provided = env_exists && repository.environment.registry_name_pattern.present? is_cv_default = repository.content_view.default? if is_env_pattern_provided || (is_pattern_provided && env_exists) pattern ||= repository.environment.registry_name_pattern allowed_methods = {} allowed_vars = {} scope_variables = { repository: repository, organization: repository.organization, product: repository.product, lifecycle_environment: repository.environment, content_view: repository.content_view_version.content_view, content_view_version: repository.content_view_version, } box = Safemode::Box.new(repository, allowed_methods) erb = ERB.new(pattern) pattern = box.eval(erb.src, allowed_vars, scope_variables) return Repository.clean_container_name(pattern) elsif is_cv_default && !is_pattern_provided items = [repository.organization.label, repository.product.label, repository.label] elsif env_exists items = [repository.organization.label, repository.environment.label, repository.content_view.label, repository.product.label, repository.label] else items = [repository.organization.label, repository.content_view.label, repository.content_view_version.version, repository.product.label, repository.label] end Repository.clean_container_name(items.compact.join("/")) end |
.search_by_content_label(_key, operator, value) ⇒ Object
933 934 935 936 937 938 939 940 941 942 |
# File 'app/models/katello/repository.rb', line 933 def self.search_by_content_label(_key, operator, value) conditions = sanitize_sql_for_conditions(["label #{operator} ?", value_to_sql(operator, value)]) contents = Katello::Content.where(conditions).pluck(:cp_content_id) root_ids = Katello::RootRepository.where(:content_id => contents).pluck(:id) if root_ids.empty? { :conditions => "1=0" } else { :conditions => "#{Katello::Repository.table_name}.root_id IN (#{root_ids.join(',')})" } end end |
.search_by_redhat(_key, operator, value) ⇒ Object
919 920 921 922 923 924 925 926 927 928 929 930 931 |
# File 'app/models/katello/repository.rb', line 919 def self.search_by_redhat(_key, operator, value) value = value == 'true' value = !value if operator == '<>' product_ids = Katello::Product.redhat.select(:id) root_ids = Katello::RootRepository.where(:product_id => product_ids).pluck(:id) if product_ids.empty? {:conditions => "1=0"} else operator = value ? 'IN' : 'NOT IN' {:conditions => "#{Katello::Repository.table_name}.root_id #{operator} (#{root_ids.join(',')})"} end end |
.smart_proxy_syncable ⇒ Object
753 754 755 756 757 |
# File 'app/models/katello/repository.rb', line 753 def self.smart_proxy_syncable joins(:content_view_version => :content_view). merge(ContentView.ignore_generated(include_library_generated: true)). where.not(environment_id: nil) end |
.synced_on_capsule(smart_proxy) ⇒ Object
638 639 640 |
# File 'app/models/katello/repository.rb', line 638 def self.synced_on_capsule(smart_proxy) smart_proxy.smart_proxy_sync_histories.map { |sph| sph.repository unless sph.finished_at.nil? } end |
.undisplayable_types ⇒ Object
296 297 298 |
# File 'app/models/katello/repository.rb', line 296 def self.undisplayable_types [::Katello::Repository::CANDLEPIN_DOCKER_TYPE] end |
.with_errata(errata) ⇒ Object
589 590 591 |
# File 'app/models/katello/repository.rb', line 589 def self.with_errata(errata) joins(:repository_errata).where("#{Katello::RepositoryErratum.table_name}.erratum_id" => errata) end |
.with_type(content_type) ⇒ Object
197 198 199 |
# File 'app/models/katello/repository.rb', line 197 def self.with_type(content_type) joins(:root).where("#{RootRepository.table_name}.content_type" => content_type) end |
Instance Method Details
#all_instances ⇒ Object
473 474 475 |
# File 'app/models/katello/repository.rb', line 473 def all_instances self.root.repositories end |
#archive? ⇒ Boolean
331 332 333 |
# File 'app/models/katello/repository.rb', line 331 def archive? self.environment.nil? end |
#archived_instance ⇒ Object
717 718 719 720 721 722 723 724 725 |
# File 'app/models/katello/repository.rb', line 717 def archived_instance if self.environment_id.nil? || self.library_instance_id.nil? self elsif self.content_view.rolling? self.library_instance else self.content_view_version.archived_repos.where(:root_id => self.root_id).first end end |
#assert_deletable ⇒ Object
865 866 867 |
# File 'app/models/katello/repository.rb', line 865 def assert_deletable throw :abort unless destroyable? end |
#audit_sync ⇒ Object
251 252 253 |
# File 'app/models/katello/repository.rb', line 251 def audit_sync write_audit(action: AUDIT_SYNC_ACTION, comment: _('Successfully synchronized.'), audited_changes: {}) end |
#backend_content_service(smart_proxy) ⇒ Object
231 232 233 |
# File 'app/models/katello/repository.rb', line 231 def backend_content_service(smart_proxy) backend_service(smart_proxy).content_service end |
#backend_content_unit_service(smart_proxy, content_unit_type) ⇒ Object
235 236 237 |
# File 'app/models/katello/repository.rb', line 235 def backend_content_unit_service(smart_proxy, content_unit_type) backend_service(smart_proxy).content_service(content_unit_type) end |
#backend_service(smart_proxy) ⇒ Object
225 226 227 228 229 |
# File 'app/models/katello/repository.rb', line 225 def backend_service(smart_proxy) fail('Pulp 3 not supported') unless smart_proxy.pulp3_support?(self) @service ||= Katello::Pulp3::Repository.instance_for_type(self, smart_proxy) end |
#blocking_task ⇒ Object
684 685 686 687 688 689 690 691 692 693 694 695 696 |
# File 'app/models/katello/repository.rb', line 684 def blocking_task blocking_task_labels = [ ::Actions::Katello::Repository::Sync.name, ::Actions::Katello::Repository::UploadFiles.name, ::Actions::Katello::Repository::RemoveContent.name, ::Actions::Katello::Repository::MetadataGenerate.name, ] ForemanTasks::Task::DynflowTask.where(:label => blocking_task_labels) .where.not(state: 'stopped') .for_resource(self) .order(:started_at) .last end |
#build_clone(options) ⇒ Object
TODO: break up method
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'app/models/katello/repository.rb', line 599 def build_clone() to_env = [:environment] version = [:version] content_view = [:content_view] || to_env.default_content_view to_version = version || content_view.version(to_env) fail _("Cannot clone into the Default Content View") if content_view.default? if to_env && version fail "Cannot clone into both an environment and a content view version archive" end if to_version.nil? fail _("View %{view} has not been promoted to %{env}") % {:view => content_view.name, :env => to_env.name} end if to_env && self.clones.in_content_views([content_view]).in_environment(to_env).any? fail _("Repository has already been cloned to %{cv_name} in environment %{to_env}") % {:to_env => to_env, :cv_name => content_view.name} end if self.yum? if self.library_instance? checksum_type = root.checksum_type else checksum_type = self.saved_checksum_type end end clone = Repository.new(:environment => to_env, :library_instance => library_instance_or_self, :root => self.root, :content_view_version => to_version, :saved_checksum_type => checksum_type) clone.relative_path = clone.docker? ? clone.generate_docker_repo_path : clone.generate_repo_path clone end |
#cancel_dynflow_sync ⇒ Object
666 667 668 669 670 671 672 673 674 675 676 |
# File 'app/models/katello/repository.rb', line 666 def cancel_dynflow_sync if latest_dynflow_sync plan = latest_dynflow_sync.execution_plan plan.steps.each_pair do |_number, step| if step.cancellable? && step.is_a?(Dynflow::ExecutionPlan::Steps::RunStep) ::ForemanTasks.dynflow.world.event(plan.id, step.id, Dynflow::Action::Cancellable::Cancel) end end end end |
#check_ready_to_act! ⇒ Object
698 699 700 701 702 703 704 705 706 707 708 709 |
# File 'app/models/katello/repository.rb', line 698 def check_ready_to_act! blocking_tasks = content_views&.map { |cv| cv.blocking_task }&.compact if blocking_tasks&.any? errored_tasks = blocking_tasks .uniq .map { |task| "- #{Setting['foreman_url']}/foreman_tasks/tasks/#{task&.id}" } .join("\n") fail _("Repository #{self.label} has pending tasks in associated content views. Please wait for the tasks: " + errored_tasks + " to complete before proceeding.") end end |
#clear_smart_proxy_sync_histories(smart_proxy = nil) ⇒ Object
642 643 644 645 646 647 648 |
# File 'app/models/katello/repository.rb', line 642 def clear_smart_proxy_sync_histories(smart_proxy = nil) if smart_proxy self.smart_proxy_sync_histories.where(:smart_proxy_id => smart_proxy.id).try(:delete_all) else self.smart_proxy_sync_histories.delete_all end end |
#cloned_in?(env) ⇒ Boolean
is the repo cloned in the specified environment
498 499 500 |
# File 'app/models/katello/repository.rb', line 498 def cloned_in?(env) !get_clone(env).nil? end |
#clones ⇒ Object
469 470 471 |
# File 'app/models/katello/repository.rb', line 469 def clones self.root.repositories.where.not(:id => library_instance_id || id) end |
#component_source_repositories ⇒ Object
905 906 907 908 909 |
# File 'app/models/katello/repository.rb', line 905 def component_source_repositories #find other copies of this repositories, in the CV version's components, that are in the 'archive' Katello::Repository.where(:content_view_version_id => self.content_view_version.components, :environment_id => nil, :root_id => self.root_id) end |
#content ⇒ Object
217 218 219 |
# File 'app/models/katello/repository.rb', line 217 def content Katello::Content.find_by(:cp_content_id => self.content_id, :organization_id => self.product.organization_id) end |
#content_counts ⇒ Object
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'app/models/katello/repository.rb', line 369 def content_counts content_counts = {} RepositoryTypeManager.defined_repository_types[content_type].content_types_to_index.each do |content_type| case content_type&.model_class::CONTENT_TYPE when DockerTag::CONTENT_TYPE content_counts[DockerTag::CONTENT_TYPE] = .count when GenericContentUnit::CONTENT_TYPE content_counts[content_type.content_type] = content_type&.model_class&.in_repositories(self)&.where(:content_type => content_type.content_type)&.count else content_counts[content_type.label] = content_type&.model_class&.in_repositories(self)&.count end end content_counts['module_stream'] = content_counts.delete('modulemd') if content_counts.key?('modulemd') content_counts end |
#content_id ⇒ Object
211 212 213 214 215 |
# File 'app/models/katello/repository.rb', line 211 def content_id # Currently deb content will store a content_id on each Repository, while all other content # types will store one on the RootRepository. self[:content_id] || root.content_id end |
#content_view ⇒ Object
278 279 280 |
# File 'app/models/katello/repository.rb', line 278 def content_view self.content_view_version.content_view end |
#content_view_environment ⇒ Object
282 283 284 |
# File 'app/models/katello/repository.rb', line 282 def content_view_environment self.content_view.content_view_environment(self.environment) end |
#content_views_all(include_composite: false) ⇒ Object
845 846 847 848 849 850 851 852 |
# File 'app/models/katello/repository.rb', line 845 def content_views_all(include_composite: false) if include_composite cv_ids = library_instances_inverse&.joins(:content_view_version)&.map { |cvv| cvv&.content_view&.id } return ContentView.where(id: cv_ids.uniq) else return self.content_views end end |
#copy_indexed_data(source_repository) ⇒ Object
1012 1013 1014 1015 1016 1017 |
# File 'app/models/katello/repository.rb', line 1012 def copy_indexed_data(source_repository) repository_type.content_types_to_index.each do |type| type.model_class.copy_repository_associations(source_repository, self) repository_type.index_additional_data_proc&.call(self, source_repository) end end |
#create_smart_proxy_sync_history(smart_proxy) ⇒ Object
650 651 652 653 654 655 656 657 658 659 660 |
# File 'app/models/katello/repository.rb', line 650 def create_smart_proxy_sync_history(smart_proxy) clear_smart_proxy_sync_histories(smart_proxy) sp_history_args = { :smart_proxy_id => smart_proxy.id, :repository_id => self.id, :started_at => Time.now, } sp_history = ::Katello::SmartProxySyncHistory.create sp_history_args sp_history.save! sp_history.id end |
#custom_docker_repo_path ⇒ Object
1004 1005 1006 1007 1008 1009 1010 |
# File 'app/models/katello/repository.rb', line 1004 def custom_docker_repo_path if [environment, product, root.label].any?(&:nil?) return nil # can't generate valid path end parts = [environment.organization.label, product.label, root.label] parts.map { |x| x.gsub(/[^-\w]/, "_") }.join("-").downcase end |
#custom_repo_path ⇒ Object
995 996 997 998 999 1000 1001 1002 |
# File 'app/models/katello/repository.rb', line 995 def custom_repo_path return custom_docker_repo_path if docker? if [environment, product, root.label].any?(&:nil?) return nil # can't generate valid path end prefix = [environment.organization.label, environment.label].map { |x| x.gsub(/[^-\w]/, "_") }.join("/") prefix + root.custom_content_path end |
#deb_content_url_options ⇒ Object
1058 1059 1060 1061 1062 1063 1064 |
# File 'app/models/katello/repository.rb', line 1058 def return '' if version_href.blank? backend_service = self.backend_service(SmartProxy.pulp_primary) distributions, components = backend_service.pulp_distributions_and_components "/?comp=#{components.join(',')}&rel=#{distributions.join(',')}" end |
#destroyable?(remove_from_content_view_versions = false) ⇒ Boolean
deleteable? is already taken by the authorization mixin
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 |
# File 'app/models/katello/repository.rb', line 824 def destroyable?(remove_from_content_view_versions = false) if self.environment.try(:library?) && self.content_view.default? if self.environment.organization.being_deleted? return true elsif self.custom? && self.deletable?(remove_from_content_view_versions) return true elsif !self.custom? && self.redhat_deletable?(remove_from_content_view_versions) return true elsif Setting.find_by(name: 'delete_repo_across_cv')&.value return true else errors.add(:base, _("Repository cannot be deleted since it has already been included in a published Content View. " \ "Please delete all Content View versions containing this repository before attempting to delete it "\ "or use --remove-from-content-view-versions flag to automatically remove the repository from all published versions.")) return false end end return true end |
#distribution_information ⇒ Object
813 814 815 816 817 818 819 820 821 |
# File 'app/models/katello/repository.rb', line 813 def distribution_information { distribution_version: self.distribution_version, distribution_arch: self.distribution_arch, distribution_family: self.distribution_family, distribution_variant: self.distribution_variant, distribution_bootable: self.distribution_bootable, } end |
#docker_meta_tag_count ⇒ Object
869 870 871 |
# File 'app/models/katello/repository.rb', line 869 def DockerMetaTag.in_repositories(self.id).count end |
#dynflow_handled_last_sync?(pulp_task_id) ⇒ Boolean
Returns true if the pulp_task_id was triggered by the last synchronization action for the repository. Dynflow action handles the synchronization by it's own so no need to synchronize it again in this callback. Since the callbacks are run just after synchronization is finished, it should be enough to check for the last synchronization task.
526 527 528 529 530 |
# File 'app/models/katello/repository.rb', line 526 def dynflow_handled_last_sync?(pulp_task_id) task = ForemanTasks::Task::DynflowTask.for_action(::Actions::Katello::Repository::Sync). for_resource(self).order(:started_at).last return task && task.main_action.pulp_task_id == pulp_task_id end |
#environmental_instances(view) ⇒ Object
returns other instances of this repo with the same library equivalent of repo
713 714 715 |
# File 'app/models/katello/repository.rb', line 713 def environmental_instances(view) self.all_instances.non_archived.in_content_views([view]) end |
#errata_filenames ⇒ Object
593 594 595 596 |
# File 'app/models/katello/repository.rb', line 593 def errata_filenames Katello::ErratumPackage.joins(:erratum => :repository_errata). where("#{RepositoryErratum.table_name}.repository_id" => self.id).pluck("#{Katello::ErratumPackage.table_name}.filename") end |
#exist_for_environment?(environment, content_view, attribute = nil) ⇒ Boolean
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 |
# File 'app/models/katello/repository.rb', line 759 def exist_for_environment?(environment, content_view, attribute = nil) if environment.present? && content_view.in_environment?(environment) repos = content_view.version(environment).repos(environment) repos.any? do |repo| not_self = (repo.id != self.id) same_product = (repo.product.id == self.product.id) repo_exists = same_product && not_self if repo_exists && attribute same_attribute = repo.send(attribute) == self.send(attribute) repo_exists = same_attribute end repo_exists end else false end end |
#fetch_module_errata_to_filter ⇒ Object
434 435 436 437 438 439 440 441 442 443 |
# File 'app/models/katello/repository.rb', line 434 def fetch_module_errata_to_filter errata_counts = ::Katello::Repository.errata_with_module_stream_counts(self) errata_counts_in_library = ::Katello::Repository.errata_with_module_stream_counts(library_instance) if errata_counts_in_library.any? errata_counts_in_library.keep_if { |id| errata_counts[id] != errata_counts_in_library[id] } errata_counts_in_library.keys else [] end end |
#fetch_package_errata_to_keep ⇒ Object
423 424 425 426 427 428 429 430 431 432 |
# File 'app/models/katello/repository.rb', line 423 def fetch_package_errata_to_keep errata_counts = ::Katello::Repository.errata_with_package_counts(self) if errata_counts.any? errata_counts_in_library = ::Katello::Repository.errata_with_package_counts(library_instance) errata_counts.keep_if { |id| errata_counts[id] == errata_counts_in_library[id] } errata_counts.keys else [] end end |
#flatpak_dependencies? ⇒ Boolean
735 736 737 738 739 740 741 742 743 |
# File 'app/models/katello/repository.rb', line 735 def flatpak_dependencies? return false unless root.docker? return false if root.docker_upstream_name.blank? flatpak_repo = FlatpakRemoteRepository.find_by(name: root.docker_upstream_name) return false unless flatpak_repo flatpak_repo.repository_dependencies.any? end |
#full_gpg_key_path(smart_proxy = nil, force_http = false) ⇒ Object
358 359 360 361 362 363 |
# File 'app/models/katello/repository.rb', line 358 def full_gpg_key_path(smart_proxy = nil, force_http = false) return if self.root.gpg_key.try(:content).blank? pulp_uri = URI.parse(smart_proxy ? smart_proxy.url : ::SmartProxy.pulp_primary.url) scheme = force_http ? 'http' : 'https' "#{scheme}://#{pulp_uri.host.downcase}#{gpg_key_content_api_repository_url(self, :only_path => true)}" end |
#full_path(smart_proxy = nil, force_http = false) ⇒ Object
481 482 483 484 485 486 487 488 489 490 491 |
# File 'app/models/katello/repository.rb', line 481 def full_path(smart_proxy = nil, force_http = false) pulp_uri = URI.parse(smart_proxy ? smart_proxy.url : ::SmartProxy.pulp_primary.url) scheme = force_http ? 'http' : 'https' if docker? "#{pulp_uri.host.downcase}/#{container_repository_name}" elsif ansible_collection? "#{scheme}://#{pulp_uri.host.downcase}/pulp_ansible/galaxy/#{relative_path}/api/" else "#{scheme}://#{pulp_uri.host.downcase}/pulp/content/#{relative_path}/" end end |
#generate_content_path ⇒ Object
532 533 534 535 536 537 538 |
# File 'app/models/katello/repository.rb', line 532 def generate_content_path path = content.content_url root.substitutions.each do |key, value| path = path.gsub("$#{key}", value) if value end path end |
#generate_docker_repo_path ⇒ Object
556 557 558 559 560 561 562 563 564 565 566 567 568 |
# File 'app/models/katello/repository.rb', line 556 def generate_docker_repo_path org = self.organization.label.downcase if self.environment cvenv = ContentViewEnvironment.where(:environment_id => self.environment, :content_view_id => self.content_view).first view = self.content_view.label product = self.product.label env = cvenv.label.split('/').first "#{org}/#{env.downcase}/#{view}/#{product}/#{self.root.label}" else "#{org}/#{self.content_view.label}/#{self.content_view_version.version}/#{self.root.product.label}/#{self.root.label}" end end |
#generate_repo_path(content_path = nil) ⇒ Object
544 545 546 547 548 549 550 551 552 553 554 |
# File 'app/models/katello/repository.rb', line 544 def generate_repo_path(content_path = nil) _org, _content, content_path = library_instance_or_self.relative_path.split("/", 3) if content_path.blank? content_path = content_path.sub(%r|^/|, '') if self.environment cvenv = ContentViewEnvironment.where(:environment_id => self.environment, :content_view_id => self.content_view).first "#{organization.label}/#{cvenv.label}/#{content_path}" else "#{organization.label}/#{ContentView::CONTENT_DIR}/#{self.content_view.label}/#{self.content_view_version.version}/#{content_path}" end end |
#get_clone(env) ⇒ Object
510 511 512 513 514 515 516 517 518 519 |
# File 'app/models/katello/repository.rb', line 510 def get_clone(env) if self.content_view.default # this repo is part of a default content view Repository.in_environment(env).clones. joins(:content_view_version => :content_view).where("#{Katello::ContentView.table_name}.default" => true).first else # this repo is part of a content view that was published from a user created view self.content_view.get_repo_clone(env, self).first end end |
#group ⇒ Object
477 478 479 |
# File 'app/models/katello/repository.rb', line 477 def group all_instances end |
#immediate? ⇒ Boolean
347 348 349 |
# File 'app/models/katello/repository.rb', line 347 def immediate? root.download_policy == ::Katello::RootRepository::DOWNLOAD_IMMEDIATE end |
#import_distribution_data(target_repo = nil) ⇒ Object
799 800 801 802 803 804 805 806 807 808 809 810 811 |
# File 'app/models/katello/repository.rb', line 799 def import_distribution_data(target_repo = nil) if target_repo self.update!( :distribution_version => target_repo.distribution_version, :distribution_arch => target_repo.distribution_arch, :distribution_family => target_repo.distribution_family, :distribution_variant => target_repo.distribution_variant, :distribution_bootable => target_repo.distribution_bootable ) else self.backend_service(SmartProxy.pulp_primary).import_distribution_data end end |
#in_content_view?(content_view) ⇒ Boolean
1054 1055 1056 |
# File 'app/models/katello/repository.rb', line 1054 def in_content_view?(content_view) content_view.repositories.include? self end |
#in_default_view? ⇒ Boolean
339 340 341 |
# File 'app/models/katello/repository.rb', line 339 def in_default_view? content_view_version&.default_content_view? end |
#index_content(options = {}) ⇒ Object
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 |
# File 'app/models/katello/repository.rb', line 1027 def index_content( = {}) # set full_index to true if you want to force fetch all data from pulp # This is automatically done for library instance repos # However for non-library instance as in those belonging to a version # by default we fetch only ids and match them with the library instance # some times we want to force fetch all data even for non-library repos. # Use the full_index for those times full_index = .fetch(:full_index, false) source_repository = .fetch(:source_repository, nil) if self.yum? && !self.primary? index_linked_repo elsif source_repository && !repository_type.unique_content_per_repo copy_indexed_data(source_repository) else repository_type.content_types_to_index.each do |type| Katello::Logging.time("CONTENT_INDEX", data: {type: type.model_class}) do Katello::ContentUnitIndexer.new(content_type: type, repository: self, optimized: !full_index).import_all end end repository_type.index_additional_data_proc&.call(self) end self.update!(last_indexed: DateTime.now) true end |
#index_linked_repo ⇒ Object
1019 1020 1021 1022 1023 1024 1025 |
# File 'app/models/katello/repository.rb', line 1019 def index_linked_repo if (base_repo = self.target_repository) copy_indexed_data(base_repo) else Rails.logger.error("Cannot index #{self.id}, no target repository found.") end end |
#latest_dynflow_sync ⇒ Object
678 679 680 681 682 |
# File 'app/models/katello/repository.rb', line 678 def latest_dynflow_sync sync_repo = library_instance_or_self @latest_dynflow_sync ||= ForemanTasks::Task::DynflowTask.where(:label => ::Actions::Katello::Repository::Sync.name). for_resource(sync_repo).order(:started_at).last end |
#latest_sync_audit ⇒ Object
662 663 664 |
# File 'app/models/katello/repository.rb', line 662 def latest_sync_audit library_instance_or_self.audits.where(:action => AUDIT_SYNC_ACTION).order(:created_at).last end |
#library_instance? ⇒ Boolean
292 293 294 |
# File 'app/models/katello/repository.rb', line 292 def library_instance? self.content_view.default? end |
#library_instance_or_self ⇒ Object
540 541 542 |
# File 'app/models/katello/repository.rb', line 540 def library_instance_or_self self.library_instance || self end |
#link? ⇒ Boolean
a link repository has no content in the pulp repository and serves as a shell. It will always be empty. Only the YumCloneDistributor can be used to publish yum metadata, and it cannot be indexed from pulp, but must have its indexed associations copied from another repository (its target).
885 886 887 |
# File 'app/models/katello/repository.rb', line 885 def link? !primary? end |
#module_streams_without_errata ⇒ Object
578 579 580 581 582 583 584 585 586 587 |
# File 'app/models/katello/repository.rb', line 578 def module_streams_without_errata module_stream_errata = Katello::ModuleStreamErratumPackage.joins(:erratum_package => {:erratum => :repository_errata}) .where("#{RepositoryErratum.table_name}.repository_id" => self.id) .pluck("#{Katello::ModuleStreamErratumPackage.table_name}.module_stream_id") if module_stream_errata.any? self.module_streams.where("#{ModuleStream.table_name}.id NOT in (?)", module_stream_errata) else self.module_streams end end |
#node_syncable? ⇒ Boolean
749 750 751 |
# File 'app/models/katello/repository.rb', line 749 def node_syncable? environment end |
#on_demand? ⇒ Boolean
343 344 345 |
# File 'app/models/katello/repository.rb', line 343 def on_demand? root.download_policy == ::Katello::RootRepository::DOWNLOAD_ON_DEMAND end |
#organization ⇒ Object
239 240 241 242 243 244 245 |
# File 'app/models/katello/repository.rb', line 239 def organization if self.environment self.environment.organization else self.content_view.organization end end |
#organization_id ⇒ Object
247 248 249 |
# File 'app/models/katello/repository.rb', line 247 def organization_id organization&.id end |
#packages_without_errata ⇒ Object
570 571 572 573 574 575 576 |
# File 'app/models/katello/repository.rb', line 570 def packages_without_errata if errata_filenames.any? self.rpms.where("#{Rpm.table_name}.filename NOT in (?)", errata_filenames) else self.rpms end end |
#partial_errata ⇒ Object
445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'app/models/katello/repository.rb', line 445 def partial_errata return [] if library_instance? partial_errata = self.errata errata_to_keep = fetch_package_errata_to_keep - fetch_module_errata_to_filter if errata_to_keep.any? partial_errata = self.errata.where("#{Katello::Erratum.table_name}.id NOT IN (?)", errata_to_keep) end partial_errata end |
#primary? ⇒ Boolean
a primary repository actually has content (rpms, errata, etc) in the pulp repository. For these repositories, we can use the YumDistributor to generate metadata and can index the content from pulp, or for the case of content view archives without filters, can also use the YumCloneDistributor
876 877 878 879 880 881 |
# File 'app/models/katello/repository.rb', line 876 def primary? !self.yum? || # non-yum repos self.in_default_view? || # default content view repos (self.archive? && !self.content_view.composite) || # non-composite content view archive repos (self.archive? && self.content_view.composite? && self.component_source_repositories.count > 1) # composite archive repo with more than 1 source repository end |
#product_type ⇒ Object
365 366 367 |
# File 'app/models/katello/repository.rb', line 365 def product_type redhat? ? "redhat" : "custom" end |
#promoted? ⇒ Boolean
502 503 504 505 506 507 508 |
# File 'app/models/katello/repository.rb', line 502 def promoted? if environment&.library? self.clones.any? else false end end |
#published_in_versions ⇒ Object
386 387 388 389 |
# File 'app/models/katello/repository.rb', line 386 def published_in_versions Katello::ContentViewVersion.with_repositories(self.library_instances_inverse) .where(content_view_id: Katello::ContentView.ignore_generated).distinct end |
#rabl_path ⇒ Object
861 862 863 |
# File 'app/models/katello/repository.rb', line 861 def rabl_path "katello/api/v2/#{self.class.to_s.demodulize.tableize}/show" end |
#related_resources ⇒ Object
745 746 747 |
# File 'app/models/katello/repository.rb', line 745 def self.product end |
#remove_partial_errata! {|found| ... } ⇒ Object
458 459 460 461 462 463 |
# File 'app/models/katello/repository.rb', line 458 def remove_partial_errata! found = partial_errata.to_a yield(found) if block_given? self.repository_errata.where(:erratum_id => found.map(&:id)).delete_all found end |
#requires_yum_clone_distributor? ⇒ Boolean
727 728 729 |
# File 'app/models/katello/repository.rb', line 727 def requires_yum_clone_distributor? self.yum? && self.environment_id && !self.in_default_view? end |
#set_container_repository_name ⇒ Object
274 275 276 |
# File 'app/models/katello/repository.rb', line 274 def set_container_repository_name self.container_repository_name = Repository.safe_render_container_name(self) end |
#set_pulp_id ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'app/models/katello/repository.rb', line 255 def set_pulp_id return if self.pulp_id if self.content_view.default? items = [SecureRandom.uuid] elsif self.environment items = [organization.id, content_view.label, environment.label, library_instance.pulp_id] else version = self.content_view_version.version.gsub('.', '_') items = [organization.id, content_view.label, "v#{version}", library_instance.pulp_id] end self.pulp_id = items.join('-') self.pulp_id = SecureRandom.uuid if self.pulp_id.length > PULP_ID_MAX_LENGTH end |
#siblings ⇒ Object
465 466 467 |
# File 'app/models/katello/repository.rb', line 465 def siblings content_view_version.archived_repos.where.not(:id => id) end |
#skip_container_name? ⇒ Boolean
Skip setting container name if the repository is not container type or if it's a library instance of a container-push repo, indicating that the container name is set by the user.
288 289 290 |
# File 'app/models/katello/repository.rb', line 288 def skip_container_name? !self.root.docker? || (self.root.is_container_push && self.library_instance?) end |
#soft_copy_of_library? ⇒ Boolean
326 327 328 329 |
# File 'app/models/katello/repository.rb', line 326 def soft_copy_of_library? return false if self.version_href.nil? self.version_href.starts_with?(self.library_instance.backend_service(SmartProxy.pulp_primary).repository_reference.repository_href) end |
#sync_hook ⇒ Object
854 855 856 857 858 859 |
# File 'app/models/katello/repository.rb', line 854 def sync_hook run_callbacks :sync do logger.debug "custom hook after_sync on #{name} will be executed if defined." true end end |
#sync_status ⇒ Object
1066 1067 1068 |
# File 'app/models/katello/repository.rb', line 1066 def sync_status return latest_dynflow_sync end |
#target_repository ⇒ Object
A link (empty repo) points to a target (a repository that actually has units in pulp). Target repos are always archive repos of a content view version (a repo with no environment) But for composite view versions, an archive repo, usually won't be a primary (but might be if multple components contain the same repo)
891 892 893 894 895 896 897 898 899 900 901 902 903 |
# File 'app/models/katello/repository.rb', line 891 def target_repository fail _("This is not a linked repository") if primary? return nil if self.archived_instance.nil? #this is an environment repo, and the archived_instance is a primary (not always true with composite) if self.environment_id? && self.archived_instance.primary? self.archived_instance elsif self.environment_id #this is an environment repo, but a composite who's archived_instance isn't a primary self.archived_instance.target_repository || self.archived_instance #to archived_instance if nil else #must be a composite archive repo, with only one component repo self.component_source_repositories.first end end |
#to_hash(content_source = nil, force_http = false) ⇒ Object
493 494 495 |
# File 'app/models/katello/repository.rb', line 493 def to_hash(content_source = nil, force_http = false) {id: id, name: label, url: full_path(content_source, force_http)} end |
#to_label ⇒ Object
221 222 223 |
# File 'app/models/katello/repository.rb', line 221 def to_label name end |
#units_for_removal(ids, type_class = nil) ⇒ Object
781 782 783 784 785 786 787 788 789 790 791 |
# File 'app/models/katello/repository.rb', line 781 def units_for_removal(ids, type_class = nil) removable_unit_association = unit_type_for_removal(type_class) table_name = removable_unit_association.table_name is_integer = Integer(ids.first) rescue false #assume all ids are either integers or not if is_integer removable_unit_association.where("#{table_name}.id in (?)", ids) else removable_unit_association.where("#{table_name}.pulp_id in (?)", ids) end end |
#url? ⇒ Boolean
731 732 733 |
# File 'app/models/katello/repository.rb', line 731 def url? root.url.present? end |
#using_mirrored_metadata? ⇒ Boolean
335 336 337 |
# File 'app/models/katello/repository.rb', line 335 def self.yum? && self.library_instance? && self.root.mirroring_policy == Katello::RootRepository::MIRRORING_POLICY_COMPLETE end |
#yum_gpg_key_url ⇒ Object
351 352 353 354 355 356 |
# File 'app/models/katello/repository.rb', line 351 def yum_gpg_key_url # if the repo has a gpg key return a url to access it if self.root.gpg_key.try(:content).present? "../..#{gpg_key_content_api_repository_url(self, :only_path => true)}" end end |