-
Notifications
You must be signed in to change notification settings - Fork 126
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
Conversation
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class MavenExtensionDownloadHandler implements MavenInjectionAware { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path parent = root.toPath().resolve(DOWNLOAD_CACHE_DIR); | |
Path cacheDir = root.toPath().resolve(DOWNLOAD_CACHE_DIR); |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private static String getExtensionDigest(InjectionConfig injectionConfig, Path parent, MavenExtension extension) throws IOException { | |
private static String getExtensionDigest(InjectionConfig injectionConfig, Path cacheDir, MavenExtension extension) throws IOException { |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path parent, | |
Path cacheDir, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
src/test/groovy/hudson/plugins/gradle/injection/MavenExtensionDownloadHandlerTest.groovy
Outdated
Show resolved
Hide resolved
|
||
then: | ||
sameExtensions.size() == 2 | ||
sameExtensions.get(MavenExtension.DEVELOCITY) == originalDevelocityDigest && sameExtensions.get(MavenExtension.CCUD) == originalCcudDigest |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, exactly
There was a problem hiding this comment.
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>
* 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>
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