我正在尝试将我的整个Jenkins配置从RHEL 6.7复制到RHEL 6.9,这样做一切看起来都不错,但只有一个jenkins构建失败并出现以下错误
Enter pass phrase:
can't connect to `/usr/share/tomcat6/.gnupg/S.gpg-agent': No such file or directory
gpg: skipped "Credit": Bad passphrase
gpg: signing failed: Bad passphrase
Pass phrase check failed
gpg私钥1.4.5存在于jenkins配置中。奇怪的是,所有其他构建都能够签署rpm,但只有一个构建失败
任何人都知道如何修复它?
答案 0 :(得分:0)
RPM读取密码短语使用getpass(3)并通过附加文件描述符发送到gnupg。
这会产生两个需要通过自动签名机制来处理的问题:
1)某些版本的rpm使用getpass(3),它将使用tty(禁用回显)并需要设置伪tty,以便将自动密码传递给RPM。确保已安装pty文件系统,并且expect(1)是设置可从中读取密码的pty的一种方法。还有另一种使用/ proc文件描述符的方法可以在linux上尝试。然后使用--passphrase-fd将密码发送到gnupg。
2)gnupg2还可以在单独的代理进程中处理持久性密码,这有时很难设置并“自动”继续运行,因为检测取决于用户/进程ID。您的报告似乎有一个代理(这意味着gnupg2或特殊的gpg1配置),即使您提到1.4.5(似乎使用gnupg1)。
答案 1 :(得分:0)
我在您的日志中看到两个单独的问题,需要解决。
无法连接到`/usr/share/tomcat6/.gnupg/S.gpg-agent':没有这样的文件 或目录
gpg-agent需要作为守护程序在构建主机上运行,它将在其中连接到套接字以侦听请求。也许它已经在运行,但是Jenkins正在错误的目录中寻找它的套接字,因为GNUPGHOME
设置为一些异常值。也许gpg-agent
不在运行,需要启动一个新实例。
类似此脚本的内容可用于安全地附加到现有的gpg-agent
或启动新实例。
#!/bin/bash
# Decide whether to start gpg-agent daemon.
# Create necessary symbolic link in $GNUPGHOME/.gnupg/S.gpg-agent
SOCKET=S.gpg-agent
PIDOF=`pgrep gpg-agent`
RETVAL=$?
if [ "$RETVAL" -eq 1 ]; then
echo "Starting gpg-agent daemon."
eval `gpg-agent --daemon `
else
echo "Daemon gpg-agent already running."
fi
# Nasty way to find gpg-agent's socket file...
GPG_SOCKET_FILE=`find /tmp/gpg-* -name $SOCKET`
echo "Updating socket file link."
cp -fs $GPG_SOCKET_FILE $GNUPGHOME/.gnupg/S.gpg-agent
您可能要用pgrep
代替pidof
,具体取决于您的外壳。
如果您确实要启动新的代理,则可以通过运行gpg --list-keys
来检查密钥是否已装入其中。如果您没有看到它,则需要使用gpg --import
添加它。按照Using Credentials的Jenkins文档进行操作。
解决gpg-agent
问题可能会解决您的其他问题,因此在执行其他任何操作之前,请先检查您的工作是否正常。
参考:
gpg:跳过了“信用”:密码短语错误
GPG密钥受密码保护。 rpm
正在要求输入此密码,并希望手动输入。当然,詹金斯(Jenkins)是非交互地运行事物,因此这是不可能的。我们需要某种方式将密码短语提供给rpm
,以便它可以将其转发到gpg
,否则我们需要通过某种缓存机制直接将密码短语提供给gpg
。 / p>
期望方法
通过将rpm --addsign
调用包装在expect脚本中,我们可以使用expect
无头输入密码。这种做法很普遍。假设以下脚本名为rpm_sign.exp
:
#!/usr/bin/expect -f
set password [lindex $argv 0]
set files [lrange $argv 1 1]
spawn rpm --define --addsign $files
expect "Enter pass phrase:"
send -- "$password\r"
expect eof
该脚本可以在Jenkins Shell步骤或管道中使用,如下所示:
echo "Signing rpms ..."
sh "./rpm_sign.exp '${GPG_PASSPHRASE}' <list-of-files>"
请注意,经过一些修改,可以指定您要用来签名RPM的GPG身份。这是通过在包装脚本中将--define {_gpg_name $YOUR_KEY_ID_HERE}
作为参数传递给rpm来完成的。请注意TCL语法。由于我们是在詹金斯上进行的,因此可能会提供多组凭据,因此我认为这是相关信息。
参考:
其他方法
还有其他解决方案可能更适合您的配置。一种这样的解决方案是使用RpmSignPlugin,它在后台使用expect
。可以在unix.stackexchange.com的此帖子中找到其他解决方案。