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();
}
}
use of hudson.model.Computer in project workflow-cps-plugin by jenkinsci.
the class CpsFlowDefinition2Test method endlessRecursionNonCPS.
/**
* Verify that we kill endlessly recursive NonCPS code cleanly and don't leave remnants.
* This is a bit of extra caution to go along with {@link #endlessRecursion()} to ensure
* we don't trigger other forms of failure with the StackOverflowError.
*/
@Test
@Ignore
public /**
* Intermittent failures because triggers a longstanding unrelated SandboxResolvingClassloader bug
* resolved in https://github.com/jenkinsci/script-security-plugin/pull/160
*/
void endlessRecursionNonCPS() throws Exception {
// Sidestep false failures specific to a few Windows build environments.
Assume.assumeTrue(!Functions.isWindows());
String script = "@NonCPS def getThing(){return thing == null}; \n" + "node { echo getThing(); } ";
WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "recursion");
job.setDefinition(new CpsFlowDefinition(script, true));
// Should have failed with error about excessive recursion depth
WorkflowRun r = jenkins.assertBuildStatus(Result.FAILURE, job.scheduleBuild2(0).get());
Assert.assertTrue("No queued FlyWeightTask for job should remain after failure", jenkins.jenkins.getQueue().isEmpty());
for (Computer c : jenkins.jenkins.getComputers()) {
for (Executor ex : c.getExecutors()) {
if (ex.isBusy()) {
fail(ex.getCurrentExecutable().toString());
}
}
}
}
use of hudson.model.Computer in project configuration-as-code-plugin by jenkinsci.
the class RoleStrategyTest method shouldReadRolesCorrectly.
@Test
@Issue("Issue #48")
@ConfiguredWithCode("RoleStrategy1.yml")
public void shouldReadRolesCorrectly() throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
User admin = User.get("admin");
User user1 = User.get("user1");
User user2 = User.get("user2");
Computer agent1 = j.jenkins.getComputer("agent1");
Computer agent2 = j.jenkins.getComputer("agent2");
Folder folderA = j.jenkins.createProject(Folder.class, "A");
FreeStyleProject jobA1 = folderA.createProject(FreeStyleProject.class, "1");
Folder folderB = j.jenkins.createProject(Folder.class, "B");
FreeStyleProject jobB2 = folderB.createProject(FreeStyleProject.class, "2");
AuthorizationStrategy s = j.jenkins.getAuthorizationStrategy();
assertThat("Authorization Strategy has been read incorrectly", s, instanceOf(RoleBasedAuthorizationStrategy.class));
RoleBasedAuthorizationStrategy rbas = (RoleBasedAuthorizationStrategy) s;
Map<Role, Set<String>> globalRoles = rbas.getGrantedRoles(RoleBasedAuthorizationStrategy.GLOBAL);
assertThat(globalRoles.size(), equalTo(2));
// Admin has configuration access
assertHasPermission(admin, j.jenkins, Jenkins.ADMINISTER, Jenkins.READ);
assertHasPermission(user1, j.jenkins, Jenkins.READ);
assertHasNoPermission(user1, j.jenkins, Jenkins.ADMINISTER, Jenkins.RUN_SCRIPTS);
// Folder A is restricted to admin
assertHasPermission(admin, folderA, Item.CONFIGURE);
assertHasPermission(user1, folderA, Item.READ, Item.DISCOVER);
assertHasNoPermission(user1, folderA, Item.CONFIGURE, Item.DELETE, Item.BUILD);
// But they have access to jobs in Folder A
assertHasPermission(admin, folderA, Item.CONFIGURE, Item.CANCEL);
assertHasPermission(user1, jobA1, Item.READ, Item.DISCOVER, Item.CONFIGURE, Item.BUILD, Item.DELETE);
assertHasPermission(user2, jobA1, Item.READ, Item.DISCOVER, Item.CONFIGURE, Item.BUILD, Item.DELETE);
assertHasNoPermission(user1, folderA, Item.CANCEL);
// FolderB is editable by user2, but he cannot delete it
assertHasPermission(user2, folderB, Item.READ, Item.DISCOVER, Item.CONFIGURE, Item.BUILD);
assertHasNoPermission(user2, folderB, Item.DELETE);
assertHasNoPermission(user1, folderB, Item.CONFIGURE, Item.BUILD, Item.DELETE);
// Only user1 can run on agent1, but he still cannot configure it
assertHasPermission(admin, agent1, Computer.CONFIGURE, Computer.DELETE, Computer.BUILD);
assertHasPermission(user1, agent1, Computer.BUILD);
assertHasNoPermission(user1, agent1, Computer.CONFIGURE, Computer.DISCONNECT);
// Same user still cannot build on agent2
assertHasNoPermission(user1, agent2, Computer.BUILD);
}
Aggregations