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

[JENKINS-2111] Managed workspace indices #129

Merged
merged 19 commits into from
Nov 9, 2018

Conversation

jglick
Copy link
Member

@jglick jglick commented Sep 21, 2018

JENKINS-2111: the long-discussed overhaul of workspace selection at least for branch projects. Unlikely the previous technique from #50 (JENKINS-34564), the workspace path stays short (like JENKINS-30148) as we do not need to add any cryptographic hash to prevent collisions between projects: workspace subdirectories are allocated and tracked, so we can just add a simple uniquifying suffix as needed. That should allow JENKINS-38706 to be closed. Also handles renames (JENKINS-22240).

pom.xml Outdated
@@ -29,7 +29,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.37</version>
<version>3.22</version>
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 for fun.

pom.xml Outdated
@@ -65,7 +65,8 @@
</scm>

<properties>
<jenkins.version>1.642.3</jenkins.version>
<jenkins.version>2.73.3</jenkins.version>
Copy link
Member Author

Choose a reason for hiding this comment

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

Made various things more convenient, such as jenkinsci/jenkins#2914.

@@ -85,16 +86,6 @@
</pluginRepositories>

<dependencies>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>access-modifier-annotation</artifactId>
Copy link
Member Author

Choose a reason for hiding this comment

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

These should not have been here.

