Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-19844

Maven agent socket bind too inflexible (allow Jenkins in virtualized environment)

XMLWordPrintable

    • Icon: Improvement Improvement
    • Resolution: Fixed
    • Icon: Major Major
    • maven-plugin
    • None

      When creating the Maven agent Jenkins currently does the following in AbstractMavenProcessFactory:

      static final class AcceptorImpl implements Acceptor, Serializable {
          private transient final ServerSocket serverSocket;
      
          AcceptorImpl() throws IOException {
              // open a TCP socket to talk to the launched Maven process.
              // let the OS pick up a random open port
              this.serverSocket = new ServerSocket();
              serverSocket.bind(null);
              ...
          }
          ...
      }
      

      If the argument to bind is null then Java will bind to a random port on the wildcard interface. This is typically not allowed in a virtualized environment (think RedHat's OpenShift).

      First off, please note that the Javadoc in the JDK is slightly misleading for this method as it says :

      If the address is null, then the system will pick up an ephemeral port and a valid local address to bind the socket.

      The word "local address" in that sentence gives you the impression that Java will bind to 'localhost' interface. That is not what happens. It will bind on the wildcard interface. In many environments such action is not allowed and will fail with java.net.BindException: Permission denied

      (if you are not familiar with the term 'wildcard interface' it simply means all network interfaces, typically shown in netstat as a "*." prefix for IPv4 and as a "::" prefix for IPv6)

      So we need a way to override the address that the bind operation will use.
      Something like:

      String address = System.getenv("JENKINS_MAVEN_AGENT_ADDRESS");
      if (address != null) {
          serverSocket.bind(new InetSocketAddress(InetAddress.getByName(address), 0));
      } else {
          serverSocket.bind(null);
      }
      

      There's a guy (not me) who has cloned Jenkins and made his own Jenkins just for this one purpose. Here's the project : https://github.com/siasia/jenkins/tree/jenkins-1.504-openshift

      It would be much better if this was to become part of standard Jenkins.

            Unassigned Unassigned
            phansson Peter Hansson
            Votes:
            3 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: