Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #38048 - Add rolling content views #11240

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def show_all
CAST (#{kcc}.composite_content_view_id as BOOLEAN) ASC, #{kc}.name
SQL
query = Katello::ContentView.readable.in_organization(@organization)
query = query&.non_composite&.non_default&.generated_for_none
query = query&.non_composite&.non_default&.non_rolling&.generated_for_none
component_cv_ids = Katello::ContentViewComponent.where(composite_content_view_id: @view.id).select(:content_view_id)
query = case params[:status]
when "Not added"
Expand Down Expand Up @@ -145,23 +145,23 @@ def update
def get_total(status)
case status
when 'All'
return Katello::ContentView.non_default.non_composite.in_organization(@organization).count
return Katello::ContentView.non_default.non_composite.non_rolling.in_organization(@organization).count
when 'Added'
return Katello::ContentViewComponent.where(composite_content_view_id: @view.id).count
when 'Not added'
return Katello::ContentView.non_default.non_composite.in_organization(@organization).count - Katello::ContentViewComponent.where(composite_content_view_id: @view.id).count
return Katello::ContentView.non_default.non_composite.non_rolling.in_organization(@organization).count - Katello::ContentViewComponent.where(composite_content_view_id: @view.id).count
else
return Katello::ContentView.non_default.non_composite.in_organization(@organization).count
return Katello::ContentView.non_default.non_composite.non_rolling.in_organization(@organization).count
end
end

def find_composite_content_view
@view = ContentView.composite.non_default.readable.find_by(id: params[:composite_content_view_id])
@view = ContentView.composite.non_default.non_rolling.readable.find_by(id: params[:composite_content_view_id])
throw_resource_not_found(name: 'composite content view', id: params[:composite_content_view_id]) if @view.nil?
end

def find_composite_content_view_for_edit
@view = ContentView.composite.non_default.editable.find_by(id: params[:composite_content_view_id])
@view = ContentView.composite.non_default.non_rolling.editable.find_by(id: params[:composite_content_view_id])
throw_resource_not_found(name: 'composite content view', id: params[:composite_content_view_id]) if @view.nil?
end

Expand Down
10 changes: 9 additions & 1 deletion app/controllers/katello/api/v2/content_views_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Api::V2::ContentViewsController < Api::V2::ApiController

wrap_parameters :include => (ContentView.attribute_names + %w(repository_ids component_ids))

around_action :add_to_environment, :only => [:create]
resource_description do
api_version "v2"
end
Expand Down Expand Up @@ -84,6 +85,7 @@ def index_relation
param :name, String, :desc => N_("Name of the content view"), :required => true
param :label, String, :desc => N_("Content view label")
param :composite, :bool, :desc => N_("Composite content view")
param :rolling, :bool, :desc => N_("Rolling content view")
param_group :content_view
def create
@content_view = ContentView.create!(view_params) do |view|
Expand Down Expand Up @@ -284,7 +286,7 @@ def ensure_non_generated
def view_params
attrs = [:name, :description, :auto_publish, :solve_dependencies, :import_only,
:default, :created_at, :updated_at, :next_version, {:component_ids => []}]
attrs.push(:label, :composite) if action_name == "create"
attrs.push(:label, :composite, :rolling) if action_name == "create"
if (!@content_view || !@content_view.composite?)
attrs.push({:repository_ids => []}, :repository_ids)
end
Expand All @@ -307,5 +309,11 @@ def add_use_latest_records(module_records, selected_latest_versions)
end
module_records
end

def add_to_environment
yield
return unless params[:rolling]
async_task(::Actions::Katello::ContentView::AddToEnvironment, @content_view.create_new_version, @content_view.organization.library)
end
end
end
28 changes: 28 additions & 0 deletions app/lib/actions/katello/content_view/add_rolling_repo_clone.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Actions
module Katello
module ContentView
class AddRollingRepoClone < Actions::EntryAction
def plan(content_view, repository_ids)
library = content_view.organization.library

concurrence do
::Katello::Repository.where(id: repository_ids).each do |repository|
sequence do
clone = content_view.get_repo_clone(library, repository).first
if clone.nil?
clone = repository.build_clone(content_view: content_view, environment: library)
clone.save!
end
plan_action(RefreshRollingRepo, clone)

view_env_cp_id = content_view.content_view_environment(library).cp_id
content_id = repository.content_id
plan_action(Actions::Candlepin::Environment::AddContentToEnvironment, :view_env_cp_id => view_env_cp_id, :content_id => content_id)
end
end
end
end
end
end
end
end
30 changes: 30 additions & 0 deletions app/lib/actions/katello/content_view/refresh_rolling_repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Actions
module Katello
module ContentView
class RefreshRollingRepo < Actions::EntryAction
def plan(repository)
action_subject repository
sequence do
plan_self(repository_id: repository.id)
plan_action(Pulp3::Repository::RefreshDistribution, repository, SmartProxy.pulp_primary)
plan_action(Repository::IndexContent, id: repository.id, source_repository_id: repository.library_instance.id)
end
end

def run
repository = ::Katello::Repository.find(input[:repository_id])
library_instance = repository.library_instance
# ensure IndexContent is not skipped!
repository.last_contents_changed = DateTime.now if repository.version_href != library_instance.version_href

repository.version_href = library_instance.version_href
repository.publication_href = library_instance.publication_href
if repository.deb_using_structured_apt?
repository.content_id = library_instance.content_id
end
repository.save!
end
end
end
end
end
28 changes: 28 additions & 0 deletions app/lib/actions/katello/content_view/remove_rolling_repo_clone.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Actions
module Katello
module ContentView
class RemoveRollingRepoClone < Actions::EntryAction
def plan(content_view, repository_ids)
library = content_view.organization.library

clone_repo_ids = []
concurrence do
::Katello::Repository.where(id: repository_ids).each do |repository|
clone_repo = content_view.get_repo_clone(library, repository).first
next if clone_repo.nil?

clone_repo_ids << clone_repo.id
plan_action(Actions::Pulp3::Repository::DeleteDistributions, clone_repo.id, SmartProxy.pulp_primary)
end
plan_action(Candlepin::Environment::SetContent, content_view, library, content_view.content_view_environment(library))
end
plan_self(repository_ids: clone_repo_ids)
end

def run
::Katello::Repository.where(id: input[:repository_ids]).destroy_all
end
end
end
end
end
8 changes: 8 additions & 0 deletions app/lib/actions/katello/content_view/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ def plan(content_view, content_view_params)
end
end

if content_view.rolling? && content_view_params.key?(:repository_ids)
repo_ids_to_add = content_view_params[:repository_ids] - content_view.repository_ids
repo_ids_to_remove = content_view.repository_ids - content_view_params[:repository_ids]

plan_action(AddRollingRepoClone, content_view, repo_ids_to_add) if repo_ids_to_add.any?
plan_action(RemoveRollingRepoClone, content_view, repo_ids_to_remove) if repo_ids_to_remove.any?
end

content_view.update!(content_view_params)
end
end
Expand Down
9 changes: 9 additions & 0 deletions app/lib/actions/katello/repository/import_upload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ def plan(repository, uploads, options = {})
plan_action(Katello::Repository::MetadataGenerate, repository, force_publication: true) if generate_metadata
plan_action(Actions::Katello::Applicability::Repository::Regenerate, :repo_ids => [repository.id]) if generate_applicability
plan_self(repository_id: repository.id, sync_capsule: sync_capsule, upload_results: upload_results)

# Refresh rolling CVs that have this repository
repos = repository.root.repositories.in_environment(1).where(content_view_version: ::Katello::ContentViewVersion.where(content_view: ::Katello::ContentView.rolling))

concurrence do
repos.each do |rolling_repo|
plan_action(ContentView::RefreshRollingRepo, rolling_repo)
end
end
end
end
# rubocop:enable Metrics/MethodLength
Expand Down
11 changes: 11 additions & 0 deletions app/lib/actions/katello/repository/sync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def plan(repo, options = {})
end
plan_self(:id => repo.id, :sync_result => output, :skip_metadata_check => skip_metadata_check, :validate_contents => validate_contents,
:contents_changed => output[:contents_changed])
update_rolling_content_views(repo)
plan_action(Katello::Repository::SyncHook, :id => repo.id)
end
end
Expand Down Expand Up @@ -110,6 +111,16 @@ def update_deb_content(repo)
metadata_expire: repo.root.metadata_expire)
end

