7

When Jenkins triggers maven-gpg-plugin in a remote Linux shell it fails with gpg: signing failed: Inappropriate ioctl for device. This used to work until recently. I don't know what changed.

I found a lot of online references suggesting export GPG_TTY=$(tty) but this doesn't work for ssh connections as tty is null. Any ideas?

Gili
  • 86,244
  • 97
  • 390
  • 689

4 Answers4

21

I found an excellent explanation over at https://myshittycode.com/2017/08/07/maven-gpg-plugin-prevent-signing-prompt-or-gpg-signing-failed-no-such-file-or-directory-error/

I will re-post the gist of the post in case the page goes down:

If you 1) initially had it working in the past, and 2) have tried all sorts of solutions from the web, and still couldn’t get it working, chances are you have unconsciously upgraded GPG version from 2.0 to 2.1.

Sounds about right...

To fix this, GPG 2.1 requires --pinentry-mode to be set to loopback in order to pick up gpg.passphrase value defined in Maven settings.xml.

So, update Maven GPG Plugin configuration in pom.xml to the following:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-gpg-plugin</artifactId>
    <version>1.6</version>
    <executions>
        <execution>
            <id>sign-artifacts</id>
            <phase>verify</phase>
            <goals>
                <goal>sign</goal>
            </goals>
            <configuration>
                <gpgArguments>
                    <arg>--pinentry-mode</arg>
                    <arg>loopback</arg>
                </gpgArguments>
            </configuration>
        </execution>
    </executions>
</plugin>
Gili
  • 86,244
  • 97
  • 390
  • 689
  • I'm still getting `gpg: signing failed: Inappropriate ioctl for device` with this configuration. I'm using Maven 3.6.3 and GnuPG 2.2.12. – Guss Mar 24 '21 at 20:56
  • 2
    Also, apparently this feature is handled automatically in the (as of yet unreleased) maven-gpg-plugin version 3.0.0: https://github.com/apache/maven-gpg-plugin/commit/11aca384c4005747d797dcc4857280d0d578d05f/ – Guss Mar 24 '21 at 21:02
  • 1
    I managed to get it working by moving the `` section to directly under `` – Guss Mar 24 '21 at 21:07
  • @Guss tried with maven-gpg-plugin 3.0.1 and this problem still persists. – wlnirvana Jun 28 '22 at 03:05
  • @wlnirvana - did you try my solution with the `` section? – Guss Jun 28 '22 at 13:47
  • This fixes it for gpg 2.1+, however, it breaks it for older versions, so if you have a mixed pool of machines, you may prefer to conditionally configure this setting in `~/.gnupg/gpg.conf` and leave your pom.xml files alone. – Akom Jul 07 '22 at 19:23
2

To build on Gili's answer:

Rather than modify every pom.xml to make Jenkins happy, you can add the following to ~/.gnupg/gpg.conf on Jenkins slaves with newer gpg:

pinentry-mode loopback

Puppet

You can also automate this. I'm using puppet to create gpg.conf files with this entry if gpg version is 2.1 or higher:

Template

<% if scope.lookupvar("gpg_version").to_f >= 2.1 %>
pinentry-mode loopback
<% end %>

Fact

Facter.add("gpg_version") do
  setcode do

    result = ''
    begin
      first_line = `gpg --version`.split("\n")[0]
      match = first_line.match /.* ([0-9\.]*)$/
      result = match[1]
    rescue

    end
    result
  end
end

Akom
  • 1,484
  • 19
  • 25
2

Upgrading to a newer maven-gpg-plugin version helped in my case. From 1.5 to 3.0.1.

Hopefully it will be at least a try for somebody

0

This worked for me:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
    <execution>
        <id>sign-artifacts</id>
        <phase>verify</phase>
        <goals>
            <goal>sign</goal>
        </goals>
    </execution>
</executions>
<configuration>
    <gpgArguments>
        <argument>--pinentry-mode</argument>
        <argument>loopback</argument>
    </gpgArguments>
</configuration>
</plugin>
Jakob Vad Nielsen
  • 722
  • 1
  • 7
  • 13
  • Isn't this already covered by the accepted answer? The code seems to be identical. – Gili Jul 08 '22 at 21:18
  • @Gili, in this answer the `...` part is after `...`, whereas in the accepted answer it was in `` right after ``. Anyway, it didn't fix the issue for me. – i01573 Aug 03 '22 at 20:21
  • @i01573 In the case of a single execution, both forms are equivalent. As far as I can tell, this answer doesn't add anything new to the discussion. – Gili Aug 04 '22 at 21:59
  • I stand corrected. This answer adds one thing to the discussion: upgrading the plugin version helps! – Gili Jan 27 '23 at 20:23