Example #1
0
 public void run() {
   String threadName = Thread.currentThread().getName();
   Thread.currentThread().setName("SCM polling for " + job);
   try {
     startTime = System.currentTimeMillis();
     if (runPolling()) {
       AbstractProject p = job.asProject();
       String name = " #" + p.getNextBuildNumber();
       SCMTriggerCause cause;
       try {
         cause = new SCMTriggerCause(getLogFile());
       } catch (IOException e) {
         LOGGER.log(WARNING, "Failed to parse the polling log", e);
         cause = new SCMTriggerCause();
       }
       if (p.scheduleBuild(p.getQuietPeriod(), cause, additionalActions)) {
         LOGGER.info("SCM changes detected in " + job.getName() + ". Triggering " + name);
       } else {
         LOGGER.info(
             "SCM changes detected in " + job.getName() + ". Job is already in the queue");
       }
     }
   } finally {
     Thread.currentThread().setName(threadName);
   }
 }
Example #2
0
    private boolean runPolling() {
      try {
        // to make sure that the log file contains up-to-date text,
        // don't do buffering.
        StreamTaskListener listener = new StreamTaskListener(getLogFile());

        try {
          PrintStream logger = listener.getLogger();
          long start = System.currentTimeMillis();
          logger.println("Started on " + DateFormat.getDateTimeInstance().format(new Date()));
          boolean result = job.poll(listener).hasChanges();
          logger.println(
              "Done. Took " + Util.getTimeSpanString(System.currentTimeMillis() - start));
          if (result) logger.println("Changes found");
          else logger.println("No changes");
          return result;
        } catch (Error e) {
          e.printStackTrace(listener.error("Failed to record SCM polling"));
          LOGGER.log(Level.SEVERE, "Failed to record SCM polling", e);
          throw e;
        } catch (RuntimeException e) {
          e.printStackTrace(listener.error("Failed to record SCM polling"));
          LOGGER.log(Level.SEVERE, "Failed to record SCM polling", e);
          throw e;
        } finally {
          listener.close();
        }
      } catch (IOException e) {
        LOGGER.log(Level.SEVERE, "Failed to record SCM polling", e);
        return false;
      }
    }
Example #3
0
  public CLI(URL jenkins, ExecutorService exec) throws IOException, InterruptedException {
    String url = jenkins.toExternalForm();
    if (!url.endsWith("/")) url += '/';

    ownsPool = exec == null;
    pool = exec != null ? exec : Executors.newCachedThreadPool();

    int clip = getCliTcpPort(url);
    if (clip >= 0) {
      // connect via CLI port
      String host = new URL(url).getHost();
      LOGGER.fine("Trying to connect directly via TCP/IP to port " + clip + " of " + host);
      Socket s = new Socket(host, clip);
      DataOutputStream dos = new DataOutputStream(s.getOutputStream());
      dos.writeUTF("Protocol:CLI-connect");

      channel =
          new Channel(
              "CLI connection to " + jenkins,
              pool,
              new BufferedInputStream(new SocketInputStream(s)),
              new BufferedOutputStream(new SocketOutputStream(s)));
    } else {
      // connect via HTTP
      LOGGER.fine("Trying to connect to " + url + " via HTTP");
      url += "cli";
      jenkins = new URL(url);

      FullDuplexHttpStream con = new FullDuplexHttpStream(jenkins);
      channel =
          new Channel(
              "Chunked connection to " + jenkins,
              pool,
              con.getInputStream(),
              con.getOutputStream());
      new PingThread(channel, 30 * 1000) {
        protected void onDead() {
          // noop. the point of ping is to keep the connection alive
          // as most HTTP servers have a rather short read time out
        }
      }.start();
    }

    // execute the command
    entryPoint = (CliEntryPoint) channel.waitForRemoteProperty(CliEntryPoint.class.getName());

    if (entryPoint.protocolVersion() != CliEntryPoint.VERSION)
      throw new IOException(Messages.CLI_VersionMismatch());
  }
Example #4
0
 /** try all the default key locations */
 private static void addDefaultPrivateKeyLocations(List<KeyPair> keyFileCandidates) {
   File home = new File(System.getProperty("user.home"));
   for (String path : new String[] {".ssh/id_rsa", ".ssh/id_dsa", ".ssh/identity"}) {
     File key = new File(home, path);
     if (key.exists()) {
       try {
         keyFileCandidates.add(loadKey(key));
       } catch (IOException e) {
         // don't report an error. the user can still see it by using the -i option
         LOGGER.log(FINE, "Failed to load " + key, e);
       } catch (GeneralSecurityException e) {
         LOGGER.log(FINE, "Failed to load " + key, e);
       }
     }
   }
 }
