Skip to content

Conversation

@jglick
Copy link
Member

@jglick jglick commented Feb 19, 2018

See JENKINS-49635 and also JENKINS-26810, and JEP-202.

Reference implementation is in the artifact-manager-s3 plugin.

@reviewbybees @jenkinsci/code-reviewers

@jglick jglick added the work-in-progress The PR is under active development, not ready to the final review label Feb 19, 2018
@daniel-beck daniel-beck self-requested a review February 19, 2018 23:51
@jglick jglick changed the title [JENKINS-49635] Defining new VirtualFile methods to better support external artifact storage [JENKINS-49635] [JENKINS-26810] Extending VirtualFile API Feb 21, 2018
@jglick jglick changed the title [JENKINS-49635] [JENKINS-26810] Extending VirtualFile API [JENKINS-49635] [JENKINS-26810] Extending VirtualFile Feb 21, 2018
*/
@CheckForNull
public static String resolveSymlink(@Nonnull File link) throws InterruptedException, IOException {
public static String resolveSymlink(@Nonnull File link) 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.

Binary compatible simplification—the body never actually threw that exception.

Copy link
Member

Choose a reason for hiding this comment

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

Not source compatible IIRC (javac fails when there is a catch block for impossible exception), may impact PCT. There are usages of it externally, e.g. in the Support Core plugin: https://github.com/search?p=1&q=org%3Ajenkinsci+resolveSymlink&type=Code

I would propose to detach it to a separate PR if you feel it's important enough

Copy link
Member

Choose a reason for hiding this comment

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

@oleg-nenashev Jesse already disputed this in #3340 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

ok

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, PCT should be unaffected, though it could impede

buildPlugin(jenkinsVersions: [null, '2.222']) // or whatever

Why the Java language treats an exception which cannot be thrown as a fatal error rather than a warning (ditto unreachable statements etc.), I do not know.

Copy link
Member Author

Choose a reason for hiding this comment

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

The simple workaround for the buildPlugin case would be to just catch (Exception I guess.

Copy link
Member

Choose a reason for hiding this comment

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

would be better to fix it tho

try (ZipOutputStream zos = new ZipOutputStream(outputStream)) {
zos.setEncoding(System.getProperty("file.encoding")); // TODO JENKINS-20663 make this overridable via query parameter
for (String n : dir.list(glob.length() == 0 ? "**" : glob)) {
for (String n : dir.list(glob.isEmpty() ? "**" : glob, null, /* TODO what is the user expectation? */true)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Retaining default excludes functionality here to maintain semantics but I am unsure whether users would want this or not.

}
return r.stream().filter(p -> {
TokenizedPath path = new TokenizedPath(p.replace('/', File.separatorChar));
return includePatterns.stream().anyMatch(patt -> patt.matchPath(path, true)) && !excludePatterns.stream().anyMatch(patt -> patt.matchPath(path, true));
Copy link
Member Author

Choose a reason for hiding this comment

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

VirtualFileTest.Ram checks all this implementation.

* <p>Generally this will be harder to implement than {@link #asRemotable},
* which would have the opportunity to perform arbitrary preparation for {@link #open}
* such as negotiating session authentication.
* @return an externally usable URL like {@code https://gist.githubusercontent.com/ACCT/GISTID/raw/COMMITHASH/FILE}, or null if there is no such support
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 the most familiar download URL example I could come up with—certainly not a choice for artifact storage!

Copy link
Member

Choose a reason for hiding this comment

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

Whoever implements this as a weekend project will get 🍻 from me.

Copy link
Member

Choose a reason for hiding this comment

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

Adding some 🍺 to the trophy

@jglick jglick added on-hold This pull request depends on another event/release, and it cannot be merged right now and removed work-in-progress The PR is under active development, not ready to the final review labels Feb 21, 2018
* <p>Since some implementations may in fact use external file storage,
* callers may request optional APIs to access those services more efficiently.
* Otherwise, for example, a plugin copying a file
* previously saved by {@link ArtifactManager} to an external storage servuce
Copy link
Member

Choose a reason for hiding this comment

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

s/servuce/service/

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

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

Looks good so far though I would still prefer InterruptedException. Accmod is still waiting for the release by @kohsuke

*/
@CheckForNull
public static String resolveSymlink(@Nonnull File link) throws InterruptedException, IOException {
public static String resolveSymlink(@Nonnull File link) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

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

would be better to fix it tho

*/
private static List<List<Path>> patternScan(VirtualFile baseDir, String pattern, String baseRef) throws IOException {
String[] files = baseDir.list(pattern);
Collection<String> files = baseDir.list(pattern, null, /* TODO what is the user expectation? */true);
Copy link
Member

Choose a reason for hiding this comment

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

Note that there was a JEP-200 regression in the similar code recently

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, in DirScanner.Glob IIRC, which is called by some list implementations.

/** {@link Run.ArtifactList} without the implicit link to {@link Run} */
private static final class SerializableArtifactList extends ArrayList<SerializableArtifact> {
private static final long serialVersionUID = 1L;
private LinkedHashMap<SerializableArtifact, String> tree = new LinkedHashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

Even for a private class not looks a bit dangerous since you do not override modification methods to put data to both containers (array and tree)

Copy link
Member Author

Choose a reason for hiding this comment

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

This code was already a mess and I am trying to touch it as little as possible. The problem here was that Artifact and ArtifactList were, surprisingly, nonstatic—they held a Run reference—which is unsupportable when they must be constructed inside a callable which might run remotely. (If using the FilePath-based VirtualFile, for example. In fact this is not currently used by any ArtifactManager, only workspace browsing, but the API does not preclude the possibility, so…)

* only on the node on which the object was created.
*
* <p>Since some implementations may in fact use external file storage,
* callers may request optional APIs to access those services more efficiently.
Copy link
Member

Choose a reason for hiding this comment

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

I still feel that we grow a technical debt in API, but Ican live with that.

throw (IOException) new InterruptedIOException().initCause(e);
target = Util.resolveSymlink(f);
} catch (IOException x) { // JENKINS-13202
target = null;
Copy link
Member

Choose a reason for hiding this comment

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

agreed

@carlossg
Copy link
Contributor

this is stable now for final review

@carlossg
Copy link
Contributor

@daniel-beck can you take a look at the new changes to see if your positive review still stands?

@Vlatombe Vlatombe self-requested a review April 16, 2018 08:42
@oleg-nenashev oleg-nenashev self-requested a review April 16, 2018 17:10
Copy link
Contributor

@carlossg carlossg left a comment

Choose a reason for hiding this comment

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

This is tested with the https://github.com/jenkinsci/artifact-manager-s3-plugin and works fine

@jglick jglick requested review from carlossg and oleg-nenashev and removed request for oleg-nenashev April 16, 2018 17:11
Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

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

🐝 The diff from the previous review looks good to me. Since all APIs are annotated with Beta, we can reconsider APIs in the worst case

@oleg-nenashev
Copy link
Member

@reviewbybees done

@jglick jglick changed the title [JENKINS-49635] [JENKINS-26810] Extending VirtualFile [JEP-202] Extending VirtualFile Apr 16, 2018
@carlossg
Copy link
Contributor

Given the JEP is in place, no objections have been raised and all apis are marked as @beta I think this is ready to be merged for the benefit of downstream consumers, both the initial s3 implementation and any other interested implementers, and provide feedback

@jglick jglick added ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback and removed on-hold This pull request depends on another event/release, and it cannot be merged right now labels Apr 20, 2018
/**
* @deprecated use {@link #list(String, String, boolean)} instead
*/
@Deprecated
Copy link
Member

Choose a reason for hiding this comment

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

This deprecation points to a Beta API. This seems unhelpful.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, the only callers will be updated anyway.

@daniel-beck
Copy link
Member

FTR, agree with @carlossg regarding the eligibility for this to be merged. Beta annotations allow this to evolve if needed without breaking existing API commitments.

@jglick
Copy link
Member Author

jglick commented Apr 20, 2018

FTR jenkinsci/jep#96

@jglick jglick merged commit 51cac7d into jenkinsci:master Apr 20, 2018
@jglick jglick deleted the VirtualFile-JENKINS-49635 branch April 20, 2018 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants