foreman_content 0.3 → 0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/app/assets/javascripts/content/content.js +23 -12
- data/app/assets/javascripts/content/repository.js +19 -0
- data/app/controllers/content/content_views_controller.rb +19 -6
- data/app/controllers/content/products_controller.rb +1 -1
- data/app/controllers/content/repositories_controller.rb +9 -3
- data/app/helpers/content/content_views_helper.rb +24 -4
- data/app/helpers/content/repositories_helper.rb +28 -0
- data/app/models/concerns/content/host_extensions.rb +1 -1
- data/app/models/concerns/content/operatingsystem_extensions.rb +1 -1
- data/app/models/concerns/content/orchestration/pulp.rb +1 -1
- data/app/models/concerns/content/orchestration/pulp/sync.rb +37 -2
- data/app/models/concerns/content/redhat_extensions.rb +19 -3
- data/app/models/concerns/content/repository_common.rb +13 -0
- data/app/models/content/content_view.rb +21 -15
- data/app/models/content/content_view_repository_clone.rb +2 -2
- data/app/models/content/product.rb +1 -1
- data/app/models/content/repository.rb +24 -8
- data/app/models/content/repository/operating_system.rb +11 -2
- data/app/models/content/repository/product.rb +8 -3
- data/app/models/content/repository_clone.rb +5 -10
- data/app/services/content/content_view_factory.rb +46 -25
- data/app/services/content/pulp/repository.rb +13 -0
- data/app/services/content/pulp/repository_sync_history.rb +8 -2
- data/app/views/content/content_views/{_step2.html.erb → _composite.html.erb} +1 -1
- data/app/views/content/content_views/_form.html.erb +17 -14
- data/app/views/content/content_views/index.html.erb +4 -3
- data/app/views/content/content_views/new.html.erb +1 -7
- data/app/views/content/content_views/show.erb +22 -0
- data/app/views/content/products/_form.html.erb +3 -9
- data/app/views/content/repositories/_fields.html.erb +9 -0
- data/app/views/content/repositories/_os_form.html.erb +6 -11
- data/app/views/content/repositories/_product_form.html.erb +7 -11
- data/app/views/content/repositories/_repository.html.erb +4 -0
- data/app/views/content/repositories/_sync_schedule.erb +10 -0
- data/app/views/content/repositories/edit.html.erb +2 -0
- data/app/views/content/repositories/index.html.erb +14 -16
- data/app/views/content/repositories/new.html.erb +2 -0
- data/app/views/content/repositories/show.html.erb +51 -37
- data/db/migrate/20130807121629_create_content_content_views.rb +1 -1
- data/db/migrate/20130828173006_change_content_view_index_name.rb +10 -0
- data/db/migrate/20130901070945_add_publish_boolean_to_content_repository.rb +6 -0
- data/db/migrate/20130902130445_change_repository_to_polymorphic.rb +42 -0
- data/db/migrate/20130902142326_add_polymorphic_repo_to_content_view_repository_clone.rb +8 -0
- data/lib/content/version.rb +1 -1
- metadata +14 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 316501d63ca9034ac6248b472b539ebd12313e41
|
4
|
+
data.tar.gz: 4771b0bdb3ec5e080a321e0e69ed28a5e13ae747
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac73329310ab942e6858b833bf4f9e112951b36f78a9bc5065506166dc3bbf79af922364939801e411ccc536775fb0edbe011e7c20cd88be4d622e100bf43d42
|
7
|
+
data.tar.gz: b49837ce5b77ed3443b7d93a56a2ab0fb140eddef907905cce0c7f75529ab89470cf6f86f76cbd293443d8c6fc9955c881a45a10d84b1d36d0a939fd241aa78b
|
data/README.md
CHANGED
@@ -29,6 +29,7 @@ touch tmp/restart.txt (if using passeger)
|
|
29
29
|
|
30
30
|
## Pulp
|
31
31
|
* enable oauth authentication
|
32
|
+
* make sure you have enough disk space! lots of GB to /var/lib/pulp and /var/lib/mongo
|
32
33
|
|
33
34
|
## UI config
|
34
35
|
|
@@ -50,6 +51,11 @@ You would see in the UI under More, a new sub menu called content, in it:
|
|
50
51
|
* Product - The actual product you are managing, for example CentOS 6
|
51
52
|
* Repository - list of repositories that belong to the above product, for
|
52
53
|
example, CentOS 6.4 + CentOS updates.
|
54
|
+
* Content View - a collection of cloned repositories
|
55
|
+
|
56
|
+
## Create a Product
|
57
|
+
|
58
|
+
If you are planning to sync non OS packages (e.g. 3rd party yum repo), you should first create a product, e.g. Foreman 1.2-stable, afterwards, you can add repositories to it.
|
53
59
|
|
54
60
|
## Syncing Repositories
|
55
61
|
|
@@ -63,8 +69,6 @@ of an Installation media.
|
|
63
69
|
* Architecture - type of files within the repo, usually X86_64 or noarch etc.
|
64
70
|
* Operating Systems - list of valid OS's that this repo applies to.
|
65
71
|
* Enabled - true / false
|
66
|
-
* Unprotected - weather pulp should expose this repo via http and https or just
|
67
|
-
over https.
|
68
72
|
* Product - the product from above.
|
69
73
|
* GPG key - not implemented
|
70
74
|
|
@@ -1,12 +1,23 @@
|
|
1
|
-
|
2
|
-
//
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
//
|
11
|
-
|
12
|
-
|
1
|
+
$(function () {
|
2
|
+
// Disable repository selection input based on checkbox
|
3
|
+
$('.repository_selection input:checkbox').click(function () {
|
4
|
+
var checked = $(this).is(':checked');
|
5
|
+
$(this).parent().find($(':input')).each (function ( index, input) {
|
6
|
+
$(input).attr('disabled', !checked);
|
7
|
+
});
|
8
|
+
|
9
|
+
});
|
10
|
+
// toggle repository ID's to send based on the repo type
|
11
|
+
$('.cv-repo-selection').change(function () {
|
12
|
+
enable_selected_repository(this);
|
13
|
+
});
|
14
|
+
$('.cv-repo-selection').change();
|
15
|
+
});
|
16
|
+
|
17
|
+
function enable_selected_repository(element) {
|
18
|
+
var select = $(element);
|
19
|
+
var id = select.attr('id').replace(/[^\d]/g, '');
|
20
|
+
var clone = select.val() == 'clone';
|
21
|
+
$('#clone-' + id).attr('disabled', !clone);
|
22
|
+
$('#latest-' + id).attr('disabled', clone);
|
23
|
+
};
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$(function () {
|
2
|
+
// Disable repository sync input based on checkbox
|
3
|
+
$('#content_repository_schedule').click(function () {
|
4
|
+
$('#sync_schedule_form select').attr('disabled', !$(this).is(':checked'));
|
5
|
+
});
|
6
|
+
// try to guess architecture based on the URL
|
7
|
+
$('#content_repository_feed').focusout(function() {
|
8
|
+
url = $(this).val();
|
9
|
+
if (url == undefined || url == '')
|
10
|
+
return;
|
11
|
+
|
12
|
+
$('#content_repository_architecture_id option').each (function ( index, option) {
|
13
|
+
if (url.match(option.text)) {
|
14
|
+
$('#content_repository_architecture_id').val(option.value);
|
15
|
+
return false;
|
16
|
+
}
|
17
|
+
})
|
18
|
+
});
|
19
|
+
});
|
@@ -5,16 +5,29 @@ module Content
|
|
5
5
|
|
6
6
|
def index
|
7
7
|
@content_views = ContentView.search_for(params[:search], :order => params[:order]).
|
8
|
-
|
9
|
-
@counter
|
8
|
+
paginate(:page => params[:page])
|
9
|
+
@counter = ContentViewRepositoryClone.where(:content_view_id => @content_views.map(&:id)).group(:content_view_id).count
|
10
10
|
|
11
11
|
end
|
12
12
|
|
13
|
+
def show
|
14
|
+
end
|
15
|
+
|
13
16
|
def new
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
options = if params[:product]
|
18
|
+
{:originator_id => params[:product], :originator_type => 'Content::Product'}
|
19
|
+
elsif params[:operatingsystem]
|
20
|
+
{:originator_id => params[:operatingsystem], :originator_type => 'Operatingsystem'}
|
21
|
+
elsif params[:hostgroup]
|
22
|
+
@hostgroup = Hostgroup.find_by_id(params[:hostgroup])
|
23
|
+
{:originator_id => params[:hostgroup], :originator_type => 'Hostgroup'}
|
24
|
+
elsif params[:content_content_view_factory]
|
25
|
+
params[:content_content_view_factory]
|
26
|
+
elsif params[:type].blank?
|
27
|
+
process_error(:error_msg => _('Must provide a type'))
|
28
|
+
end
|
29
|
+
@factory = ContentViewFactory.new(options || {})
|
30
|
+
@content_view = @factory.try(:content_view) if @factory.originator_id
|
18
31
|
end
|
19
32
|
|
20
33
|
def create
|
@@ -6,7 +6,7 @@ module Content
|
|
6
6
|
def index
|
7
7
|
@products = Product.search_for(params[:search], :order => params[:order]).
|
8
8
|
paginate(:page => params[:page])
|
9
|
-
@counter = Repository::Product.group(:
|
9
|
+
@counter = Repository::Product.group(:originator_id).where(:originator_id => @products.map(&:id)).count
|
10
10
|
end
|
11
11
|
|
12
12
|
def new
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Content
|
2
2
|
class RepositoriesController < ::ApplicationController
|
3
3
|
include Foreman::Controller::AutoCompleteSearch
|
4
|
-
before_filter :
|
4
|
+
before_filter :find_repo, :only => %w{show edit update destroy sync}
|
5
5
|
|
6
6
|
def index
|
7
7
|
@repositories = Repository.search_for(params[:search], :order => params[:order]).
|
8
|
-
paginate(:page => params[:page])
|
8
|
+
paginate(:page => params[:page])
|
9
9
|
end
|
10
10
|
|
11
11
|
def new
|
@@ -13,7 +13,7 @@ module Content
|
|
13
13
|
when "operatingsystem"
|
14
14
|
Repository::OperatingSystem.new(:unprotected => true)
|
15
15
|
when "product"
|
16
|
-
Repository::Product.new(:
|
16
|
+
Repository::Product.new(:originator_id => params[:product_id])
|
17
17
|
else
|
18
18
|
not_found
|
19
19
|
end
|
@@ -56,5 +56,11 @@ module Content
|
|
56
56
|
rescue => e
|
57
57
|
process_error(:error_msg => _("Failed to start sync for %s") % @repository.to_label)
|
58
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def find_repo
|
63
|
+
@repository = Content::Repository.find(params[:id])
|
64
|
+
end
|
59
65
|
end
|
60
66
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module Content
|
2
2
|
module ContentViewsHelper
|
3
3
|
|
4
|
-
def repositories
|
5
|
-
|
6
|
-
|
4
|
+
def repositories
|
5
|
+
cv_repos = @content_view.repository_clones + @content_view.repository_sources
|
6
|
+
|
7
|
+
if @content_view.new_record? && cv_repos.empty? # new form
|
8
|
+
@factory.repositories
|
7
9
|
else
|
8
|
-
|
10
|
+
cv_repos # edit or new after validation failure
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
@@ -17,5 +19,23 @@ module Content
|
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
22
|
+
def step?
|
23
|
+
if params[:type]
|
24
|
+
'step1'
|
25
|
+
elsif @hostgroup
|
26
|
+
'composite'
|
27
|
+
else
|
28
|
+
'form'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def options_for_type_selection repo
|
33
|
+
options = [[_('Clone (snapshot)'), 'clone']]
|
34
|
+
options << [_('Latest'),'latest'] if repo.kind_of?(Content::Repository) && repo.publish?
|
35
|
+
selected = 'clone' if @factory # default
|
36
|
+
selected ||= @content_view.repository_clone_ids.include?(repo.id) ? 'clone' : 'latest' # on validation error
|
37
|
+
options_for_select(options, selected)
|
38
|
+
end
|
39
|
+
|
20
40
|
end
|
21
41
|
end
|
@@ -6,5 +6,33 @@ module Content
|
|
6
6
|
time_ago_in_words(time) + ' ago'
|
7
7
|
end
|
8
8
|
|
9
|
+
def sync_schedule schedules
|
10
|
+
return _('None') if schedules.empty?
|
11
|
+
schedules.map{|s| s[:schedule]}.join(', ')
|
12
|
+
rescue => e
|
13
|
+
logger.warn _("Failed to fetch sync schedule: ") + e.to_s
|
14
|
+
_('unknown')
|
15
|
+
end
|
16
|
+
|
17
|
+
def time_selector f
|
18
|
+
html_options = { :class => 'span1', :disabled => f.object.schedule.blank? }
|
19
|
+
f.select(:hour, options_for_time(0..23), {}, html_options) +
|
20
|
+
f.select(:minute, options_for_time(0..59), {}, html_options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def sync_schedule_selector f
|
24
|
+
content_tag :div, :id => 'sync_schedule_form', :class => 'input-prepend input-append' do
|
25
|
+
f.select(:interval, [%w(Daily D), %w(Weekly W)], {}, { :disabled => f.object.schedule.blank? , :class => 'span1' }) +
|
26
|
+
content_tag(:span, :class => 'add-on') { '@' } +
|
27
|
+
time_selector(f)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def options_for_time(options)
|
34
|
+
options.map { |i| [sprintf("%02d", i), i] }
|
35
|
+
end
|
36
|
+
|
9
37
|
end
|
10
38
|
end
|
@@ -38,7 +38,7 @@ module Content::HostExtensions
|
|
38
38
|
|
39
39
|
Content::ContentView.joins(:available_content_views).
|
40
40
|
where(:content_available_content_views => {:environment_id => environment_id}).
|
41
|
-
where(:originator_type => 'Hostgroup', :originator_id => hostgroup_id).pluck(
|
41
|
+
where(:originator_type => 'Hostgroup', :originator_id => hostgroup_id).pluck('content_content_views.id')
|
42
42
|
end
|
43
43
|
|
44
44
|
def all_content_view_ids
|
@@ -2,7 +2,7 @@ module Content::OperatingsystemExtensions
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
included do
|
5
|
-
has_many :repositories, :class_name => 'Content::Repository'
|
5
|
+
has_many :repositories, :class_name => 'Content::Repository', :as => :originator
|
6
6
|
|
7
7
|
has_many :available_content_views, :dependent => :destroy, :class_name => 'Content::AvailableContentView'
|
8
8
|
has_many :content_views, :as => :originator, :class_name => 'Content::ContentView'
|
@@ -3,7 +3,7 @@ module Content::Orchestration::Pulp
|
|
3
3
|
include ::Orchestration
|
4
4
|
|
5
5
|
included do
|
6
|
-
delegate :sync_status, :sync, :counters, :sync_history, :state, :to => :repo
|
6
|
+
delegate :sync_status, :sync, :sync_schedule, :counters, :sync_history, :state, :to => :repo
|
7
7
|
end
|
8
8
|
|
9
9
|
def orchestration_errors?
|
@@ -5,6 +5,9 @@ module Content::Orchestration::Pulp::Sync
|
|
5
5
|
included do
|
6
6
|
after_validation :queue_pulp
|
7
7
|
before_destroy :queue_pulp_destroy unless Rails.env.test?
|
8
|
+
attr_accessor :interval, :hour, :minute, :schedule
|
9
|
+
validates :interval, :inclusion => { :in => %w(D W) }, :if => :schedule_sync?
|
10
|
+
validates :hour, :minute, :numericality => true, :if => :schedule_sync?
|
8
11
|
end
|
9
12
|
|
10
13
|
def last_sync
|
@@ -22,8 +25,14 @@ module Content::Orchestration::Pulp::Sync
|
|
22
25
|
logger.debug "Scheduling new Pulp Repository"
|
23
26
|
queue.create(:name => _("Create Pulp Repository for %s") % self, :priority => 10,
|
24
27
|
:action => [self, :set_pulp_repo])
|
28
|
+
logger.debug "Scheduling new Pulp Repository Sync"
|
25
29
|
queue.create(:name => _("Sync Pulp Repository %s") % self, :priority => 20,
|
26
30
|
:action => [self, :set_sync_pulp_repo])
|
31
|
+
if schedule_sync?
|
32
|
+
logger.debug "Scheduling Pulp Repository sync scheduler"
|
33
|
+
queue.create(:name => _("Sync Schedule Pulp Repository %s") % self, :priority => 30,
|
34
|
+
:action => [self, :set_sync_schedule_pulp_repo])
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
def queue_pulp_update
|
@@ -38,7 +47,7 @@ module Content::Orchestration::Pulp::Sync
|
|
38
47
|
end
|
39
48
|
|
40
49
|
def set_pulp_repo
|
41
|
-
repo.create
|
50
|
+
publish ? repo.create_with_distributor : repo.create
|
42
51
|
end
|
43
52
|
|
44
53
|
def del_pulp_repo
|
@@ -53,6 +62,14 @@ module Content::Orchestration::Pulp::Sync
|
|
53
62
|
repo.cancel_running_sync!
|
54
63
|
end
|
55
64
|
|
65
|
+
def set_sync_schedule_pulp_repo
|
66
|
+
repo.sync_schedule = sync_schedule_time
|
67
|
+
end
|
68
|
+
|
69
|
+
def del_sync_schedule_pulp_repo
|
70
|
+
repo.sync_schedule = nil
|
71
|
+
end
|
72
|
+
|
56
73
|
def repo_options
|
57
74
|
{
|
58
75
|
:pulp_id => pulp_repo_id,
|
@@ -61,10 +78,28 @@ module Content::Orchestration::Pulp::Sync
|
|
61
78
|
:feed => feed,
|
62
79
|
:content_type => content_type,
|
63
80
|
:protected => unprotected,
|
81
|
+
:relative_path => relative_path,
|
82
|
+
:auto_publish => publish
|
64
83
|
}
|
65
84
|
end
|
66
85
|
|
67
86
|
def repo
|
68
87
|
@repo ||= Content::Pulp::Repository.new(repo_options)
|
69
88
|
end
|
70
|
-
|
89
|
+
|
90
|
+
def relative_path
|
91
|
+
"#{entity_name}/#{name}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def schedule_sync?
|
95
|
+
schedule.present? && schedule != '0'
|
96
|
+
end
|
97
|
+
|
98
|
+
def sync_schedule_time
|
99
|
+
return if schedule.blank?
|
100
|
+
time = Time.parse("00:#{hour}:#{minute}").iso8601
|
101
|
+
repetition = "R1" # no limit of hour many syncs
|
102
|
+
"#{repetition}/#{time}/P1#{interval}"
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -6,7 +6,7 @@ module Content::RedhatExtensions
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def medium_uri_with_content_uri host, url = nil
|
9
|
-
if url.nil? && (full_path =
|
9
|
+
if url.nil? && (full_path = kickstart_repo(host).try(:full_path))
|
10
10
|
URI.parse(full_path)
|
11
11
|
else
|
12
12
|
medium_uri_without_content_uri(host, url)
|
@@ -16,7 +16,14 @@ module Content::RedhatExtensions
|
|
16
16
|
# return an array of repositories for kickstart script as additional repos
|
17
17
|
# to the kickstart main repo, this list will typically include updates and epel
|
18
18
|
def repos host
|
19
|
-
host.
|
19
|
+
yum_repos(host).map { |repo| format_repo(repo) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def boot_files_uri(medium, architecture)
|
23
|
+
Redhat::PXEFILES.values.collect do |img|
|
24
|
+
medium_vars_to_uri("#{medium.path}/#{pxedir}/#{img}", architecture.name, self)
|
25
|
+
URI.parse(interpolate_medium_vars(url, arch, os)).normalize
|
26
|
+
end
|
20
27
|
end
|
21
28
|
|
22
29
|
private
|
@@ -25,9 +32,18 @@ module Content::RedhatExtensions
|
|
25
32
|
{
|
26
33
|
:baseurl => repo.full_path,
|
27
34
|
:name => repo.to_label,
|
28
|
-
:description => repo.
|
35
|
+
:description => repo.description,
|
29
36
|
:enabled => repo.enabled,
|
30
37
|
:gpgcheck => !!repo.gpg_key
|
31
38
|
}
|
32
39
|
end
|
40
|
+
|
41
|
+
def kickstart_repo host
|
42
|
+
host.attached_repositories.detect{|r| r.content_type == Content::Repository::KICKSTART_TYPE}
|
43
|
+
end
|
44
|
+
|
45
|
+
def yum_repos host
|
46
|
+
host.attached_repositories.select{|r| r.content_type == Content::Repository::YUM_TYPE}
|
47
|
+
end
|
48
|
+
|
33
49
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Content::RepositoryCommon
|
2
|
+
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
REPO_PREFIX = '/pulp/repos/'
|
6
|
+
|
7
|
+
def full_path
|
8
|
+
pulp_url = URI.parse(Setting.pulp_url)
|
9
|
+
scheme = (unprotected ? 'http' : 'https')
|
10
|
+
port = (pulp_url.port == 443 || pulp_url.port == 80 ? "" : ":#{pulp_url.port}")
|
11
|
+
"#{scheme}://#{pulp_url.host}#{port}#{REPO_PREFIX}#{relative_path}"
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Content
|
2
2
|
class ContentView < ActiveRecord::Base
|
3
3
|
has_ancestry :orphan_strategy => :rootify
|
4
|
+
attr_accessor :repository_ids_to_clone
|
4
5
|
|
5
6
|
belongs_to :originator, :polymorphic => true
|
6
7
|
has_many :available_content_views, :dependent => :destroy
|
@@ -10,18 +11,23 @@ module Content
|
|
10
11
|
has_many :content_view_hosts, :dependent => :destroy, :uniq => true, :foreign_key => :content_view_id, :class_name => 'Content::ContentViewHost'
|
11
12
|
has_many :hosts, :through => :content_view_hosts
|
12
13
|
|
14
|
+
before_destroy :clean_unused_clone_repos
|
13
15
|
has_many :content_view_repository_clones, :dependent => :destroy
|
14
|
-
|
15
|
-
has_many :
|
16
|
+
|
17
|
+
has_many :repository_clones, :through => :content_view_repository_clones,
|
18
|
+
:source => :repository, :source_type => 'Content::RepositoryClone'
|
19
|
+
|
20
|
+
has_many :repository_sources, :through => :content_view_repository_clones,
|
21
|
+
:source => :repository, :source_type => 'Content::Repository'
|
16
22
|
|
17
23
|
scope :hostgroups, where(:originator_type => 'Hostgroup')
|
18
24
|
scope :products, where(:originator_type => 'Content::Product')
|
19
25
|
scope :operatingsystem, where(:originator_type => 'Operatingsystem')
|
20
26
|
|
21
|
-
|
22
|
-
before_destroy :clean_unused_clone_repos
|
27
|
+
after_create :clone_repos
|
23
28
|
|
24
29
|
validates_presence_of :name
|
30
|
+
validates_uniqueness_of :name, :scope => [:originator_id, :originator_type]
|
25
31
|
|
26
32
|
# special relationships needed for search with polymorphic associations
|
27
33
|
belongs_to :search_hostgroups, :class_name => 'Hostgroup', :foreign_key => :originator_id,
|
@@ -38,28 +44,28 @@ module Content
|
|
38
44
|
scoped_search :in => :search_hostgroups, :on => :label, :complete_value => true,
|
39
45
|
:rename => :hostgroup, :only_explicit => true
|
40
46
|
|
41
|
-
attr_accessor :source_repositories
|
42
|
-
|
43
47
|
def to_label
|
44
48
|
name || "#{originator.to_label} - #{DateTime.now.strftime("%m/%d/%Y")}".parameterize
|
45
49
|
end
|
46
50
|
|
51
|
+
private
|
52
|
+
|
47
53
|
def clone_repos
|
48
|
-
return unless
|
49
|
-
Repository.where(:id =>
|
50
|
-
repository.
|
54
|
+
return unless repository_ids_to_clone
|
55
|
+
Repository.where(:id => repository_ids_to_clone).each do |repository|
|
56
|
+
repository.clone self
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
54
|
-
private
|
55
|
-
|
56
60
|
def clean_unused_clone_repos
|
57
|
-
current_repos = Content::ContentViewRepositoryClone.where(:content_view_id => id).pluck(:
|
58
|
-
used_repos
|
59
|
-
where(:
|
60
|
-
where(['content_view_id IS NOT ?', id]).pluck(:
|
61
|
+
current_repos = Content::ContentViewRepositoryClone.where(:content_view_id => id, :repository_type => 'Content::RepositoryClone').pluck(:repository_id)
|
62
|
+
used_repos = Content::ContentViewRepositoryClone.
|
63
|
+
where(:repository_id => current_repos).
|
64
|
+
where(['content_view_id IS NOT ?', id]).pluck(:repository_id)
|
61
65
|
|
62
66
|
repos_to_delete = current_repos - used_repos
|
67
|
+
logger.debug('All Cloned repositories are used elsewhere, nothing to do') if repos_to_delete.empty?
|
68
|
+
logger.debug("Clone Repos IDS: #{repos_to_delete.join(', ')} are unused - deleting...") if repos_to_delete.any?
|
63
69
|
Content::RepositoryClone.destroy(repos_to_delete) if repos_to_delete.any?
|
64
70
|
end
|
65
71
|
end
|