Skip to content

Commit

Permalink
[api] split release_package into logical parts
Browse files Browse the repository at this point in the history
  • Loading branch information
coolo committed Nov 8, 2013
1 parent aee0206 commit c9ca474
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 116 deletions.
239 changes: 135 additions & 104 deletions src/api/app/helpers/maintenance_helper.rb
Expand Up @@ -338,7 +338,7 @@ def do_branch params
next unless p[:package].class == Package # only for local packages

pkg = p[:package]
if pkg.is_of_kind? 'link'
if pkg.is_link?
# is the package itself a local link ?
link = Suse::Backend.get( "/source/#{p[:package].project.name}/#{p[:package].name}/_link")
ret = ActiveXML::Node.new(link.body)
Expand Down Expand Up @@ -552,64 +552,101 @@ def release_package(sourcePackage, targetProjectName, targetPackageName,
targetProject = Project.get_by_name targetProjectName

# create package container, if missing
tpkg = nil
if Package.exists_by_project_and_name(targetProject.name, targetPackageName, follow_project_links: false)
tpkg = Package.get_by_project_and_name(targetProject.name, targetPackageName, use_source: false, follow_project_links: false)
else
tpkg = Package.new(:name => targetPackageName, :title => sourcePackage.title, :description => sourcePackage.description)
targetProject.packages << tpkg
if sourcePackage.is_of_kind? 'patchinfo'
# publish patchinfos only
tpkg.flags.create( :flag => 'publish', :status => 'enable')
end
tpkg.store
end
tpkg = create_package_container_if_missing(sourcePackage, targetPackageName, targetProject)

# get updateinfo id in case the source package comes from a maintenance project
mi = MaintenanceIncident.find_by_db_project_id( sourcePackage.db_project_id )
updateinfoId = nil
if mi
id_template = nil
# check for a definition in maintenance project
if a = mi.maintenance_db_project.find_attribute('OBS', 'MaintenanceIdTemplate')
id_template = a.values[0].value
end
# a definition in channel release project is superseeding this
if sourcePackage.is_of_kind?('channel') and a = targetProject.find_attribute('OBS', 'MaintenanceIdTemplate')
id_template = a.values[0].value
end
updateinfoId = mi.getUpdateinfoId( id_template )
end
updateinfoId = get_updateinfo_id(sourcePackage, targetProject)

# detect local links
link = nil
begin
link = sourcePackage.source_file('_link')
link = ActiveXML::Node.new(link)
rescue ActiveXML::Transport::Error
link = nil
end
if link and (link.project.nil? or link.project == sourcePackage.project.name)
release_package_relink(link, request, targetPackageName, targetProject, tpkg)
else
# copy sources
release_package_copy_sources(request, sourcePackage, targetPackageName, targetProject, updateinfoId)
tpkg.sources_changed
end

# copy binaries
copy_binaries(filterSourceRepository, sourcePackage, targetPackageName, targetProject, updateinfoId)

# create or update main package linking to incident package
unless sourcePackage.is_patchinfo?
release_package_create_main_package(request, sourcePackage, targetPackageName, targetProject, updateinfoId)
end

# publish incident if source is read protect, but release target is not. assuming it got public now.
if f=sourcePackage.project.flags.find_by_flag_and_status( 'access', 'disable' )
unless targetProject.flags.find_by_flag_and_status( 'access', 'disable' )
sourcePackage.project.flags.delete(f)
sourcePackage.project.store({:comment => 'project become public though release'})
# patchinfos stay unpublished, it is anyway too late to test them now ...
end
end
if link and ret = ActiveXML::Node.new(link) and (ret.project.nil? or ret.project == sourcePackage.project.name)
ret.delete_attribute('project') # its a local link, project name not needed
ret.set_attribute('package', ret.package.gsub(/\..*/,'') + targetPackageName.gsub(/.*\./, '.')) # adapt link target with suffix
link_xml = ret.dump_xml
answer = Suse::Backend.put "/source/#{URI.escape(targetProject.name)}/#{URI.escape(targetPackageName)}/_link?rev=repository&user=#{CGI.escape(User.current.login)}", link_xml
md5 = Digest::MD5.hexdigest(link_xml)
# commit with noservice parameneter
upload_params = {
end

def release_package_relink(link, request, targetPackageName, targetProject, tpkg)
link.delete_attribute('project') # its a local link, project name not needed
link.set_attribute('package', link.package.gsub(/\..*/, '') + targetPackageName.gsub(/.*\./, '.')) # adapt link target with suffix
link_xml = link.dump_xml
answer = Suse::Backend.put "/source/#{URI.escape(targetProject.name)}/#{URI.escape(targetPackageName)}/_link?rev=repository&user=#{CGI.escape(User.current.login)}", link_xml
md5 = Digest::MD5.hexdigest(link_xml)
# commit with noservice parameneter
upload_params = {
:user => User.current.login,
:cmd => 'commitfilelist',
:noservice => '1',
:comment => "Set link to #{targetPackageName} via maintenance_release request",
}
upload_params[:requestid] = request.id if request
upload_path = "/source/#{URI.escape(targetProject.name)}/#{URI.escape(targetPackageName)}"
upload_path << Suse::Backend.build_query_from_hash(upload_params, [:user, :comment, :cmd, :noservice, :requestid])
answer = Suse::Backend.post upload_path, "<directory> <entry name=\"_link\" md5=\"#{md5}\" /> </directory>"
tpkg.sources_changed(answer)
}
upload_params[:requestid] = request.id if request
upload_path = "/source/#{URI.escape(targetProject.name)}/#{URI.escape(targetPackageName)}"
upload_path << Suse::Backend.build_query_from_hash(upload_params, [:user, :comment, :cmd, :noservice, :requestid])
answer = Suse::Backend.post upload_path, "<directory> <entry name=\"_link\" md5=\"#{md5}\" /> </directory>"
tpkg.sources_changed(answer)
end

def release_package_create_main_package(request, sourcePackage, targetPackageName, targetProject, updateinfoId)
basePackageName = targetPackageName.gsub(/\.[^\.]*$/, '')

# only if package does not contain a _patchinfo file
lpkg = nil
if Package.exists_by_project_and_name(targetProject.name, basePackageName, follow_project_links: false)
lpkg = Package.get_by_project_and_name(targetProject.name, basePackageName, use_source: false, follow_project_links: false)
else
# copy sources
# backend copy of current sources as full copy
# that means the xsrcmd5 is different, but we keep the incident project anyway.
cp_params = {
lpkg = Package.new(:name => basePackageName, :title => sourcePackage.title, :description => sourcePackage.description)
targetProject.packages << lpkg
lpkg.store
end
upload_params = {
:user => User.current.login,
:rev => 'repository',
:comment => "Set link to #{targetPackageName} via maintenance_release request",
}
upload_params[:comment] += ", for updateinfo ID #{updateinfoId}" if updateinfoId
upload_path = "/source/#{URI.escape(targetProject.name)}/#{URI.escape(basePackageName)}/_link"
upload_path << Suse::Backend.build_query_from_hash(upload_params, [:user, :rev])
link = "<link package='#{targetPackageName}' cicount='copy' />\n"
md5 = Digest::MD5.hexdigest(link)
answer = Suse::Backend.put upload_path, link
# commit
upload_params[:cmd] = 'commitfilelist'
upload_params[:noservice] = '1'
upload_params[:requestid] = request.id if request
upload_path = "/source/#{URI.escape(targetProject.name)}/#{URI.escape(basePackageName)}"
upload_path << Suse::Backend.build_query_from_hash(upload_params, [:user, :comment, :cmd, :noservice, :requestid])
answer = Suse::Backend.post upload_path, "<directory> <entry name=\"_link\" md5=\"#{md5}\" /> </directory>"
lpkg.sources_changed(answer)
end

def release_package_copy_sources(request, sourcePackage, targetPackageName, targetProject, updateinfoId)
# backend copy of current sources as full copy
# that means the xsrcmd5 is different, but we keep the incident project anyway.
cp_params = {
:cmd => 'copy',
:user => User.current.login,
:oproject => sourcePackage.project.name,
Expand All @@ -618,34 +655,22 @@ def release_package(sourcePackage, targetProjectName, targetPackageName,
:expand => '1',
:withvrev => '1',
:noservice => '1',
}
cp_params[:comment] += ", setting updateinfo to #{updateinfoId}" if updateinfoId
cp_params[:requestid] = request.id if request
cp_path = "/source/#{CGI.escape(targetProject.name)}/#{CGI.escape(targetPackageName)}"
cp_path << Suse::Backend.build_query_from_hash(cp_params, [:cmd, :user, :oproject, :opackage, :comment, :requestid, :expand, :withvrev, :noservice])
Suse::Backend.post cp_path, nil
tpkg.sources_changed
end
}
cp_params[:comment] += ", setting updateinfo to #{updateinfoId}" if updateinfoId
cp_params[:requestid] = request.id if request
cp_path = "/source/#{CGI.escape(targetProject.name)}/#{CGI.escape(targetPackageName)}"
cp_path << Suse::Backend.build_query_from_hash(cp_params, [:cmd, :user, :oproject, :opackage, :comment, :requestid, :expand, :withvrev, :noservice])
Suse::Backend.post cp_path, nil
end

# copy binaries
def copy_binaries(filterSourceRepository, sourcePackage, targetPackageName, targetProject, updateinfoId)
sourcePackage.project.repositories.each do |sourceRepo|
next if filterSourceRepository and filterSourceRepository != sourceRepo
sourceRepo.release_targets.each do |releasetarget|
#FIXME2.5: filter given release and/or target repos here
sourceRepo.architectures.each do |arch|
if releasetarget.target_repository.project == targetProject
cp_params = {
:cmd => 'copy',
:oproject => sourcePackage.project.name,
:opackage => sourcePackage.name,
:orepository => sourceRepo.name,
:user => User.current.login,
:resign => '1',
}
cp_params[:setupdateinfoid] = updateinfoId if updateinfoId
cp_path = "/build/#{CGI.escape(releasetarget.target_repository.project.name)}/#{URI.escape(releasetarget.target_repository.name)}/#{URI.escape(arch.name)}/#{URI.escape(targetPackageName)}"
cp_path << Suse::Backend.build_query_from_hash(cp_params, [:cmd, :oproject, :opackage, :orepository, :setupdateinfoid, :resign])
Suse::Backend.post cp_path, nil
copy_single_binary(arch, releasetarget, sourcePackage, sourceRepo, targetPackageName, updateinfoId)
end
end
# remove maintenance release trigger in source
Expand All @@ -656,49 +681,55 @@ def release_package(sourcePackage, targetProjectName, targetPackageName,
end
end
end
end

# create or update main package linking to incident package
unless sourcePackage.is_of_kind? 'patchinfo'
basePackageName = targetPackageName.gsub(/\.[^\.]*$/, '')
def copy_single_binary(arch, releasetarget, sourcePackage, sourceRepo, targetPackageName, updateinfoId)
cp_params = {
:cmd => 'copy',
:oproject => sourcePackage.project.name,
:opackage => sourcePackage.name,
:orepository => sourceRepo.name,
:user => User.current.login,
:resign => '1',
}
cp_params[:setupdateinfoid] = updateinfoId if updateinfoId
cp_path = "/build/#{CGI.escape(releasetarget.target_repository.project.name)}/#{URI.escape(releasetarget.target_repository.name)}/#{URI.escape(arch.name)}/#{URI.escape(targetPackageName)}"
cp_path << Suse::Backend.build_query_from_hash(cp_params, [:cmd, :oproject, :opackage, :orepository, :setupdateinfoid, :resign])
Suse::Backend.post cp_path, nil
end

# only if package does not contain a _patchinfo file
lpkg = nil
if Package.exists_by_project_and_name(targetProject.name, basePackageName, follow_project_links: false)
lpkg = Package.get_by_project_and_name(targetProject.name, basePackageName, use_source: false, follow_project_links: false)
else
lpkg = Package.new(:name => basePackageName, :title => sourcePackage.title, :description => sourcePackage.description)
targetProject.packages << lpkg
lpkg.store
def get_updateinfo_id(sourcePackage, targetProject)
mi = MaintenanceIncident.find_by_db_project_id(sourcePackage.db_project_id)
updateinfoId = nil
if mi
id_template = nil
# check for a definition in maintenance project
if a = mi.maintenance_db_project.find_attribute('OBS', 'MaintenanceIdTemplate')
id_template = a.values[0].value
end
upload_params = {
:user => User.current.login,
:rev => 'repository',
:comment => "Set link to #{targetPackageName} via maintenance_release request",
}
upload_params[:comment] += ", for updateinfo ID #{updateinfoId}" if updateinfoId
upload_path = "/source/#{URI.escape(targetProject.name)}/#{URI.escape(basePackageName)}/_link"
upload_path << Suse::Backend.build_query_from_hash(upload_params, [:user, :rev])
link = "<link package='#{targetPackageName}' cicount='copy' />\n"
md5 = Digest::MD5.hexdigest(link)
answer = Suse::Backend.put upload_path, link
# commit
upload_params[:cmd] = 'commitfilelist'
upload_params[:noservice] = '1'
upload_params[:requestid] = request.id if request
upload_path = "/source/#{URI.escape(targetProject.name)}/#{URI.escape(basePackageName)}"
upload_path << Suse::Backend.build_query_from_hash(upload_params, [:user, :comment, :cmd, :noservice, :requestid])
answer = Suse::Backend.post upload_path, "<directory> <entry name=\"_link\" md5=\"#{md5}\" /> </directory>"
lpkg.sources_changed(answer)
# a definition in channel release project is superseeding this
if sourcePackage.is_channel? and a = targetProject.find_attribute('OBS', 'MaintenanceIdTemplate')
id_template = a.values[0].value
end
updateinfoId = mi.getUpdateinfoId(id_template)
end
updateinfoId
end

# publish incident if source is read protect, but release target is not. assuming it got public now.
if f=sourcePackage.project.flags.find_by_flag_and_status( 'access', 'disable' )
unless targetProject.flags.find_by_flag_and_status( 'access', 'disable' )
sourcePackage.project.flags.delete(f)
sourcePackage.project.store({:comment => 'project become public though release'})
# patchinfos stay unpublished, it is anyway too late to test them now ...
def create_package_container_if_missing(sourcePackage, targetPackageName, targetProject)
tpkg = nil
if Package.exists_by_project_and_name(targetProject.name, targetPackageName, follow_project_links: false)
tpkg = Package.get_by_project_and_name(targetProject.name, targetPackageName, use_source: false, follow_project_links: false)
else
tpkg = Package.new(:name => targetPackageName, :title => sourcePackage.title, :description => sourcePackage.description)
targetProject.packages << tpkg
if sourcePackage.is_patchinfo?
# publish patchinfos only
tpkg.flags.create(:flag => 'publish', :status => 'enable')
end
tpkg.store
end
tpkg
end

end
4 changes: 2 additions & 2 deletions src/api/app/models/bs_request_action.rb
Expand Up @@ -751,7 +751,7 @@ def create_expand_package(packages, opts = {})
end
newAction.source_rev = rev if rev
if self.is_maintenance_release?
if pkg.is_of_kind? 'channel'
if pkg.is_channel?
pkg.channels.each do |channel|
# no action if channel has no targets defined, the single release action
# will move binaries and sources to the right place in that case
Expand Down Expand Up @@ -800,7 +800,7 @@ def create_expand_package(packages, opts = {})
newTargets.uniq!
newPackages.each do |pkg|
releaseTargets=nil
if pkg.is_of_kind? 'patchinfo'
if pkg.is_patchinfo?
releaseTargets = Patchinfo.new.fetch_release_targets(pkg)
end
newTargets.each do |p|
Expand Down
4 changes: 2 additions & 2 deletions src/api/app/models/bs_request_action_maintenance_incident.rb
Expand Up @@ -17,7 +17,7 @@ class NoMaintenanceReleaseTarget < APIException
end

def get_releaseproject(pkg, tprj)
return nil if pkg.is_of_kind? 'patchinfo'
return nil if pkg.is_patchinfo?
releaseproject = nil
if self.target_releaseproject
releaseproject = Project.get_by_name self.target_releaseproject
Expand Down Expand Up @@ -62,7 +62,7 @@ def merge_into_maintenance_incident(incidentProject, base, releaseproject=nil, r
next
end
# patchinfos are handled as new packages
if pkg.is_of_kind? 'patchinfo'
if pkg.is_patchinfo?
if Package.exists_by_project_and_name(incidentProject.name, pkg.name, follow_project_links: false)
new_pkg = Package.get_by_project_and_name(incidentProject.name, pkg.name, use_source: false, follow_project_links: false)
else
Expand Down
24 changes: 20 additions & 4 deletions src/api/app/models/package.rb
Expand Up @@ -371,14 +371,30 @@ def private_set_package_kind(dir)

end

def is_patchinfo?
is_of_kind? :patchinfo
end

def is_link?
is_of_kind? :link
end

def is_channel?
is_of_kind? :channel
end

def is_product?
is_of_kind? :channel
end

def is_of_kind? kind
update_if_dirty
self.package_kinds.where(kind: kind).exists?
end

def update_issue_list
current_issues = []
if self.is_of_kind? 'patchinfo'
if self.is_patchinfo?
xml = Patchinfo.new.read_patchinfo_xmlhash(self)
xml.elements('issue') do |i|
begin
Expand Down Expand Up @@ -440,7 +456,7 @@ def find_changed_issues
end

# issues introduced by local changes
return issue_change unless self.is_of_kind? 'link'
return issue_change unless self.is_link?
query = { cmd: :linkdiff, onlyissues: 1, linkrev: :base, view: :xml }
parse_issues_xml(query) do |issue, state|
issue_change[issue] = state
Expand All @@ -452,7 +468,7 @@ def find_changed_issues
def update_channel_list
Channel.transaction do
self.channels.destroy_all
if self.is_of_kind? 'channel'
if self.is_channel?
xml = Suse::Backend.get(self.source_path('_channel'))
channel = self.channels.create
channel.update_from_xml(xml.body.to_s)
Expand All @@ -461,7 +477,7 @@ def update_channel_list
end

def update_product_list
return unless self.is_of_kind? 'product'
return unless self.is_product?
Product.transaction do
begin
xml = Xmlhash.parse(Suse::Backend.get(self.source_path(nil, view: :products)).body)
Expand Down

0 comments on commit c9ca474

Please sign in to comment.