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); } }
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; } }
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()); }
/** 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); } } } }
/** * 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(); } }
/** * 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"); } }
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(); } }