Example #5
0
  /**
   * Run the SCM trigger with additional build actions. Used by SubversionRepositoryStatus to
   * trigger a build at a specific revisionn number.
   *
   * @param additionalActions
   * @since 1.375
   */
  public void run(Action[] additionalActions) {
    if (Hudson.getInstance().isQuietingDown()) return; // noop

    DescriptorImpl d = getDescriptor();

    LOGGER.fine("Scheduling a polling for " + job);
    if (d.synchronousPolling) {
      LOGGER.fine(
          "Running the trigger directly without threading, "
              + "as it's already taken care of by Trigger.Cron");
      new Runner(additionalActions).run();
    } else {
      // schedule the polling.
      // even if we end up submitting this too many times, that's OK.
      // the real exclusion control happens inside Runner.
      LOGGER.fine("scheduling the trigger to (asynchronously) run");
      d.queue.execute(new Runner(additionalActions));
      d.clogCheck();
    }
  }
Example #6
0
  /**
   * Attend to channels in the hub.
   *
   * <p>This method returns when {@link #close()} is called and the selector is shut down.
   */
  public void run() {
    synchronized (startedLock) {
      started = true;
      selectorThread = Thread.currentThread();
      startedLock.notifyAll();
    }
    final String oldName = selectorThread.getName();

    try {
      while (true) {
        try {
          while (true) {
            Callable<Void, IOException> t = selectorTasks.poll();
            if (t == null) break;
            try {
              t.call();
            } catch (IOException e) {
              LOGGER.log(WARNING, "Failed to process selectorTasks", e);
              // but keep on at the next task
            }
          }

          selectorThread.setName(
              "NioChannelHub keys=" + selector.keys().size() + " gen=" + (gen++) + ": " + oldName);
          selector.select();
        } catch (IOException e) {
          whatKilledSelectorThread = e;
          LOGGER.log(WARNING, "Failed to select", e);
          abortAll(e);
          return;
        }

        Iterator<SelectionKey> itr = selector.selectedKeys().iterator();
        while (itr.hasNext()) {
          SelectionKey key = itr.next();
          itr.remove();
          Object a = key.attachment();

          if (a instanceof NioTransport) {
            final NioTransport t = (NioTransport) a;

            try {
              if (key.isReadable()) {
                if (t.rb.receive(t.rr()) == -1) {
                  t.closeR();
                }

                final byte[] buf = new byte[2]; // space for reading the chunk header
                int pos = 0;
                int packetSize = 0;
                while (true) {
                  if (t.rb.peek(pos, buf) < buf.length)
                    break; // we don't have enough to parse header
                  int header = ChunkHeader.parse(buf);
                  int chunk = ChunkHeader.length(header);
                  pos += buf.length + chunk;
                  packetSize += chunk;
                  boolean last = ChunkHeader.isLast(header);
                  if (last
                      && pos <= t.rb.readable()) { // do we have the whole packet in our buffer?
                    // read in the whole packet
                    final byte[] packet = new byte[packetSize];
                    int r_ptr = 0;
                    do {
                      int r = t.rb.readNonBlocking(buf);
                      assert r == buf.length;
                      header = ChunkHeader.parse(buf);
                      chunk = ChunkHeader.length(header);
                      last = ChunkHeader.isLast(header);
                      t.rb.readNonBlocking(packet, r_ptr, chunk);
                      packetSize -= chunk;
                      r_ptr += chunk;
                    } while (!last);
                    assert packetSize == 0;
                    if (packet.length > 0) {
                      t.swimLane.submit(
                          new Runnable() {
                            public void run() {
                              t.receiver.handle(packet);
                            }
                          });
                    }
                    pos = 0;
                  }
                }

                if (t.rb.writable() == 0 && t.rb.readable() > 0) {
                  String msg =
                      "Command buffer overflow. Read "
                          + t.rb.readable()
                          + " bytes but still too small for a single command";
                  LOGGER.log(WARNING, msg);
                  // to avoid infinite hang, abort this connection
                  t.abort(new IOException(msg));
                }
                if (t.rb.isClosed()) {
                  // EOF. process this synchronously with respect to packets
                  t.swimLane.submit(
                      new Runnable() {
                        public void run() {
                          // if this EOF is unexpected, report an error.
                          if (!t.getChannel().isInClosed())
                            t.getChannel().terminate(new EOFException());
                        }
                      });
                }
              }
              if (key.isValid() && key.isWritable()) {
                t.wb.send(t.ww());
                if (t.wb.readable() < 0) {
                  // done with sending all the data
                  t.closeW();
                }
              }
              t.reregister();
            } catch (IOException e) {
              LOGGER.log(WARNING, "Communication problem", e);
              t.abort(e);
            } catch (CancelledKeyException e) {
              // see JENKINS-24050. I don't understand how this can happen, given that the selector
              // thread is the only thread that cancels keys. So to better understand what's going
              // on,
              // report the problem.
              LOGGER.log(SEVERE, "Unexpected key cancellation for " + t, e);
              // to be on the safe side, abort the communication. if we don't do this, it's possible
              // that the key never gets re-registered to the selector, and the traffic will hang
              // on this channel.
              t.abort(e);
            }
          } else {
            onSelected(key);
          }
        }
      }
    } catch (ClosedSelectorException e) {
      // end normally
      // TODO: what happens to all the registered ChannelPairs? don't we need to shut them down?
      whatKilledSelectorThread = e;
    } catch (RuntimeException e) {
      whatKilledSelectorThread = e;
      LOGGER.log(WARNING, "Unexpected shutdown of the selector thread", e);
      abortAll(e);
      throw e;
    } catch (Error e) {
      whatKilledSelectorThread = e;
      LOGGER.log(WARNING, "Unexpected shutdown of the selector thread", e);
      abortAll(e);
      throw e;
    } finally {
      selectorThread.setName(oldName);
      selectorThread = null;
      if (whatKilledSelectorThread == null)
        whatKilledSelectorThread = new AssertionError("NioChannelHub shouldn't exit normally");
    }
  }