def update_rolling_content_views(repo)
concurrence do
repos = repo.root.repositories.in_environment(1).where(content_view_version: ::Katello::ContentViewVersion.where(content_view: ::Katello::ContentView.rolling))

repos.each do |rolling_repo|
plan_action(ContentView::RefreshRollingRepo, rolling_repo)
end
end
end

def rescue_strategy
Dynflow::Action::Rescue::Skip
end
Expand Down
14 changes: 12 additions & 2 deletions app/lib/actions/katello/repository/upload_files.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Actions
module Katello
module Repository
class UploadFiles < Actions::EntryAction
def plan(repository, files, content_type = nil, options = {})
def plan(repository, files, content_type = nil, options = {}) # rubocop:disable Metrics/MethodLength
action_subject(repository)
repository.check_ready_to_act!
repository.clear_smart_proxy_sync_histories
Expand Down Expand Up @@ -38,6 +38,15 @@ def plan(repository, files, content_type = nil, options = {})
plan_action(FinishUpload, repository, content_type: content_type, upload_actions: upload_actions)
plan_self(tmp_files: tmp_files)
plan_action(Actions::Katello::Applicability::Repository::Regenerate, :repo_ids => [repository.id]) if generate_applicability

# Refresh rolling CVs that have this repository
repos = repository.root.repositories.in_environment(1).where(content_view_version: ::Katello::ContentViewVersion.where(content_view: ::Katello::ContentView.rolling))

concurrence do
repos.each do |rolling_repo|
plan_action(ContentView::RefreshRollingRepo, rolling_repo)
end
end
end
ensure
# Delete tmp files when some exception occurred. Would be
Expand All @@ -46,7 +55,8 @@ def plan(repository, files, content_type = nil, options = {})
end

