Search in sources :

Example 1 with PodAnnotation

use of org.csanchez.jenkins.plugins.kubernetes.PodAnnotation in project kubernetes-plugin by jenkinsci.

the class PodTemplateStepExecution method start.

@Override
public boolean start() throws Exception {
    KubernetesCloud cloud = resolveCloud();
    Run<?, ?> run = getContext().get(Run.class);
    if (cloud.isUsageRestricted()) {
        checkAccess(run, cloud);
    }
    PodTemplateContext podTemplateContext = getContext().get(PodTemplateContext.class);
    String parentTemplates = podTemplateContext != null ? podTemplateContext.getName() : null;
    String label = step.getLabel();
    if (label == null) {
        label = labelify(run.getExternalizableId());
    }
    // Let's generate a random name based on the user specified to make sure that we don't have
    // issues with concurrent builds, or messing with pre-existing configuration
    String randString = RandomStringUtils.random(5, "bcdfghjklmnpqrstvwxz0123456789");
    String stepName = step.getName();
    if (stepName == null) {
        stepName = label;
    }
    String name = String.format(NAME_FORMAT, stepName, randString);
    String namespace = checkNamespace(cloud, podTemplateContext);
    newTemplate = new PodTemplate();
    newTemplate.setName(name);
    newTemplate.setNamespace(namespace);
    if (step.getInheritFrom() == null) {
        newTemplate.setInheritFrom(PodTemplateUtils.emptyToNull(parentTemplates));
    } else {
        newTemplate.setInheritFrom(PodTemplateUtils.emptyToNull(step.getInheritFrom()));
    }
    newTemplate.setInstanceCap(step.getInstanceCap());
    newTemplate.setIdleMinutes(step.getIdleMinutes());
    newTemplate.setSlaveConnectTimeout(step.getSlaveConnectTimeout());
    newTemplate.setLabel(label);
    newTemplate.setEnvVars(step.getEnvVars());
    newTemplate.setVolumes(step.getVolumes());
    if (step.getWorkspaceVolume() != null) {
        newTemplate.setWorkspaceVolume(step.getWorkspaceVolume());
    }
    newTemplate.setContainers(step.getContainers());
    newTemplate.setNodeSelector(step.getNodeSelector());
    newTemplate.setNodeUsageMode(step.getNodeUsageMode());
    newTemplate.setServiceAccount(step.getServiceAccount());
    newTemplate.setSchedulerName(step.getSchedulerName());
    newTemplate.setRunAsUser(step.getRunAsUser());
    newTemplate.setRunAsGroup(step.getRunAsGroup());
    if (step.getHostNetwork() != null) {
        newTemplate.setHostNetwork(step.getHostNetwork());
    }
    newTemplate.setAnnotations(step.getAnnotations());
    TaskListener listener = getContext().get(TaskListener.class);
    newTemplate.setListener(listener);
    newTemplate.setYamlMergeStrategy(step.getYamlMergeStrategy());
    if (run != null) {
        String url = cloud.getJenkinsUrlOrNull();
        if (url != null) {
            newTemplate.getAnnotations().add(new PodAnnotation("buildUrl", url + run.getUrl()));
            newTemplate.getAnnotations().add(new PodAnnotation("runUrl", run.getUrl()));
        }
    }
    newTemplate.setImagePullSecrets(step.getImagePullSecrets().stream().map(x -> new PodImagePullSecret(x)).collect(toList()));
    newTemplate.setYaml(step.getYaml());
    if (step.isShowRawYamlSet()) {
        newTemplate.setShowRawYaml(step.isShowRawYaml());
    }
    newTemplate.setPodRetention(step.getPodRetention());
    if (step.getActiveDeadlineSeconds() != 0) {
        newTemplate.setActiveDeadlineSeconds(step.getActiveDeadlineSeconds());
    }
    for (ContainerTemplate container : newTemplate.getContainers()) {
        if (!PodTemplateUtils.validateContainerName(container.getName())) {
            throw new AbortException(Messages.RFC1123_error(container.getName()));
        }
    }
    Collection<String> errors = PodTemplateUtils.validateYamlContainerNames(newTemplate.getYamls());
    if (!errors.isEmpty()) {
        throw new AbortException(Messages.RFC1123_error(String.join(", ", errors)));
    }
    if (VERBOSE) {
        listener.getLogger().println("Registering template with id=" + newTemplate.getId() + ",label=" + newTemplate.getLabel());
    }
    cloud.addDynamicTemplate(newTemplate);
    BodyInvoker invoker = getContext().newBodyInvoker().withContexts(step, new PodTemplateContext(namespace, name)).withCallback(new PodTemplateCallback(newTemplate));
    if (step.getLabel() == null) {
        invoker.withContext(EnvironmentExpander.merge(getContext().get(EnvironmentExpander.class), EnvironmentExpander.constant(Collections.singletonMap("POD_LABEL", label))));
    }
    invoker.start();
    return false;
}
Also used : PodAnnotation(org.csanchez.jenkins.plugins.kubernetes.PodAnnotation) PodImagePullSecret(org.csanchez.jenkins.plugins.kubernetes.PodImagePullSecret) KubernetesCloud(org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud) ContainerTemplate(org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate) TaskListener(hudson.model.TaskListener) BodyInvoker(org.jenkinsci.plugins.workflow.steps.BodyInvoker) PodTemplate(org.csanchez.jenkins.plugins.kubernetes.PodTemplate) AbortException(hudson.AbortException)