Example #7
0
  public static int _main(String[] _args) throws Exception {
    List<String> args = Arrays.asList(_args);
    List<KeyPair> candidateKeys = new ArrayList<KeyPair>();
    boolean sshAuthRequestedExplicitly = false;

    String url = System.getenv("JENKINS_URL");

    if (url == null) url = System.getenv("HUDSON_URL");

    while (!args.isEmpty()) {
      String head = args.get(0);
      if (head.equals("-s") && args.size() >= 2) {
        url = args.get(1);
        args = args.subList(2, args.size());
        continue;
      }
      if (head.equals("-i") && args.size() >= 2) {
        File f = new File(args.get(1));
        if (!f.exists()) {
          printUsage(Messages.CLI_NoSuchFileExists(f));
          return -1;
        }
        try {
          candidateKeys.add(loadKey(f));
        } catch (IOException e) {
          throw new Exception("Failed to load key: " + f, e);
        } catch (GeneralSecurityException e) {
          throw new Exception("Failed to load key: " + f, e);
        }
        args = args.subList(2, args.size());
        sshAuthRequestedExplicitly = true;
        continue;
      }
      break;
    }

    if (url == null) {
      printUsage(Messages.CLI_NoURL());
      return -1;
    }

    if (args.isEmpty()) args = Arrays.asList("help"); // default to help

    if (candidateKeys.isEmpty()) addDefaultPrivateKeyLocations(candidateKeys);

    CLI cli = new CLI(new URL(url));
    try {
      if (!candidateKeys.isEmpty()) {
        try {
          // TODO: server verification
          cli.authenticate(candidateKeys);
        } catch (IllegalStateException e) {
          if (sshAuthRequestedExplicitly) {
            System.err.println("The server doesn't support public key authentication");
            return -1;
          }
        } catch (UnsupportedOperationException e) {
          if (sshAuthRequestedExplicitly) {
            System.err.println("The server doesn't support public key authentication");
            return -1;
          }
        } catch (GeneralSecurityException e) {
          if (sshAuthRequestedExplicitly) {
            System.err.println(e.getMessage());
            LOGGER.log(FINE, e.getMessage(), e);
            return -1;
          }
          System.err.println(
              "Failed to authenticate with your SSH keys. Proceeding with anonymous access");
          LOGGER.log(
              FINE,
              "Failed to authenticate with your SSH keys. Proceeding with anonymous access",
              e);
        }
      }

      // execute the command
      // Arrays.asList is not serializable --- see 6835580
      args = new ArrayList<String>(args);
      return cli.execute(args, System.in, System.out, System.err);
    } finally {
      cli.close();
    }
  }