diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-13 15:10:13 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-13 15:10:13 +0300 |
commit | 70ce746bd011b101605e6d84f141d1f0c3175831 (patch) | |
tree | 1b76e654f61579b79b34116fa6bb06db2f511d94 /scripts/packages | |
parent | 61ca90e0b462bfe69e0b400dfe403bd95281b90f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'scripts/packages')
-rwxr-xr-x | scripts/packages/automated_cleanup.rb | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/scripts/packages/automated_cleanup.rb b/scripts/packages/automated_cleanup.rb new file mode 100755 index 00000000000..ce8a23315a9 --- /dev/null +++ b/scripts/packages/automated_cleanup.rb @@ -0,0 +1,120 @@ +#!/usr/bin/env ruby + +# frozen_string_literal: true + +require 'optparse' +require 'gitlab' + +module Packages + class AutomatedCleanup + PACKAGES_PER_PAGE = 100 + + # $GITLAB_PROJECT_PACKAGES_CLEANUP_API_TOKEN => `Packages Cleanup` project token + def initialize( + project_path: ENV['CI_PROJECT_PATH'], + gitlab_token: ENV['GITLAB_PROJECT_PACKAGES_CLEANUP_API_TOKEN'], + options: {} + ) + @project_path = project_path + @gitlab_token = gitlab_token + @dry_run = options[:dry_run] + + puts "Dry-run mode." if dry_run + end + + def gitlab + @gitlab ||= begin + Gitlab.configure do |config| + config.endpoint = 'https://gitlab.com/api/v4' + config.private_token = gitlab_token + end + + Gitlab + end + end + + def perform_gitlab_package_cleanup!(package_name:, days_for_delete:) + puts "Checking for '#{package_name}' packages created at least #{days_for_delete} days ago..." + + gitlab.project_packages(project_path, + package_type: 'generic', + package_name: package_name, + per_page: PACKAGES_PER_PAGE).auto_paginate do |package| + next unless package.name == package_name # the search is fuzzy, so we better check the actual package name + + if old_enough(package, days_for_delete) && not_recently_downloaded(package, days_for_delete) + delete_package(package) + end + end + end + + private + + attr_reader :project_path, :gitlab_token, :dry_run + + def delete_package(package) + print_package_state(package) + gitlab.delete_project_package(project_path, package.id) unless dry_run + rescue Gitlab::Error::Forbidden + puts "Package #{package_full_name(package)} is forbidden: skipping it" + end + + def time_ago(days:) + Time.now - days * 24 * 3600 + end + + def old_enough(package, days_for_delete) + Time.parse(package.created_at) < time_ago(days: days_for_delete) + end + + def not_recently_downloaded(package, days_for_delete) + package.last_downloaded_at.nil? || + Time.parse(package.last_downloaded_at) < time_ago(days: days_for_delete) + end + + def print_package_state(package) + download_text = + if package.last_downloaded_at + "last downloaded on #{package.last_downloaded_at}" + else + "never downloaded" + end + + puts "\nPackage #{package_full_name(package)} (created on #{package.created_at}) was " \ + "#{download_text}: deleting it.\n" + end + + def package_full_name(package) + "'#{package.name}/#{package.version}'" + end + end +end + +def timed(task) + start = Time.now + yield(self) + puts "#{task} finished in #{Time.now - start} seconds.\n" +end + +if $0 == __FILE__ + options = { + dry_run: false + } + + OptionParser.new do |opts| + opts.on("-d", "--dry-run", "Whether to perform a dry-run or not.") do |value| + options[:dry_run] = true + end + + opts.on("-h", "--help", "Prints this help") do + puts opts + exit + end + end.parse! + + automated_cleanup = Packages::AutomatedCleanup.new(options: options) + + timed('"assets" packages cleanup') do + automated_cleanup.perform_gitlab_package_cleanup!(package_name: 'assets', days_for_delete: 7) + end +end |