在Windows上为Jenkins配置SSH代理插件

时间:2018-02-03 00:31:10

标签: windows jenkins sh jenkins-pipeline ssh-agent

我正在尝试在Windows安装的Jenkins(v2.103)上配置SSH代理插件(v1.15),以便能够通过ssh向远程计算机发出命令。

我已经安装了插件,并在Jenkins Credentials中添加了一个条目(如下所示),其中包含可以登录到远程计算机的私钥和密码(hostname:corp-wfdemo)。我已经确认此密钥用于验证运行Jenkins的用户。

Credentials in Jenkins

我已经创建了一个Pipeline项目,并添加了这个Groovy脚本来测试ssh:

node ('ssh') {
    stage ('test') {
        sshagent(['corp-wfdemo']) {
            sh 'ls -la'
        }
    }
}

Jenkins大师的标签为ssh。这是安装了Git Bash(MINGW64)的Windows Server 2012计算机。

当我尝试运行此作业时,它在尝试查找一些自动生成的askpass.sh脚本时失败。这是输出:

Jenkins job output

有人可以帮忙吗?提前谢谢!

此外,每次我尝试运行此作业时,都会生成ssh-agent的新实例而不会终止,从而导致这个混乱:

ssh-agent processes

1 个答案:

答案 0 :(得分:0)

我已经在 Windows 上使用 Git 很长时间了,但我一直在为同样的问题而苦苦挣扎。在使用 github 或其他远程 ssh 存储库时,我希望能够打开多个窗口,但让它们共享同一个 ssh 代理。

以下是我为 Git Bash 调用的 assure_ssh_agent shell 函数的完整内容。在您运行的每个独立会话中获取其定义。我的 ~/.profile 中有以下两行。

. ~/ssh-agent.sh
assure_ssh_agent

在定义函数后,您可以通过 ssh-添加您的密钥文件,或者,如果您在 .ssh/keylist 中定义了它们的列表,则只需运行 addkeys,它会将所有密钥文件加载到代理默认10小时,对于一个正常工作日和长时间的午休来说应该足够了。

工作原理:脚本在文件 .ssh/pid_store 中维护共享状态。 如果 assure_ssh_agent() 找不到有效的 pid,它将启动一个新的代理,并将其 pid 和套接字写入那里,用于任何后续会话。


ssh-agent.sh 的内容:

# echo $SSH_AUTH_SOCK $SSH_AGENT_PID

is_running() {
  (kill -0 ${1:?PID}) 2> /dev/null
}

agent_pid_store() {
  (
  pid_store=$HOME/.ssh/agent_pid
  touch -a $pid_store
  case $1 in
  ( read ) read pid sock < $pid_store && echo $pid $sock
      [ -n "$sock" ]
  ;;
  ( write) echo \
            ${SSH_AGENT_PID:?} \
            ${SSH_AUTH_SOCK:?} > $pid_store
  ;;
  ( clear ) rm -f ${pid_store:?}
  esac
  )
}

find_active_ssh_agent() {
  (
  set -- $(agent_pid_store read)
  pid=$1 sock=$2
  case $1 in
  ("") return 1
  ;;
  ($SSH_AGENT_PID)
     is_running $SSH_AGENT_PID && echo $SSH_AGENT_PID $2
  ;;
  (*)
     is_running $pid && echo $pid $sock && return
     return 1
  ;;
  esac
  )
}

ssh_agent_is_running() {
  (find_active_ssh_agent | read _was_there_something_to_read_)
}


assure_ssh_agent() {
  unset GIT_SSH
  unset SVN_SSH

  set -- $(
    find_active_ssh_agent
  ) && pid=$1 sock=$2

  :  "pid='$pid' sock='$sock'"
  :  "length: pid:${#pid} sock:${#sock}"

  case $pid$sock in
  ( "" )
    printf  "* " >& 2 
    eval $( ssh-agent ) > /dev/null
    agent_pid_store write
    echo "ssh agent ${SSH_AGENT_PID}" >& 2 
    return
  ;;
  ( * )
    export SSH_AGENT_PID=$pid SSH_AUTH_SOCK=$sock
    echo "ssh agent ${SSH_AGENT_PID}" >& 2 
    set +x
    return
  ;;
  esac
}

addkeys(){
  (set -e #-x
  unset GIT_SSH
  unset SVN_SSH
  Keyfile_Timeout=36000

  cd ~/.ssh 
  exec < keylist || 
    exit 1 $(echo >& 2 "Add names of keyfiles to $HOME/.ssh/keylist")
  while read keyfile
  do
    ssh-add -t ${Keyfile_Timeout} ~/.ssh/$keyfile
  done
  )
}