@@ -204,7 +204,7 @@ public P decorate(P project) {
List<BranchProperty> properties = new ArrayList<BranchProperty>(branch.getProperties());
Collections.sort(properties, DescriptorOrder.reverse(BranchProperty.class));
for (BranchProperty property : properties) {
JobDecorator<P, R> decorator = property.jobDecorator(project.getClass());
JobDecorator<P, R> decorator = property.jobDecorator((Class) project.getClass());
Copy link
Member Author

Choose a reason for hiding this comment

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

Incomprehensible compiler errors in -source 8.

@@ -41,7 +41,7 @@
*/
public final class NameMangler {

private static final int MAX_SAFE_LENGTH = 32;
static final int MAX_SAFE_LENGTH = 32;
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 is now the default being applied to workspace lengths.

static /* not final */ int PATH_MAX = Integer.getInteger(WorkspaceLocatorImpl.class.getName() + ".PATH_MAX", PATH_MAX_DEFAULT);

static /* not final */ int MAX_LENGTH = Integer.getInteger(WorkspaceLocatorImpl.class.getName() + ".MAX_LENGTH", NameMangler.MAX_SAFE_LENGTH);

static /* not final */ boolean MULTIBRANCH_ONLY = Boolean.parseBoolean(System.getProperty(WorkspaceLocatorImpl.class.getName() + ".MULTIBRANCH_ONLY", /* TBD */ "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.

Could be set to false to turn on the smarter behavior for all projects, including standalone Pipeline and even freestyle, matrix, etc. On the one hand I do not like having installation of what is otherwise a library plugin affect behavior of core functionality. On the other hand, the name shortening is very useful for projects in deep folder hierarchies; the character sanitization is useful for all sorts of project generation systems other than multibranch; and the automatic cleanup is useful for pretty much everyone, since WorkspaceCleanupThread is unreliable.

}

private static FilePath locate(TopLevelItem item, Node node, boolean create) {
if (MULTIBRANCH_ONLY && !(item.getParent() instanceof MultiBranchProject)) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe could be a three-way flag to disable the feature altogether?

@jglick
Copy link
Member Author

jglick commented Sep 22, 2018

Test failure is due to a Windows FS problem which I am tracking down.

@jglick
Copy link
Member Author

jglick commented Sep 24, 2018

Seems to be another Windows test failure I cannot reproduce locally and which looks unrelated to my changes. Will see if it goes away after planned test expansion commits.

jglick added a commit to jglick/workflow-multibranch-plugin that referenced this pull request Oct 5, 2018
…oyed on ci.jenkins.io and/or tests depend on that version.
@svanoort
Copy link
Member

svanoort commented Oct 5, 2018

@joseblas or @dwnusbaum Could one of you give this a peek please? If you think it's solid, happy to see it released.

@jglick jglick requested a review from joseblas October 5, 2018 13:39
@jglick
Copy link
Member Author

jglick commented Oct 5, 2018

If you are reviewing, then you should also check an update to the integration test in jenkinsci/workflow-multibranch-plugin#82, plus the two other PRs that depends on.

if (!workspaceDir.contains("ITEM_FULL")) {
LOGGER.log(Level.WARNING, "JENKINS-34564 path sanitization ineffective when using legacy Workspace Root Directory ‘{0}’; switch to $'{'JENKINS_HOME'}'/workspace/$'{'ITEM_FULLNAME'}' as in JENKINS-8446 / JENKINS-21942", workspaceDir);
if (fullName.contains("\n") || fullName.equals(INDEX_FILE_NAME)) {
throw new IllegalArgumentException(); // better not to mess around
Copy link
Member

Choose a reason for hiding this comment

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

Can we add a message and the invalid name to the exception?

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, will do.

"ITEM_FULLNAME", itemFullName, // legacy, deprecated
"ITEM_FULL_NAME", itemFullName.replace(':','$'))); // safe, see JENKINS-12251
private static void save(Map<String, String> index, FilePath workspace) throws IOException, InterruptedException {
// FilePath.renameTo does not support REPLACE_EXISTING, and AtomicFileWriter does not work remotely.
Copy link
Member

Choose a reason for hiding this comment

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

FilePath.renameTo not using REPLACE_EXISTING might just have been something we missed when reviewing jenkinsci/jenkins#3173, although based on the File#renameTo documentation it looks like the behavior when a file existed was previously platform dependent so it could have gone either way. Do you think it would be helpful to add the flag? (Doesn't matter for this PR, but better to clean up the default flags sooner than later if they aren't useful)

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 behavior when a file existed was previously platform dependent so it could have gone either way

Exactly. It seems that the original behavior on Windows did replace an existing file and the new behavior does not. The renameTo Javadoc does not go into any details about behavior so it is a matter of interpretation whether this is a core bug or not.

"ITEM_FULL_NAME", itemFullName.replace(':','$'))); // safe, see JENKINS-12251
private static void save(Map<String, String> index, FilePath workspace) throws IOException, InterruptedException {
// FilePath.renameTo does not support REPLACE_EXISTING, and AtomicFileWriter does not work remotely.
// Anyway we are synchronizing access to this file so the only potential problem is half-written content.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe you could add something like the expected number of pairs to the first line of the file to help diagnose a corrupted index in #load, although with os/disk caches I'm not sure how likely it would be for that data to be written correctly if there is a problem with the rest of the file.

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'm not sure how likely it would be for that data to be written correctly if there is a problem with the rest of the file

My feelings as well.

Probably best to bite the bullet and copy-paste some code from AtomicFileWriter.

@vivek
Copy link

vivek commented Nov 8, 2018

@dwnusbaum good to merge this one?

@stephenc
Copy link
Member

stephenc commented Nov 8, 2018

As I understand, one of the biggest issues for Windows systems is too long a path, for some people even the 32 character mangled names may prove too long.

It would be awesome - now we have tracking - to allow a per-node configurable strategy (default is to use the name mangler, and only default provided here)

That way a Windows User could install a mangler that just picks an available one or two character name (failing up to 3+ characters) where they are willing to trade knowing which workspace is which from the name for shortest possible paths and having to look up in the index file

@dwnusbaum
Copy link
Member

@vivek It looks fine to me, but I am not very familiar with this API, so it would probably be best for @rsandell or @stephenc to review it.

@jglick
Copy link
Member Author

jglick commented Nov 8, 2018

allow a per-node configurable strategy […so] a Windows User could install a mangler that just picks an available one or two character name (failing up to 3+ characters)

Might be overkill. I think the new default maximum should be small enough for most users (assuming they use a reasonably concise remoteFS); if not, they can still run with

-Djenkins.branch.WorkspaceLocatorImpl.MAX_LENGTH=10

or whatever.

Note that the max length includes any applied uniquification suffix, so it is really a hard limit¹ and you cannot set the max so small that an exponentially large number of workspaces would overflow. You would of course have to have an absurdly large number of Jenkins projects for that to be an issue.

¹This does not apply to suffixes added by WorkspaceList, such as @2, or the @tmp added by various build steps.

@jglick
Copy link
Member Author

jglick commented Nov 8, 2018

Of course we could also just set a smaller default max value on Windows. I do not have a strong opinion either way. Can always be tweaked later.

@rsandell rsandell merged commit 67c6d3d into jenkinsci:master Nov 9, 2018
@jglick jglick deleted the WorkspaceLocatorImpl-JENKINS-2111 branch November 9, 2018 18:53
jglick added a commit to jglick/workflow-multibranch-plugin that referenced this pull request Nov 9, 2018
This was referenced Nov 9, 2018
jglick added a commit to jglick/branch-api-plugin that referenced this pull request Nov 14, 2018
@daniel-beck
Copy link
Member

daniel-beck commented Oct 4, 2019

The logging here is really annoying with masters that don't have executors (so their master workspace path shouldn't matter). From ci.j.io:

Oct 04, 2019 12:05:02 PM WARNING jenkins.branch.WorkspaceLocatorImpl getWorkspaceRoot
JENKINS-2111 path sanitization ineffective when using legacy Workspace Root Directory ‘${ITEM_ROOTDIR}/workspace’; switch to ‘${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}’ as in JENKINS-8446 / JENKINS-21942
Oct 04, 2019 12:05:02 PM FINE jenkins.branch.WorkspaceLocatorImpl locate
no available workspace root for hudson.model.Hudson@2ad98027 so skipping org.jenkinsci.plugins.workflow.job.WorkflowJob@615a99f0[Infra/infra-reports/PR-22]
Oct 04, 2019 12:07:01 PM WARNING jenkins.branch.WorkspaceLocatorImpl getWorkspaceRoot
JENKINS-2111 path sanitization ineffective when using legacy Workspace Root Directory ‘${ITEM_ROOTDIR}/workspace’; switch to ‘${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}’ as in JENKINS-8446 / JENKINS-21942
Oct 04, 2019 12:07:01 PM FINE jenkins.branch.WorkspaceLocatorImpl locate
no available workspace root for hudson.model.Hudson@2ad98027 so skipping org.jenkinsci.plugins.workflow.job.WorkflowJob@723417aa[Infra/charts/master]
Oct 04, 2019 12:07:01 PM WARNING jenkins.branch.WorkspaceLocatorImpl getWorkspaceRoot
JENKINS-2111 path sanitization ineffective when using legacy Workspace Root Directory ‘${ITEM_ROOTDIR}/workspace’; switch to ‘${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}’ as in JENKINS-8446 / JENKINS-21942
Oct 04, 2019 12:07:01 PM FINE jenkins.branch.WorkspaceLocatorImpl locate
no available workspace root for hudson.model.Hudson@2ad98027 so skipping org.jenkinsci.plugins.workflow.job.WorkflowJob@7b8287f7[Infra/acceptance-tests/install-lts-debian-package]

Since https://jenkins.io/changelog/#v2.119 this is more cumbersome to implement since it got caught in JENKINS-50164.

@jglick
Copy link
Member Author

jglick commented Dec 10, 2019

@daniel-beck

The logging here is really annoying with masters that don't have executors (so their master workspace path shouldn't matter).

No such log message should be printed for a system with no master executor, because this code path is only run when looking for a workspace on the master node. I cannot speculate as to the cause of such messages on ci.jenkins.io; would need to have some sort of debug access, or steps to reproduce from scratch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants