aboutsummaryrefslogtreecommitdiffstats
path: root/modules/buildsystem/templates/cleaner.rb
diff options
context:
space:
mode:
Diffstat (limited to 'modules/buildsystem/templates/cleaner.rb')
-rwxr-xr-xmodules/buildsystem/templates/cleaner.rb301
1 files changed, 211 insertions, 90 deletions
diff --git a/modules/buildsystem/templates/cleaner.rb b/modules/buildsystem/templates/cleaner.rb
index 338d66ba..fa0d08ca 100755
--- a/modules/buildsystem/templates/cleaner.rb
+++ b/modules/buildsystem/templates/cleaner.rb
@@ -1,114 +1,235 @@
#!/usr/bin/ruby
def usage
- puts "Usage: #{$0} [options]"
- puts "Moves obsolete packages"
- puts
- puts "-h, --help show help"
- puts "-m, --media <path> path to the binary media"
- puts "-s, --src <path> path to the associated src media"
- puts "-d, --destination <path> path to the old packages storage"
+ puts "Usage: #{$0} [options]"
+ puts "Moves obsolete packages"
+ puts
+ puts "-h, --help show this help"
+ puts "-a, --archs <arch1>,<arch2>,... list of architectures to clean"
+ puts "-a, --auto do not ask confirmation"
+ puts "-p, --base <path> base path to the repository"
+ puts "-m, --media <media1>,<media2>,... list of media to clean (default: core/release,tainted/release,nonfree/release)"
+ puts "-d, --destination <path> path to the old packages storage"
+ puts "-v, --version <version> version to clean (default: cauldron)"
end
require 'fileutils'
require 'getoptlong'
require 'readline'
-opts = GetoptLong.new(
- [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
- [ '--archs', '-a', GetoptLong::REQUIRED_ARGUMENT ],
- [ '--base', '-p', GetoptLong::REQUIRED_ARGUMENT ],
- [ '--media', '-m', GetoptLong::REQUIRED_ARGUMENT ],
- [ '--bmedia', '-b', GetoptLong::REQUIRED_ARGUMENT ],
- [ '--smedia', '-s', GetoptLong::REQUIRED_ARGUMENT ],
- [ '--destination', '-d', GetoptLong::REQUIRED_ARGUMENT ],
- [ '--version', '-v', GetoptLong::REQUIRED_ARGUMENT ]
-)
-
-base_path = "<%= repository_root %>/distrib"
-archs = [ "i586", "x86_64" ]
-media = "core/release"
-old_path = "<%= packages_archivedir %>"
-version = "cauldron"
-
-opts.each do |opt, arg|
- case opt
- when '--help'
- usage
- exit 0
- when '--bmedia'
- bin_path = arg.split(",")
- when '--smedia'
- src_path = arg
- when '--destination'
- old_path = arg
- when '--media'
- media = arg
- when '--archs'
- archs = arg.split(",")
- when '--base'
- base_path = arg
- when '--version'
- version = arg
- end
-end
+def process
+ opts = GetoptLong.new(
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
+ [ '--archs', '-a', GetoptLong::REQUIRED_ARGUMENT ],
+ [ '--auto', '-A', GetoptLong::NO_ARGUMENT ],
+ [ '--base', '-p', GetoptLong::REQUIRED_ARGUMENT ],
+ [ '--media', '-m', GetoptLong::REQUIRED_ARGUMENT ],
+ [ '--destination', '-d', GetoptLong::REQUIRED_ARGUMENT ],
+ [ '--version', '-v', GetoptLong::REQUIRED_ARGUMENT ],
+ [ '--lockfile', '-l', GetoptLong::REQUIRED_ARGUMENT ],
+ )
+
+ base_path = "<%= scope.lookupvar('buildsystem::var::repository::bootstrap_root') %>/distrib"
+ archs = [ "x86_64", "i686", "aarch64", "armv7hl" ]
+ medias = ["core/release", "tainted/release", "nonfree/release"]
+ old_path = "<%= scope.lookupvar('buildsystem::var::youri::packages_archivedir') %>"
+ version = "cauldron"
+ auto = false
+ lockfile = nil
+
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ usage
+ exit 0
+ when '--destination'
+ old_path = arg
+ when '--media'
+ medias = arg.split(",")
+ when '--archs'
+ archs = arg.split(",")
+ when '--auto'
+ auto = true
+ when '--base'
+ base_path = arg
+ when '--version'
+ version = arg
+ when '--lockfile'
+ lockfile = arg
+ end
+ end
+
+ take_upload_lock(lockfile) if lockfile
-bin_path ||= archs.map{|arch| "#{base_path}/#{version}/#{arch}/media/#{media}" }
-src_path ||= "#{base_path}/#{version}/SRPMS/#{media}"
-debug_path = bin_path.map{|path| path.sub("/media/", "/media/debug/")}
+ medias.each{|media|
+ src_path = "#{base_path}/#{version}/SRPMS/#{media}"
-$used_srcs = {}
-$srcs = {}
+ $used_srcs = {}
+ $old_srcs = {}
+ $srcs = {}
+ $srcages = {}
+ $noarch = {}
-# Get a list of all src.rpm
+ # Get a list of all src.rpm and their build time
+ `urpmf --synthesis "#{src_path}/media_info/synthesis.hdlist.cz" --qf '%filename:%buildtime:%buildarchs' "."`.each_line{|l|
+ l2 = l.split(':')
+ filename = l2[0]
+ buildtime = l2[1].to_i
+ buildarch = l2[2].rstrip
+ name = name_from_filename(filename)
+ if $srcages[name] then
+ if buildtime < $srcages[name][1] then
+ # This src.rpm is older, ignore it and store it in the list to be deleted
+ $old_srcs[filename] = true
+ next
+ else
+ # This src.rpm has an older version, ignore that version and store it in the list to be deleted
+ old_filename = $srcages[name][0]
+ $old_srcs[old_filename] = true
+ $srcs.delete(old_filename)
+ end
+ end
+ $srcages[name] = [ filename, buildtime ]
+ $srcs[filename] = true
+ $noarch[name] = true if buildarch == 'noarch'
+ }
+ archs.each{|arch|
+ bin_path = "#{base_path}/#{version}/#{arch}/media/#{media}"
+ debug_path = bin_path.sub("/media/", "/media/debug/")
+ old_packages = check_binaries(arch, $srcs, $srcages, src_path, bin_path, $used_srcs)
+ old_debug_packages = check_binaries(arch, $srcs, {}, src_path, debug_path, nil)
+ move_packages(bin_path, old_path, old_packages, auto)
+ move_packages(debug_path, old_path, old_debug_packages, auto)
+ }
+ $used_srcs.keys.each{|s| $srcs.delete(s)}
-`urpmf --synthesis "#{src_path}/media_info/synthesis.hdlist.cz" --qf '%filename' "."`.each_line{|l|
- $srcs[l.rstrip] = true
-}
+ move_packages(src_path, old_path, $srcs.keys + $old_srcs.keys, auto)
+ }
+end
+
+def take_upload_lock(path)
+ start_time = Time.new
+ has_lock = false
+ at_exit {
+ if File.exists?(path)
+ if File.readlines(path)[0].to_i == Process.pid
+ File.delete(path)
+ end
+ end
+ }
+ until has_lock
+ while File.exists?(path)
+ if Time.new - start_time > 2*3600.0
+ puts "Could not acquire upload lock for more than 2h, giving up"
+ end
+ sleep(5)
+ end
+ File.write(path, Process.pid)
+ if File.readlines(path)[0].to_i == Process.pid
+ has_lock = true
+ end
+ end
+end
+
+def move_packages(src, dst, list, auto)
+ list.reject!{|f| !File.exist?(src + "/" + f)}
+ return if list.empty?
+ list.each{|b|
+ puts b
+ }
+ puts "The #{list.length} listed packages will be moved from #{src} to #{dst}."
+ line = Readline::readline('Are you sure [Yn]? ') unless auto
+ if auto || line =~ /^y?$/i
+ list.each{|s|
+ oldfile = src + "/" + s
+ newfile = dst + "/" + s
+ next unless File.exist?(oldfile)
+ if (File.exist?(newfile))
+ File.unlink(oldfile)
+ else
+ FileUtils.mv(oldfile, newfile)
+ end
+ }
+ end
+end
# For each binary media:
# - Check if we have the src.rpm (else the binary package is obsolete)
+# * If we don't have the src.rpm, check if we have a newer version
+# - If there is a new version:
+# * check if this architecture has packages from it to avoid deleting armv7hl packages before the new one get rebuilt
+# * check if the new version is old enough to allow rebuilding everything (7d?)
# - Mark used src.rpm (if one is never marked, the src.rpm is obsolete)
-def move_packages(src, dst, list)
- list.reject!{|f| !File.exist?(src + "/" + f)}
- return if list.empty?
- list.each{|b|
- puts b
- }
- puts "The #{list.length} listed packages will be moved from #{src} to #{dst}."
- line = Readline::readline('Are you sure [Yn]? ')
- if (line =~ /^y?$/i)
- list.each{|s|
- oldfile = src + "/" + s
- newfile = dst + "/" + s
- next unless File.exist?(oldfile)
- if (File.exist?(newfile))
- File.unlink(oldfile)
- else
- FileUtils.mv(oldfile, newfile)
- end
- }
- end
+def packages(path)
+ `urpmf --synthesis "#{path}/media_info/synthesis.hdlist.cz" --qf '%sourcerpm:%filename:%buildtime' ":"`.each_line{|l|
+ l2 = l.split(':')
+ sourcerpm = l2[0]
+ filename = l2[1]
+ buildtime = l2[2].to_i
+ yield(sourcerpm, filename, buildtime)
+ }
end
-def check_binaries(path_list, old_path, mark_used)
- path_list.each{|bm|
- old_binaries = []
- `urpmf --synthesis "#{bm}/media_info/synthesis.hdlist.cz" --qf '%sourcerpm:%filename' ":"`.each_line{|l|
- l2 = l.split(':')
- src = l2[0]
- filename = l2[1].rstrip
- old_binaries << filename unless $srcs[src]
- $used_srcs[src] = true if mark_used
- }
- move_packages(bm, old_path, old_binaries)
- }
+def name_from_filename(filename)
+ filename.sub(/-[^-]*-[^-]*$/, '')
end
-check_binaries(bin_path, old_path, true)
-check_binaries(debug_path, old_path, false)
+def arch_wanted(src, arch)
+ exclusive_arch = `rpmquery -p #{src} --qf '[%{EXCLUSIVEARCH} ]'`.rstrip
+ if exclusive_arch != "" then
+ if !exclusive_arch.split(/ /).include?(arch) then
+ return false
+ end
+ end
+ exclude_arch = `rpmquery -p #{src} --qf '[%{EXCLUDEARCH} ]'`.rstrip
+ if exclude_arch != "" then
+ if exclude_arch.split(/ /).include?(arch) then
+ return false
+ end
+ end
+
+ return true
+end
-$used_srcs.keys.each{|s| $srcs.delete(s)}
+def check_binaries(arch, srcs, srcages, src_path, path, used_srcs)
+ used_here_srcs = {}
+ all_versions = {}
+ packages(path) {|src, filename, buildtime|
+ used_srcs[src] = true if used_srcs != nil
+ if filename =~ /noarch.rpm$/ then
+ # We need to mark the src.rpm present on this arch only for full noarch packages
+ used_here_srcs[src] = true if $noarch[name_from_filename(src)]
+ else
+ used_here_srcs[src] = true
+ end
+ name = name_from_filename(filename)
+ if all_versions[name] then
+ all_versions[name] << src
+ else
+ all_versions[name] = [src]
+ end
+ }
+ old_binaries = []
+ packages(path) {|src, filename, buildtime|
+ if ! srcs[src] then
+ srcname = name_from_filename(src)
+ if srcages[srcname] then
+ # The src.rpm is gone but there is a different version of it
+ latestsrc = srcages[srcname][0]
+ # Only delete old binaries after 7d or if there is a new version
+ name = name_from_filename(filename)
+ next unless (srcages[srcname][1] < Time.now.to_i - 24*60*60*7 || all_versions[name].include?(latestsrc))
+ # Do not delete if the new version of the package hasn't been built for this arch yet
+ # but still delete it if it is no longer expected to be built.
+ next unless (used_here_srcs[latestsrc] || !arch_wanted("#{src_path}/#{latestsrc}", arch))
+ end
+ old_binaries << filename
+ end
+ }
+ old_binaries
+end
-move_packages(src_path, old_path, $srcs.keys)
+if __FILE__ == $0 then
+ process
+end