Simplified plugin impl, removed unreliable onResume#152
Simplified plugin impl, removed unreliable onResume#152jglick merged 4 commits intojenkinsci:masterfrom
onResume#152Conversation
| <changelist>999999-SNAPSHOT</changelist> | ||
| <gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo> | ||
| <jenkins.version>2.387.3</jenkins.version> | ||
| <jenkins.baseline>2.440</jenkins.baseline> |
There was a problem hiding this comment.
Just updating to a recommended baseline while we are here.
| * might change in between usages and where it is not possible to propagate | ||
| * the object in other ways. |
There was a problem hiding this comment.
We can just pass the Launcher to each call.
| import java.io.IOException; | ||
|
|
||
| /** | ||
| * Need an interface in order to export the object from the channel. |
There was a problem hiding this comment.
Not sure if this was actually true prior to #48, but it is certainly not true now—this interface was not being passed to Channel.export.
| import hudson.model.TaskListener; | ||
|
|
||
| /** | ||
| * Extension point for ssh-agent providers. |
There was a problem hiding this comment.
When there is just a single impl for years, this was unnecessary complexity.
| * @throws Throwable if things go wrong. | ||
| * @deprecated use {@link #SSHAgentEnvironment(hudson.Launcher, hudson.model.BuildListener, java.util.List)} | ||
| */ | ||
| @Deprecated |
There was a problem hiding this comment.
No reason to keep these long-deprecated overloads around; who would call them?
| Map<String, Throwable> faults = new LinkedHashMap<>(); | ||
| for (RemoteAgentFactory factory : Jenkins.get().getExtensionList(RemoteAgentFactory.class)) { | ||
| if (factory.isSupported(launcher, listener)) { | ||
| try { | ||
| listener.getLogger().println("[ssh-agent] " + factory.getDisplayName()); | ||
| agent = factory.start(new SingletonLauncherProvider(launcher), listener, | ||
| workspace != null ? SSHAgentStepExecution.tempDir(workspace) : null); | ||
| break; | ||
| } catch (Throwable t) { | ||
| faults.put(factory.getDisplayName(), t); | ||
| } | ||
| } | ||
| } | ||
| if (agent == null) { | ||
| listener.getLogger().println("[ssh-agent] FATAL: Could not find a suitable ssh-agent provider"); | ||
| listener.getLogger().println("[ssh-agent] Diagnostic report"); | ||
| for (Map.Entry<String, Throwable> fault : faults.entrySet()) { | ||
| listener.getLogger().println("[ssh-agent] * " + fault.getKey()); | ||
| StringWriter sw = new StringWriter(); | ||
| fault.getValue().printStackTrace(new PrintWriter(sw)); | ||
| for (String line : StringUtils.split(sw.toString(), "\n")) { | ||
| listener.getLogger().println("[ssh-agent] " + line); | ||
| } | ||
| } | ||
| throw new RuntimeException("[ssh-agent] Could not find a suitable ssh-agent provider."); | ||
| } | ||
| this.agent = agent; | ||
| agent = new ExecRemoteAgent(launcher, listener); |
There was a problem hiding this comment.
When there is no list of factories to consult, the code is simpler and the error handling should be as well: either running ssh-agent works, or it does not.
| @Override | ||
| public void buildEnvVars(Map<String, String> env) { | ||
| env.put("SSH_AUTH_SOCK", agent.getSocket()); | ||
| env.putAll(agent.getEnv()); |
There was a problem hiding this comment.
Probably only this one variable really needs to be passed to nested steps, but ssh-agent(1) suggests you just eval the env, so why not?
| public class SSHAgentStep extends AbstractStepImpl implements Serializable { | ||
|
|
||
| private static final long serialVersionUID = 1L; | ||
| public class SSHAgentStep extends Step { |
There was a problem hiding this comment.
Getting rid of long-deprecated Guice usage.
| return new StandardUsernameListBoxModel() | ||
| .includeMatchingAs( | ||
| item instanceof Queue.Task ? Tasks.getAuthenticationOf((Queue.Task)item) : ACL.SYSTEM, | ||
| item instanceof Queue.Task ? Tasks.getAuthenticationOf2((Queue.Task)item) : ACL.SYSTEM2, |
| } catch (Exception x) { | ||
| cause.addSuppressed(x); | ||
| } | ||
| super.stop(cause); |
There was a problem hiding this comment.
Probably better, so we pass along interruptions and so on as is. Otherwise I think I have seen builds whose terminating error was supposedly running ssh-agent -k, when this was just a side effect.
| @Override | ||
| public void onResume() { | ||
| super.onResume(); | ||
| try { | ||
| purgeSockets(); | ||
| initRemoteAgent(); |
There was a problem hiding this comment.
This never made sense, and probably contributed to the instability of the plugin. Why would we stop and restart the SSH agent process, running on some agent computer, just because the controller restarted?
|
|
||
| /** | ||
| * Purges all socket files created previously. | ||
| * Especially useful when Jenkins is restarted during the execution of this step. |
There was a problem hiding this comment.
Something else dating to #4 but of unclear purpose. We already call ssh-agent -k, which deletes the socket file.
| File socket = new File(it.next()); | ||
| if (socket.exists()) { |
There was a problem hiding this comment.
Furthermore, this was looking up the socket path on the controller filesystem, where it would never exist. So this was dead code AFAICT.
| * Runs a native SSH agent installed on a system. | ||
| */ | ||
| public class ExecRemoteAgent implements RemoteAgent { | ||
| public final class ExecRemoteAgent implements Serializable { |
There was a problem hiding this comment.
OK to serialize now that this merely contains a Map<String, String>, and means that the StepExecution does not need to recreate it.
| @Override | ||
| public boolean isSupported(Launcher launcher, final TaskListener listener) { | ||
| try { | ||
| int status = launcher.launch().cmds("ssh-agent", "-k").quiet(true).start().joinWithTimeout(1, TimeUnit.MINUTES, listener); |
There was a problem hiding this comment.
Pointless overhead; we are just going to run it for real shortly afterwards.
onResume
There was a problem hiding this comment.
This file being replaced by something. I've got failures all over the place with the removal of this.
There was a problem hiding this comment.
Can you be more specific please? Do you have a Pipeline build which was in the middle of sshagent at the time of an upgrade? I do not think there is a functional test for that yet…
There was a problem hiding this comment.
After the server is restarted, with the latest release from a few hours ago of ssh-agent, I have other plugins failing on start because they are looking for LauncherProvider class. Notice in your latest merges/release this class has been removed.
So trying to determine if this LauncherProvider has been replaced with something so I can at the very least alter my own plugin to use the new setup.
There was a problem hiding this comment.
other plugins failing on start because they are looking for LauncherProvider
Which plugins? There are no outside references to this class that I am aware of.
if this LauncherProvider has been replaced with something
No.
There was a problem hiding this comment.
So yes there are some outside references. I think I see how to modify my own code by looking at the changes. If I figure out the other plugins I'll let you know, chances are if your unaware it's going to be something unregistered.
There was a problem hiding this comment.
I do not think there is a functional test for [a Pipeline build which was in the middle of
sshagentat the time of an upgrade] yet
Tried to write one, but it looked hard since the plugin depends on a specific process running. Tested interactively and the step survived upgrade.
There was a problem hiding this comment.
This file being replaced by something. I've got failures all over the place with the removal of this.
There was a problem hiding this comment.
Can you be more specific please? Do you have a Pipeline build which was in the middle of sshagent at the time of an upgrade? I do not think there is a functional test for that yet…
There was a problem hiding this comment.
After the server is restarted, with the latest release from a few hours ago of ssh-agent, I have other plugins failing on start because they are looking for LauncherProvider class. Notice in your latest merges/release this class has been removed.
So trying to determine if this LauncherProvider has been replaced with something so I can at the very least alter my own plugin to use the new setup.
There was a problem hiding this comment.
other plugins failing on start because they are looking for LauncherProvider
Which plugins? There are no outside references to this class that I am aware of.
if this LauncherProvider has been replaced with something
No.
There was a problem hiding this comment.
So yes there are some outside references. I think I see how to modify my own code by looking at the changes. If I figure out the other plugins I'll let you know, chances are if your unaware it's going to be something unregistered.
There was a problem hiding this comment.
I do not think there is a functional test for [a Pipeline build which was in the middle of
sshagentat the time of an upgrade] yet
Tried to write one, but it looked hard since the plugin depends on a specific process running. Tested interactively and the step survived upgrade.
Cleaning up after #48.