diff --git a/docs/api/api/api.txt b/docs/api/api/api.txt index 3583bf2ac92..b5623f26aa8 100644 --- a/docs/api/api/api.txt +++ b/docs/api/api/api.txt @@ -572,6 +572,9 @@ POST /source//?cmd=release Parameters: comment: description for the history repository: limit the release to the specified repository + target_repository: specify the target repository name (together with target_project) + target_project: overwrites the target definition from project meta + (repository and target_repository parameter required as well) XmlResult: status diff --git a/src/api/app/controllers/source_controller.rb b/src/api/app/controllers/source_controller.rb index 82a3ab5c18d..da074ff6a78 100644 --- a/src/api/app/controllers/source_controller.rb +++ b/src/api/app/controllers/source_controller.rb @@ -309,7 +309,7 @@ def require_package @deleted_package = params.has_key? :deleted # FIXME: for OBS 3, api of branch and copy calls have target and source in the opossite place - if params[:cmd] == 'branch' + if ['branch', 'release'].include? params[:cmd] @target_package_name = params[:package] @target_project_name = params[:target_project] # might be nil @target_package_name = params[:target_package] if params[:target_package] @@ -356,10 +356,9 @@ def package_command # Check for existens/access of origin package when specified @spkg = nil Project.get_by_name origin_project_name if origin_project_name - if origin_package_name && !%w(_project _pattern).include?(origin_package_name) && !(params[:missingok] && @command == 'branch') - @spkg = Package.get_by_project_and_name(origin_project_name, origin_package_name) if origin_package_name && !%w(_project _pattern).include?(origin_package_name) + if origin_package_name && !%w(_project _pattern).include?(origin_package_name) && !(params[:missingok] && [ 'branch', 'release' ].include?(@command)) + @spkg = Package.get_by_project_and_name(origin_project_name, origin_package_name) end - unless Package_creating_commands.include? @command and not Project.exists_by_name(@target_project_name) # even when we can create the package, an existing instance must be checked if permissions are right @project = Project.get_by_name @target_project_name @@ -374,7 +373,7 @@ def package_command Source_untouched_commands = %w(branch diff linkdiff servicediff showlinked rebuild wipe remove_flag set_flag getprojectservices) # list of cammands which create the target package - Package_creating_commands = %w(branch copy undelete) + Package_creating_commands = %w(branch release copy undelete) # list of commands which are allowed even when the project has the package only via a project link Read_commands = %w(branch diff linkdiff servicediff showlinked getprojectservices release) @@ -1522,22 +1521,47 @@ def reparse_backend_package(spackage, sproject) # POST /source//?cmd=release def package_command_release - spkg = Package.get_by_project_and_name(params[:project], params[:package]) - - verify_repos_match!(spkg.project) - pkg = Package.get_by_project_and_name params[:project], params[:package], use_source: true, follow_project_links: false - pkg.project.repositories.each do |repo| - next if params[:repository] and params[:repository] != repo.name - repo.release_targets.each do |releasetarget| - # find md5sum and release source and binaries - release_package(pkg, releasetarget.target_repository.project.name, pkg.name, repo, nil, params[:setrelease], true) + + # specified target + if params[:target_project] + # we do not create it ourself + Project.get_by_name(params[:target_project]) + _package_command_release_manual_target(pkg) + else + spkg = Package.get_by_project_and_name(params[:project], params[:package]) + verify_repos_match!(spkg.project) + + # loop via all defined targets + pkg.project.repositories.each do |repo| + next if params[:repository] and params[:repository] != repo.name + repo.release_targets.each do |releasetarget| + # find md5sum and release source and binaries + release_package(pkg, releasetarget.target_repository.project.name, pkg.name, repo, nil, params[:setrelease], true) + end end end render_ok end + def _package_command_release_manual_target(pkg) + verify_can_modify_target! + + if params[:target_repository].blank? or params[:repository].blank? + raise MissingParameterError.new 'release action with specified target project needs also "repository" and "target_repository" parameter' + end + targetrepo=Repository.find_by_project_and_repo_name(@target_project_name, params[:target_repository]) + raise UnknownRepository.new "Repository does not exist #{params[:target_repository]}" unless targetrepo + + repo=pkg.project.repositories.where(name: params[:repository]) + raise UnknownRepository.new "Repository does not exist #{params[:repository]}" unless repo.count > 0 + repo=repo.first + + release_package(pkg, targetrepo.project.name, pkg.name, repo, nil, params[:setrelease], true) + end + private :_package_command_release_manual_target + # POST /source//?cmd=runservice def package_command_runservice diff --git a/src/api/test/functional/source_controller_test.rb b/src/api/test/functional/source_controller_test.rb index 5287b4d83fa..a5c5e510b3e 100644 --- a/src/api/test/functional/source_controller_test.rb +++ b/src/api/test/functional/source_controller_test.rb @@ -2073,11 +2073,29 @@ def test_release_project assert_response :success # this user is not allowed - post '/source/home:Iggy?cmd=release', nil + post '/source/home:Iggy/TestPack?cmd=release', nil assert_response 403 assert_xml_tag :tag => 'status', :attributes => { :code => 'cmd_execution_no_permission' } - # release for real + # but he can release it to own space + post '/source/home:Iggy/TestPack?cmd=release&target_project=home:Iggy', nil + assert_response 400 + assert_xml_tag :tag => 'status', :attributes => { :code => 'missing_parameter' } + + post '/source/home:Iggy/TestPack?cmd=release&target_project=home:Iggy:TEST&repository=10.2&target_repository=10.2', nil + assert_response 404 + assert_xml_tag :tag => 'status', :attributes => { :code => 'unknown_project' } + # create project + doc.root.attributes['name'] = "home:Iggy:TEST" + put '/source/home:Iggy:TEST/_meta', doc.to_s + assert_response :success + # but now it works for real + post '/source/home:Iggy/TestPack?cmd=release&target_project=home:Iggy:TEST&repository=10.2&target_repository=10.2', nil + assert_response :success + delete '/source/home:Iggy:TEST' + assert_response :success + + # release entire project as well to default target login_adrian post '/source/home:Iggy?cmd=release', nil assert_response :success