foreman_content 0.2 → 0.3
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 +40 -1
- data/app/controllers/content/api/repositories_controller.rb +3 -5
- data/app/controllers/content/content_views_controller.rb +48 -0
- data/app/controllers/content/products_controller.rb +1 -1
- data/app/controllers/content/repositories_controller.rb +9 -6
- data/app/helpers/content/content_views_helper.rb +21 -0
- data/app/helpers/content/products_helper.rb +9 -0
- data/app/helpers/content/repositories_helper.rb +3 -49
- data/app/models/concerns/content/environment_extensions.rb +2 -2
- data/app/models/concerns/content/home_helper.rb +1 -0
- data/app/models/concerns/content/host_extensions.rb +17 -1
- data/app/models/concerns/content/hostgroup_extensions.rb +14 -0
- data/app/models/concerns/content/operatingsystem_extensions.rb +6 -5
- data/app/models/concerns/content/orchestration/pulp/clone.rb +77 -0
- data/app/models/concerns/content/orchestration/pulp/sync.rb +70 -0
- data/app/models/concerns/content/orchestration/pulp.rb +25 -0
- data/app/models/content/available_content_view.rb +12 -0
- data/app/models/content/content_view.rb +66 -0
- data/app/models/content/content_view_host.rb +9 -0
- data/app/models/content/content_view_repository_clone.rb +5 -0
- data/app/models/content/host_product.rb +0 -11
- data/app/models/content/hostgroup_product.rb +0 -11
- data/app/models/content/operatingsystem_repository.rb +0 -11
- data/app/models/content/product.rb +6 -5
- data/app/models/content/repository/operating_system.rb +14 -0
- data/app/models/content/repository/product.rb +21 -0
- data/app/models/content/repository.rb +28 -39
- data/app/models/content/repository_clone.rb +29 -0
- data/app/models/content/validators/content_validator.rb +0 -12
- data/app/models/content/validators/description_format.rb +0 -12
- data/app/models/content/validators/no_trailing_space.rb +0 -12
- data/app/models/setting/content.rb +0 -18
- data/app/overrides/{add_host_conent_tab.rb → add_host_content_tab.rb} +2 -2
- data/app/overrides/{add_hostgroup_conent_tab.rb → add_hostgroup_content_tab.rb} +1 -1
- data/app/services/content/content_view_factory.rb +41 -0
- data/app/services/content/{pulp_configuration.rb → pulp/configuration.rb} +1 -1
- data/app/services/content/pulp/event_handler.rb +61 -0
- data/app/services/content/pulp/repository.rb +200 -0
- data/app/services/content/pulp/repository_clone.rb +24 -0
- data/app/services/content/pulp/repository_sync_history.rb +35 -0
- data/app/services/content/pulp/repository_sync_status.rb +30 -0
- data/app/views/content/content_views/_form.html.erb +49 -0
- data/app/views/content/content_views/_form_tab.html.erb +3 -0
- data/app/views/content/content_views/_host_tab_pane.html.erb +5 -0
- data/app/views/content/content_views/_step1.html.erb +18 -0
- data/app/views/content/content_views/_step2.html.erb +16 -0
- data/app/views/content/content_views/edit.html.erb +5 -0
- data/app/views/content/content_views/index.html.erb +27 -0
- data/app/views/content/content_views/new.html.erb +11 -0
- data/app/views/content/products/_form.html.erb +2 -13
- data/app/views/content/products/_form_tab.html.erb +3 -3
- data/app/views/content/products/_hostgroup_tab_pane.html.erb +2 -2
- data/app/views/content/products/index.html.erb +6 -1
- data/app/views/content/repositories/_os_form.html.erb +22 -0
- data/app/views/content/repositories/{_form.html.erb → _product_form.html.erb} +4 -6
- data/app/views/content/repositories/edit.html.erb +5 -2
- data/app/views/content/repositories/index.html.erb +12 -9
- data/app/views/content/repositories/new.html.erb +5 -2
- data/app/views/content/repositories/show.html.erb +9 -16
- data/config/environment.rb +0 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20130702140034_create_content_repositories.rb +6 -2
- data/db/migrate/20130722084911_create_content_operatingsystem_repositories.rb +1 -1
- data/db/migrate/20130807121629_create_content_content_views.rb +15 -0
- data/db/migrate/20130807123220_create_content_available_content_views.rb +11 -0
- data/db/migrate/20130812154754_create_content_content_view_hosts.rb +9 -0
- data/db/migrate/20130813110455_create_content_repository_clones.rb +17 -0
- data/db/migrate/20130825145431_create_content_content_view_repository_clones.rb +12 -0
- data/lib/content/engine.rb +2 -0
- data/lib/content/version.rb +1 -1
- data/test/fixtures/content/repository_clones.yml +21 -0
- data/test/unit/content/repository_clone_test.rb +7 -0
- metadata +44 -17
- data/app/models/concerns/content/custom_repository_paths.rb +0 -29
- data/app/models/content/environment_product.rb +0 -19
- data/app/models/content/orchestration/pulp.rb +0 -93
- data/app/models/content/product_operatingsystem.rb +0 -19
- data/app/models/content/remote/pulp/repository.rb +0 -48
- data/app/overrides/add_os_conent_tab.rb +0 -9
- data/app/services/content/pulp_event_handler.rb +0 -25
- data/app/views/content/products/_host_tab_pane.html.erb +0 -5
- data/app/views/content/products/_operatingsystem_tab_pane.html.erb +0 -5
- data/db/migrate/20130717032320_create_content_environments_products.rb +0 -9
- data/db/migrate/20130729032320_create_content_product_operatingsystems.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 81d2b11da956bb0d25160db53a69e130cd4d6d93
|
|
4
|
+
data.tar.gz: b7ea75653438011efd63b158822f68f6769f6965
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 651ee332a371f5aab119b72c3d684372e028815fc91ed6fc407e39eda537a525771ec8b84e82b8ffd49ac8d3eb67d256b44d9070f8c80f5b8d1e3c988c8ee4a6
|
|
7
|
+
data.tar.gz: dce982b68ab1038d275a3ded98acca1763611805999aecff410a8f9312a6f4879802520ab99e44c8c565600791374cfc02583e2f55bb32fa42eab79adee01f3c
|
data/README.md
CHANGED
|
@@ -68,7 +68,28 @@ of an Installation media.
|
|
|
68
68
|
* Product - the product from above.
|
|
69
69
|
* GPG key - not implemented
|
|
70
70
|
|
|
71
|
-
Once created, the repo would automatically be synced
|
|
71
|
+
Once created, the repo would automatically be synced but not yet visible for
|
|
72
|
+
end users, for that you would need to create a Content View.
|
|
73
|
+
|
|
74
|
+
## Creating Content Views
|
|
75
|
+
|
|
76
|
+
Content Views, are a collection of immutibal repositories, these repositories
|
|
77
|
+
are cloned from the synced repository and allow you to have multiple
|
|
78
|
+
repositories definitions per Operation Systems, Custom yum repos, and
|
|
79
|
+
Hostgroups.
|
|
80
|
+
|
|
81
|
+
You would first need to create a content view per Product / Operation system.
|
|
82
|
+
|
|
83
|
+
## Configuring Hostgroups (and hosts) to consume content views
|
|
84
|
+
|
|
85
|
+
In your hostgroup definiton, you can select the operation system and the custom
|
|
86
|
+
products you are interested in.
|
|
87
|
+
|
|
88
|
+
next under the content view, you can create a new hostgroup content view, and
|
|
89
|
+
select the releavnt content view you would like to consume within your hostgroup.
|
|
90
|
+
|
|
91
|
+
You could also define the puppet environment(s) in which the content view is
|
|
92
|
+
used.
|
|
72
93
|
|
|
73
94
|
## Consuming Repos within your Kickstart
|
|
74
95
|
|
|
@@ -111,3 +132,21 @@ pulp-admin event listener http create --event-type '*' --url https://foreman.exa
|
|
|
111
132
|
|
|
112
133
|
* https://trello.com/b/NtzVcPkD/foreman-backlog
|
|
113
134
|
filter engine spike
|
|
135
|
+
|
|
136
|
+
# License
|
|
137
|
+
|
|
138
|
+
foreman_content plugin
|
|
139
|
+
Copyright (c) 2013 Red Hat Inc.
|
|
140
|
+
|
|
141
|
+
This program is free software: you can redistribute it and/or modify
|
|
142
|
+
it under the terms of the GNU General Public License as published by
|
|
143
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
144
|
+
(at your option) any later version.
|
|
145
|
+
|
|
146
|
+
This program is distributed in the hope that it will be useful,
|
|
147
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
148
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
149
|
+
GNU General Public License for more details.
|
|
150
|
+
|
|
151
|
+
You should have received a copy of the GNU General Public License
|
|
152
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
@@ -7,11 +7,9 @@ module Content
|
|
|
7
7
|
|
|
8
8
|
# callback event from pulp upon tasks/events finished up
|
|
9
9
|
def events
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
render_error 'not_found', :status => :not_found and return false if repo.nil?
|
|
14
|
-
PulpEventHandler.new(repo_id, params)
|
|
10
|
+
repo_id = params['payload']['repo_id'] if params['payload']
|
|
11
|
+
render_error 'not_found', :status => :not_found and return false if repo_id.blank?
|
|
12
|
+
Content::Pulp::EventHandler.new(repo_id, params)
|
|
15
13
|
head :status => 202
|
|
16
14
|
end
|
|
17
15
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Content
|
|
2
|
+
class ContentViewsController < ::ApplicationController
|
|
3
|
+
include Foreman::Controller::AutoCompleteSearch
|
|
4
|
+
before_filter :find_by_name, :only => %w{show edit update destroy}
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
@content_views = ContentView.search_for(params[:search], :order => params[:order]).
|
|
8
|
+
paginate(:page => params[:page])
|
|
9
|
+
@counter = RepositoryClone.joins(:content_view_repository_clones).group(:content_view_id).count
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def new
|
|
14
|
+
@hostgroup = Hostgroup.find_by_id(params[:hostgroup]) if params[:hostgroup]
|
|
15
|
+
@content_view = ContentViewFactory.create_product_content_view(params[:product]) if params[:product]
|
|
16
|
+
@content_view ||= ContentViewFactory.create_os_content_view(params[:operatingsystem]) if params[:operatingsystem]
|
|
17
|
+
@content_view ||= ContentViewFactory.create_composite_content_view(params[:content_content_view_factory]) if params[:content_content_view_factory]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def create
|
|
21
|
+
@content_view = ContentView.new(params[:content_content_view])
|
|
22
|
+
if @content_view.save
|
|
23
|
+
process_success
|
|
24
|
+
else
|
|
25
|
+
process_error
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def edit
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def update
|
|
33
|
+
if @content_view.update_attributes(params[:content_content_view])
|
|
34
|
+
process_success
|
|
35
|
+
else
|
|
36
|
+
process_error
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def destroy
|
|
41
|
+
if @content_view.destroy
|
|
42
|
+
process_success
|
|
43
|
+
else
|
|
44
|
+
process_error
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -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.group(:product_id).where(:product_id => @products.map(&:id)).count
|
|
9
|
+
@counter = Repository::Product.group(:product_id).where(:product_id => @products.map(&:id)).count
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def new
|
|
@@ -5,11 +5,18 @@ module Content
|
|
|
5
5
|
|
|
6
6
|
def index
|
|
7
7
|
@repositories = Repository.search_for(params[:search], :order => params[:order]).
|
|
8
|
-
paginate(:page => params[:page]).includes(:product, :
|
|
8
|
+
paginate(:page => params[:page]).includes(:product, :operatingsystem)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def new
|
|
12
|
-
@repository =
|
|
12
|
+
@repository = case params[:type]
|
|
13
|
+
when "operatingsystem"
|
|
14
|
+
Repository::OperatingSystem.new(:unprotected => true)
|
|
15
|
+
when "product"
|
|
16
|
+
Repository::Product.new(:product_id => params[:product_id])
|
|
17
|
+
else
|
|
18
|
+
not_found
|
|
19
|
+
end
|
|
13
20
|
end
|
|
14
21
|
|
|
15
22
|
def create
|
|
@@ -33,10 +40,6 @@ module Content
|
|
|
33
40
|
end
|
|
34
41
|
|
|
35
42
|
def show
|
|
36
|
-
@details = @repository.retrieve_with_details
|
|
37
|
-
@sync_history = @repository.sync_history
|
|
38
|
-
rescue
|
|
39
|
-
redirect_back_or_to(edit_repository_path)
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
def destroy
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Content
|
|
2
|
+
module ContentViewsHelper
|
|
3
|
+
|
|
4
|
+
def repositories(view)
|
|
5
|
+
if view.new_record?
|
|
6
|
+
view.source_repositories + view.repository_clones
|
|
7
|
+
else
|
|
8
|
+
view.repository_clones
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def next_or_cancel path, args={}
|
|
13
|
+
args[:cancel_path] ||= send("#{controller_name}_path")
|
|
14
|
+
content_tag(:div, :class => "form-actions") do
|
|
15
|
+
link_to(_("Cancel"), args[:cancel_path], :class => "btn") + " " +
|
|
16
|
+
submit_tag( _("Next"), :class => "btn btn-primary")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -1,55 +1,9 @@
|
|
|
1
1
|
module Content
|
|
2
2
|
module RepositoriesHelper
|
|
3
3
|
|
|
4
|
-
def
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
status.first[:state]
|
|
8
|
-
else
|
|
9
|
-
details = repo.retrieve_with_details
|
|
10
|
-
details[:importers][0][:last_sync] if details && details[:importers] && details[:importers][0]
|
|
11
|
-
end
|
|
12
|
-
"#{time_ago_in_words(status)} ago" rescue status
|
|
13
|
-
rescue
|
|
14
|
-
'-'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def last_publish details
|
|
18
|
-
return '' unless details[:distributors] && details[:distributors].first && published = details[:distributors].first[:last_publish]
|
|
19
|
-
"#{time_ago_in_words published} ago" rescue ''
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def last_sync details
|
|
23
|
-
return '' unless details[:importers] && details[:importers].first && synced = details[:importers].first[:last_sync]
|
|
24
|
-
"#{time_ago_in_words synced} ago" rescue ''
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def sync_history_times history
|
|
28
|
-
return {} unless history && history.first && summary = history.first['summary']
|
|
29
|
-
return {} unless summary[:comps]
|
|
30
|
-
{
|
|
31
|
-
:comps => summary[:comps][:time_total_sec],
|
|
32
|
-
:errata => summary[:errata][:errata_time_total_sec],
|
|
33
|
-
:packages => summary[:packages][:time_total_sec]
|
|
34
|
-
}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def sync_history_metrics history
|
|
38
|
-
return {} unless history && last = history.first
|
|
39
|
-
{
|
|
40
|
-
:updated => last[:updated_count],
|
|
41
|
-
:removed => last[:removed_count],
|
|
42
|
-
:added => last[:added_count]
|
|
43
|
-
}
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def sync_history_status history
|
|
47
|
-
return {} unless history && last = history.first
|
|
48
|
-
{
|
|
49
|
-
'result' => last[:result],
|
|
50
|
-
'message' => last[:error_message] || last['summary']['error'],
|
|
51
|
-
'completed' => ("#{time_ago_in_words(last[:completed])} ago" rescue '')
|
|
52
|
-
}
|
|
4
|
+
def last_time(time)
|
|
5
|
+
return if time.blank?
|
|
6
|
+
time_ago_in_words(time) + ' ago'
|
|
53
7
|
end
|
|
54
8
|
|
|
55
9
|
end
|
|
@@ -2,8 +2,8 @@ module Content::EnvironmentExtensions
|
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
4
|
included do
|
|
5
|
-
has_many :
|
|
6
|
-
has_many :
|
|
5
|
+
has_many :available_content_views, :dependent => :destroy, :class_name => 'Content::AvailableContentView'
|
|
6
|
+
has_many :content_views, :through => :available_content_views, :class_name => 'Content::ContentView'
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
end
|
|
@@ -11,6 +11,7 @@ module Content::HomeHelper
|
|
|
11
11
|
[
|
|
12
12
|
[_('Products'), :"content/products"],
|
|
13
13
|
[_('Repositories'), :"content/repositories"],
|
|
14
|
+
[_('Content Views'), :"content/content_views"],
|
|
14
15
|
[_('Gpg keys'), :"content/gpg_keys"]
|
|
15
16
|
]
|
|
16
17
|
choices.insert(3, [:divider], [:group, _("Content"), content_group])
|
|
@@ -5,6 +5,9 @@ module Content::HostExtensions
|
|
|
5
5
|
has_many :host_products, :dependent => :destroy, :uniq => true, :foreign_key => :host_id, :class_name => 'Content::HostProduct'
|
|
6
6
|
has_many :products, :through => :host_products, :class_name => 'Content::Product'
|
|
7
7
|
|
|
8
|
+
has_many :content_view_hosts, :dependent => :destroy, :uniq => true, :foreign_key => :host_id, :class_name => 'Content::ContentViewHost'
|
|
9
|
+
has_many :content_views, :through => :content_view_hosts, :class_name => 'Content::ContentView'
|
|
10
|
+
|
|
8
11
|
scoped_search :in => :products, :on => :name, :complete_value => true, :rename => :product
|
|
9
12
|
|
|
10
13
|
alias_method_chain :params, :repositories
|
|
@@ -30,8 +33,21 @@ module Content::HostExtensions
|
|
|
30
33
|
(inherited_product_ids + product_ids).uniq
|
|
31
34
|
end
|
|
32
35
|
|
|
36
|
+
def inherited_content_view_ids
|
|
37
|
+
return [] if hostgroup_id.nil? or environment_id.nil?
|
|
38
|
+
|
|
39
|
+
Content::ContentView.joins(:available_content_views).
|
|
40
|
+
where(:content_available_content_views => {:environment_id => environment_id}).
|
|
41
|
+
where(:originator_type => 'Hostgroup', :originator_id => hostgroup_id).pluck(:id)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def all_content_view_ids
|
|
45
|
+
(inherited_content_view_ids + content_view_ids).uniq
|
|
46
|
+
end
|
|
47
|
+
|
|
33
48
|
def attached_repositories
|
|
34
|
-
|
|
49
|
+
return [] if all_content_view_ids.empty?
|
|
50
|
+
Content::RepositoryClone.for_content_views(all_content_view_ids)
|
|
35
51
|
end
|
|
36
52
|
|
|
37
53
|
private
|
|
@@ -4,15 +4,29 @@ module Content::HostgroupExtensions
|
|
|
4
4
|
included do
|
|
5
5
|
has_many :hostgroup_products, :dependent => :destroy, :uniq => true, :class_name => 'Content::HostgroupProduct'
|
|
6
6
|
has_many :products, :through => :hostgroup_products, :class_name => 'Content::Product'
|
|
7
|
+
has_many :content_views, :as => :originator, :class_name => 'Content::ContentView'
|
|
8
|
+
|
|
9
|
+
scope :has_content_views, joins(:content_views)
|
|
7
10
|
|
|
8
11
|
scoped_search :in => :products, :on => :name, :complete_value => true, :rename => :product
|
|
12
|
+
scoped_search :in => :content_views, :on => :name, :complete_value => true, :rename => :content_view
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
def inherited_product_ids
|
|
16
|
+
return [] if hostgroup.ancestor_ids.empty?
|
|
12
17
|
Content::HostgroupProduct.where(:hostgroup_id => hostgroup.ancestor_ids).pluck(:product_id)
|
|
13
18
|
end
|
|
14
19
|
|
|
15
20
|
def all_product_ids
|
|
16
21
|
(inherited_product_ids + product_ids).uniq
|
|
17
22
|
end
|
|
23
|
+
|
|
24
|
+
def inherited_content_view_ids
|
|
25
|
+
return [] if hostgroup.ancestor_ids.empty?
|
|
26
|
+
Content::ContentView.where(:originator_id => hostgroup.ancestor_ids, :originator_type => 'Hostgroup').pluck(:id)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def all_content_views_ids
|
|
30
|
+
(inherited_content_view_ids + content_view_ids).uniq
|
|
31
|
+
end
|
|
18
32
|
end
|
|
@@ -2,11 +2,12 @@ module Content::OperatingsystemExtensions
|
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
4
|
included do
|
|
5
|
-
has_many :
|
|
6
|
-
|
|
7
|
-
has_many :
|
|
8
|
-
has_many :
|
|
9
|
-
|
|
5
|
+
has_many :repositories, :class_name => 'Content::Repository'
|
|
6
|
+
|
|
7
|
+
has_many :available_content_views, :dependent => :destroy, :class_name => 'Content::AvailableContentView'
|
|
8
|
+
has_many :content_views, :as => :originator, :class_name => 'Content::ContentView'
|
|
9
|
+
|
|
10
|
+
scope :has_repos, joins(:repositories).uniq
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module Content::Orchestration::Pulp::Clone
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
include Content::Orchestration::Pulp
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
after_validation :repository_clone_save unless Rails.env.test?
|
|
7
|
+
before_destroy :repository_clone_destroy unless Rails.env.test?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def last_published
|
|
11
|
+
read_attribute(:last_published) || repo.last_publish
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def repository_clone_save
|
|
17
|
+
return unless (pulp? and errors.empty? and new_record?)
|
|
18
|
+
queue_pulp_create
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def queue_pulp_create
|
|
22
|
+
logger.debug "Scheduling new Pulp Repository"
|
|
23
|
+
queue.create(:name => _("Create Pulp Repository for %s") % self, :priority => 10,
|
|
24
|
+
:action => [self, :set_pulp_repo])
|
|
25
|
+
queue.create(:name => _("Copy Pulp Repository %s") % self, :priority => 20,
|
|
26
|
+
:action => [self, :set_copy_pulp_repo])
|
|
27
|
+
queue.create(:name => _("Create Event Notifier") % self, :priority => 30,
|
|
28
|
+
:action => [self, :set_create_event_notifier])
|
|
29
|
+
queue.create(:name => _("Publish Pulp Repository %s") % self, :priority => 40,
|
|
30
|
+
:action => [self, :set_publish_pulp_repo])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def repository_clone_destroy
|
|
34
|
+
return unless pulp? and errors.empty?
|
|
35
|
+
logger.debug _("Scheduling removal of Pulp Repository %s") % name
|
|
36
|
+
queue.create(:name => _("Delete Pulp repository for %s") % name, :priority => 50,
|
|
37
|
+
:action => [self, :del_pulp_repo])
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def set_pulp_repo
|
|
41
|
+
repo.create_with_distributor
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def set_copy_pulp_repo
|
|
45
|
+
repo.copy_from(repository.pulp_id)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def set_publish_pulp_repo
|
|
49
|
+
repo.publish
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def set_create_event_notifier
|
|
53
|
+
repo.create_event_notifier
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def del_create_event_notifier; end
|
|
57
|
+
|
|
58
|
+
def del_copy_pulp_repo; end
|
|
59
|
+
|
|
60
|
+
def del_pulp_repo
|
|
61
|
+
repo.delete
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def repo_options
|
|
65
|
+
{
|
|
66
|
+
:pulp_id => pulp_repo_id,
|
|
67
|
+
:name => "#{to_label}_clone",
|
|
68
|
+
:relative_path => relative_path,
|
|
69
|
+
:content_type => content_type,
|
|
70
|
+
:protected => false,
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def repo
|
|
75
|
+
@repo ||= Content::Pulp::RepositoryClone.new(repo_options)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Content::Orchestration::Pulp::Sync
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
include Content::Orchestration::Pulp
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
after_validation :queue_pulp
|
|
7
|
+
before_destroy :queue_pulp_destroy unless Rails.env.test?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def last_sync
|
|
11
|
+
read_attribute(:last_sync) || repo.last_sync
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def queue_pulp
|
|
17
|
+
return unless pulp? and errors.empty?
|
|
18
|
+
new_record? ? queue_pulp_create : queue_pulp_update
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def queue_pulp_create
|
|
22
|
+
logger.debug "Scheduling new Pulp Repository"
|
|
23
|
+
queue.create(:name => _("Create Pulp Repository for %s") % self, :priority => 10,
|
|
24
|
+
:action => [self, :set_pulp_repo])
|
|
25
|
+
queue.create(:name => _("Sync Pulp Repository %s") % self, :priority => 20,
|
|
26
|
+
:action => [self, :set_sync_pulp_repo])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def queue_pulp_update
|
|
30
|
+
# TODO: handle repo updates.
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def queue_pulp_destroy
|
|
34
|
+
return unless pulp? and errors.empty?
|
|
35
|
+
logger.debug _("Scheduling removal of Pulp Repository %s") % name
|
|
36
|
+
queue.create(:name => _("Delete Pulp repository for %s") % name, :priority => 50,
|
|
37
|
+
:action => [self, :del_pulp_repo])
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def set_pulp_repo
|
|
41
|
+
repo.create
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def del_pulp_repo
|
|
45
|
+
repo.delete
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def set_sync_pulp_repo
|
|
49
|
+
repo.sync
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def del_sync_pulp_repo
|
|
53
|
+
repo.cancel_running_sync!
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def repo_options
|
|
57
|
+
{
|
|
58
|
+
:pulp_id => pulp_repo_id,
|
|
59
|
+
:name => to_label,
|
|
60
|
+
:description => description,
|
|
61
|
+
:feed => feed,
|
|
62
|
+
:content_type => content_type,
|
|
63
|
+
:protected => unprotected,
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def repo
|
|
68
|
+
@repo ||= Content::Pulp::Repository.new(repo_options)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Content::Orchestration::Pulp
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
include ::Orchestration
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
delegate :sync_status, :sync, :counters, :sync_history, :state, :to => :repo
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def orchestration_errors?
|
|
10
|
+
errors.empty?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def pulp?
|
|
14
|
+
@use_pulp ||= Setting.use_pulp
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def update_cache; nil; end
|
|
18
|
+
def progress_report_id
|
|
19
|
+
@progress_report_id ||= Foreman.uuid
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def pulp_repo_id
|
|
23
|
+
self.pulp_id ||= Foreman.uuid.gsub("-", '')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Content
|
|
2
|
+
class AvailableContentView < ActiveRecord::Base
|
|
3
|
+
belongs_to :environment
|
|
4
|
+
belongs_to :operatingsystem
|
|
5
|
+
belongs_to :content_view
|
|
6
|
+
|
|
7
|
+
validates_presence_of :content_view_id, :environment_id
|
|
8
|
+
|
|
9
|
+
#todo needs to validate that default can't be archived and vice-versa
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Content
|
|
2
|
+
class ContentView < ActiveRecord::Base
|
|
3
|
+
has_ancestry :orphan_strategy => :rootify
|
|
4
|
+
|
|
5
|
+
belongs_to :originator, :polymorphic => true
|
|
6
|
+
has_many :available_content_views, :dependent => :destroy
|
|
7
|
+
has_many :environments, :through => :available_content_views
|
|
8
|
+
delegate :operatingsystems, :to => :available_content_views, :allow_nil => true
|
|
9
|
+
|
|
10
|
+
has_many :content_view_hosts, :dependent => :destroy, :uniq => true, :foreign_key => :content_view_id, :class_name => 'Content::ContentViewHost'
|
|
11
|
+
has_many :hosts, :through => :content_view_hosts
|
|
12
|
+
|
|
13
|
+
has_many :content_view_repository_clones, :dependent => :destroy
|
|
14
|
+
has_many :repository_clones, :through => :content_view_repository_clones, :class_name => 'Content::RepositoryClone'
|
|
15
|
+
has_many :repositories, :through => :repository_clones
|
|
16
|
+
|
|
17
|
+
scope :hostgroups, where(:originator_type => 'Hostgroup')
|
|
18
|
+
scope :products, where(:originator_type => 'Content::Product')
|
|
19
|
+
scope :operatingsystem, where(:originator_type => 'Operatingsystem')
|
|
20
|
+
|
|
21
|
+
after_save :clone_repos
|
|
22
|
+
before_destroy :clean_unused_clone_repos
|
|
23
|
+
|
|
24
|
+
validates_presence_of :name
|
|
25
|
+
|
|
26
|
+
# special relationships needed for search with polymorphic associations
|
|
27
|
+
belongs_to :search_hostgroups, :class_name => 'Hostgroup', :foreign_key => :originator_id,
|
|
28
|
+
:conditions => '"content_content_views"."originator_type" = "Hostgroup"'
|
|
29
|
+
belongs_to :search_operatingsystems, :class_name => 'Operatingsystem', :foreign_key => :originator_id,
|
|
30
|
+
:conditions => '"content_content_views"."originator_type" = "Operatingsystem"'
|
|
31
|
+
belongs_to :search_products, :class_name => 'Content::Product', :foreign_key => :originator_id,
|
|
32
|
+
:conditions => '"content_content_views"."originator_type" = "Content::Product"'
|
|
33
|
+
scoped_search :on => [:name, :created_at], :complete_value => :true
|
|
34
|
+
scoped_search :in => :search_products, :on => :name, :rename => :product,
|
|
35
|
+
:complete_value => :true, :only_explicit => true
|
|
36
|
+
scoped_search :in => :search_operatingsystems, :on => :name, :rename => :operatingsystem,
|
|
37
|
+
:complete_value => :true, :only_explicit => true
|
|
38
|
+
scoped_search :in => :search_hostgroups, :on => :label, :complete_value => true,
|
|
39
|
+
:rename => :hostgroup, :only_explicit => true
|
|
40
|
+
|
|
41
|
+
attr_accessor :source_repositories
|
|
42
|
+
|
|
43
|
+
def to_label
|
|
44
|
+
name || "#{originator.to_label} - #{DateTime.now.strftime("%m/%d/%Y")}".parameterize
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def clone_repos
|
|
48
|
+
return unless @source_repositories
|
|
49
|
+
Repository.where(:id => @source_repositories).each do |repository|
|
|
50
|
+
repository.publish self
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def clean_unused_clone_repos
|
|
57
|
+
current_repos = Content::ContentViewRepositoryClone.where(:content_view_id => id).pluck(:repository_clone_id)
|
|
58
|
+
used_repos = Content::ContentViewRepositoryClone.
|
|
59
|
+
where(:repository_clone_id => current_repos).
|
|
60
|
+
where(['content_view_id IS NOT ?', id]).pluck(:repository_clone_id)
|
|
61
|
+
|
|
62
|
+
repos_to_delete = current_repos - used_repos
|
|
63
|
+
Content::RepositoryClone.destroy(repos_to_delete) if repos_to_delete.any?
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Copyright 2013 Red Hat, Inc.
|
|
3
|
-
#
|
|
4
|
-
# This software is licensed to you under the GNU General Public
|
|
5
|
-
# License as published by the Free Software Foundation; either version
|
|
6
|
-
# 2 of the License (GPLv2) or (at your option) any later version.
|
|
7
|
-
# There is NO WARRANTY for this software, express or implied,
|
|
8
|
-
# including the implied warranties of MERCHANTABILITY,
|
|
9
|
-
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
|
10
|
-
# have received a copy of GPLv2 along with this software; if not, see
|
|
11
|
-
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
|
12
1
|
module Content
|
|
13
2
|
class HostProduct < ActiveRecord::Base
|
|
14
3
|
belongs_to :product
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Copyright 2013 Red Hat, Inc.
|
|
3
|
-
#
|
|
4
|
-
# This software is licensed to you under the GNU General Public
|
|
5
|
-
# License as published by the Free Software Foundation; either version
|
|
6
|
-
# 2 of the License (GPLv2) or (at your option) any later version.
|
|
7
|
-
# There is NO WARRANTY for this software, express or implied,
|
|
8
|
-
# including the implied warranties of MERCHANTABILITY,
|
|
9
|
-
# NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should
|
|
10
|
-
# have received a copy of GPLv2 along with this software; if not, see
|
|
11
|
-
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
|
12
1
|
module Content
|
|
13
2
|
class HostgroupProduct < ActiveRecord::Base
|
|
14
3
|
belongs_to :product
|