Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download extensions only once and if the version changes #488

Merged
merged 8 commits into from
Sep 18, 2024

Conversation

welandaz
Copy link
Member

@welandaz welandaz commented Sep 16, 2024

This change will download Maven extensions only once to the controller node and then use the same copying mechanism we originally had. The only difference is that before we had a predefined location where the extensions where stored (as they were bundled), and now they will be re-downloaded if needed into jenkins-gradle-plugin/cache on the controller node.

The download happens for the first time when injection get's enabled or when a user updates the version they want to inject. We now store a metadata file with a downloaded version and a digest of the JAR which we use for a comparison to determine if we need to copy it to an agent node.

Manual testing was also performed on the locally installed instance in addition to the automated tests we have

@welandaz welandaz requested review from alextu and guylabs September 16, 2024 22:42
@welandaz welandaz self-assigned this Sep 16, 2024
import java.util.List;
import java.util.Map;

public class MavenExtensionDownloadHandler implements MavenInjectionAware {
Copy link
Member Author

@welandaz welandaz Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this logic manually, but I'm also going to add a test as part of this PR for this specific class

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test added

return;
}

injector.inject(computer, globalEnvVars);
Map<MavenExtension, String> extensionsDigest = mavenExtensionDownloadHandler.ensureExtensionsDownloaded(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be called concurrently (multiple agents launching at the same time). If somehow the extension was not downloaded after saving the configuration, it could get corrupted when downloaded multiple times. If we think it's a realistic issue we can just have ensureExtensionDownloaded making sure the extension is there without downloading it (so no injection in that case). After all now it has to be an explicit action to enable the Maven injection. Wdyt?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed downloading on agent's onOnline event as we discussed.

Everything else stays as it's sequential and synchronized by Jenkins

public Map<MavenExtension, String> ensureExtensionsDownloaded(File root, InjectionConfig injectionConfig) throws IOException {
if (!isInjectionDisabledGlobally(injectionConfig)) {
Map<MavenExtension, String> extensionsDigest = new HashMap<>();
Path parent = root.toPath().resolve(DOWNLOAD_CACHE_DIR);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Path parent = root.toPath().resolve(DOWNLOAD_CACHE_DIR);
Path cacheDir = root.toPath().resolve(DOWNLOAD_CACHE_DIR);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

return Collections.emptyMap();
}

private static String getExtensionDigest(InjectionConfig injectionConfig, Path parent, MavenExtension extension) throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static String getExtensionDigest(InjectionConfig injectionConfig, Path parent, MavenExtension extension) throws IOException {
private static String getExtensionDigest(InjectionConfig injectionConfig, Path cacheDir, MavenExtension extension) throws IOException {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


private static String downloadExtension(
InjectionConfig injectionConfig,
Path parent,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Path parent,
Path cacheDir,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


then:
sameExtensions.size() == 2
sameExtensions.get(MavenExtension.DEVELOCITY) == originalDevelocityDigest && sameExtensions.get(MavenExtension.CCUD) == originalCcudDigest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 how does it test if it's not re-downloaded?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just by verifying that the digest of the one downloaded before hasn't changed.
Or do you mean that it can still download it, just the same version again, which will produce same digest?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, exactly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added additional check for lastModified

…DownloadHandlerTest.groovy

Co-authored-by: Alexis Tual <atual@gradle.com>
@guylabs guylabs removed their request for review September 17, 2024 15:08
@welandaz welandaz merged commit e435729 into master Sep 18, 2024
20 of 22 checks passed
@welandaz welandaz deleted the welandaz/download-extensions-once branch September 18, 2024 12:20
alextu added a commit that referenced this pull request Sep 25, 2024
* Download extensions only once and if the version changes

* Update tests

* Update src/test/groovy/hudson/plugins/gradle/injection/MavenExtensionDownloadHandlerTest.groovy

Co-authored-by: Alexis Tual <atual@gradle.com>

* Do not download extensions on agents onOnline

* Fix CCUD extension handling

* Do not set bogus extension repository URL in test

* Disable a couple of tests to validate windows failures

* Reenable tests again

---------

Co-authored-by: Alexis Tual <atual@gradle.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants