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-71959] Rename blank cloud names to be non-blank #1010

Merged
merged 4 commits into from
Sep 4, 2023

Conversation

MarkEWaite
Copy link
Contributor

@MarkEWaite MarkEWaite commented Sep 3, 2023

[JENKINS-71959] Rename blank cloud names to be non-blank

jenkinsci/jenkins#7658 reworks cloud management to use multiple pages instead of a single large page. That rework also requires that a cloud may not be named with an empty string.

The docker plugin previously tested that a cloud was allowed to have an empty string as its name, but performed no other operations with a cloud named with an empty string. Clouds named with an empty string may have worked prior to Jenkins 2.403, but they would have been complicated to manage, especially in a controller with multiple clouds defined.

A cloud named with an empty string is much more difficult to manage. It is better to mention in the changelog that clouds are no longer allowed to have an empty name rather than wrestling with all the ways that an empty name will break cloud administration.

  • JENKINS-70729 is the enhancement request that implements the change in Jenkins core 2.403
  • JENKINS-71825 is the bug report for the automated test failure that started this investigation
  • JENKINS-71959 is the bug report that a Docker cloud that uses a blank name cannot be edited in Jenkins 2.403 or later without the fix in this pull request

Testing done

Confirmed that a Docker cloud named with an empty string can be edited in 2.401.3 with no apparent loss of functionality and when that cloud with the empty named string is loaded into the plugin changes with this pull request, it is assigned a name docker-cloud-[hashCode]. That cloud can be edited in Jenkins 2.414.1 without any issue.

Discovered that a Docker cloud name uniqueness check is not performed. I was able to create two distinct Docker clouds with the same name. Editing the Docker clouds that shared the same name resulted in erratic behavior. I could delete one of the two clouds that used the duplicate name, but immediately after that the other cloud with the same name would fail some operations. Handling duplicate Docker cloud names is out of scope for this pull request. Another pull request can be filed to handle that case.

Confirmed that Jenkins 2.421 automated tests fail as reported in JENKINS-71825 without this change.

Confirmed that Jenkins 2.421 automated tests pass with this change.

Confirmed that Jenkins 2.421 already rejects an empty cloud name from the cloud creation page, whether or not this change is implemented.

Confirmed that Jenkins 2.421 accepts an empty cloud name from an earlier version but then rejects all attempts to use the cloud configuration page to modify the definition. I modified the XML file that configures the cloud so that the cloud name was an empty string to perform that interactive test.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

jenkinsci/jenkins#7658 reworks cloud management
to use multiple pages instead of a single large page.  That rework also
requires that a cloud may not be named with an empty string.

The docker plugin specifically tested that a cloud was allowed to have an
empty string as its name, but performed no other operations with a cloud
that is named with an empty string.  Cloud named with an empty string may
have worked prior to Jenkins 2.403, but they would have been complicated
to manage, especially in a controller with multiple clouds defined.

A cloud named with an empty string is much more difficult to manage.
It is better to mention in the changelog that clouds are no longer
allowed to have an empty name rather than wrestling with all the ways
that an empty name will break cloud administration.

https://issues.jenkins.io/browse/JENKINS-70729 is the enhancement request
that implements the change.

https://issues.jenkins.io/browse/JENKINS-71825 is the bug report for
the automated test failure that started this investigation.
@MarkEWaite MarkEWaite requested a review from a team as a code owner September 3, 2023 14:24
@MarkEWaite MarkEWaite added the bug An issue reporting a bug or a PR fixing one. label Sep 3, 2023
@MarkEWaite MarkEWaite changed the title [JENKINS-70729] Stop supporting an empty cloud name [JENKINS-70729] Stop supporting empty cloud names Sep 3, 2023
Do not break existing usage of blank names, but warn in the log file
that blank names are no longer supported after Jenkins 2.402.

The Jenkins 2.421 cloud creation UI will not allow a blank name, but
earlier versions may have allowed it.

Assert the log message for blank or name cloud name
@MarkEWaite MarkEWaite changed the title [JENKINS-70729] Stop supporting empty cloud names [JENKINS-70729] Stop testing empty cloud names Sep 3, 2023
@MarkEWaite MarkEWaite changed the title [JENKINS-70729] Stop testing empty cloud names [JENKINS-70729] Log warning on empty cloud names Sep 4, 2023
@MarkEWaite
Copy link
Contributor Author

MarkEWaite commented Sep 4, 2023

@gounthar and @Vlatombe I am sure there is a better way to handle this than telling the user to stop Jenkins and edit the name attribute in the conifig.xml file section for the docker plugin. However, I don't see it. There is a readResolve() method in DockerfCloud but I don't see how it can adjust the name attribute and have it applied correctly. Any suggestions?

I like the new cloud management UI very much but would like to make the transition smooth for users of the Docker cloud plugin. If they made the mistake of naming their docker cloud with an empty string, they won't be able to edit from the web page once they are using Jenkins 2.403 or newer.

@@ -727,6 +730,10 @@ protected Object readResolve() {
dockerApi = new DockerAPI(dockerHost, connectTimeout, readTimeout, version, dockerHostname);
}

if (name == null || name.isBlank()) {
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
Copy link
Member

@Vlatombe Vlatombe Sep 4, 2023

Choose a reason for hiding this comment

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

Suggested change
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
return new DockerCloud("docker-" + UUID.randomUUID().toString().substring(0, 8), this);

And implement a copy constructor like this (this is what is used in kubernetes-plugin)

  public DockerCloud(@NonNull String name, @NonNull DockerCloud source) {
    super(name);
    XStream2 xs = new XStream2();
    xs.omitField(Cloud.class, "name");
    xs.unmarshal(XStream2.getDefaultDriver().createReader(new StringReader(xs.toXML(source))), this);
  }

Probably requires saving configuration afterwards (or switch uuid to a digest based on current content) to avoid getting a different name on each instance start.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks very much @Vlatombe !

The XStream2 call caused complaints from Jenkins core that it was trying to marshal unsafe entities, so I switched to a simple assignment in 57d3010 . I'll run some interactive tests to confirm that change is behaving as expected. Let me know if you detect errors in 57d3010

Copy link
Member

Choose a reason for hiding this comment

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

Simple assignment works too, but can be source of maintenance issues because you need to remember that it needs to be updated every time a field is added.

Jenkins 2.403 improves the cloud management user interface.  Each cloud is
now managed from a separate page.  That separate page requires a non-blank
name for the cloud.  Jenkins 2.402 and later allowed a blank name.

When a blank name is detected, convert it to a non-blank name based on
the hashCode of the DockerAPI and templates.
@MarkEWaite MarkEWaite changed the title [JENKINS-70729] Log warning on empty cloud names [JENKINS-70729] Rename blank cloud names to be non-blank Sep 4, 2023
@MarkEWaite MarkEWaite changed the title [JENKINS-70729] Rename blank cloud names to be non-blank [JENKINS-71959] Rename blank cloud names to be non-blank Sep 4, 2023
@@ -731,7 +738,9 @@ protected Object readResolve() {
}

if (name == null || name.isBlank()) {
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
String newName = "docker-cloud-" + Integer.toHexString(hashCode());
Copy link
Member

Choose a reason for hiding this comment

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

hashCode() is not collision-free so could cause duplicate names.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I confirmed that collisions happen when the hashCode values of two clouds are the same and the cloud name of both clouds is blank. Since the hashCode includes the DockerAPI object and the list of templates, I think it will be very rare that a Jenkins controller has more than one docker cloud definition that have the same values for DockerAPI and template list and use blank names for the cloud name.

I think it is better to risk a collision and prefer a stable transformation from blank name to generated name. If I remove the risk of collision, it seems like I am accepting that the transformation from blank name to generated name will choose a unique name each time it is run.

Does that seem like an acceptable risk to you or should I accept that the transformation will be different each time it is applied to a docker cloud that has a blank name?

Copy link
Member

Choose a reason for hiding this comment

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

Worse thing that will happen is you will see the same entry twice in the cloud list, causing a weird UX. Clicking on one of them will show you the first entry appearing in the underlying persisted list.
I think it can still be renamed to a different name by the user to clear the ambiguity.
However until the rename happens, the second cloud with the same name won't be editable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When I did the rename in my test of editing the first in the list, it showed the new name for both in the web page. However, I didn't spend a lot of time exploring beyond that.

I think this is ready to merge. Interactive testing is complete. The pull request description includes details of that testing. Anything else that you feel should be changed before it is merged and released?

@MarkEWaite MarkEWaite merged commit 4579c0c into jenkinsci:master Sep 4, 2023
15 checks passed
@MarkEWaite MarkEWaite deleted the fix-test-with-newer-jenkins branch September 4, 2023 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An issue reporting a bug or a PR fixing one.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants