From ed584395ab0025d15d8448e10acb78ef80b00887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Tue, 7 Jul 2026 12:49:35 +0300 Subject: [PATCH] Garbage collect old p2 profiles When old snapshot of p2 profiles is garbage collected plugins/features referenced by it are also removed. --- .../META-INF/MANIFEST.MF | 1 + .../net.openchrom.installer.ui/plugin.xml | 5 +- ...{RepositoryCleanup.java => P2Cleanup.java} | 59 +++++++++++++++++-- 3 files changed, 57 insertions(+), 8 deletions(-) rename openchrom/plugins/net.openchrom.installer.ui/src/net/openchrom/installer/ui/{RepositoryCleanup.java => P2Cleanup.java} (55%) diff --git a/openchrom/plugins/net.openchrom.installer.ui/META-INF/MANIFEST.MF b/openchrom/plugins/net.openchrom.installer.ui/META-INF/MANIFEST.MF index 7b5bcdd51..271c4f37a 100644 --- a/openchrom/plugins/net.openchrom.installer.ui/META-INF/MANIFEST.MF +++ b/openchrom/plugins/net.openchrom.installer.ui/META-INF/MANIFEST.MF @@ -31,6 +31,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.equinox.p2.operations;bundle-version="2.7.100", org.eclipse.equinox.p2.repository;bundle-version="2.7.100", org.eclipse.equinox.p2.engine;bundle-version="2.10.600", + org.eclipse.equinox.p2.garbagecollector;bundle-version="1.3.0", org.eclipse.equinox.p2.ui;bundle-version="2.8.100", org.eclipse.chemclipse.progress;bundle-version="0.9.0", net.openchrom.feature.branding;bundle-version="1.6.13", diff --git a/openchrom/plugins/net.openchrom.installer.ui/plugin.xml b/openchrom/plugins/net.openchrom.installer.ui/plugin.xml index 9a5b6ff1c..77456f2ba 100644 --- a/openchrom/plugins/net.openchrom.installer.ui/plugin.xml +++ b/openchrom/plugins/net.openchrom.installer.ui/plugin.xml @@ -4,11 +4,8 @@ point="org.eclipse.ui.startup"> - - + class="net.openchrom.installer.ui.P2Cleanup"> tracker = new ServiceTracker<>(context, IProvisioningAgent.class, null); tracker.open(); - cleanRepositories(tracker.getService(), context.getBundle().getVersion()); + IProvisioningAgent agent = tracker.getService(); + cleanRepositories(agent, context.getBundle().getVersion()); + cleanProfileStates(agent); tracker.close(); } + /* + * Delete old snapshots of the running profile so bundles referenced in it are removed from disk. + */ + private static void cleanProfileStates(IProvisioningAgent agent) { + + if(agent == null) { + return; + } + IProfileRegistry profileRegistry = agent.getService(IProfileRegistry.class); + if(profileRegistry == null) { + return; + } + IProfile profile = profileRegistry.getProfile(IProfileRegistry.SELF); + if(profile == null) { + return; + } + String profileId = profile.getProfileId(); + long[] timestamps = profileRegistry.listProfileTimestamps(profileId); + if(timestamps.length <= 1) { + return; + } + boolean removed = false; + // The last timestamp belongs to the currently running profile and must be kept. + for(int i = 0; i < timestamps.length - 1; i++) { + try { + profileRegistry.removeProfile(profileId, timestamps[i]); + removed = true; + } catch(ProvisionException e) { + logger.warn(e); + } + } + if(removed) { + runGarbageCollector(agent, profile); + } + } + + @SuppressWarnings("restriction") + private static void runGarbageCollector(IProvisioningAgent agent, IProfile profile) { + + GarbageCollector garbageCollector = agent.getService(GarbageCollector.class); + if(garbageCollector != null) { + garbageCollector.runGC(profile); + } + } + private static void cleanRepositories(IProvisioningAgent agent, Version version) { var currentVersion = version.getMajor() + "." + version.getMinor() + "." + version.getMicro();