foreman_content 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +113 -0
- data/Rakefile +111 -0
- data/app/assets/javascripts/content/content.js +12 -0
- data/app/assets/stylesheets/content/application.css +13 -0
- data/app/controllers/content/api/repositories_controller.rb +27 -0
- data/app/controllers/content/gpg_keys_controller.rb +42 -0
- data/app/controllers/content/products_controller.rb +51 -0
- data/app/controllers/content/repositories_controller.rb +57 -0
- data/app/helpers/content/application_helper.rb +5 -0
- data/app/helpers/content/repositories_helper.rb +56 -0
- data/app/models/content/custom_repository_paths.rb +27 -0
- data/app/models/content/environment_product.rb +19 -0
- data/app/models/content/gpg_key.rb +32 -0
- data/app/models/content/host_product.rb +20 -0
- data/app/models/content/hostgroup_product.rb +19 -0
- data/app/models/content/operatingsystem_repository.rb +19 -0
- data/app/models/content/orchestration/pulp.rb +93 -0
- data/app/models/content/product.rb +28 -0
- data/app/models/content/product_operatingsystem.rb +19 -0
- data/app/models/content/remote/pulp/repository.rb +46 -0
- data/app/models/content/repository.rb +70 -0
- data/app/models/content/validators/content_validator.rb +25 -0
- data/app/models/content/validators/description_format.rb +24 -0
- data/app/models/content/validators/name_format.rb +40 -0
- data/app/models/content/validators/no_trailing_space.rb +27 -0
- data/app/models/setting/content.rb +42 -0
- data/app/overrides/add_host_conent_tab.rb +9 -0
- data/app/overrides/add_hostgroup_conent_tab.rb +9 -0
- data/app/overrides/add_os_conent_tab.rb +9 -0
- data/app/services/content/pulp_event_handler.rb +25 -0
- data/app/views/content/gpg_keys/_form.html.erb +8 -0
- data/app/views/content/gpg_keys/edit.html.erb +3 -0
- data/app/views/content/gpg_keys/index.html.erb +20 -0
- data/app/views/content/gpg_keys/new.html.erb +3 -0
- data/app/views/content/products/_form.html.erb +26 -0
- data/app/views/content/products/_form_tab.html.erb +3 -0
- data/app/views/content/products/_host_tab_pane.html.erb +5 -0
- data/app/views/content/products/_hostgroup_tab_pane.html.erb +5 -0
- data/app/views/content/products/_operatingsystem_tab_pane.html.erb +5 -0
- data/app/views/content/products/edit.html.erb +3 -0
- data/app/views/content/products/index.html.erb +27 -0
- data/app/views/content/products/new.html.erb +3 -0
- data/app/views/content/products/welcome.html.erb +8 -0
- data/app/views/content/repositories/_form.html.erb +30 -0
- data/app/views/content/repositories/edit.html.erb +3 -0
- data/app/views/content/repositories/index.html.erb +32 -0
- data/app/views/content/repositories/new.html.erb +3 -0
- data/app/views/content/repositories/show.html.erb +98 -0
- data/app/views/content/repositories/welcome.html.erb +8 -0
- data/config/routes.rb +36 -0
- data/db/migrate/20130702140034_create_content_repositories.rb +19 -0
- data/db/migrate/20130702162629_create_content_products.rb +10 -0
- data/db/migrate/20130709001120_create_content_gpg_keys.rb +10 -0
- data/db/migrate/20130717032320_create_content_environments_products.rb +9 -0
- data/db/migrate/20130722084911_create_content_operatingsystem_repositories.rb +9 -0
- data/db/migrate/20130723084911_create_content_hostgroup_products.rb +9 -0
- data/db/migrate/20130723124911_create_content_host_products.rb +9 -0
- data/db/migrate/20130729032320_create_content_product_operatingsystems.rb +9 -0
- data/lib/content/engine.rb +59 -0
- data/lib/content/version.rb +3 -0
- data/lib/content_environment.rb +13 -0
- data/lib/content_home_helper_patch.rb +23 -0
- data/lib/content_host.rb +55 -0
- data/lib/content_hostgroup.rb +22 -0
- data/lib/content_operatingsystem.rb +17 -0
- data/lib/content_redhat.rb +36 -0
- data/lib/content_taxonomy.rb +18 -0
- data/lib/foreman_content.rb +4 -0
- data/lib/pulp_configuration.rb +23 -0
- data/lib/tasks/content_tasks.rake +4 -0
- data/test/content_test.rb +7 -0
- data/test/fixtures/content/products.yml +11 -0
- data/test/fixtures/content/repositories.yml +11 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +23 -0
- data/test/unit/content/description_format_validator_test.rb +20 -0
- data/test/unit/content/name_format_validator_test.rb +28 -0
- data/test/unit/content/product_validation_test.rb +18 -0
- data/test/unit/content/repositories_test.rb +7 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 66165cc1d29ef234bd0d15923511264f87045b55
|
4
|
+
data.tar.gz: 2166c67ba266eaf2c9d478ba4e64839fb7a703a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 851db5cbe0dda9500b5bd6d30506d4ab63c565e0802cd5365b81a1b5a53c15d3362410e3ae347fbe82dc1da385c8e881953f72117253925bcc973916e3d0f444
|
7
|
+
data.tar.gz: c202eedf2998d5baca4d8a76ad2df98c745b280fd2a02726ae604c43477aea38a2c1a658e0b9bbea85276a518fa9e6623fa7b1db78247e5da2dfd3d728428377
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# foreman\_content
|
2
|
+
|
3
|
+
This plugin aims to enable repository synconrinzation and managament in Foreman. It is of alpha quality
|
4
|
+
right now and currently handles only yum/rpm repositories ;)
|
5
|
+
|
6
|
+
# Dependencies
|
7
|
+
|
8
|
+
* Foreman running development or 1.2.1 (maybe 1.2 but was not tested)
|
9
|
+
* You must have a fully working pulp server, see http://www.pulpproject.org/docs/
|
10
|
+
|
11
|
+
|
12
|
+
# Installation
|
13
|
+
|
14
|
+
Require the gem in Foreman by creating `bundler.d/Gemfile.local.rb` with the
|
15
|
+
following:
|
16
|
+
|
17
|
+
```
|
18
|
+
gem 'foreman_content'
|
19
|
+
```
|
20
|
+
|
21
|
+
Update & Restart Foreman:
|
22
|
+
```
|
23
|
+
bundle update
|
24
|
+
rake db:migrate
|
25
|
+
touch tmp/restart.txt (if using passeger)
|
26
|
+
```
|
27
|
+
|
28
|
+
# Configuration
|
29
|
+
|
30
|
+
## Pulp
|
31
|
+
* enable oauth authentication
|
32
|
+
|
33
|
+
## UI config
|
34
|
+
|
35
|
+
You would need to allow foreman to communicate with pulp, under More ->
|
36
|
+
Settings -> Content, you would need to enable pulp, and set the pulp url and
|
37
|
+
oauth creds, for example:
|
38
|
+
|
39
|
+
* pulp_oauth_key foreman
|
40
|
+
* pulp_oauth_secret super_secret
|
41
|
+
* pulp_url https://pulp.server.com/pulp/api/v2/
|
42
|
+
* use_pulp true
|
43
|
+
|
44
|
+
# Usage
|
45
|
+
|
46
|
+
## Setting up
|
47
|
+
|
48
|
+
You would see in the UI under More, a new sub menu called content, in it:
|
49
|
+
|
50
|
+
* Product - The actual product you are managing, for example CentOS 6
|
51
|
+
* Repository - list of repositories that belong to the above product, for
|
52
|
+
example, CentOS 6.4 + CentOS updates.
|
53
|
+
|
54
|
+
## Syncing Repositories
|
55
|
+
|
56
|
+
Under Content -> Repository create a new repo
|
57
|
+
|
58
|
+
* Name - user friendly name, this would be reflected later on in yum configuration
|
59
|
+
* Feed URL - where we are cloning from, normally a public mirror
|
60
|
+
* Content type - Kickstart (e.g. bootable) or a plain yum repo, if the repo
|
61
|
+
contains a full OS, choose kickstart, later on foreman would use that instead
|
62
|
+
of an Installation media.
|
63
|
+
* Architecture - type of files within the repo, usually X86_64 or noarch etc.
|
64
|
+
* Operating Systems - list of valid OS's that this repo applies to.
|
65
|
+
* Enabled - true / false
|
66
|
+
* Unprotected - weather pulp should expose this repo via http and https or just
|
67
|
+
over https.
|
68
|
+
* Product - the product from above.
|
69
|
+
* GPG key - not implemented
|
70
|
+
|
71
|
+
Once created, the repo would automatically be synced and published.
|
72
|
+
|
73
|
+
## Consuming Repos within your Kickstart
|
74
|
+
|
75
|
+
Once a kickstart repo has been assigned to an OS, it would automatically prefer
|
76
|
+
that repo as an install media, so if that is all you want to do, its done
|
77
|
+
automatically.
|
78
|
+
|
79
|
+
if you wish to add more yum type repos during KS, you may add the following
|
80
|
+
snippet to your provisioning template.
|
81
|
+
|
82
|
+
```erb
|
83
|
+
<% @repos.each do |repo| %>
|
84
|
+
repo --name=<%= repo[:name] %> --baseurl=<%= repo[:baseurl] %>
|
85
|
+
<% end %>
|
86
|
+
```
|
87
|
+
|
88
|
+
## Consuming Repos with Puppet
|
89
|
+
|
90
|
+
Assuming you are using puppet with ENC functionality, its pretty simple to
|
91
|
+
let puppet manage the repositories, Foreman would expose all repository
|
92
|
+
information via the ENC as a global parameter, you can later on simply consume
|
93
|
+
it with create resources, e.g:
|
94
|
+
|
95
|
+
```puppet
|
96
|
+
if $::repositories {
|
97
|
+
create_resources('yumrepo', $::repositories)
|
98
|
+
}
|
99
|
+
```
|
100
|
+
|
101
|
+
## Callback notifications from pulp
|
102
|
+
|
103
|
+
Pulp can notify foreman when events happen (e.g. repo sync is finished etc), in
|
104
|
+
order to configure it run on your pulp server:
|
105
|
+
|
106
|
+
```
|
107
|
+
pulp-admin event listener http create --event-type '*' --url https://foreman.example.com/api/repositories/events
|
108
|
+
```
|
109
|
+
|
110
|
+
# TODO
|
111
|
+
|
112
|
+
* https://trello.com/b/NtzVcPkD/foreman-backlog
|
113
|
+
filter engine spike
|
data/Rakefile
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
ENGINE_DIR = File.expand_path('..', __FILE__)
|
10
|
+
FOREMAN_DIR = 'test/foreman_app'
|
11
|
+
|
12
|
+
namespace :test do
|
13
|
+
desc "Download latest foreman devel source and install dependencies"
|
14
|
+
task :foreman_prepare do
|
15
|
+
foreman_repo = 'https://github.com/theforeman/foreman.git'
|
16
|
+
foreman_gemfile = File.join(FOREMAN_DIR, "Gemfile")
|
17
|
+
unless File.exists?(foreman_gemfile)
|
18
|
+
puts "Foreman source code is not present at #{FOREMAN_DIR}"
|
19
|
+
puts "Downloading latest Foreman development branch into #{FOREMAN_DIR}..."
|
20
|
+
FileUtils.mkdir_p(FOREMAN_DIR)
|
21
|
+
|
22
|
+
unless system("git clone #{foreman_repo} #{FOREMAN_DIR}")
|
23
|
+
puts "Error while getting latest Foreman code from #{foreman_repo} into #{FOREMAN_DIR}"
|
24
|
+
fail
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
gemfile_content = File.read(foreman_gemfile)
|
29
|
+
unless gemfile_content.include?('FOREMAN_GEMFILE')
|
30
|
+
puts 'Preparing Gemfile'
|
31
|
+
gemfile_content.gsub!('__FILE__', 'FOREMAN_GEMFILE')
|
32
|
+
gemfile_content.insert(0, "FOREMAN_GEMFILE = __FILE__ unless defined? FOREMAN_GEMFILE\n")
|
33
|
+
File.open(foreman_gemfile, 'w') { |f| f << gemfile_content }
|
34
|
+
end
|
35
|
+
|
36
|
+
settings_file = "#{FOREMAN_DIR}/config/settings.yaml"
|
37
|
+
unless File.exists?(settings_file)
|
38
|
+
puts 'Preparing settings file'
|
39
|
+
FileUtils.copy("#{settings_file}.example", settings_file)
|
40
|
+
settings_content = File.read(settings_file)
|
41
|
+
settings_content.sub!('organizations_enabled: false', 'organizations_enabled: true')
|
42
|
+
settings_content << ":puppetgem: true\n"
|
43
|
+
File.open(settings_file, 'w') { |f| f << settings_content }
|
44
|
+
end
|
45
|
+
|
46
|
+
db_file = "#{FOREMAN_DIR}/config/database.yml"
|
47
|
+
unless File.exists?(db_file)
|
48
|
+
puts 'Preparing database file'
|
49
|
+
FileUtils.copy("#{db_file}.example", db_file)
|
50
|
+
end
|
51
|
+
|
52
|
+
["#{ENGINE_DIR}/.bundle/config", "#{FOREMAN_DIR}/.bundle/config"].each do |bundle_file|
|
53
|
+
unless File.exists?(bundle_file)
|
54
|
+
FileUtils.mkdir_p(File.dirname(bundle_file))
|
55
|
+
puts 'Preparing bundler configuration'
|
56
|
+
File.open(bundle_file, 'w') { |f| f << <<FILE }
|
57
|
+
---
|
58
|
+
BUNDLE_WITHOUT: console:development:fog:jsonp:libvirt:mysql:mysql2:ovirt:postgresql:vmware
|
59
|
+
FILE
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
local_gemfile = "#{FOREMAN_DIR}/bundler.d/Gemfile.local.rb"
|
64
|
+
unless File.exist?(local_gemfile)
|
65
|
+
File.open(local_gemfile, 'w') { |f| f << <<GEMFILE }
|
66
|
+
gem "puppet"
|
67
|
+
gem "facter"
|
68
|
+
GEMFILE
|
69
|
+
end
|
70
|
+
|
71
|
+
puts 'Installing dependencies...'
|
72
|
+
unless system('bundle install')
|
73
|
+
fail
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
task :db_prepare do
|
78
|
+
unless File.exists?(FOREMAN_DIR)
|
79
|
+
puts <<MESSAGE
|
80
|
+
Foreman source code not prepared. Run
|
81
|
+
|
82
|
+
rake test:foreman_prepare
|
83
|
+
|
84
|
+
to download foreman source and its dependencies
|
85
|
+
MESSAGE
|
86
|
+
fail
|
87
|
+
end
|
88
|
+
|
89
|
+
# once we are Ruby19 only, switch to block variant of cd
|
90
|
+
pwd = FileUtils.pwd
|
91
|
+
FileUtils.cd(FOREMAN_DIR)
|
92
|
+
unless system('rake db:test:prepare RAILS_ENV=test')
|
93
|
+
puts "Migrating database first"
|
94
|
+
system('rake db:migrate db:schema:dump db:test:prepare RAILS_ENV=test') || fail
|
95
|
+
end
|
96
|
+
FileUtils.cd(pwd)
|
97
|
+
end
|
98
|
+
|
99
|
+
task :set_loadpath do
|
100
|
+
%w[lib test].each do |dir|
|
101
|
+
$:.unshift(File.expand_path(dir, ENGINE_DIR))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
task :all => [:db_prepare, :set_loadpath] do
|
106
|
+
Dir.glob('test/**/*_test.rb') { |f| require f.sub('test/','') unless f.include? '/foreman_app/' }
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
task :test => 'test:all'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Content
|
2
|
+
module Api
|
3
|
+
class RepositoriesController < ::Api::V2::BaseController
|
4
|
+
|
5
|
+
before_filter :validate_access_to_events, :only => :events
|
6
|
+
skip_before_filter :authorize, :only => :events
|
7
|
+
|
8
|
+
# callback event from pulp upon tasks/events finished up
|
9
|
+
def events
|
10
|
+
if (repo_id = params['payload'] && params['payload']['repo_id'])
|
11
|
+
repo = Content::Repository.where(:pulp_id => repo_id).first
|
12
|
+
end
|
13
|
+
render_error 'not_found', :status => :not_found and return false if repo.nil?
|
14
|
+
PulpEventHandler.new(repo_id, params)
|
15
|
+
head :status => 202
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def validate_access_to_events
|
21
|
+
#validate our pulp server here
|
22
|
+
# we really want to use existing smart proxy infrastructure to do this.
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Content
|
2
|
+
class GpgKeysController < ::ApplicationController
|
3
|
+
include Foreman::Controller::AutoCompleteSearch
|
4
|
+
before_filter :find_by_name, :only => %w{show edit update destroy}
|
5
|
+
|
6
|
+
def index
|
7
|
+
@gpg_keys = GpgKey.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
|
8
|
+
end
|
9
|
+
|
10
|
+
def new
|
11
|
+
@gpg_key = GpgKey.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@gpg_key = GpgKey.new(params[:content_gpg_key])
|
16
|
+
if @gpg_key.save
|
17
|
+
process_success
|
18
|
+
else
|
19
|
+
process_error
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def edit
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
if @gpg_key.update_attributes(params[:content_gpg_key])
|
28
|
+
process_success
|
29
|
+
else
|
30
|
+
process_error
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
if @gpg_key.destroy
|
36
|
+
process_success
|
37
|
+
else
|
38
|
+
process_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Content
|
2
|
+
class ProductsController < ::ApplicationController
|
3
|
+
include Foreman::Controller::AutoCompleteSearch
|
4
|
+
before_filter :find_by_name, :only => %w{show edit update destroy sync}
|
5
|
+
|
6
|
+
def index
|
7
|
+
@products = Product.search_for(params[:search], :order => params[:order]).
|
8
|
+
paginate(:page => params[:page])
|
9
|
+
@counter = Repository.group(:product_id).where(:product_id => @products.map(&:id)).count
|
10
|
+
end
|
11
|
+
|
12
|
+
def new
|
13
|
+
@product = Product.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@product = Product.new(params[:content_product])
|
18
|
+
if @product.save
|
19
|
+
process_success
|
20
|
+
else
|
21
|
+
process_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def edit
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
if @product.update_attributes(params[:content_product])
|
30
|
+
process_success
|
31
|
+
else
|
32
|
+
process_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def sync
|
37
|
+
@product.sync
|
38
|
+
process_success(:success_msg => _("Successfully started sync for %s") % @product.name)
|
39
|
+
rescue => e
|
40
|
+
process_error(:error_msg => _("Failed to start sync for %s") % @product.name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def destroy
|
44
|
+
if @product.destroy
|
45
|
+
process_success
|
46
|
+
else
|
47
|
+
process_error
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Content
|
2
|
+
class RepositoriesController < ::ApplicationController
|
3
|
+
include Foreman::Controller::AutoCompleteSearch
|
4
|
+
before_filter :find_by_name, :only => %w{show edit update destroy sync}
|
5
|
+
|
6
|
+
def index
|
7
|
+
@repositories = Repository.search_for(params[:search], :order => params[:order]).
|
8
|
+
paginate(:page => params[:page]).includes(:product, :operatingsystems)
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@repository = Repository.new(:unprotected => true)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@repository = Repository.new(params[:content_repository])
|
17
|
+
if @repository.save
|
18
|
+
process_success
|
19
|
+
else
|
20
|
+
process_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
end
|
26
|
+
|
27
|
+
def update
|
28
|
+
if @repository.update_attributes(params[:content_repository])
|
29
|
+
process_success
|
30
|
+
else
|
31
|
+
process_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
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
|
+
end
|
41
|
+
|
42
|
+
def destroy
|
43
|
+
if @repository.destroy
|
44
|
+
process_success
|
45
|
+
else
|
46
|
+
process_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def sync
|
51
|
+
@repository.sync
|
52
|
+
process_success(:success_msg => _("Successfully started sync for %s") % @repository.to_label)
|
53
|
+
rescue => e
|
54
|
+
process_error(:error_msg => _("Failed to start sync for %s") % @repository.to_label)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|