示例#1
0
文件: SSHMain.java 项目: jexp/idea2
 /**
  * Start the application
  *
  * @throws IOException if there is a problem with connection
  * @throws InterruptedException if thread was interrupted
  */
 private void start() throws IOException, InterruptedException {
   Connection c = new Connection(myHost.getHostName(), myHost.getPort());
   try {
     configureKnownHosts(c);
     c.connect(new HostKeyVerifier());
     authenticate(c);
     final Session s = c.openSession();
     try {
       s.execCommand(myCommand);
       // Note that stdin is not being waited using semaphore.
       // Instead, the SSH process waits for remote process exit
       // if remote process exited, none is interested in stdin
       // anyway.
       forward("stdin", s.getStdin(), System.in, false);
       forward("stdout", System.out, s.getStdout(), true);
       forward("stderr", System.err, s.getStderr(), true);
       myForwardCompleted.acquire(2); // wait only for stderr and stdout
       s.waitForCondition(ChannelCondition.EXIT_STATUS, Long.MAX_VALUE);
       Integer exitStatus = s.getExitStatus();
       if (exitStatus == null) {
         // broken exit status
         exitStatus = 1;
       }
       System.exit(exitStatus.intValue() == 0 ? myExitCode : exitStatus.intValue());
     } finally {
       s.close();
     }
   } finally {
     c.close();
   }
 }
  private boolean runInitScript(
      final Computer computer, final PrintStream logger, final Connection conn, final SCPClient scp)
      throws IOException, InterruptedException {

    String initScript = Util.fixEmptyAndTrim(computer.getNode().getInitScript());

    if (initScript == null) {
      return true;
    }
    if (conn.exec("test -e ~/.hudson-run-init", logger) == 0) {
      return true;
    }

    logger.println("Executing init script");
    scp.put(initScript.getBytes("UTF-8"), "init.sh", "/tmp", "0700");
    Session session = conn.openSession();
    session.requestDumbPTY(); // so that the remote side bundles stdout and stderr
    session.execCommand(buildUpCommand(computer, "/tmp/init.sh"));

    session.getStdin().close(); // nothing to write here
    session.getStderr().close(); // we are not supposed to get anything from stderr
    IOUtils.copy(session.getStdout(), logger);

    int exitStatus = waitCompletion(session);
    if (exitStatus != 0) {
      logger.println("init script failed: exit code=" + exitStatus);
      return false;
    }
    session.close();

    // Needs a tty to run sudo.
    session = conn.openSession();
    session.requestDumbPTY(); // so that the remote side bundles stdout and stderr
    session.execCommand(buildUpCommand(computer, "touch ~/.hudson-run-init"));
    session.close();

    return true;
  }
  /**
   * Connects to the given {@link Computer} via SSH and installs Java/Jenkins agent if necessary.
   */
  @Override
  public void launch(SlaveComputer _computer, TaskListener listener) {

    Computer computer = (Computer) _computer;
    PrintStream logger = listener.getLogger();

    Date startDate = new Date();
    logger.println("Start time: " + getUtcDate(startDate));

    final Connection conn;
    Connection cleanupConn = null;
    boolean successful = false;

    try {
      conn = connectToSsh(computer, logger);
      cleanupConn = conn;
      logger.println("Authenticating as " + computer.getRemoteAdmin());
      if (!conn.authenticateWithPublicKey(
          computer.getRemoteAdmin(), computer.getNode().getPrivateKey().toCharArray(), "")) {
        logger.println("Authentication failed");
        throw new Exception("Authentication failed");
      }

      final SCPClient scp = conn.createSCPClient();

      if (!runInitScript(computer, logger, conn, scp)) {
        return;
      }

      if (!installJava(logger, conn)) {
        return;
      }

      logger.println("Copying slave.jar");
      scp.put(Jenkins.getInstance().getJnlpJars("slave.jar").readFully(), "slave.jar", "/tmp");
      String jvmOpts = Util.fixNull(computer.getNode().getJvmOpts());
      String launchString = "java " + jvmOpts + " -jar /tmp/slave.jar";
      logger.println("Launching slave agent: " + launchString);
      final Session sess = conn.openSession();
      sess.execCommand(launchString);
      computer.setChannel(
          sess.getStdout(),
          sess.getStdin(),
          logger,
          new Channel.Listener() {
            @Override
            public void onClosed(Channel channel, IOException cause) {
              sess.close();
              conn.close();
            }
          });

      successful = true;
    } catch (Exception e) {
      LOGGER.log(Level.WARNING, e.getMessage(), e);
      try {
        Jenkins.getInstance().removeNode(computer.getNode());
      } catch (Exception ee) {
        ee.printStackTrace(logger);
      }
      e.printStackTrace(logger);
    } finally {
      Date endDate = new Date();
      logger.println("Done setting up at: " + getUtcDate(endDate));
      logger.println(
          "Done in "
              + TimeUnit2.MILLISECONDS.toSeconds(endDate.getTime() - startDate.getTime())
              + " seconds");
      if (cleanupConn != null && !successful) {
        cleanupConn.close();
      }
    }
  }