use of hudson.remoting.VirtualChannel in project hudson-2.x by hudson.
the class Computer method getHostName.
/**
* This method tries to compute the name of the host that's reachable by all the other nodes.
*
* <p>
* Since it's possible that the slave is not reachable from the master (it may be behind a firewall,
* connecting to master via JNLP), this method may return null.
*
* It's surprisingly tricky for a machine to know a name that other systems can get to,
* especially between things like DNS search suffix, the hosts file, and YP.
*
* <p>
* So the technique here is to compute possible interfaces and names on the slave,
* then try to ping them from the master, and pick the one that worked.
*
* <p>
* The computation may take some time, so it employs caching to make the successive lookups faster.
*
* @since 1.300
* @return
* null if the host name cannot be computed (for example because this computer is offline,
* because the slave is behind the firewall, etc.)
*/
public String getHostName() throws IOException, InterruptedException {
if (hostNameCached)
// in the worst case we end up having multiple threads computing the host name simultaneously, but that's not harmful, just wasteful.
return cachedHostName;
VirtualChannel channel = getChannel();
// can't compute right now
if (channel == null)
return null;
for (String address : channel.call(new ListPossibleNames())) {
try {
InetAddress ia = InetAddress.getByName(address);
if (!(ia instanceof Inet4Address)) {
LOGGER.fine(address + " is not an IPv4 address");
continue;
}
if (!ComputerPinger.checkIsReachable(ia, 3)) {
LOGGER.fine(address + " didn't respond to ping");
continue;
}
cachedHostName = ia.getCanonicalHostName();
hostNameCached = true;
return cachedHostName;
} catch (IOException e) {
// if a given name fails to parse on this host, we get this error
LOGGER.log(Level.FINE, "Failed to parse " + address, e);
}
}
// allow the administrator to manually specify the host name as a fallback. HUDSON-5373
cachedHostName = channel.call(new GetFallbackName());
hostNameCached = true;
return null;
}
use of hudson.remoting.VirtualChannel in project hudson-2.x by hudson.
the class Fingerprinter method record.
private void record(AbstractBuild<?, ?> build, BuildListener listener, Map<String, String> record, final String targets) throws IOException, InterruptedException {
final class Record implements Serializable {
final boolean produced;
final String relativePath;
final String fileName;
final String md5sum;
public Record(boolean produced, String relativePath, String fileName, String md5sum) {
this.produced = produced;
this.relativePath = relativePath;
this.fileName = fileName;
this.md5sum = md5sum;
}
Fingerprint addRecord(AbstractBuild build) throws IOException {
FingerprintMap map = Hudson.getInstance().getFingerprintMap();
return map.getOrCreate(produced ? build : null, fileName, md5sum);
}
private static final long serialVersionUID = 1L;
}
final long buildTimestamp = build.getTimeInMillis();
FilePath ws = build.getWorkspace();
if (ws == null) {
listener.error(Messages.Fingerprinter_NoWorkspace());
build.setResult(Result.FAILURE);
return;
}
List<Record> records = ws.act(new FileCallable<List<Record>>() {
public List<Record> invoke(File baseDir, VirtualChannel channel) throws IOException {
List<Record> results = new ArrayList<Record>();
FileSet src = Util.createFileSet(baseDir, targets);
DirectoryScanner ds = src.getDirectoryScanner();
for (String f : ds.getIncludedFiles()) {
File file = new File(baseDir, f);
// consider the file to be produced by this build only if the timestamp
// is newer than when the build has started.
// 2000ms is an error margin since since VFAT only retains timestamp at 2sec precision
boolean produced = buildTimestamp <= file.lastModified() + 2000;
try {
results.add(new Record(produced, f, file.getName(), new FilePath(file).digest()));
} catch (IOException e) {
throw new IOException2(Messages.Fingerprinter_DigestFailed(file), e);
} catch (InterruptedException e) {
throw new IOException2(Messages.Fingerprinter_Aborted(), e);
}
}
return results;
}
});
for (Record r : records) {
Fingerprint fp = r.addRecord(build);
if (fp == null) {
listener.error(Messages.Fingerprinter_FailedFor(r.relativePath));
continue;
}
fp.add(build);
record.put(r.relativePath, fp.getHashString());
}
}
use of hudson.remoting.VirtualChannel in project hudson-2.x by hudson.
the class ConnectionActivityMonitor method execute.
protected void execute(TaskListener listener) throws IOException, InterruptedException {
if (!enabled)
return;
long now = System.currentTimeMillis();
for (Computer c : Hudson.getInstance().getComputers()) {
VirtualChannel ch = c.getChannel();
if (ch instanceof Channel) {
Channel channel = (Channel) ch;
if (now - channel.getLastHeard() > TIME_TILL_PING) {
// haven't heard from this slave for a while.
Long lastPing = (Long) channel.getProperty(ConnectionActivityMonitor.class);
if (lastPing != null && now - lastPing > TIMEOUT) {
LOGGER.info("Repeated ping attempts failed on " + c.getName() + ". Disconnecting");
c.disconnect(OfflineCause.create(Messages._ConnectionActivityMonitor_OfflineCause()));
} else {
// send a ping. if we receive a reply, it will be reflected in the next getLastHeard() call.
channel.callAsync(PING_COMMAND);
if (lastPing == null)
channel.setProperty(ConnectionActivityMonitor.class, now);
}
} else {
// we are receiving data nicely
channel.setProperty(ConnectionActivityMonitor.class, null);
}
}
}
}
use of hudson.remoting.VirtualChannel in project hudson-2.x by hudson.
the class SU method execute.
/**
* Starts a new priviledge-escalated environment, execute a closure, and shut it down.
*/
public static <V, T extends Throwable> V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable<V, T> closure) throws T, IOException, InterruptedException {
VirtualChannel ch = start(listener, rootUsername, rootPassword);
try {
return ch.call(closure);
} finally {
ch.close();
// give some time for orderly shutdown, but don't block forever.
ch.join(3000);
}
}
use of hudson.remoting.VirtualChannel in project hudson-2.x by hudson.
the class Slave method getClockDifference.
public ClockDifference getClockDifference() throws IOException, InterruptedException {
VirtualChannel channel = getChannel();
if (channel == null)
throw new IOException(getNodeName() + " is offline");
long startTime = System.currentTimeMillis();
long slaveTime = channel.call(new GetSystemTime());
long endTime = System.currentTimeMillis();
return new ClockDifference((startTime + endTime) / 2 - slaveTime);
}
Aggregations