diff --git a/pom.xml b/pom.xml index 7696a6534..cd45cffae 100644 --- a/pom.xml +++ b/pom.xml @@ -175,6 +175,13 @@ test + + org.jenkins-ci.plugins.workflow + workflow-scm-step + 2.2 + test + + org.jenkins-ci.plugins.workflow workflow-support @@ -237,6 +244,9 @@ ALL ALL + + / + diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildCause.java b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildCause.java index dbc98a9bf..e5e8c9d24 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildCause.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildCause.java @@ -33,15 +33,19 @@ public class BuildCause extends Cause { private String commit; - public BuildCause(String uid, String namespace, String name, String gitUri, String commit) { + private String buildConfigUid; + + public BuildCause(String uid, String namespace, String name, String gitUri, String commit, String buildConfigUid) { this.uid = uid; this.namespace = namespace; this.name = name; this.gitUri = gitUri; this.commit = commit; + this.buildConfigUid = buildConfigUid; } - public BuildCause(Build build) { + public BuildCause(Build build, String buildConfigUid) { + this.buildConfigUid = buildConfigUid; if (build == null || build.getMetadata() == null) { return; } @@ -96,4 +100,8 @@ public String getGitUri() { public String getCommit() { return commit; } + + public String getBuildConfigUid() { + return buildConfigUid; + } } diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigProjectProperty.java b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigProjectProperty.java index 01133e073..6f81a10d4 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigProjectProperty.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigProjectProperty.java @@ -20,7 +20,7 @@ import hudson.model.JobProperty; import hudson.model.JobPropertyDescriptor; import io.fabric8.openshift.api.model.BuildConfig; -import jenkins.model.ParameterizedJobMixIn; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.kohsuke.stapler.DataBoundConstructor; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.getOpenShiftClient; @@ -31,6 +31,8 @@ * - Namespace * - Build config name * - Build config uid + * - Build config resource version + * - Build config run policy */ public class BuildConfigProjectProperty extends JobProperty> { @@ -43,15 +45,15 @@ public class BuildConfigProjectProperty extends JobProperty> { private String resourceVersion; - private String contextDir; + private String buildRunPolicy; @DataBoundConstructor - public BuildConfigProjectProperty(String namespace, String name, String uid, String resourceVersion, String contextDir) { + public BuildConfigProjectProperty(String namespace, String name, String uid, String resourceVersion, String buildRunPolicy) { this.namespace = namespace; this.name = name; this.uid = uid; this.resourceVersion = resourceVersion; - this.contextDir = contextDir; + this.buildRunPolicy = buildRunPolicy; } public BuildConfigProjectProperty(BuildConfig bc) { @@ -60,12 +62,7 @@ public BuildConfigProjectProperty(BuildConfig bc) { bc.getMetadata().getName(), bc.getMetadata().getUid(), bc.getMetadata().getResourceVersion(), - bc.getSpec().getSource().getContextDir() - ); - } - - public String getUid() { - return uid; + bc.getSpec().getRunPolicy()); } public BuildConfig getBuildConfig() { @@ -76,14 +73,30 @@ public BuildConfig getBuildConfig() { return null; } + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + public String getNamespace() { return namespace; } + public void setNamespace(String namespace) { + this.namespace = namespace; + } + public String getResourceVersion() { return resourceVersion; } @@ -92,14 +105,18 @@ public void setResourceVersion(String resourceVersion) { this.resourceVersion = resourceVersion; } - public String getContextDir() { - return contextDir; + public String getBuildRunPolicy() { + return buildRunPolicy; + } + + public void setBuildRunPolicy(String buildRunPolicy) { + this.buildRunPolicy = buildRunPolicy; } @Extension public static final class DescriptorImpl extends JobPropertyDescriptor { public boolean isApplicable(Class jobType) { - return ParameterizedJobMixIn.ParameterizedJob.class.isAssignableFrom(jobType); + return WorkflowJob.class.isAssignableFrom(jobType); } } } diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigWatcher.java b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigWatcher.java index 173b27283..9d10745db 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigWatcher.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildConfigWatcher.java @@ -32,7 +32,6 @@ import org.apache.tools.ant.filters.StringInputStream; import org.jenkinsci.plugins.workflow.flow.FlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.jvnet.hudson.reactor.ReactorException; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; @@ -44,6 +43,8 @@ import java.util.logging.Logger; import static io.fabric8.jenkins.openshiftsync.BuildConfigToJobMapper.mapBuildConfigToFlow; +import static io.fabric8.jenkins.openshiftsync.BuildRunPolicy.SERIAL; +import static io.fabric8.jenkins.openshiftsync.BuildRunPolicy.SERIAL_LATEST_ONLY; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.getOpenShiftClient; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.isJenkinsBuildConfig; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.parseResourceVersion; @@ -81,20 +82,18 @@ public void start(final Callable completionCallback) { public void doRun() { logger.info("Waiting for Jenkins to be started"); while (true) { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - Computer[] computers = jenkins.getComputers(); - boolean ready = false; - for (Computer c : computers) { - // Jenkins.isAcceptingTasks() results in hudson.model.Node.isAcceptingTasks() getting called, and that always returns true; - // the Computer.isAcceptingTasks actually introspects various Jenkins data structures to determine readiness - if (c.isAcceptingTasks()) { - ready = true; - break; - } - } - if (ready) - break; + Computer[] computers = Jenkins.getActiveInstance().getComputers(); + boolean ready = false; + for (Computer c : computers) { + // Jenkins.isAcceptingTasks() results in hudson.model.Node.isAcceptingTasks() getting called, and that always returns true; + // the Computer.isAcceptingTasks actually introspects various Jenkins data structures to determine readiness + if (c.isAcceptingTasks()) { + ready = true; + break; + } + } + if (ready) { + break; } try { Thread.sleep(500); @@ -181,7 +180,7 @@ public Void call() throws Exception { WorkflowJob job = BuildTrigger.getDscp().getJobFromBuildConfigUid(buildConfig.getMetadata().getUid()); boolean newJob = job == null; if (newJob) { - job = new WorkflowJob(Jenkins.getInstance(), jobName); + job = new WorkflowJob(Jenkins.getActiveInstance(), jobName); } FlowDefinition flowFromBuildConfig = mapBuildConfigToFlow(buildConfig); @@ -189,11 +188,6 @@ public Void call() throws Exception { return null; } - String contextDir = null; - if (buildConfig.getSpec() != null && buildConfig.getSpec().getSource() != null) { - contextDir = buildConfig.getSpec().getSource().getContextDir(); - } - job.setDefinition(flowFromBuildConfig); BuildTrigger trigger = new BuildTrigger(); @@ -205,28 +199,35 @@ public Void call() throws Exception { if (buildConfigProjectProperty != null) { long updatedBCResourceVersion = parseResourceVersion(buildConfig); long oldBCResourceVersion = parseResourceVersion(buildConfigProjectProperty.getResourceVersion()); - if (oldBCResourceVersion > updatedBCResourceVersion) { + BuildConfigProjectProperty newProperty = new BuildConfigProjectProperty(buildConfig); + if (updatedBCResourceVersion <= oldBCResourceVersion && + newProperty.getUid().equals(buildConfigProjectProperty.getUid()) && + newProperty.getNamespace().equals(buildConfigProjectProperty.getNamespace()) && + newProperty.getName().equals(buildConfigProjectProperty.getName()) && + newProperty.getBuildRunPolicy().equals(buildConfigProjectProperty.getBuildRunPolicy()) + ) { return null; } - buildConfigProjectProperty.setResourceVersion(buildConfig.getMetadata().getResourceVersion()); + buildConfigProjectProperty.setUid(newProperty.getUid()); + buildConfigProjectProperty.setNamespace(newProperty.getNamespace()); + buildConfigProjectProperty.setName(newProperty.getName()); + buildConfigProjectProperty.setResourceVersion(newProperty.getResourceVersion()); + buildConfigProjectProperty.setBuildRunPolicy(newProperty.getBuildRunPolicy()); } else { job.addProperty( - new BuildConfigProjectProperty( - buildConfig.getMetadata().getNamespace(), - buildConfig.getMetadata().getName(), - buildConfig.getMetadata().getUid(), - buildConfig.getMetadata().getResourceVersion(), - contextDir - ) + new BuildConfigProjectProperty(buildConfig) ); } - InputStream jobStream = new StringInputStream(new XStream2().toXML(job)); + job.setConcurrentBuild( + !(buildConfig.getSpec().getRunPolicy().equals(SERIAL) || + buildConfig.getSpec().getRunPolicy().equals(SERIAL_LATEST_ONLY)) + ); - Jenkins jenkins = Jenkins.getInstance(); + InputStream jobStream = new StringInputStream(new XStream2().toXML(job)); if (newJob) { - jenkins.createProjectFromXML( + Jenkins.getActiveInstance().createProjectFromXML( jobName, jobStream ).save(); @@ -260,14 +261,7 @@ private void deleteJob(final BuildConfig buildConfig) throws Exception { @Override public Void call() throws Exception { job.delete(); - try { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - jenkins.reload(); - } - } catch (ReactorException e) { - logger.log(Level.SEVERE, "Failed to reload jenkins job after deleting " + job.getName() + " from BuildConfig " + NamespaceName.create(buildConfig)); - } + Jenkins.getActiveInstance().rebuildDependencyGraphAsync(); return null; } }); diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildRunPolicy.java b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildRunPolicy.java new file mode 100644 index 000000000..fafc7cfdf --- /dev/null +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildRunPolicy.java @@ -0,0 +1,11 @@ +package io.fabric8.jenkins.openshiftsync; + +public class BuildRunPolicy { + + public static final String PARALLEL = "Parallel"; + + public static final String SERIAL = "Serial"; + + public static final String SERIAL_LATEST_ONLY = "SerialLatestOnly"; + +} diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildSyncRunListener.java b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildSyncRunListener.java index 509f023f1..9d0d3cbbe 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/BuildSyncRunListener.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/BuildSyncRunListener.java @@ -29,11 +29,15 @@ import hudson.triggers.SafeTimerTask; import io.fabric8.openshift.api.model.Build; import jenkins.util.Timer; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowRun; import org.kohsuke.stapler.DataBoundConstructor; import javax.annotation.Nonnull; import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.TimeUnit; @@ -44,6 +48,7 @@ import static io.fabric8.jenkins.openshiftsync.Constants.ANNOTATION_JENKINS_BUILD_URI; import static io.fabric8.jenkins.openshiftsync.Constants.ANNOTATION_JENKINS_LOG_URL; import static io.fabric8.jenkins.openshiftsync.Constants.ANNOTATION_JENKINS_STATUS_JSON; +import static io.fabric8.jenkins.openshiftsync.NewBuildWatcher.buildAdded; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.formatTimestamp; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.getOpenShiftClient; @@ -142,6 +147,7 @@ public synchronized void onCompleted(Run run, @Nonnull TaskListener listener) { runsToPoll.remove(run); pollRun(run); logger.info("onCompleted " + run.getUrl()); + maybeScheduleNext(((WorkflowRun) run).getParent()); } super.onCompleted(run, listener); } @@ -152,6 +158,7 @@ public synchronized void onDeleted(Run run) { runsToPoll.remove(run); pollRun(run); logger.info("onDeleted " + run.getUrl()); + maybeScheduleNext(((WorkflowRun) run).getParent()); } super.onDeleted(run); } @@ -295,4 +302,30 @@ private String runToBuildPhase(Run run) { protected boolean shouldPollRun(Run run) { return run instanceof WorkflowRun && run.getCause(BuildCause.class) != null; } + + private void maybeScheduleNext(WorkflowJob job) { + BuildConfigProjectProperty bcp = job.getProperty(BuildConfigProjectProperty.class); + if (bcp == null) { + return; + } + List builds = getOpenShiftClient().builds().inNamespace(bcp.getNamespace()) + .withField("status", BuildPhases.NEW).withLabel("openshift.io/build-config.name", bcp.getName()).list().getItems(); + Collections.sort(builds, new Comparator() { + @Override + public int compare(Build b1, Build b2) { + return Long.compare( + Long.parseLong(b1.getMetadata().getAnnotations().get("openshift.io/build.number")), + Long.parseLong(b2.getMetadata().getAnnotations().get("openshift.io/build.number")) + ); + } + }); + + for (Build b : builds) { + try { + buildAdded(b); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/CancelledBuildWatcher.java b/src/main/java/io/fabric8/jenkins/openshiftsync/CancelledBuildWatcher.java index 76ce7b4e0..de38f69c2 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/CancelledBuildWatcher.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/CancelledBuildWatcher.java @@ -26,6 +26,8 @@ import java.util.logging.Level; import java.util.logging.Logger; +import static io.fabric8.jenkins.openshiftsync.BuildPhases.NEW; +import static io.fabric8.jenkins.openshiftsync.BuildPhases.RUNNING; import static io.fabric8.jenkins.openshiftsync.JenkinsUtils.getJobFromBuild; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.getOpenShiftClient; import static java.net.HttpURLConnection.HTTP_GONE; @@ -42,11 +44,11 @@ public CancelledBuildWatcher(String defaultNamespace) { public void start() { final BuildList builds; if (namespace != null && !namespace.isEmpty()) { - builds = getOpenShiftClient().builds().inNamespace(namespace).withField("status", BuildPhases.RUNNING).list(); - buildsWatch = getOpenShiftClient().builds().inNamespace(namespace).withField("status", BuildPhases.RUNNING).withResourceVersion(builds.getMetadata().getResourceVersion()).watch(this); + builds = getOpenShiftClient().builds().inNamespace(namespace).list(); + buildsWatch = getOpenShiftClient().builds().inNamespace(namespace).withResourceVersion(builds.getMetadata().getResourceVersion()).watch(this); } else { - builds = getOpenShiftClient().builds().withField("status", BuildPhases.RUNNING).list(); - buildsWatch = getOpenShiftClient().builds().withField("status", BuildPhases.RUNNING).withResourceVersion(builds.getMetadata().getResourceVersion()).watch(this); + builds = getOpenShiftClient().builds().list(); + buildsWatch = getOpenShiftClient().builds().withResourceVersion(builds.getMetadata().getResourceVersion()).watch(this); } } @@ -84,7 +86,8 @@ public void eventReceived(Action action, Build build) { } private void buildModified(Build build) { - if (Boolean.TRUE.equals(build.getStatus().getCancelled())) { + if ((build.getStatus().getPhase().equals(NEW) || build.getStatus().getPhase().equals(RUNNING)) && + Boolean.TRUE.equals(build.getStatus().getCancelled())) { Job job = getJobFromBuild(build); if (job != null) { JenkinsUtils.cancelBuild(job, build); diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/CredentialsUtils.java b/src/main/java/io/fabric8/jenkins/openshiftsync/CredentialsUtils.java index 65c9a2ee5..ea701a579 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/CredentialsUtils.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/CredentialsUtils.java @@ -43,7 +43,7 @@ public static synchronized String updateSourceCredentials(BuildConfig buildConfi Credentials existingCreds = lookupCredentials(id); final SecurityContext previousContext = ACL.impersonate(ACL.SYSTEM); try { - CredentialsStore s = CredentialsProvider.lookupStores(Jenkins.getInstance()).iterator().next(); + CredentialsStore s = CredentialsProvider.lookupStores(Jenkins.getActiveInstance()).iterator().next(); if (existingCreds != null) { s.updateCredentials(Domain.global(), existingCreds, creds); } else { @@ -61,7 +61,7 @@ private static Credentials lookupCredentials(String id) { return CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials( Credentials.class, - Jenkins.getInstance(), + Jenkins.getActiveInstance(), ACL.SYSTEM, Collections. emptyList() ), diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/JenkinsUtils.java b/src/main/java/io/fabric8/jenkins/openshiftsync/JenkinsUtils.java index 77d0301f3..9beaa9b29 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/JenkinsUtils.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/JenkinsUtils.java @@ -21,6 +21,7 @@ import hudson.model.Run; import hudson.model.TopLevelItem; import io.fabric8.openshift.api.model.Build; +import io.fabric8.openshift.api.model.BuildBuilder; import io.fabric8.openshift.api.model.BuildConfig; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; @@ -28,22 +29,25 @@ import org.jenkinsci.plugins.workflow.job.WorkflowRun; import java.io.IOException; +import java.util.logging.Logger; +import static io.fabric8.jenkins.openshiftsync.BuildRunPolicy.SERIAL; +import static io.fabric8.jenkins.openshiftsync.BuildRunPolicy.SERIAL_LATEST_ONLY; import static io.fabric8.jenkins.openshiftsync.CredentialsUtils.updateSourceCredentials; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.cancelOpenShiftBuild; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.getOpenShiftClient; +import static org.apache.commons.lang.StringUtils.isBlank; /** */ public class JenkinsUtils { + private static final Logger LOGGER = Logger.getLogger(JenkinsUtils.class.getName()); + public static Job getJob(String job) { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - TopLevelItem item = jenkins.getItem(job); - if (item instanceof Job) { - return (Job) item; - } + TopLevelItem item = Jenkins.getActiveInstance().getItem(job); + if (item instanceof Job) { + return (Job) item; } return null; } @@ -62,22 +66,39 @@ public static Run getRun(BuildName buildName) { public static String getRootUrl() { // TODO is there a better place to find this? - String root = null; - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - root = jenkins.getRootUrl(); - } + String root = Jenkins.getActiveInstance().getRootUrl(); if (root == null || root.length() == 0) { - root = "http://localhost:8080/jenkins/"; + root = "http://localhost:8080/"; } return root; } - public static void triggerJob(WorkflowJob job, Build build) throws IOException { + public synchronized static void triggerJob(WorkflowJob job, Build build) throws IOException { String buildConfigName = build.getStatus().getConfig().getName(); - if (StringUtils.isEmpty(buildConfigName)) { + if (isBlank(buildConfigName)) { return; } + + BuildConfigProjectProperty bcProp = job.getProperty(BuildConfigProjectProperty.class); + if (bcProp == null) { + return; + } + + switch (bcProp.getBuildRunPolicy()) { + case SERIAL_LATEST_ONLY: + cancelQueuedBuilds(bcProp.getUid()); + if (job.getLastBuild().isBuilding()) { + return; + } + break; + case SERIAL: + if (hasQueuedBuilds(bcProp.getUid()) || job.getLastBuild().isBuilding()) { + return; + } + break; + default: + } + BuildConfig buildConfig = getOpenShiftClient().buildConfigs().inNamespace(build.getMetadata().getNamespace()).withName(buildConfigName).get(); if (buildConfig == null) { return; @@ -85,11 +106,11 @@ public static void triggerJob(WorkflowJob job, Build build) throws IOException { updateSourceCredentials(buildConfig); - Cause cause = new BuildCause(build); + Cause cause = new BuildCause(build, bcProp.getUid()); job.scheduleBuild(cause); } - public static void cancelBuild(Job job, Build build) { + public synchronized static void cancelBuild(Job job, Build build) { boolean cancelledQueuedBuild = cancelQueuedBuild(build); if (!cancelledQueuedBuild) { cancelRunningBuild(job, build); @@ -100,7 +121,7 @@ public static void cancelBuild(Job job, Build build) { private static boolean cancelRunningBuild(Job job, Build build) { String buildUid = build.getMetadata().getUid(); - for (Object obj : job.getNewBuilds()) { + for (Object obj : job.getBuilds()) { if (obj instanceof WorkflowRun) { final WorkflowRun b = (WorkflowRun) obj; BuildCause cause = b.getCause(BuildCause.class); @@ -116,21 +137,40 @@ private static boolean cancelRunningBuild(Job job, Build build) { public static boolean cancelQueuedBuild(Build build) { String buildUid = build.getMetadata().getUid(); - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - Queue buildQueue = jenkins.getQueue(); - for (Queue.Item item : buildQueue.getItems()) { - for (Cause cause : item.getCauses()) { - if (cause instanceof BuildCause && ((BuildCause) cause).getUid().equals(buildUid)) { - buildQueue.cancel(item); - return true; - } + Queue buildQueue = Jenkins.getActiveInstance().getQueue(); + for (Queue.Item item : buildQueue.getItems()) { + for (Cause cause : item.getCauses()) { + if (cause instanceof BuildCause && ((BuildCause) cause).getUid().equals(buildUid)) { + buildQueue.cancel(item); + return true; } } } return false; } + public static void cancelQueuedBuilds(String bcUid) { + Queue buildQueue = Jenkins.getActiveInstance().getQueue(); + for (Queue.Item item : buildQueue.getItems()) { + for (Cause cause : item.getCauses()) { + if (cause instanceof BuildCause) { + BuildCause buildCause = (BuildCause) cause; + if (buildCause.getBuildConfigUid().equals(bcUid)) { + if (buildQueue.cancel(item)) { + cancelOpenShiftBuild( + new BuildBuilder() + .withNewMetadata() + .withNamespace(buildCause.getNamespace()) + .withName(buildCause.getName()) + .and().build() + ); + } + } + } + } + } + } + public static WorkflowJob getJobFromBuild(Build build) { String buildConfigName = build.getStatus().getConfig().getName(); if (StringUtils.isEmpty(buildConfigName)) { @@ -142,4 +182,19 @@ public static WorkflowJob getJobFromBuild(Build build) { } return BuildTrigger.DESCRIPTOR.getJobFromBuildConfigUid(buildConfig.getMetadata().getUid()); } + + private static boolean hasQueuedBuilds(String bcUid) { + Queue buildQueue = Jenkins.getActiveInstance().getQueue(); + for (Queue.Item item : buildQueue.getItems()) { + for (Cause cause : item.getCauses()) { + if (cause instanceof BuildCause) { + BuildCause buildCause = (BuildCause) cause; + if (buildCause.getBuildConfigUid().equals(bcUid)) { + return true; + } + } + } + } + return false; + } } diff --git a/src/main/java/io/fabric8/jenkins/openshiftsync/NewBuildWatcher.java b/src/main/java/io/fabric8/jenkins/openshiftsync/NewBuildWatcher.java index cc0001382..b369195ee 100644 --- a/src/main/java/io/fabric8/jenkins/openshiftsync/NewBuildWatcher.java +++ b/src/main/java/io/fabric8/jenkins/openshiftsync/NewBuildWatcher.java @@ -35,9 +35,9 @@ import java.util.logging.Logger; import static io.fabric8.jenkins.openshiftsync.JenkinsUtils.getJobFromBuild; +import static io.fabric8.jenkins.openshiftsync.JenkinsUtils.triggerJob; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.cancelOpenShiftBuild; import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.getOpenShiftClient; -import static io.fabric8.jenkins.openshiftsync.OpenShiftUtils.parseTimestamp; import static java.net.HttpURLConnection.HTTP_GONE; public class NewBuildWatcher implements Watcher { @@ -68,11 +68,8 @@ public void start() { public void doRun() { logger.info("Waiting for Jenkins to be started"); while (true) { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - if (jenkins.isAcceptingTasks()) { - break; - } + if (Jenkins.getActiveInstance().isAcceptingTasks()) { + break; } try { Thread.sleep(500); @@ -113,7 +110,7 @@ public void onClose(KubernetesClientException e) { } } - public void onInitialBuilds(BuildList buildList) { + public synchronized void onInitialBuilds(BuildList buildList) { List items = buildList.getItems(); if (items != null) { @@ -122,8 +119,8 @@ public void onInitialBuilds(BuildList buildList) { @Override public int compare(Build b1, Build b2) { return Long.compare( - parseTimestamp(b1.getMetadata().getCreationTimestamp()), - parseTimestamp(b2.getMetadata().getCreationTimestamp()) + Long.parseLong(b1.getMetadata().getAnnotations().get("openshift.io/build.number")), + Long.parseLong(b2.getMetadata().getAnnotations().get("openshift.io/build.number")) ); } }); @@ -152,7 +149,7 @@ public void eventReceived(Action action, Build build) { } } - private void buildAdded(Build build) throws IOException { + public static synchronized void buildAdded(Build build) throws IOException { if (build.getStatus() != null && Boolean.TRUE.equals(build.getStatus().getCancelled())) { cancelOpenShiftBuild(build); return; @@ -160,9 +157,8 @@ private void buildAdded(Build build) throws IOException { WorkflowJob job = getJobFromBuild(build); if (job != null) { - JenkinsUtils.triggerJob(job, build); + triggerJob(job, build); } } - }