From 8e879ef0c7f78ddc6cfbaead88d35123f42b4bec Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Fri, 26 Jul 2013 18:41:39 +0400 Subject: [PATCH 01/10] #83: added ability to lock repository --- .../platforms/repositories_controller.rb | 12 ++++++++ app/models/ability.rb | 5 ++-- app/models/repository.rb | 28 +++++++++++++++++++ .../platforms/repositories/edit.html.haml | 25 ++++++++++++++++- config/locales/models/repository.en.yml | 7 +++++ config/locales/models/repository.ru.yml | 6 ++++ config/routes.rb | 16 ++++++----- 7 files changed, 89 insertions(+), 10 deletions(-) diff --git a/app/controllers/platforms/repositories_controller.rb b/app/controllers/platforms/repositories_controller.rb index fc96434a6..a0b7a6a7f 100644 --- a/app/controllers/platforms/repositories_controller.rb +++ b/app/controllers/platforms/repositories_controller.rb @@ -149,6 +149,18 @@ class Platforms::RepositoriesController < Platforms::BaseController redirect_to platform_repository_path(@platform, @repository) end + def lock_sync + @repository.lock_sync + flash[:notice] = t('flash.repository.sync_locked') + redirect_to edit_platform_repository_path(@platform, @repository) + end + + def unlock_sync + @repository.unlock_sync + flash[:notice] = t('flash.repository.sync_unlocked') + redirect_to edit_platform_repository_path(@platform, @repository) + end + protected def set_members diff --git a/app/models/ability.rb b/app/models/ability.rb index 3cbbd06f2..27707e5b4 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -119,7 +119,7 @@ class Ability can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories')) {|repository| can? :show, repository.platform} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform} - can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata], Repository) {|repository| local_admin? repository.platform} + can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata, :lock_sync, :unlock_sync], Repository) {|repository| local_admin? repository.platform} can([:remove_members, :remove_member, :add_member, :signatures], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(:id => user.id)} can(:clear, Platform) {|platform| owner?(platform) && platform.personal?} @@ -164,7 +164,8 @@ class Ability # Shared cannot rights for all users (registered, admin) cannot :destroy, Platform, :platform_type => 'personal' cannot [:create, :destroy], Repository, :platform => {:platform_type => 'personal'}, :name => 'main' - cannot [:remove_members, :remove_member, :add_member], Repository, :platform => {:platform_type => 'personal'} + cannot [:remove_members, :remove_member, :add_member, :lock_sync, :unlock_sync], Repository, :platform => {:platform_type => 'personal'} + cannot :clear, Platform, :platform_type => 'main' cannot :destroy, Issue diff --git a/app/models/repository.rb b/app/models/repository.rb index 6802c4c0e..918673357 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -45,6 +45,18 @@ class Repository < ActiveRecord::Base end end + def sync_locked? + sync_actions :check + end + + def lock_sync + sync_actions :lock + end + + def unlock_sync + sync_actions :unlock + end + def add_member(member, role = 'admin') Relation.add_member(member, self, role) end @@ -72,6 +84,22 @@ class Repository < ActiveRecord::Base protected + def sync_actions(action) + result = false + (['SRPMS'] << Arch.pluck(:name)).each do |arch| + path = "#{platform.path}/repository/#{arch}/#{name}/.sync.lock" + case action + when :lock + result ||= system 'touch', path + when :unlock + result ||= system 'rm', '-rf', path + when :check + return true if File.exist?(path) + end + end + return result + end + def detele_directory return unless platform repository_path = platform.path << '/repository' diff --git a/app/views/platforms/repositories/edit.html.haml b/app/views/platforms/repositories/edit.html.haml index 088c0fae4..f839cf9d1 100644 --- a/app/views/platforms/repositories/edit.html.haml +++ b/app/views/platforms/repositories/edit.html.haml @@ -8,7 +8,30 @@ = render "form", :f => f %br -= render 'regenerate_metadata' if can?(:regenerate_metadata, @repository) +=# render 'regenerate_metadata' if can?(:regenerate_metadata, @repository) + + +- if can?(:update, @repository) + .hr + %h3= t('layout.repositories.extra_actions') + + = link_to t('layout.repositories.regenerate_metadata'), + regenerate_metadata_platform_repository_path(@platform, @repository), + :method => :put, :confirm => t('layout.confirm'), :class => 'button' + + - if @platform.main? + - if @repository.sync_locked? + - label = t('layout.repositories.unlock_sync') + - path = unlock_sync_platform_repository_path(@platform, @repository) + - else + - label = t('layout.repositories.lock_sync') + - path = lock_sync_platform_repository_path(@platform, @repository) + + = link_to label, path, :method => :put, :confirm => t('layout.confirm'), :class => 'button' + .both + .hr + + - if @platform.main? = render "shared/members_table", diff --git a/config/locales/models/repository.en.yml b/config/locales/models/repository.en.yml index 3b5720897..4541d2ede 100644 --- a/config/locales/models/repository.en.yml +++ b/config/locales/models/repository.en.yml @@ -1,6 +1,9 @@ en: layout: repositories: + extra_actions: Extra actions + lock_sync: Lock sync with mirrors + unlock_sync: Unlock sync with mirrors add_project_to: Add project to repository edit: Settings list: List @@ -28,6 +31,10 @@ en: flash: repository: + sync_locked: Sync of repository with mirrors has been locked + sync_unlocked: Sync of repository with mirrors has been unlocked + + saved: Repository added updated: Repository updated save_error: Unable to add repository diff --git a/config/locales/models/repository.ru.yml b/config/locales/models/repository.ru.yml index 21bc8f5cd..44d6f3e12 100644 --- a/config/locales/models/repository.ru.yml +++ b/config/locales/models/repository.ru.yml @@ -1,6 +1,9 @@ ru: layout: repositories: + extra_actions: Дополнительные действия + lock_sync: Заблокировать синхронизацию с зеркалами + unlock_sync: Разблокировать синхронизацию с зеркалами add_project_to: Добавить проект к репозиторию edit: Настройки list: Список @@ -28,6 +31,9 @@ ru: flash: repository: + sync_locked: Синхронизация репозитория c зеркалами заблокирована + sync_unlocked: Синхронизация репозитория c зеркалами разблокирована + saved: Репозиторий успешно добавлен updated: Репозиторий успешно обновлен save_error: Не удалось добавить репозиторий diff --git a/config/routes.rb b/config/routes.rb index f296ebe97..de3859f66 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -174,13 +174,15 @@ Rosa::Application.routes.draw do resources :repositories do member do - get :add_project - delete :remove_project - get :projects_list - post :remove_members # fixme: change post to delete - delete :remove_member - post :add_member - put :regenerate_metadata + get :add_project + delete :remove_project + get :projects_list + post :remove_members # fixme: change post to delete + delete :remove_member + post :add_member + put :regenerate_metadata + put :lock_sync + put :unlock_sync end end resources :key_pairs, :only => [:create, :index, :destroy] From 92bc79600770c7964ac49518300d66cefd469c87 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Fri, 26 Jul 2013 18:52:43 +0400 Subject: [PATCH 02/10] #83: removed unnecessary code --- app/views/platforms/repositories/edit.html.haml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/views/platforms/repositories/edit.html.haml b/app/views/platforms/repositories/edit.html.haml index f839cf9d1..46266eafc 100644 --- a/app/views/platforms/repositories/edit.html.haml +++ b/app/views/platforms/repositories/edit.html.haml @@ -8,9 +8,6 @@ = render "form", :f => f %br -=# render 'regenerate_metadata' if can?(:regenerate_metadata, @repository) - - - if can?(:update, @repository) .hr %h3= t('layout.repositories.extra_actions') From ad46e256546e7c0702b4837f5737c9d60ce19658 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Fri, 26 Jul 2013 19:38:39 +0400 Subject: [PATCH 03/10] #83: added #start_sync and #stop_sync actions into Repository API --- .../api/v1/repositories_controller.rb | 10 ++++++++++ app/models/ability.rb | 4 ++-- app/models/repository.rb | 12 ++++++++++-- .../repositories/_regenerate_metadata.html.haml | 8 -------- config/routes.rb | 16 +++++++++------- 5 files changed, 31 insertions(+), 19 deletions(-) delete mode 100644 app/views/platforms/repositories/_regenerate_metadata.html.haml diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index 642ad7ca0..93076072b 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -33,6 +33,16 @@ class Api::V1::RepositoriesController < Api::V1::BaseController def key_pair end + def start_sync + @repository.start_sync + render :nothing => true + end + + def stop_sync + @repository.stop_sync + render :nothing => true + end + def add_project project = Project.where(:id => params[:project_id]).first if project diff --git a/app/models/ability.rb b/app/models/ability.rb index 27707e5b4..9e2e886e3 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -119,7 +119,7 @@ class Ability can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories')) {|repository| can? :show, repository.platform} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform} - can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata, :lock_sync, :unlock_sync], Repository) {|repository| local_admin? repository.platform} + can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata, :lock_sync, :unlock_sync, :start_sync, :stop_sync], Repository) {|repository| local_admin? repository.platform} can([:remove_members, :remove_member, :add_member, :signatures], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(:id => user.id)} can(:clear, Platform) {|platform| owner?(platform) && platform.personal?} @@ -164,7 +164,7 @@ class Ability # Shared cannot rights for all users (registered, admin) cannot :destroy, Platform, :platform_type => 'personal' cannot [:create, :destroy], Repository, :platform => {:platform_type => 'personal'}, :name => 'main' - cannot [:remove_members, :remove_member, :add_member, :lock_sync, :unlock_sync], Repository, :platform => {:platform_type => 'personal'} + cannot [:remove_members, :remove_member, :add_member, :lock_sync, :unlock_sync, :start_sync, :stop_sync], Repository, :platform => {:platform_type => 'personal'} cannot :clear, Platform, :platform_type => 'main' cannot :destroy, Issue diff --git a/app/models/repository.rb b/app/models/repository.rb index 918673357..88c729e83 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -57,6 +57,14 @@ class Repository < ActiveRecord::Base sync_actions :unlock end + def start_sync + sync_actions :lock, '.repo.lock' + end + + def stop_sync + sync_actions :unlock, '.repo.lock' + end + def add_member(member, role = 'admin') Relation.add_member(member, self, role) end @@ -84,10 +92,10 @@ class Repository < ActiveRecord::Base protected - def sync_actions(action) + def sync_actions(action, lock_file = '.sync.lock') result = false (['SRPMS'] << Arch.pluck(:name)).each do |arch| - path = "#{platform.path}/repository/#{arch}/#{name}/.sync.lock" + path = "#{platform.path}/repository/#{arch}/#{name}/#{lock_file}" case action when :lock result ||= system 'touch', path diff --git a/app/views/platforms/repositories/_regenerate_metadata.html.haml b/app/views/platforms/repositories/_regenerate_metadata.html.haml deleted file mode 100644 index 89bee4eb5..000000000 --- a/app/views/platforms/repositories/_regenerate_metadata.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -.hr -= form_for @repository, :url => regenerate_metadata_platform_repository_path(@platform, @repository), :html => { :class => :form, :method => :put } do |f| - .leftside= t('layout.repositories.regenerate_metadata') - .rightside - = select_tag :build_for_platform_id, options_from_collection_for_select(Platform.main, :id, :name) if @platform.personal? - = f.submit t('layout.repositories.regenerate_metadata'), :confirm => t('layout.confirm') - .hr{:style => 'padding-bottom:20px;'} -.both \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index de3859f66..ac5f5131c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -39,13 +39,15 @@ Rosa::Application.routes.draw do end resources :repositories, :only => [:show, :update, :destroy] do member { - get :projects - get :key_pair - put :add_member - delete :remove_member - put :add_project - delete :remove_project - put :signatures + get :projects + get :key_pair + put :add_member + delete :remove_member + put :add_project + delete :remove_project + put :signatures + put :start_sync + put :stop_sync } end resources :projects, :only => [:index, :show, :update, :create, :destroy] do From afb0bb40e66a1e5ef57def6d6cc72360a6a60366 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 13:50:45 +0400 Subject: [PATCH 04/10] #83: added specs for repositories_controller --- .../platforms/repositories_controller_spec.rb | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spec/controllers/platforms/repositories_controller_spec.rb b/spec/controllers/platforms/repositories_controller_spec.rb index f0568077e..da218db67 100644 --- a/spec/controllers/platforms/repositories_controller_spec.rb +++ b/spec/controllers/platforms/repositories_controller_spec.rb @@ -20,6 +20,25 @@ shared_examples_for 'user with change projects in repository rights' do @repository.projects.should_not include(@project) end + +end + +shared_examples_for 'user with rights of lock/unlock sync of repository' do + [:lock_sync, :unlock_sync].each do |action| + it "should be able to perform #{action} action" do + put action, :id => @repository.id, :platform_id => @platform.id + response.should redirect_to(edit_platform_repository_path(@platform, @repository)) + end + end +end + +shared_examples_for 'user without rights of lock/unlock sync of repository' do + [:lock_sync, :unlock_sync].each do |action| + it "should not be able to perform #{action} action" do + put action, :id => @repository.id, :platform_id => @platform.id + response.should redirect_to(redirect_path) + end + end end shared_examples_for 'user without change projects in repository rights' do @@ -133,6 +152,7 @@ end shared_examples_for 'platform admin user' do it_should_behave_like 'registered user' + it_should_behave_like 'user with rights of lock/unlock sync of repository' it 'should be able to perform new action' do get :new, :platform_id => @platform.id @@ -240,6 +260,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { new_user_session_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user without change projects in repository rights' + it_should_behave_like 'user without rights of lock/unlock sync of repository' it "should not be able to perform show action", :anonymous_access => false do get :show, :id => @repository @@ -264,6 +285,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { forbidden_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user without change projects in repository rights' + it_should_behave_like 'user without rights of lock/unlock sync of repository' end context 'for admin' do @@ -311,6 +333,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { forbidden_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user with change projects in repository rights' + it_should_behave_like 'user without rights of lock/unlock sync of repository' context 'for hidden platform' do before do @@ -322,6 +345,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { forbidden_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user with change projects in repository rights' + it_should_behave_like 'user without rights of lock/unlock sync of repository' end end From 16fdad15a5a2b46934b5a00ebe204f9d0f032278 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 14:13:15 +0400 Subject: [PATCH 05/10] abf/abf-ideas#83: added specs for Repository API --- .../api/v1/repositories_controller.rb | 4 ++-- .../api/v1/repositories_controller_spec.rb | 18 ++++++++++++++++++ .../platforms/repositories_controller_spec.rb | 1 - 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index 93076072b..649bdc2e3 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -35,12 +35,12 @@ class Api::V1::RepositoriesController < Api::V1::BaseController def start_sync @repository.start_sync - render :nothing => true + render_json_response @repository, 'Repository has been locked for sync successfully' end def stop_sync @repository.stop_sync - render :nothing => true + render_json_response @repository, 'Repository has been unlocked for sync successfully' end def add_project diff --git a/spec/controllers/api/v1/repositories_controller_spec.rb b/spec/controllers/api/v1/repositories_controller_spec.rb index 3d591343e..a3ec16153 100644 --- a/spec/controllers/api/v1/repositories_controller_spec.rb +++ b/spec/controllers/api/v1/repositories_controller_spec.rb @@ -62,6 +62,15 @@ shared_examples_for 'api repository user with writer rights' do end end + context 'api repository user with start/stop sync rights' do + [:start_sync, :stop_sync].each do |action| + it "should be able to perform #{action} action" do + put action, :id => @repository.id, :format => :json + response.should be_success + end + end + end + context 'api repository user with add_member rights' do let(:member) { FactoryGirl.create(:user) } before do @@ -179,6 +188,15 @@ shared_examples_for 'api repository user without writer rights' do end end + context 'api repository user without start/stop sync rights' do + [:start_sync, :stop_sync].each do |action| + it "should not be able to perform #{action} action" do + put action, :id => @repository.id, :format => :json + response.should_not be_success + end + end + end + context 'api repository user without add_member rights' do let(:member) { FactoryGirl.create(:user) } before do diff --git a/spec/controllers/platforms/repositories_controller_spec.rb b/spec/controllers/platforms/repositories_controller_spec.rb index da218db67..a6c66d1b8 100644 --- a/spec/controllers/platforms/repositories_controller_spec.rb +++ b/spec/controllers/platforms/repositories_controller_spec.rb @@ -20,7 +20,6 @@ shared_examples_for 'user with change projects in repository rights' do @repository.projects.should_not include(@project) end - end shared_examples_for 'user with rights of lock/unlock sync of repository' do From 6d2ca8eee41f2a4bd9f049559f3f1c3756974085 Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 14:46:49 +0400 Subject: [PATCH 06/10] abf/abf-ideas#83: added specs for Repository model --- app/models/repository.rb | 13 ++++++++++-- spec/models/repository_spec.rb | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index 88c729e83..abbeb47de 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -45,22 +45,31 @@ class Repository < ActiveRecord::Base end end + # Checks locking of sync def sync_locked? sync_actions :check end + # Uses for locking sync + # Calls from UI def lock_sync sync_actions :lock end + # Uses for unlocking sync + # Calls from UI def unlock_sync sync_actions :unlock end + # Uses for locking publishing + # Calls from API def start_sync sync_actions :lock, '.repo.lock' end + # Uses for unlocking publishing + # Calls from API def stop_sync sync_actions :unlock, '.repo.lock' end @@ -98,9 +107,9 @@ class Repository < ActiveRecord::Base path = "#{platform.path}/repository/#{arch}/#{name}/#{lock_file}" case action when :lock - result ||= system 'touch', path + result ||= FileUtils.touch(path) rescue nil when :unlock - result ||= system 'rm', '-rf', path + result ||= FileUtils.rm_f(path) when :check return true if File.exist?(path) end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 35ea72a33..2af7684d4 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -30,6 +30,44 @@ describe Repository do end + context '#sync_locked?, #lock_sync, #unlock_sync, #start_sync, #stop_sync' do + let(:repository) { FactoryGirl.create(:repository) } + let(:path) { "#{repository.platform.path}/repository/SRPMS/#{repository.name}" } + before { FileUtils.mkdir_p path } + + it 'ensures that #sync_locked? returns false if .sync.lock file does not exist' do + repository.sync_locked?.should be_false + end + + it 'ensures that #sync_locked? returns true if .sync.lock file does exist' do + FileUtils.touch "#{path}/.sync.lock" + repository.sync_locked?.should be_true + end + + it 'ensures that #lock_sync creates .sync.lock file' do + repository.lock_sync + File.exist?("#{path}/.sync.lock").should be_true + end + + it 'ensures that #unlock_sync removes .sync.lock file' do + FileUtils.touch "#{path}/.sync.lock" + repository.unlock_sync + File.exist?("#{path}/.sync.lock").should be_false + end + + it 'ensures that #start_sync creates .repo.lock file' do + repository.start_sync + File.exist?("#{path}/.repo.lock").should be_true + end + + it 'ensures that #stop_sync removes .repo.lock file' do + FileUtils.touch "#{path}/.repo.lock" + repository.stop_sync + File.exist?("#{path}/.repo.lock").should be_false + end + + end + context 'when create with same owner that platform' do before do @platform = FactoryGirl.create(:platform) From c996769a4b27a47d94a48ff6952f98e95ad0a69f Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 16:24:41 +0400 Subject: [PATCH 07/10] abf/abf-ideas#83: small refactoring according to Alexander's comments --- .../api/v1/repositories_controller.rb | 8 ++--- .../platforms/repositories_controller.rb | 17 +++++------ app/models/ability.rb | 4 +-- app/models/repository.rb | 10 +++---- .../platforms/repositories/edit.html.haml | 16 +++++----- config/locales/models/repository.en.yml | 9 +++--- config/locales/models/repository.ru.yml | 9 +++--- config/routes.rb | 7 ++--- .../api/v1/repositories_controller_spec.rb | 8 ++--- .../platforms/repositories_controller_spec.rb | 30 ++++++++----------- spec/models/repository_spec.rb | 26 ++++++++-------- 11 files changed, 71 insertions(+), 73 deletions(-) diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index 649bdc2e3..f04b30003 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -33,13 +33,13 @@ class Api::V1::RepositoriesController < Api::V1::BaseController def key_pair end - def start_sync - @repository.start_sync + def add_repo_lock_file + @repository.add_repo_lock_file render_json_response @repository, 'Repository has been locked for sync successfully' end - def stop_sync - @repository.stop_sync + def remove_repo_lock_file + @repository.remove_repo_lock_file render_json_response @repository, 'Repository has been unlocked for sync successfully' end diff --git a/app/controllers/platforms/repositories_controller.rb b/app/controllers/platforms/repositories_controller.rb index a0b7a6a7f..a1b7bfa06 100644 --- a/app/controllers/platforms/repositories_controller.rb +++ b/app/controllers/platforms/repositories_controller.rb @@ -149,15 +149,14 @@ class Platforms::RepositoriesController < Platforms::BaseController redirect_to platform_repository_path(@platform, @repository) end - def lock_sync - @repository.lock_sync - flash[:notice] = t('flash.repository.sync_locked') - redirect_to edit_platform_repository_path(@platform, @repository) - end - - def unlock_sync - @repository.unlock_sync - flash[:notice] = t('flash.repository.sync_unlocked') + def sync_lock_file + if params[:remove] + @repository.remove_sync_lock_file + flash[:notice] = t('flash.repository.sync_lock_file_removed') + else + flash[:notice] = t('flash.repository.sync_lock_file_added') + @repository.add_sync_lock_file + end redirect_to edit_platform_repository_path(@platform, @repository) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 9e2e886e3..404e063ae 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -119,7 +119,7 @@ class Ability can [:read, :projects_list, :projects], Repository, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories')) {|repository| can? :show, repository.platform} can([:read, :projects_list, :projects], Repository, read_relations_for('repositories', 'platforms')) {|repository| local_reader? repository.platform} - can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata, :lock_sync, :unlock_sync, :start_sync, :stop_sync], Repository) {|repository| local_admin? repository.platform} + can([:create, :edit, :update, :destroy, :projects_list, :projects, :add_project, :remove_project, :regenerate_metadata, :sync_lock_file, :add_repo_lock_file, :remove_repo_lock_file], Repository) {|repository| local_admin? repository.platform} can([:remove_members, :remove_member, :add_member, :signatures], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)} can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(:id => user.id)} can(:clear, Platform) {|platform| owner?(platform) && platform.personal?} @@ -164,7 +164,7 @@ class Ability # Shared cannot rights for all users (registered, admin) cannot :destroy, Platform, :platform_type => 'personal' cannot [:create, :destroy], Repository, :platform => {:platform_type => 'personal'}, :name => 'main' - cannot [:remove_members, :remove_member, :add_member, :lock_sync, :unlock_sync, :start_sync, :stop_sync], Repository, :platform => {:platform_type => 'personal'} + cannot [:remove_members, :remove_member, :add_member, :sync_lock_file, :add_repo_lock_file, :remove_repo_lock_file], Repository, :platform => {:platform_type => 'personal'} cannot :clear, Platform, :platform_type => 'main' cannot :destroy, Issue diff --git a/app/models/repository.rb b/app/models/repository.rb index abbeb47de..f3814fb1b 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -46,31 +46,31 @@ class Repository < ActiveRecord::Base end # Checks locking of sync - def sync_locked? + def sync_lock_file_exists? sync_actions :check end # Uses for locking sync # Calls from UI - def lock_sync + def add_sync_lock_file sync_actions :lock end # Uses for unlocking sync # Calls from UI - def unlock_sync + def remove_sync_lock_file sync_actions :unlock end # Uses for locking publishing # Calls from API - def start_sync + def add_repo_lock_file sync_actions :lock, '.repo.lock' end # Uses for unlocking publishing # Calls from API - def stop_sync + def remove_repo_lock_file sync_actions :unlock, '.repo.lock' end diff --git a/app/views/platforms/repositories/edit.html.haml b/app/views/platforms/repositories/edit.html.haml index 46266eafc..91d0c2eb7 100644 --- a/app/views/platforms/repositories/edit.html.haml +++ b/app/views/platforms/repositories/edit.html.haml @@ -12,19 +12,21 @@ .hr %h3= t('layout.repositories.extra_actions') - = link_to t('layout.repositories.regenerate_metadata'), + .leftlist= t('layout.repositories.regenerate_metadata') + .rightlist= link_to t('layout.repositories.regenerate_metadata'), regenerate_metadata_platform_repository_path(@platform, @repository), :method => :put, :confirm => t('layout.confirm'), :class => 'button' - if @platform.main? - - if @repository.sync_locked? - - label = t('layout.repositories.unlock_sync') - - path = unlock_sync_platform_repository_path(@platform, @repository) + .leftlist= t('layout.repositories.sync_lock_file_info') + - if @repository.sync_lock_file_exists? + - label = t('layout.repositories.remove_sync_lock_file') + - path = sync_lock_file_platform_repository_path(@platform, @repository, :remove => true) - else - - label = t('layout.repositories.lock_sync') - - path = lock_sync_platform_repository_path(@platform, @repository) + - label = t('layout.repositories.add_sync_lock_file') + - path = sync_lock_file_platform_repository_path(@platform, @repository) - = link_to label, path, :method => :put, :confirm => t('layout.confirm'), :class => 'button' + .rightlist= link_to label, path, :method => :put, :confirm => t('layout.confirm'), :class => 'button' .both .hr diff --git a/config/locales/models/repository.en.yml b/config/locales/models/repository.en.yml index 4541d2ede..5feef3825 100644 --- a/config/locales/models/repository.en.yml +++ b/config/locales/models/repository.en.yml @@ -2,8 +2,9 @@ en: layout: repositories: extra_actions: Extra actions - lock_sync: Lock sync with mirrors - unlock_sync: Unlock sync with mirrors + add_sync_lock_file: "Add '.sync.lock' file" + remove_sync_lock_file: "Remove '.sync.lock' file" + sync_lock_file_info: "Presence of '.sync.lock' file means that repository is not ready for sync with mirror" add_project_to: Add project to repository edit: Settings list: List @@ -31,8 +32,8 @@ en: flash: repository: - sync_locked: Sync of repository with mirrors has been locked - sync_unlocked: Sync of repository with mirrors has been unlocked + sync_lock_file_added: "'.sync.lock' file has been added to repository" + sync_lock_file_removed: "'.sync.lock' file has been removed from repository" saved: Repository added diff --git a/config/locales/models/repository.ru.yml b/config/locales/models/repository.ru.yml index 44d6f3e12..1042b0b51 100644 --- a/config/locales/models/repository.ru.yml +++ b/config/locales/models/repository.ru.yml @@ -2,8 +2,9 @@ ru: layout: repositories: extra_actions: Дополнительные действия - lock_sync: Заблокировать синхронизацию с зеркалами - unlock_sync: Разблокировать синхронизацию с зеркалами + add_sync_lock_file: "Добавить '.sync.lock' файл" + remove_sync_lock_file: "Удалить '.sync.lock' файл" + sync_lock_file_info: "Наличие '.sync.lock' файла означает, что репозиторий не готов для синхронизации с зеркалом" add_project_to: Добавить проект к репозиторию edit: Настройки list: Список @@ -31,8 +32,8 @@ ru: flash: repository: - sync_locked: Синхронизация репозитория c зеркалами заблокирована - sync_unlocked: Синхронизация репозитория c зеркалами разблокирована + sync_lock_file_added: "'.sync.lock' файл добавлен в репозиторий" + sync_lock_file_removed: "'.sync.lock' файл удален из репозитория" saved: Репозиторий успешно добавлен updated: Репозиторий успешно обновлен diff --git a/config/routes.rb b/config/routes.rb index ac5f5131c..5fb294376 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -46,8 +46,8 @@ Rosa::Application.routes.draw do put :add_project delete :remove_project put :signatures - put :start_sync - put :stop_sync + put :add_repo_lock_file + put :remove_repo_lock_file } end resources :projects, :only => [:index, :show, :update, :create, :destroy] do @@ -183,8 +183,7 @@ Rosa::Application.routes.draw do delete :remove_member post :add_member put :regenerate_metadata - put :lock_sync - put :unlock_sync + put :sync_lock_file end end resources :key_pairs, :only => [:create, :index, :destroy] diff --git a/spec/controllers/api/v1/repositories_controller_spec.rb b/spec/controllers/api/v1/repositories_controller_spec.rb index a3ec16153..37abe5e93 100644 --- a/spec/controllers/api/v1/repositories_controller_spec.rb +++ b/spec/controllers/api/v1/repositories_controller_spec.rb @@ -62,8 +62,8 @@ shared_examples_for 'api repository user with writer rights' do end end - context 'api repository user with start/stop sync rights' do - [:start_sync, :stop_sync].each do |action| + context 'api repository user with add/remove repo_lock_file rights' do + [:add_repo_lock_file, :remove_repo_lock_file].each do |action| it "should be able to perform #{action} action" do put action, :id => @repository.id, :format => :json response.should be_success @@ -188,8 +188,8 @@ shared_examples_for 'api repository user without writer rights' do end end - context 'api repository user without start/stop sync rights' do - [:start_sync, :stop_sync].each do |action| + context 'api repository user without add/remove repo_lock_file rights' do + [:add_repo_lock_file, :remove_repo_lock_file].each do |action| it "should not be able to perform #{action} action" do put action, :id => @repository.id, :format => :json response.should_not be_success diff --git a/spec/controllers/platforms/repositories_controller_spec.rb b/spec/controllers/platforms/repositories_controller_spec.rb index a6c66d1b8..d73536dd5 100644 --- a/spec/controllers/platforms/repositories_controller_spec.rb +++ b/spec/controllers/platforms/repositories_controller_spec.rb @@ -22,21 +22,17 @@ shared_examples_for 'user with change projects in repository rights' do end -shared_examples_for 'user with rights of lock/unlock sync of repository' do - [:lock_sync, :unlock_sync].each do |action| - it "should be able to perform #{action} action" do - put action, :id => @repository.id, :platform_id => @platform.id - response.should redirect_to(edit_platform_repository_path(@platform, @repository)) - end +shared_examples_for 'user with rights of add/remove sync_lock_file to repository' do + it 'should be able to perform sync_lock_file action' do + put :sync_lock_file, :id => @repository.id, :platform_id => @platform.id + response.should redirect_to(edit_platform_repository_path(@platform, @repository)) end end -shared_examples_for 'user without rights of lock/unlock sync of repository' do - [:lock_sync, :unlock_sync].each do |action| - it "should not be able to perform #{action} action" do - put action, :id => @repository.id, :platform_id => @platform.id - response.should redirect_to(redirect_path) - end +shared_examples_for 'user without rights of add/remove sync_lock_file to repository' do + it 'should not be able to perform #{action} action' do + put :sync_lock_file, :id => @repository.id, :platform_id => @platform.id + response.should redirect_to(redirect_path) end end @@ -151,7 +147,7 @@ end shared_examples_for 'platform admin user' do it_should_behave_like 'registered user' - it_should_behave_like 'user with rights of lock/unlock sync of repository' + it_should_behave_like 'user with rights of add/remove sync_lock_file to repository' it 'should be able to perform new action' do get :new, :platform_id => @platform.id @@ -259,7 +255,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { new_user_session_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user without change projects in repository rights' - it_should_behave_like 'user without rights of lock/unlock sync of repository' + it_should_behave_like 'user without rights of add/remove sync_lock_file to repository' it "should not be able to perform show action", :anonymous_access => false do get :show, :id => @repository @@ -284,7 +280,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { forbidden_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user without change projects in repository rights' - it_should_behave_like 'user without rights of lock/unlock sync of repository' + it_should_behave_like 'user without rights of add/remove sync_lock_file to repository' end context 'for admin' do @@ -332,7 +328,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { forbidden_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user with change projects in repository rights' - it_should_behave_like 'user without rights of lock/unlock sync of repository' + it_should_behave_like 'user without rights of add/remove sync_lock_file to repository' context 'for hidden platform' do before do @@ -344,7 +340,7 @@ describe Platforms::RepositoriesController do let(:redirect_path) { forbidden_path } it_should_behave_like 'registered user or guest' it_should_behave_like 'user with change projects in repository rights' - it_should_behave_like 'user without rights of lock/unlock sync of repository' + it_should_behave_like 'user without rights of add/remove sync_lock_file to repository' end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 2af7684d4..197df59f5 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -30,39 +30,39 @@ describe Repository do end - context '#sync_locked?, #lock_sync, #unlock_sync, #start_sync, #stop_sync' do + context '#sync_lock_file_exists?, #add_sync_lock_file, #remove_sync_lock_file, #add_repo_lock_file, #remove_repo_lock_file' do let(:repository) { FactoryGirl.create(:repository) } let(:path) { "#{repository.platform.path}/repository/SRPMS/#{repository.name}" } before { FileUtils.mkdir_p path } - it 'ensures that #sync_locked? returns false if .sync.lock file does not exist' do - repository.sync_locked?.should be_false + it 'ensures that #sync_lock_file_exists? returns false if .sync.lock file does not exist' do + repository.sync_lock_file_exists?.should be_false end - it 'ensures that #sync_locked? returns true if .sync.lock file does exist' do + it 'ensures that #sync_lock_file_exists? returns true if .sync.lock file does exist' do FileUtils.touch "#{path}/.sync.lock" - repository.sync_locked?.should be_true + repository.sync_lock_file_exists?.should be_true end - it 'ensures that #lock_sync creates .sync.lock file' do - repository.lock_sync + it 'ensures that #add_sync_lock_file creates .sync.lock file' do + repository.add_sync_lock_file File.exist?("#{path}/.sync.lock").should be_true end - it 'ensures that #unlock_sync removes .sync.lock file' do + it 'ensures that #remove_sync_lock_file removes .sync.lock file' do FileUtils.touch "#{path}/.sync.lock" - repository.unlock_sync + repository.remove_sync_lock_file File.exist?("#{path}/.sync.lock").should be_false end - it 'ensures that #start_sync creates .repo.lock file' do - repository.start_sync + it 'ensures that #add_repo_lock_file creates .repo.lock file' do + repository.add_repo_lock_file File.exist?("#{path}/.repo.lock").should be_true end - it 'ensures that #stop_sync removes .repo.lock file' do + it 'ensures that #remove_repo_lock_file removes .repo.lock file' do FileUtils.touch "#{path}/.repo.lock" - repository.stop_sync + repository.remove_repo_lock_file File.exist?("#{path}/.repo.lock").should be_false end From 31d65bfcf41467ab116dd19637974851248edcab Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 16:33:31 +0400 Subject: [PATCH 08/10] abf/abf-ideas#83: renamed #sync_actions method to #lock_file_actions, refactoring --- app/models/repository.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/app/models/repository.rb b/app/models/repository.rb index f3814fb1b..9a52e9524 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1,5 +1,6 @@ # -*- encoding : utf-8 -*- class Repository < ActiveRecord::Base + LOCK_FILE_NAMES = {:sync => '.sync.lock', :repo => '.repo.lock'} SORT = {'base' => 1, 'main' => 2, 'contrib' => 3, 'non-free' => 4, 'restricted' => 5} belongs_to :platform @@ -47,31 +48,31 @@ class Repository < ActiveRecord::Base # Checks locking of sync def sync_lock_file_exists? - sync_actions :check + lock_file_actions :check, :sync end # Uses for locking sync # Calls from UI def add_sync_lock_file - sync_actions :lock + lock_file_actions :add, :sync end # Uses for unlocking sync # Calls from UI def remove_sync_lock_file - sync_actions :unlock + lock_file_actions :remove, :sync end # Uses for locking publishing # Calls from API def add_repo_lock_file - sync_actions :lock, '.repo.lock' + lock_file_actions :add, :repo end # Uses for unlocking publishing # Calls from API def remove_repo_lock_file - sync_actions :unlock, '.repo.lock' + lock_file_actions :remove, :repo end def add_member(member, role = 'admin') @@ -101,14 +102,14 @@ class Repository < ActiveRecord::Base protected - def sync_actions(action, lock_file = '.sync.lock') + def lock_file_actions(action, lock_file) result = false (['SRPMS'] << Arch.pluck(:name)).each do |arch| - path = "#{platform.path}/repository/#{arch}/#{name}/#{lock_file}" + path = "#{platform.path}/repository/#{arch}/#{name}/#{LOCK_FILE_NAMES[lock_file]}" case action - when :lock + when :add result ||= FileUtils.touch(path) rescue nil - when :unlock + when :remove result ||= FileUtils.rm_f(path) when :check return true if File.exist?(path) From 00ffc5ece65f45179502baed8f80a388fbe3fadf Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 17:14:55 +0400 Subject: [PATCH 09/10] abf/abf-ideas#83: changed type of #remove_repo_lock_file action, updated text messages --- app/controllers/api/v1/repositories_controller.rb | 4 ++-- config/routes.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/repositories_controller.rb b/app/controllers/api/v1/repositories_controller.rb index f04b30003..a5d7a2f60 100644 --- a/app/controllers/api/v1/repositories_controller.rb +++ b/app/controllers/api/v1/repositories_controller.rb @@ -35,12 +35,12 @@ class Api::V1::RepositoriesController < Api::V1::BaseController def add_repo_lock_file @repository.add_repo_lock_file - render_json_response @repository, 'Repository has been locked for sync successfully' + render_json_response @repository, "'.repo.lock' file has been added to repository successfully" end def remove_repo_lock_file @repository.remove_repo_lock_file - render_json_response @repository, 'Repository has been unlocked for sync successfully' + render_json_response @repository, "'.repo.lock' file has been removed from repository successfully" end def add_project diff --git a/config/routes.rb b/config/routes.rb index 5fb294376..ea1cfcdb3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,7 +47,7 @@ Rosa::Application.routes.draw do delete :remove_project put :signatures put :add_repo_lock_file - put :remove_repo_lock_file + delete :remove_repo_lock_file } end resources :projects, :only => [:index, :show, :update, :create, :destroy] do From 2b04d0bcf94c923f6face80f9310acfb048baedd Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Mon, 29 Jul 2013 19:35:16 +0400 Subject: [PATCH 10/10] abf/abf-ideas#83: updated AbfWorker::BuildListsPublishTaskManager --- app/models/repository.rb | 5 +++++ lib/abf_worker/build_lists_publish_task_manager.rb | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/app/models/repository.rb b/app/models/repository.rb index 9a52e9524..3b981ac2f 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -75,6 +75,11 @@ class Repository < ActiveRecord::Base lock_file_actions :remove, :repo end + # Presence of `.repo.lock` file means that mirror is currently synchronising the repository state. + def repo_lock_file_exists? + lock_file_actions :check, :repo + end + def add_member(member, role = 'admin') Relation.add_member(member, self, role) end diff --git a/lib/abf_worker/build_lists_publish_task_manager.rb b/lib/abf_worker/build_lists_publish_task_manager.rb index 79449636f..d6eb11df0 100644 --- a/lib/abf_worker/build_lists_publish_task_manager.rb +++ b/lib/abf_worker/build_lists_publish_task_manager.rb @@ -173,6 +173,8 @@ module AbfWorker resign_repos = @redis.lrange RESIGN_REPOSITORIES, 0, -1 Repository.where(:id => (resign_repos - locked_repositories)).each do |r| + # Checks mirror sync status + next if r.repo_lock_file_exists? @redis.lrem RESIGN_REPOSITORIES, 0, r.id @redis.lpush LOCKED_REPOSITORIES, r.id @@ -274,6 +276,9 @@ module AbfWorker return false if !bl && old_packages[:sources].empty? save_to_repository = Repository.find save_to_repository_id + # Checks mirror sync status + return false if save_to_repository.repo_lock_file_exists? + save_to_platform = save_to_repository.platform build_for_platform = Platform.find build_for_platform_id platform_path = "#{save_to_platform.path}/repository" @@ -346,6 +351,8 @@ module AbfWorker regen_repos = regen_repos_and_pl.map{ |r| r.gsub(/\-[\d]*$/, '') } Repository.where(:id => regen_repos).each do |rep| + # Checks mirror sync status + next if rep.repo_lock_file_exists? regen_repos_and_pl.select{ |kind| kind =~ /^#{rep.id}\-/ }.each do |lock_str| next if locked_rep_and_pl.include?(lock_str) @redis.lrem REGENERATE_METADATA, 0, lock_str