Ejemplo n.º 1
0
 /**
  * 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 int waitCompletion(Session session) throws InterruptedException {
   // I noticed that the exit status delivery often gets delayed. Wait up to 1 sec.
   for (int i = 0; i < 10; i++) {
     Integer r = session.getExitStatus();
     if (r != null) return r;
     Thread.sleep(100);
   }
   return -1;
 }
  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();
      }
    }
  }
  public static void main(String[] args) {
    String hostname = "127.0.0.1";
    String username = "******";
    String password = "******";

    try {
      /* Create a connection instance */

      Connection conn = new Connection(hostname);

      /* Now connect */

      conn.connect();

      /* Authenticate */

      boolean isAuthenticated = conn.authenticateWithPassword(username, password);

      if (isAuthenticated == false) throw new IOException("Authentication failed.");

      /* Create a session */

      Session sess = conn.openSession();

      sess.execCommand("echo \"Text on STDOUT\"; echo \"Text on STDERR\" >&2");

      InputStream stdout = new StreamGobbler(sess.getStdout());
      InputStream stderr = new StreamGobbler(sess.getStderr());

      BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
      BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));

      System.out.println("Here is the output from stdout:");

      while (true) {
        String line = stdoutReader.readLine();
        if (line == null) break;
        System.out.println(line);
      }

      System.out.println("Here is the output from stderr:");

      while (true) {
        String line = stderrReader.readLine();
        if (line == null) break;
        System.out.println(line);
      }

      /* Close this session */

      sess.close();

      /* Close the connection */

      conn.close();

    } catch (IOException e) {
      e.printStackTrace(System.err);
      System.exit(2);
    }
  }