Example 2 with PodAnnotation

use of org.csanchez.jenkins.plugins.kubernetes.PodAnnotation in project kubernetes-plugin by jenkinsci.

the class KubernetesPipelineTest method runInPod.

@Issue("JENKINS-57993")
@Test
public void runInPod() throws Exception {
    warnings.record("", Level.WARNING).capture(1000);
    SemaphoreStep.waitForStart("podTemplate/1", b);
    List<PodTemplate> templates = podTemplatesWithLabel(name.getMethodName(), cloud.getAllTemplates());
    assertThat(templates, hasSize(1));
    SemaphoreStep.success("podTemplate/1", null);
    // check if build failed
    assertTrue("Build has failed early: " + b.getResult(), b.isBuilding() || Result.SUCCESS.equals(b.getResult()));
    LOGGER.log(Level.INFO, "Found templates with label runInPod: {0}", templates);
    for (PodTemplate template : cloud.getAllTemplates()) {
        LOGGER.log(Level.INFO, "Cloud template \"{0}\" labels: {1}", new Object[] { template.getName(), template.getLabelSet() });
    }
    Map<String, String> labels = getLabels(cloud, this, name);
    SemaphoreStep.waitForStart("pod/1", b);
    for (Computer c : Arrays.stream(r.jenkins.getComputers()).filter(c -> c instanceof SlaveComputer).collect(Collectors.toList())) {
        // TODO perhaps this should be built into JenkinsRule via ComputerListener.preLaunch?
        new Thread(() -> {
            long pos = 0;
            try {
                while (Jenkins.getInstanceOrNull() != null) {
                    // otherwise get NPE from Computer.getLogDir
                    if (c.getLogFile().isFile()) {
                        // TODO should LargeText.FileSession handle this?
                        pos = c.getLogText().writeLogTo(pos, System.out);
                    }
                    Thread.sleep(100);
                }
            } catch (Exception x) {
                x.printStackTrace();
            }
        }, "watching logs for " + c.getDisplayName()).start();
        System.out.println(c.getLog());
    }
    PodList pods = cloud.connect().pods().withLabels(labels).list();
    assertThat("Expected one pod with labels " + labels + " but got: " + pods.getItems().stream().map(pod -> pod.getMetadata()).collect(Collectors.toList()), pods.getItems(), hasSize(1));
    SemaphoreStep.success("pod/1", null);
    PodTemplate template = templates.get(0);
    List<PodAnnotation> annotations = template.getAnnotations();
    assertNotNull(annotations);
    boolean foundBuildUrl = false;
    for (PodAnnotation pd : annotations) {
        if (pd.getKey().equals("buildUrl")) {
            assertTrue(pd.getValue().contains(p.getUrl()));
            foundBuildUrl = true;
        }
    }
    assertTrue(foundBuildUrl);
    assertEquals(Integer.MAX_VALUE, template.getInstanceCap());
    assertThat(template.getLabelsMap(), hasEntry("jenkins/label", name.getMethodName()));
    Pod pod = pods.getItems().get(0);
    LOGGER.log(Level.INFO, "One pod found: {0}", pod);
    assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave"));
    assertThat("Pod labels are wrong: " + pod, pod.getMetadata().getLabels(), hasEntry("jenkins/label", name.getMethodName()));
    SemaphoreStep.waitForStart("after-podtemplate/1", b);
    assertThat(podTemplatesWithLabel(name.getMethodName(), cloud.getAllTemplates()), hasSize(0));
    SemaphoreStep.success("after-podtemplate/1", null);
    r.assertBuildStatusSuccess(r.waitForCompletion(b));
    r.assertLogContains("container=busybox", b);
    r.assertLogContains("script file contents: ", b);
    r.assertLogContains("Created container jnlp", b);
    assertFalse("There are pods leftover after test execution, see previous logs", deletePods(cloud.connect(), getLabels(cloud, this, name), true));
    assertThat("routine build should not issue warnings", warnings.getRecords().stream().filter(// TODO .record(…, WARNING) does not accomplish this
    lr -> lr.getLevel().intValue() >= Level.WARNING.intValue()).map(lr -> lr.getSourceClassName() + "." + lr.getSourceMethodName() + ": " + lr.getMessage()).collect(// LogRecord does not override toString
    Collectors.toList()), emptyIterable());
    assertTrue(Metrics.metricRegistry().counter(MetricNames.PODS_LAUNCHED).getCount() > 0);
    assertTrue(Metrics.metricRegistry().meter(MetricNames.metricNameForLabel(Label.parseExpression("runInPod"))).getCount() > 0);
}
Also used : Arrays(java.util.Arrays) Issue(org.jvnet.hudson.test.Issue) POD_ENV_VAR_FROM_SECRET_VALUE(org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.POD_ENV_VAR_FROM_SECRET_VALUE) Label(hudson.model.Label) Metrics(jenkins.metrics.api.Metrics) FlagRule(org.jvnet.hudson.test.FlagRule) Locale(java.util.Locale) Map(java.util.Map) After(org.junit.After) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) KubernetesTestUtil.assumeWindows(org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.assumeWindows) PodTemplateUtils(org.csanchez.jenkins.plugins.kubernetes.PodTemplateUtils) Jenkins(jenkins.model.Jenkins) KubernetesTestUtil.getLabels(org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels) SlaveComputer(hudson.slaves.SlaveComputer) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) Run(hudson.model.Run) ExecutorStepExecution(org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution) KubernetesSlave(org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave) HtmlElement(com.gargoylesoftware.htmlunit.html.HtmlElement) List(java.util.List) MatcherAssert(org.hamcrest.MatcherAssert) Assert.assertFalse(org.junit.Assert.assertFalse) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) Result(hudson.model.Result) Optional(java.util.Optional) VersionNumber(hudson.util.VersionNumber) WorkflowRun(org.jenkinsci.plugins.workflow.job.WorkflowRun) MetricNames(org.csanchez.jenkins.plugins.kubernetes.MetricNames) SemaphoreStep(org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep) CONTAINER_ENV_VAR_FROM_SECRET_VALUE(org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.CONTAINER_ENV_VAR_FROM_SECRET_VALUE) WINDOWS_1809_BUILD(org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.WINDOWS_1809_BUILD) Level(java.util.logging.Level) Computer(hudson.model.Computer) FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) KubernetesTestUtil.deletePods(org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods) LoggerRule(org.jvnet.hudson.test.LoggerRule) Matchers.hasSize(org.hamcrest.Matchers.hasSize) DomNodeUtil(com.gargoylesoftware.htmlunit.html.DomNodeUtil) Assume(org.junit.Assume) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) MockAuthorizationStrategy(org.jvnet.hudson.test.MockAuthorizationStrategy) Before(org.junit.Before) Matchers.hasEntry(org.hamcrest.Matchers.hasEntry) Matchers.oneOf(org.hamcrest.Matchers.oneOf) Assert.assertNotNull(org.junit.Assert.assertNotNull) GlobalDefaultFlowDurabilityLevel(org.jenkinsci.plugins.workflow.flow.GlobalDefaultFlowDurabilityLevel) Assert.assertTrue(org.junit.Assert.assertTrue) Pod(io.fabric8.kubernetes.api.model.Pod) Matchers(org.hamcrest.Matchers) PodTemplate(org.csanchez.jenkins.plugins.kubernetes.PodTemplate) Test(org.junit.Test) HtmlPage(com.gargoylesoftware.htmlunit.html.HtmlPage) Matchers.emptyIterable(org.hamcrest.Matchers.emptyIterable) Assert.assertNull(org.junit.Assert.assertNull) ContainerTemplate(org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate) Rule(org.junit.Rule) PodList(io.fabric8.kubernetes.api.model.PodList) Ignore(org.junit.Ignore) JenkinsRuleNonLocalhost(org.jvnet.hudson.test.JenkinsRuleNonLocalhost) JenkinsRule(org.jvnet.hudson.test.JenkinsRule) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) PodAnnotation(org.csanchez.jenkins.plugins.kubernetes.PodAnnotation) TemporaryFolder(org.junit.rules.TemporaryFolder) SlaveComputer(hudson.slaves.SlaveComputer) PodList(io.fabric8.kubernetes.api.model.PodList) PodAnnotation(org.csanchez.jenkins.plugins.kubernetes.PodAnnotation) Pod(io.fabric8.kubernetes.api.model.Pod) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) SlaveComputer(hudson.slaves.SlaveComputer) Computer(hudson.model.Computer) PodTemplate(org.csanchez.jenkins.plugins.kubernetes.PodTemplate) Issue(org.jvnet.hudson.test.Issue) Test(org.junit.Test)

Aggregations

ContainerTemplate (org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate)2 PodAnnotation (org.csanchez.jenkins.plugins.kubernetes.PodAnnotation)2 PodTemplate (org.csanchez.jenkins.plugins.kubernetes.PodTemplate)2 DomNodeUtil (com.gargoylesoftware.htmlunit.html.DomNodeUtil)1 HtmlElement (com.gargoylesoftware.htmlunit.html.HtmlElement)1 HtmlPage (com.gargoylesoftware.htmlunit.html.HtmlPage)1 AbortException (hudson.AbortException)1 Computer (hudson.model.Computer)1 Label (hudson.model.Label)1 Result (hudson.model.Result)1 Run (hudson.model.Run)1 TaskListener (hudson.model.TaskListener)1 SlaveComputer (hudson.slaves.SlaveComputer)1 VersionNumber (hudson.util.VersionNumber)1 ObjectMeta (io.fabric8.kubernetes.api.model.ObjectMeta)1 Pod (io.fabric8.kubernetes.api.model.Pod)1 PodList (io.fabric8.kubernetes.api.model.PodList)1 KubernetesClientException (io.fabric8.kubernetes.client.KubernetesClientException)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1