jenkinsci / jenkinsci/ssh-agent-plugin

[JENKINS-29810] ssagent step to survive Jenkins restarts

Open
#197 2 comments 0 reactions 0 assignees View on GitHub
component:ssh-agent-plugin enhancement imported-jira-issue pipeline priority:major resolution:unresolved
Dominant language
Java
Stars
63
Forks
81
Avg merge
5h 36m
Merged PRs (30d)
9

Description

As of JENKINS-28689">JENKINS-28689 there is a Workflow step binding the agent. This survives Jenkins restarts in the common case:

node {

sshagent('...') {
sh 'ssh user@​host command' // restart Jenkins after connection made
}
}

or

node {

sshagent('...') {
sleep 999 // ← restart Jenkins here
sh 'ssh user@​host command'
}
}

but in this case

node {

sshagent('...') {
sh '''
sleep 999 # ← restart Jenkins here
ssh ...
'''
}
}

the shell script will be launched with one $SSH_AUTH_SOCK; then Jenkins will be restarted, killing the agent server; then after restart a new server will be started with a new socket address, defining a new $SSH_AUTH_SOCK for subsequent forked processes, yet the existing scripts continues to run and when ssh is launched it will fail to connect to the old server and die.

The solution for this problem would be to reuse a socket address across restarts.

Another even less common case would be

node {

sshagent('...') {
sh '''
sleep 999
# ← restart Jenkins here
ssh ...
'''
}
}

where the request to use the private key happens to come while Jenkins is restarting. That can only be solved by forking an external process for the agent server so that it survives the loss of the slave agent.

A related issue is that the current implementation will probably not survive a disconnection and reconnection of the slave agent with the Jenkins master still running, since it relies on onResume and lacks a ComputerListener. The forked agent approach would of course address that as well.

---
Originally reported by jglick, imported from: ssagent step to survive Jenkins restarts


  • status: Open
  • priority: Major
  • component(s): ssh-agent-plugin
  • label(s): pipeline
  • resolution: Unresolved
  • votes: 0
  • watchers: 2
  • imported: 20260604-211335

Raw content of original issue

As of JENKINS-28689 there is a Workflow step binding the agent. This survives Jenkins restarts in the common case:


node {

sshagent('...') {
sh 'ssh user@host command' // restart Jenkins after connection made
}
}

or


node {

sshagent('...') {
sleep 999 // ← restart Jenkins here
sh 'ssh user@host command'
}
}

but in this case


node {

sshagent('...') {
sh '''
sleep 999 # ← restart Jenkins here
ssh ...
'''
}
}

the shell script will be launched with one $SSH_AUTH_SOCK; then Jenkins will be restarted, killing the agent server; then after restart a new server will be started with a new socket address, defining a new $SSH_AUTH_SOCK for subsequent forked processes, yet the existing scripts continues to run and when ssh is launched it will fail to connect to the old server and die.

The solution for this problem would be to reuse a socket address across restarts.

Another even less common case would be


node {

sshagent('...') {
sh '''
sleep 999
# ← restart Jenkins here
ssh ...
'''
}
}

where the request to use the private key happens to come while Jenkins is restarting. That can only be solved by forking an external process for the agent server so that it survives the loss of the slave agent.

A related issue is that the current implementation will probably not survive a disconnection and reconnection of the slave agent with the Jenkins master still running, since it relies on onResume and lacks a ComputerListener. The forked agent approach would of course address that as well.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.