From 26a4ca42bba2e216862ddf2fbf7e3e67e6838650 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Mon, 16 Dec 2024 12:11:14 -0600 Subject: [PATCH] Port grim-reaper to C++ --- cpp/fetch-indexes.cpp | 91 ++++++++++++++++++++++++++++++++++++++++--- grim-reaper | 71 --------------------------------- 2 files changed, 86 insertions(+), 76 deletions(-) delete mode 100755 grim-reaper diff --git a/cpp/fetch-indexes.cpp b/cpp/fetch-indexes.cpp index ad337f5..d6310e5 100644 --- a/cpp/fetch-indexes.cpp +++ b/cpp/fetch-indexes.cpp @@ -649,13 +649,94 @@ void processRelease(const std::string& RELEASE, const YAML::Node& config) { } } - std::cout << "Run the grim reaper..." << std::endl; - std::string grimCmd = "./grim-reaper " + RELEASE; - int grimResult = executeAndLog(grimCmd); - if (grimResult != 0) { - std::cerr << "Error: Grim reaper execution failed for release " << RELEASE << std::endl; + // Now inline what was previously the Python "grim-reaper" script. + std::cout << "Run the grim reaper (integrated)..." << std::endl; + + // We assume we already have global_lp, series, etc. + if (!global_lp_opt.has_value()) { + auto lp_opt = launchpad::login(); + if (!lp_opt.has_value()) { + std::cerr << "Failed to authenticate with Launchpad during grim-reaper stage.\n"; + return; + } + global_lp_opt = lp_opt; + global_lp = global_lp_opt.value().get(); + } + + auto lp = global_lp; + auto ubuntu_opt = lp->distributions["ubuntu"]; + if (!ubuntu_opt.has_value()) { + std::cerr << "Failed to retrieve ubuntu (grim-reaper stage).\n"; return; } + distribution ubuntu = ubuntu_opt.value(); + + auto lubuntu_ci_opt = lp->people["lubuntu-ci"]; + if (!lubuntu_ci_opt.has_value()) { + std::cerr << "Failed to retrieve lubuntu-ci (grim-reaper stage).\n"; + return; + } + person lubuntu_ci = lubuntu_ci_opt.value(); + + auto regular_opt = lubuntu_ci.getPPAByName(ubuntu, "unstable-ci"); + if (!regular_opt.has_value()) { + std::cerr << "Failed to retrieve regular PPA (grim-reaper stage).\n"; + return; + } + archive regular = regular_opt.value(); + + auto proposed_opt = lubuntu_ci.getPPAByName(ubuntu, "unstable-ci-proposed"); + if (!proposed_opt.has_value()) { + std::cerr << "Failed to retrieve proposed PPA (grim-reaper stage).\n"; + return; + } + archive proposed = proposed_opt.value(); + + auto series_opt = ubuntu.getSeries(RELEASE); + if (!series_opt.has_value()) { + std::cerr << "Failed to retrieve series for: " << RELEASE << " (grim-reaper stage)\n"; + return; + } + distro_series series = series_opt.value(); + + std::cout << "IS THAT THE GRIM REAPER?!?!?!?!!!" << std::endl; + + // Fetch superseded packages + auto proposed_superseded_gen = proposed.getPublishedSources("", "", series, false, false, "", "", "Superseded", ""); + std::vector proposed_superseded; + for (auto s : proposed_superseded_gen) proposed_superseded.push_back(s); + + auto regular_superseded_gen = regular.getPublishedSources("", "", series, false, false, "", "", "Superseded", ""); + std::vector regular_superseded; + for (auto s : regular_superseded_gen) regular_superseded.push_back(s); + + int total_removals = (int)proposed_superseded.size() + (int)regular_superseded.size(); + std::cout << "Total packages to remove: " << total_removals << std::endl; + + int current_package = 1; + int current_percentage = 0; + + auto process_removals = [&](std::vector& pkgs) { + for (auto &pkg : pkgs) { + for (auto build : pkg.getBuilds()) { + if (build.buildstate == "Currently building" || build.buildstate == "Needs building") { + if (build.can_be_cancelled) { + build.cancel(); + } + } + } + pkg.requestDeletion("superseded"); + int new_percentage = (current_package * 100) / total_removals; + if (new_percentage > current_percentage) { + current_percentage = new_percentage; + std::cout << current_percentage << "% complete (" << current_package << "/" << total_removals << ")" << std::endl; + } + current_package++; + } + }; + + process_removals(proposed_superseded); + process_removals(regular_superseded); std::cout << "Done processing release " << RELEASE << "." << std::endl; } diff --git a/grim-reaper b/grim-reaper deleted file mode 100755 index cb97f21..0000000 --- a/grim-reaper +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2024 Simon Quigley -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import argparse -from concurrent.futures import ThreadPoolExecutor, as_completed -from datetime import datetime, timedelta -from launchpadlib.launchpad import Launchpad - -now = datetime.now() - -def print_log(string): - global now - old_now = now - now = datetime.now() - time_elapsed = now - old_now - print(f"[{now}] (took {time_elapsed}) {string}") - -parser = argparse.ArgumentParser() -parser.add_argument("release") -args = parser.parse_args() - -print(f"[{now}] Logging into Launchpad...") -launchpad = Launchpad.login_with("grim-reaper", "production", version="devel") - -print_log("Logged in. Initializing repositories...") -ubuntu = launchpad.distributions["ubuntu"] -series = ubuntu.getSeries(name_or_version=args.release) -lubuntu_ci = launchpad.people["lubuntu-ci"] -regular = lubuntu_ci.getPPAByName(distribution=ubuntu, name="unstable-ci") -proposed = lubuntu_ci.getPPAByName(distribution=ubuntu, name="unstable-ci-proposed") - -print_log("IS THAT THE GRIM REAPER?!?!?!?!!!") - -# Fetch packages once -packages = [] -for repository in [proposed, regular]: - packages.append(repository.getPublishedSources(status="Superseded", distro_series=series)) -total_removals = sum(len(repository) for repository in packages) - -print_log(f"Total packages to remove: {total_removals}") -current_package = 1 -current_percentage = 0 -for repository in packages: - for pkg in repository: - # Cancel all running builds for the package - for build in pkg.getBuilds(): - if build.buildstate in ["Currently building", "Needs building"]: - # Only cancel the build if we can - if build.can_be_cancelled: - build.cancel() - # Delete the source package - pkg.requestDeletion(removal_comment="superseded") - new_percentage = int(current_package / total_removals) - if new_percentage > current_percentage: - current_percentage = new_percentage - print_log(f"{new_percentage}% complete ({current_package}/{total_removals})") - current_package += 1