def run
ForemanTasks.async_task(Repository::CapsuleSync, ::Katello::Repository.find(input[:repository][:id])) if Setting[:foreman_proxy_content_auto_sync]
repository = ::Katello::Repository.find(input[:repository][:id])
ForemanTasks.async_task(Repository::CapsuleSync, repository) if Setting[:foreman_proxy_content_auto_sync]
rescue ::Katello::Errors::CapsuleCannotBeReached # skip any capsules that cannot be connected to
end

Expand Down
15 changes: 14 additions & 1 deletion app/models/katello/content_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ class ContentView < Katello::Model
validates :composite,
inclusion: { in: [false], message: "Composite Content Views can not solve dependencies" },
if: :solve_dependencies
validates :rolling, :inclusion => [true, false]
validates :rolling,
inclusion: { in: [false], message: "Rolling content views can not solve dependencies" },
if: :solve_dependencies
validates :rolling,
inclusion: { in: [false], message: "Rolling content views can not be composite" },
if: :composite
validates :rolling,
inclusion: { in: [false], message: "Rolling content views can not be import only" },
if: :import_only
validates :import_only, :inclusion => [true, false]
validates :import_only,
inclusion: { in: [false], message: "Import-only Content Views can not be Composite" },
Expand All @@ -93,6 +103,8 @@ class ContentView < Katello::Model
scope :non_default, -> { where(:default => false) }
scope :composite, -> { where(:composite => true) }
scope :non_composite, -> { where(:composite => [nil, false]) }
scope :rolling, -> { where(:rolling => true) }
scope :non_rolling, -> { where(:rolling => [nil, false]) }
scope :generated, -> { where.not(:generated_for => :none) }
scope :generated_for_repository, -> {
where(:generated_for => [:repository_export,
Expand All @@ -113,6 +125,7 @@ class ContentView < Katello::Model
scoped_search :on => :organization_id, :complete_value => true, :only_explicit => true, :validator => ScopedSearch::Validators::INTEGER
scoped_search :on => :label, :complete_value => true
scoped_search :on => :composite, :complete_value => true
scoped_search :on => :rolling, :complete_value => true
scoped_search :on => :generated_for, :complete_value => true
scoped_search :on => :default # just for ordering
scoped_search :on => :name, :complete_value => true,
Expand Down Expand Up @@ -802,7 +815,7 @@ def cv_repo_indexed_after_last_published?
end

def unpublishable?
default? || import_only? || generated?
default? || import_only? || generated? || rolling?
end

def needs_publish?
Expand Down
4 changes: 4 additions & 0 deletions app/models/katello/content_view_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def ensure_valid_content_view
errors.add(:base, _("Cannot add default content view to composite content view"))
end

if view.rolling?
errors.add(:base, _("Cannot add rolling content view to composite content view"))
end

if attached_content_view_ids.include?(view.id)
errors.add(:base, _("Another component already includes content view with ID %s" % view.id))
end
Expand Down
3 changes: 2 additions & 1 deletion app/models/katello/content_view_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ContentViewVersion < Katello::Model
:class_name => "Katello::ContentViewVersion", :inverse_of => :components
has_many :published_in_composite_content_views, through: :composites, source: :content_view
delegate :default, :default?, to: :content_view
delegate :rolling, :rolling?, to: :content_view

validates_lengths_from_database

Expand Down Expand Up @@ -383,7 +384,7 @@ def content_counts_map
end

def check_ready_to_promote!(to_env)
fail _("Default content view versions cannot be promoted") if default?
fail _("Default and Rolling content view versions cannot be promoted") if default? || rolling?
content_view.check_composite_action_allowed!(to_env)
content_view.check_docker_repository_names!(to_env)
content_view.check_orphaned_content_facets!(environments: [to_env])
Expand Down
2 changes: 2 additions & 0 deletions app/models/katello/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,8 @@ def environmental_instances(view)
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
Expand Down
1 change: 1 addition & 0 deletions app/views/katello/api/v2/content_views/base.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ extends 'katello/api/v2/common/identifier'
extends 'katello/api/v2/common/org_reference'

attributes :composite
attributes :rolling
attributes :component_ids, :duplicate_repositories_to_publish
attributes :default
attributes :version_count
Expand Down
2 changes: 2 additions & 0 deletions app/views/katello/api/v2/organizations/show.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ node :default_content_view_id do |org|
end

node(:composite_content_views_count) { Katello::ContentView.readable&.in_organization(Organization.current)&.composite&.count }
node(:rolling_content_views_count) { Katello::ContentView.readable&.in_organization(Organization.current)&.rolling&.count }
node(:content_view_components_count) do
Katello::ContentView.readable&.
in_organization(Organization.current)&.
non_composite&.
non_rolling&.
non_default&.
ignore_generated&.count
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddRollingToKatelloContentViews < ActiveRecord::Migration[6.1]
def change
add_column :katello_content_views, :rolling, :boolean, :default => false
end
end
Loading
Loading