Search in sources :

Example 6 with Computer

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();
        }
    }
}
Also used : DaemonThreadFactory(hudson.util.DaemonThreadFactory) Node(hudson.model.Node) MasterToSlaveCallable(jenkins.security.MasterToSlaveCallable) LogRecord(java.util.logging.LogRecord) PrintedContent(com.cloudbees.jenkins.support.api.PrintedContent) Computer(hudson.model.Computer) SlaveComputer(hudson.slaves.SlaveComputer) ArrayList(java.util.ArrayList) List(java.util.List) ExceptionCatchingThreadFactory(hudson.util.ExceptionCatchingThreadFactory) ExecutionException(java.util.concurrent.ExecutionException) PrintWriter(java.io.PrintWriter) TimeoutException(java.util.concurrent.TimeoutException) SlaveComputer(hudson.slaves.SlaveComputer) VirtualChannel(hudson.remoting.VirtualChannel) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) ListIterator(java.util.ListIterator) FileContent(com.cloudbees.jenkins.support.api.FileContent) ExecutorService(java.util.concurrent.ExecutorService)

Example 7 with Computer

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;
}
Also used : FilePath(hudson.FilePath) InterruptedIOException(java.io.InterruptedIOException) Action(hudson.model.Action) Node(hudson.model.Node) TopLevelItem(hudson.model.TopLevelItem) Run(hudson.model.Run) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) WorkspaceList(hudson.slaves.WorkspaceList) FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) GenericSCMStep(org.jenkinsci.plugins.workflow.steps.scm.GenericSCMStep) FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) TopLevelItem(hudson.model.TopLevelItem) Item(hudson.model.Item) WorkspaceActionImpl(org.jenkinsci.plugins.workflow.support.actions.WorkspaceActionImpl) SCMFileSystem(jenkins.scm.api.SCMFileSystem) GenericSCMStep(org.jenkinsci.plugins.workflow.steps.scm.GenericSCMStep) SCMStep(org.jenkinsci.plugins.workflow.steps.scm.SCMStep) Computer(hudson.model.Computer) Queue(hudson.model.Queue) AbortException(hudson.AbortException)

Example 8 with Computer

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();
    }
}
Also used : StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) Step(org.jenkinsci.plugins.workflow.steps.Step) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) StepExecution(org.jenkinsci.plugins.workflow.steps.StepExecution) NoStaplerConstructorException(org.kohsuke.stapler.NoStaplerConstructorException) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) IOException(java.io.IOException) MissingContextVariableException(org.jenkinsci.plugins.workflow.steps.MissingContextVariableException) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) EnvVars(hudson.EnvVars) ArgumentsActionImpl(org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl) Computer(hudson.model.Computer) MissingContextVariableException(org.jenkinsci.plugins.workflow.steps.MissingContextVariableException) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 9 with Computer

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());
            }
        }
    }
}
Also used : Executor(hudson.model.Executor) Computer(hudson.model.Computer) Matchers.containsString(org.hamcrest.Matchers.containsString) WorkflowJob(org.jenkinsci.plugins.workflow.job.WorkflowJob) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 10 with Computer

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);
}
Also used : Role(com.michelin.cio.hudson.plugins.rolestrategy.Role) AuthorizationStrategy(hudson.security.AuthorizationStrategy) RoleBasedAuthorizationStrategy(com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy) User(hudson.model.User) Set(java.util.Set) Computer(hudson.model.Computer) Folder(com.cloudbees.hudson.plugins.folder.Folder) FreeStyleProject(hudson.model.FreeStyleProject) RoleBasedAuthorizationStrategy(com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy) Issue(org.jvnet.hudson.test.Issue) Test(org.junit.Test) ConfiguredWithCode(org.jenkinsci.plugins.casc.misc.ConfiguredWithCode)

Aggregations

Computer (hudson.model.Computer)26 IOException (java.io.IOException)10 Node (hudson.model.Node)8 Executor (hudson.model.Executor)6 AbortException (hudson.AbortException)4 FilePath (hudson.FilePath)4 Jenkins (jenkins.model.Jenkins)4 EnvVars (hudson.EnvVars)3 VirtualChannel (hudson.remoting.VirtualChannel)3 PrintWriter (java.io.PrintWriter)3 Test (org.junit.Test)3 Content (com.cloudbees.jenkins.support.api.Content)2 SlaveComputer (hudson.slaves.SlaveComputer)2 WorkspaceList (hudson.slaves.WorkspaceList)2 InterruptedIOException (java.io.InterruptedIOException)2 ArrayList (java.util.ArrayList)2 Folder (com.cloudbees.hudson.plugins.folder.Folder)1 FileContent (com.cloudbees.jenkins.support.api.FileContent)1 FilePathContent (com.cloudbees.jenkins.support.api.FilePathContent)1 PrintedContent (com.cloudbees.jenkins.support.api.PrintedContent)1