Skip to content

Commit 2723538

Browse files
committed
Add delete_batch
1 parent fe41805 commit 2723538

1 file changed

Lines changed: 143 additions & 0 deletions

File tree

lib/deb/s3/cli.rb

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,149 @@ def delete(package)
562562
end
563563

564564

565+
desc "delete-batch PACKAGES...",
566+
"Batch delete many packages at once. Supply each as name or name=version."
567+
568+
option :arch,
569+
:type => :string,
570+
:aliases => "-a",
571+
:desc => "The architecture of the packages to remove."
572+
573+
option :lock,
574+
:default => false,
575+
:type => :boolean,
576+
:aliases => "-l",
577+
:desc => "Whether to lock the repository during updates."
578+
579+
option :do_package_remove,
580+
:default => false,
581+
:type => :boolean,
582+
:desc => "Whether to delete the underlying .deb files from S3."
583+
584+
def delete_batch(*pkg_args)
585+
if pkg_args.nil? || pkg_args.empty?
586+
error("You must specify at least one package, like: pkgA=1.2.3 pkgB pkgC=5.0.0")
587+
end
588+
589+
arch = options[:arch]
590+
if arch.nil?
591+
error("You must specify --arch for batch deletion.")
592+
end
593+
594+
configure_s3_client
595+
596+
# Parse package specifications
597+
# { "pkgA" => ["1.2.3"], "pkgB" => nil (delete all versions), ... }
598+
package_map = {}
599+
pkg_args.each do |arg|
600+
if arg.include?("=")
601+
name, version = arg.split("=", 2)
602+
package_map[name] ||= []
603+
package_map[name] << version
604+
else
605+
package_map[arg] = nil
606+
end
607+
end
608+
609+
begin
610+
if options[:lock]
611+
log("Checking for existing lock file")
612+
log("Locking repository for updates")
613+
Deb::S3::Lock.lock(options[:codename], component, arch, options[:cache_control])
614+
@lock_acquired = true
615+
end
616+
617+
log("Retrieving existing manifests")
618+
release = Deb::S3::Release.retrieve(options[:codename], options[:origin], options[:suite])
619+
620+
# Handle arch == all
621+
target_arches =
622+
if arch == "all"
623+
release.architectures
624+
else
625+
[arch]
626+
end
627+
628+
total_deleted = 0
629+
630+
target_arches.each do |ar|
631+
manifest = Deb::S3::Manifest.retrieve(
632+
options[:codename],
633+
component,
634+
ar,
635+
options[:cache_control],
636+
false,
637+
options[:skip_package_upload],
638+
options[:do_package_remove]
639+
)
640+
641+
log("Processing batch deletion for arch #{ar}")
642+
643+
s3_objects_to_delete = []
644+
645+
package_map.each do |name, versions|
646+
deleted = manifest.delete_package(name, versions)
647+
if deleted.empty?
648+
if versions.nil?
649+
sublog("No entries found for #{name} in arch #{ar}.")
650+
else
651+
sublog("No entries of #{name} versions #{versions.join(', ')} found in arch #{ar}.")
652+
end
653+
next
654+
end
655+
656+
deleted.each do |p|
657+
total_deleted += 1
658+
sublog("Deleting #{p.name} version #{p.full_version} from arch #{ar}")
659+
660+
if options[:do_package_remove]
661+
s3_objects_to_delete << p.url_filename(options[:codename])
662+
end
663+
end
664+
end
665+
666+
# Update manifests if necessary
667+
if total_deleted > 0
668+
log("Uploading updated manifests to S3 (arch #{ar})")
669+
manifest.write_to_s3 { |f| sublog("Transferring #{f}") }
670+
release.update_manifest(manifest)
671+
release.write_to_s3 { |f| sublog("Transferring #{f}") }
672+
end
673+
674+
# Delete .deb files from S3
675+
if options[:do_package_remove] && !s3_objects_to_delete.empty?
676+
log("Batch removing #{s3_objects_to_delete.length} S3 objects for arch #{ar}")
677+
batch_delete_s3_objects(s3_objects_to_delete)
678+
end
679+
end
680+
681+
if total_deleted == 0
682+
error("No packages were deleted. Nothing matched the provided arguments.")
683+
else
684+
log("Batch delete complete. #{total_deleted} package entries removed.")
685+
end
686+
687+
ensure
688+
if options[:lock] && @lock_acquired
689+
Deb::S3::Lock.unlock(options[:codename], component, arch, options[:cache_control])
690+
log("Lock released.")
691+
end
692+
end
693+
end
694+
695+
no_commands do
696+
def batch_delete_s3_objects(keys)
697+
keys.each_slice(1000) do |chunk|
698+
sublog("Deleting #{chunk.length} objects...")
699+
chunk.each do |key|
700+
Deb::S3::Utils.s3_remove(key)
701+
end
702+
end
703+
end
704+
end
705+
706+
707+
565708
desc "verify", "Verifies that the files in the package manifests exist"
566709

567710
option :fix_manifests,

0 commit comments

Comments
 (0)