use of hudson.model.Computer in project support-core-plugin by jenkinsci.
the class SupportPlugin method setLogLevel.
public static void setLogLevel(Level level) {
SupportPlugin instance = getInstance();
instance.handler.setLevel(level);
for (Node n : Jenkins.getInstance().getNodes()) {
Computer c = n.toComputer();
if (c == null) {
continue;
}
VirtualChannel channel = c.getChannel();
if (channel != null) {
try {
channel.callAsync(new LogUpdater(level));
} catch (IOException e) {
// ignore
}
}
}
}
use of hudson.model.Computer in project support-core-plugin by jenkinsci.
the class RootCAs method addContents.
private void addContents(@NonNull Container container, @NonNull final Node node) {
Computer c = node.toComputer();
if (c == null) {
return;
}
String name;
if (node instanceof Jenkins) {
name = "master";
} else {
name = "slave/" + node.getNodeName();
}
container.add(new Content("nodes/" + name + "/RootCA.txt") {
@Override
public void writeTo(OutputStream os) throws IOException {
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os, "utf-8")));
try {
out.println(getRootCA(node));
} catch (IOException e) {
SupportLogFormatter.printStackTrace(e, out);
} finally {
out.flush();
}
}
});
}
use of hudson.model.Computer in project support-core-plugin by jenkinsci.
the class SlaveLogs method addContents.
@Override
public void addContents(@NonNull Container container) {
// expensive remote computation are pooled together and executed later concurrently across all the agents
List<java.util.concurrent.Callable<List<FileContent>>> tasks = Lists.newArrayList();
// id is awkward because of backward compatibility
SmartLogFetcher logFetcher = new SmartLogFetcher("cache", new LogFilenameFilter());
SmartLogFetcher winswLogFetcher = new SmartLogFetcher("winsw", new WinswLogfileFilter());
final boolean needHack = SlaveLogFetcher.isRequired();
for (final Node node : Jenkins.getInstance().getNodes()) {
if (node.toComputer() instanceof SlaveComputer) {
container.add(new PrintedContent("nodes/slave/" + node.getNodeName() + "/jenkins.log") {
@Override
protected void printTo(PrintWriter out) throws IOException {
Computer computer = node.toComputer();
if (computer == null) {
out.println("N/A");
} else {
try {
List<LogRecord> records = null;
if (needHack) {
VirtualChannel channel = computer.getChannel();
if (channel != null) {
hudson.remoting.Future<List<LogRecord>> future = SlaveLogFetcher.getLogRecords(channel);
records = future.get(REMOTE_OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
}
}
if (records == null) {
records = computer.getLogRecords();
}
for (ListIterator<LogRecord> iterator = records.listIterator(records.size()); iterator.hasPrevious(); ) {
LogRecord logRecord = iterator.previous();
out.print(LOG_FORMATTER.format(logRecord));
}
} catch (Throwable e) {
out.println();
SupportLogFormatter.printStackTrace(e, out);
}
}
out.flush();
}
});
}
addSlaveJulLogRecords(container, tasks, node, logFetcher);
addWinsStdoutStderrLog(tasks, node, winswLogFetcher);
}
// execute all the expensive computations in parallel to speed up the time
if (!tasks.isEmpty()) {
ExecutorService service = Executors.newFixedThreadPool(Math.max(1, Math.min(Runtime.getRuntime().availableProcessors() * 2, tasks.size())), new ExceptionCatchingThreadFactory(new DaemonThreadFactory()));
try {
long expiresNanoTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(SupportPlugin.REMOTE_OPERATION_CACHE_TIMEOUT_SEC);
for (java.util.concurrent.Future<List<FileContent>> r : service.invokeAll(tasks, SupportPlugin.REMOTE_OPERATION_CACHE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
try {
for (FileContent c : r.get(Math.max(1, expiresNanoTime - System.nanoTime()), TimeUnit.NANOSECONDS)) {
container.add(c);
}
} catch (ExecutionException e) {
LOGGER.log(Level.WARNING, "Could not retrieve some of the remote node extra logs", e);
} catch (TimeoutException e) {
LOGGER.log(Level.WARNING, "Could not retrieve some of the remote node extra logs", e);
r.cancel(false);
}
}
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "Could not retrieve some of the remote node extra logs", e);
} finally {
service.shutdown();
}
}
}
use of hudson.model.Computer in project workflow-cps-plugin by jenkinsci.
the class CpsScmFlowDefinition method create.
@Override
public CpsFlowExecution create(FlowExecutionOwner owner, TaskListener listener, List<? extends Action> actions) throws Exception {
for (Action a : actions) {
if (a instanceof CpsFlowFactoryAction2) {
return ((CpsFlowFactoryAction2) a).create(this, owner, actions);
}
}
Queue.Executable _build = owner.getExecutable();
if (!(_build instanceof Run)) {
throw new IOException("can only check out SCM into a Run");
}
Run<?, ?> build = (Run<?, ?>) _build;
if (isLightweight()) {
try (SCMFileSystem fs = SCMFileSystem.of(build.getParent(), scm)) {
if (fs != null) {
String script = fs.child(scriptPath).contentAsString();
listener.getLogger().println("Obtained " + scriptPath + " from " + scm.getKey());
Queue.Executable exec = owner.getExecutable();
FlowDurabilityHint hint = (exec instanceof Item) ? DurabilityHintProvider.suggestedFor((Item) exec) : GlobalDefaultFlowDurabilityLevel.getDefaultDurabilityHint();
return new CpsFlowExecution(script, true, owner, hint);
} else {
listener.getLogger().println("Lightweight checkout support not available, falling back to full checkout.");
}
}
}
FilePath dir;
Node node = Jenkins.getActiveInstance();
if (build.getParent() instanceof TopLevelItem) {
FilePath baseWorkspace = node.getWorkspaceFor((TopLevelItem) build.getParent());
if (baseWorkspace == null) {
throw new IOException(node.getDisplayName() + " may be offline");
}
dir = getFilePathWithSuffix(baseWorkspace);
} else {
// should not happen, but just in case:
dir = new FilePath(owner.getRootDir());
}
listener.getLogger().println("Checking out " + scm.getKey() + " into " + dir + " to read " + scriptPath);
String script = null;
Computer computer = node.toComputer();
if (computer == null) {
throw new IOException(node.getDisplayName() + " may be offline");
}
SCMStep delegate = new GenericSCMStep(scm);
delegate.setPoll(true);
delegate.setChangelog(true);
FilePath acquiredDir;
try (WorkspaceList.Lease lease = computer.getWorkspaceList().acquire(dir)) {
for (int retryCount = Jenkins.getInstance().getScmCheckoutRetryCount(); retryCount >= 0; retryCount--) {
try {
delegate.checkout(build, dir, listener, node.createLauncher(listener));
break;
} catch (AbortException e) {
// If so, just skip echoing it.
if (e.getMessage() != null) {
listener.error(e.getMessage());
}
} catch (InterruptedIOException e) {
throw e;
} catch (IOException e) {
// checkout error not yet reported
// TODO 2.43+ use Functions.printStackTrace
listener.error("Checkout failed").println(Functions.printThrowable(e).trim());
}
if (// all attempts failed
retryCount == 0)
throw new AbortException("Maximum checkout retry attempts reached, aborting");
listener.getLogger().println("Retrying after 10 seconds");
Thread.sleep(10000);
}
FilePath scriptFile = dir.child(scriptPath);
if (!scriptFile.absolutize().getRemote().replace('\\', '/').startsWith(dir.absolutize().getRemote().replace('\\', '/') + '/')) {
// TODO JENKINS-26838
throw new IOException(scriptFile + " is not inside " + dir);
}
if (!scriptFile.exists()) {
throw new AbortException(scriptFile + " not found");
}
script = scriptFile.readToString();
acquiredDir = lease.path;
}
Queue.Executable queueExec = owner.getExecutable();
FlowDurabilityHint hint = (queueExec instanceof Run) ? DurabilityHintProvider.suggestedFor(((Run) queueExec).getParent()) : GlobalDefaultFlowDurabilityLevel.getDefaultDurabilityHint();
CpsFlowExecution exec = new CpsFlowExecution(script, true, owner, hint);
exec.flowStartNodeActions.add(new WorkspaceActionImpl(acquiredDir, null));
return exec;
}
use of hudson.model.Computer in project workflow-cps-plugin by jenkinsci.
the class DSL method invokeStep.
/**
* When {@link #invokeMethod(String, Object)} is calling a {@link StepDescriptor}
*/
protected Object invokeStep(StepDescriptor d, Object args) {
final NamedArgsAndClosure ps = parseArgs(args, d);
CpsThread thread = CpsThread.current();
FlowNode an;
// TODO: generalize the notion of Step taking over the FlowNode creation.
boolean hack = d instanceof ParallelStep.DescriptorImpl || d instanceof LoadStep.DescriptorImpl;
if (ps.body == null && !hack) {
an = new StepAtomNode(exec, d, thread.head.get());
// TODO: use CPS call stack to obtain the current call site source location. See JENKINS-23013
thread.head.setNewHead(an);
} else {
an = new StepStartNode(exec, d, thread.head.get());
thread.head.setNewHead(an);
}
final CpsStepContext context = new CpsStepContext(d, thread, handle, an, ps.body);
Step s;
boolean sync;
ClassLoader originalLoader = Thread.currentThread().getContextClassLoader();
try {
d.checkContextAvailability(context);
Thread.currentThread().setContextClassLoader(CpsVmExecutorService.ORIGINAL_CONTEXT_CLASS_LOADER.get());
s = d.newInstance(ps.namedArgs);
try {
// No point storing empty arguments, and ParallelStep is a special case where we can't store its closure arguments
if (ps.namedArgs != null && !(ps.namedArgs.isEmpty()) && isKeepStepArguments() && !(s instanceof ParallelStep)) {
// Get the environment variables to find ones that might be credentials bindings
Computer comp = context.get(Computer.class);
EnvVars allEnv = new EnvVars(context.get(EnvVars.class));
if (comp != null && allEnv != null) {
allEnv.entrySet().removeAll(comp.getEnvironment().entrySet());
}
an.addAction(new ArgumentsActionImpl(ps.namedArgs, allEnv));
}
} catch (Exception e) {
// Avoid breaking execution because we can't store some sort of crazy Step argument
LOGGER.log(Level.WARNING, "Error storing the arguments for step: " + d.getFunctionName(), e);
}
// Persist the node - block start and end nodes do their own persistence.
CpsFlowExecution.maybeAutoPersistNode(an);
StepExecution e = s.start(context);
thread.setStep(e);
sync = e.start();
} catch (Exception e) {
if (e instanceof MissingContextVariableException)
reportMissingContextVariableException(context, (MissingContextVariableException) e);
context.onFailure(e);
s = null;
sync = true;
} finally {
Thread.currentThread().setContextClassLoader(originalLoader);
}
if (sync) {
assert context.bodyInvokers.isEmpty() : "If a step claims synchronous completion, it shouldn't invoke body";
if (context.getOutcome() == null) {
context.onFailure(new AssertionError("Step " + s + " claimed to have ended synchronously, but didn't set the result via StepContext.onSuccess/onFailure"));
}
thread.setStep(null);
// we just move on accordingly
if (an instanceof StepStartNode) {
// no body invoked, so EndNode follows StartNode immediately.
thread.head.setNewHead(new StepEndNode(exec, (StepStartNode) an, an));
}
thread.head.markIfFail(context.getOutcome());
return context.replay();
} else {
// if it's in progress, suspend it until we get invoked later.
// when it resumes, the CPS caller behaves as if this method returned with the resume value
Continuable.suspend(new ThreadTaskImpl(context));
// so the execution will never reach here.
throw new AssertionError();
}
}
Aggregations