From b4c03caa094f7705d7e9d64521c3f41f4fdc068a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=B8=9C=E7=A1=95?= <410212983@qq.com> Date: Thu, 10 Jan 2019 16:16:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81promotion=E7=9A=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E3=80=81=E4=BF=AE=E6=94=B9=E3=80=81=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jenkins-client/pom.xml | 13 ++ .../com/offbytwo/jenkins/JenkinsServer.java | 2 +- .../com/offbytwo/jenkins/JenkinsTest.java | 133 ++++++++++++++++++ .../jenkins/client/JenkinsHttpClient.java | 24 ++++ .../jenkins/client/JenkinsHttpConnection.java | 2 + .../jenkins/client/util/UrlUtils.java | 4 +- .../com/offbytwo/jenkins/model/Action.java | 38 +++++ .../jenkins/model/ActionWithDetails.java | 91 ++++++++++++ .../com/offbytwo/jenkins/model/Build.java | 5 + .../jenkins/model/BuildWithDetails.java | 2 + .../jenkins/model/JobWithDetails.java | 36 ++++- .../jenkins/model/PromotedAction.java | 14 ++ 12 files changed, 357 insertions(+), 7 deletions(-) create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTest.java create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/model/Action.java create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/model/ActionWithDetails.java create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/model/PromotedAction.java diff --git a/jenkins-client/pom.xml b/jenkins-client/pom.xml index 75eb3fc9..18abb197 100644 --- a/jenkins-client/pom.xml +++ b/jenkins-client/pom.xml @@ -119,6 +119,19 @@ xml-apis xml-apis + + + org.projectlombok + lombok + 1.18.4 + provided + + + + org.jsoup + jsoup + 1.11.3 + diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index a7e0c416..778ea126 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -282,7 +282,7 @@ public JobWithDetails getJob(FolderJob folder, String jobName) throws IOExceptio try { JobWithDetails job = client.get(UrlUtils.toJobBaseUrl(folder, jobName), JobWithDetails.class); job.setClient(client); - + job.setFolder(folder); return job; } catch (HttpResponseException e) { LOGGER.debug("getJob(folder={}, jobName={}) status={}", folder, jobName, e.getStatusCode()); diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTest.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTest.java new file mode 100644 index 00000000..a9f72f78 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTest.java @@ -0,0 +1,133 @@ +package com.offbytwo.jenkins; + + +import com.offbytwo.jenkins.model.*; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.parser.Parser; +import org.jsoup.select.Elements; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by msdg on 2019/1/7. + * Look, there is a moon. + */ +public class JenkinsTest { + + public static void main(String[] args) throws URISyntaxException, IOException { + + String rooUrl = "http://ci.lianjia.com"; + JenkinsServer jenkins = new JenkinsServer(new URI(rooUrl), "qianlimei", "101379Sanctity"); + FolderJob folderJob = new FolderJob("confucius", rooUrl + "/job/confucius/"); + +// Map jobs = jenkins.getJobs(new FolderJob("confucius", "http://ci.lianjia.com/job/confucius/")); + +// jobs.forEach((k,v) -> System.out.println(k)); + +// Job job = jobs.get("mooc-server-test"); + JobWithDetails jobWithDetail = jenkins.getJob(folderJob, "viviane"); + System.out.println(jobWithDetail); + +// jobWithDetail.getLastBuild().promotionBuild("m-u44"); + + List actions = jobWithDetail.actions(); + for (Action action : actions) { + System.out.println(action.getName()); + System.out.println(action.getColor()); + System.out.println(action.getUrl()); + + ActionWithDetails actionDetail = jobWithDetail.actionDetails(action.getName()); + + String config = actionDetail.getPromotionXml(); +// Pattern pattern = Pattern.compile(".*"); +// Matcher matcher = pattern.matcher(config); +// while (matcher.find()) { +// System.out.println(matcher.group()); +// } +// + Document doc = Jsoup.parse(config, "", Parser.xmlParser()); + Elements elements = doc.getElementsByTag("command"); + Element element = elements.get(0); + + String command = element.text(); + if (command.contains("--limit")) { + command = command.replaceAll("\\s+--limit\\s+\\d+\\.\\d+\\.\\d+\\.\\d+", " --limit 10.200.17.2333"); + } else { + command += " --limit 10.200.17.22"; + } + element = element.text(command); + actionDetail.modifyPromotionXml(doc.toString()); + +// Build actionBuild = actionDetail.getBuildByNumber(actionDetail.getNextBuildNumber() - 1); +// BuildWithDetails actionBuildDetail = actionBuild.details(); +// ConsoleLog consoleLog = actionBuildDetail.getConsoleOutputText(0); +// System.out.println(consoleLog.getConsoleLog()); + } + } +// +// public static void main(String[] args) { +// String config = "\n" + +// "false\n" + +// "\n" + +// "\n" + +// "true\n" + +// "false\n" + +// "false\n" + +// "false\n" + +// "\n" + +// "false\n" + +// "\n" + +// "star-red\n" + +// "\n" + +// "\n" + +// "\n" + +// "\n" + +// "echo '========' echo $PROMOTED_NUMBER wget_path=\"ftp://ftpadmin:nQDPrUh4@ci.jenkins.ke.com/home/work/jenkins_home/jobs/ZD/jobs/app-push-ui-release/builds/${PROMOTED_NUMBER}/archive/releases/m.zhidaovip.com.tar.gz\" /usr/bin/distrsync --url $wget_path --module apppush.zhidaovip.com --access-token YZQAUUHXMZEISRX52Q7QLAUIFYVB037L1XSTELF89F3CNKIMDCV3TQZKW2WWZM44\n" + +// "\n" + +// "\n" + +// "\n" + +// "\n" + +// "cd $WORKSPACE/m.zhidaovip.com tar -czf static.tar.gz $WORKSPACE/m.zhidaovip.com/static /usr/bin/distrsync --srcroot static --module s1.ljcdn.com --submodule ruzhidao --access-token YZQAUUHXMZEISRX52Q7QLAUIFYVB037L1XSTELF89F3CNKIMDCV3TQZKW2WWZM44 rm -fr $WORKSPACE/m.zhidaovip.com/static.tar.gz\n" + +// "\n" + +// "\n" + +// "\n" + +// ""; +// +// System.out.println(config); +// Document doc = Jsoup.parse(config, "", Parser.xmlParser()); +// +// Elements elements = doc.getElementsByTag("command"); +// Element element = elements.get(0); +// String command = element.text(); +// if (command.contains("--limit")) { +// command = command.replaceAll("\\s+--limit\\s+\\d+\\.\\d+\\.\\d+\\.\\d+", " --limit 10.200.17.22"); +// } else { +// command += " --limit 1.1.1.1"; +// } +// element = element.text(command); +// System.out.println(doc.toString()); +//// +//// command = element.text(); +//// if (command.contains("--limit")) { +//// command = command.replaceAll("\\s+--limit\\s+\\d+\\.\\d+\\.\\d+\\.\\d+", " --limit 111.111.111.111"); +//// } else { +//// command += " --limit 255.255.255.255"; +//// } +//// element = element.text(command); +//// System.out.println(doc.toString()); +//// +//// command = element.text(); +//// if (command.contains("--limit")) { +//// command = command.replaceAll("\\s+--limit\\s+\\d+\\.\\d+\\.\\d+\\.\\d+", ""); +//// } +//// element = element.text(command); +//// System.out.println(doc.toString()); +// } +} diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java index 3954f952..aa51f1bc 100755 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java @@ -380,6 +380,30 @@ public String post_xml(String path, String xml_data, boolean crumbFlag) throws I } } + @Override + public String post_xml_no_api(String path, String xml_data, boolean crumbFlag) throws IOException { + HttpPost request = new HttpPost(UrlUtils.toNoApiUri(uri, context, path)); + if (crumbFlag == true) { + Crumb crumb = getQuietly("/crumbIssuer", Crumb.class); + if (crumb != null) { + request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb())); + } + } + + if (xml_data != null) { + request.setEntity(new StringEntity(xml_data, ContentType.create("text/xml", "utf-8"))); + } + HttpResponse response = client.execute(request, localContext); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); + try { + httpResponseValidator.validateResponse(response); + return IOUtils.toString(response.getEntity().getContent()); + } finally { + EntityUtils.consume(response.getEntity()); + releaseConnection(request); + } + } + /** * {@inheritDoc} */ diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java index 26a6fb01..8df6ff1f 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java @@ -220,6 +220,8 @@ public interface JenkinsHttpConnection extends Closeable { */ String post_xml(String path, String xml_data, boolean crumbFlag) throws IOException; + String post_xml_no_api(String path, String xml_data, boolean crumbFlag) throws IOException; + /** * Get the Jenkins server version. * diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java index 6f8b17d9..53126398 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java @@ -37,7 +37,7 @@ private UrlUtils() { public static String toBaseUrl(final FolderJob folder) { return folder == null ? "/" : folder.getUrl(); } - + /** @@ -59,7 +59,7 @@ public static String toJobBaseUrl(final FolderJob folder, final String jobName) } return sb.toString(); } - + /** * Helper to create the base url for a view, with or without a given folder diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Action.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Action.java new file mode 100644 index 00000000..87cffc64 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Action.java @@ -0,0 +1,38 @@ +package com.offbytwo.jenkins.model; + +import java.io.IOException; + +/** + * Created by msdg on 2019/1/8. + * Look, there is a moon. + */ +public class Action extends BaseModel{ + + private String name; + private String url; + private String color; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ActionWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ActionWithDetails.java new file mode 100644 index 00000000..d7f45cb5 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ActionWithDetails.java @@ -0,0 +1,91 @@ +package com.offbytwo.jenkins.model; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.offbytwo.jenkins.client.util.UrlUtils; +import lombok.Data; + +import java.io.IOException; +import java.util.List; + +/** + * Created by msdg on 2019/1/8. + * Look, there is a moon. + */ +@Data +public class ActionWithDetails extends Action { + private String description; + + private String displayName; + + private boolean buildable; + + private List builds; + + private Build firstBuild; + + private Build lastBuild; + + private Build lastCompletedBuild; + + private Build lastFailedBuild; + + private Build lastStableBuild; + + private Build lastSuccessfulBuild; + + private Build lastUnstableBuild; + + private Build lastUnsuccessfulBuild; + + private int nextBuildNumber; + + private boolean inQueue; + + private QueueItem queueItem; + + private List downstreamProjects; + + private List upstreamProjects; + + + public Build getBuildByNumber(final int number) { + Predicate isMatchNumber = new Predicate() { + @Override + public boolean apply(Build Build) { + return Build.getNumber() == number; + } + }; + Optional optional = Iterables.tryFind(builds, isMatchNumber); + return optional.orNull() == null ? null : buildWithClient(optional.orNull()); + } + + private Build buildWithClient(Build from) { + Build ret = from; + if (from != null) { + ret = new Build(from); + ret.setClient(client); + } + return ret; + } + + /** + * Trigger a build without parameters + * + * @return {@link QueueReference} for further analysis of the queued build. + * @throws IOException in case of an error. + */ + public QueueReference build() throws IOException { + ExtractHeader location = client.post(getUrl() + "build", null, ExtractHeader.class, false); + return new QueueReference(location.getLocation()); + } + + public String getPromotionXml() throws IOException { + return client.get(getUrl() + "/config.xml"); + } + + public void modifyPromotionXml(String newConfigXml) throws IOException { + client.post_xml_no_api(getUrl() + "/config.xml", newConfigXml, false); + } +} diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java index f48e38e8..c0b1b365 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java @@ -210,4 +210,9 @@ public int hashCode() { result = prime * result + ((url == null) ? 0 : url.hashCode()); return result; } + + public void promotionBuild(String name) throws IOException { + String path = url + "/promotion/forcePromotion?name=" + name; + client.post(path); + } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java index 8674e921..03313a96 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java @@ -10,6 +10,8 @@ import com.google.common.base.Predicate; import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; +import com.offbytwo.jenkins.client.util.EncodingUtils; +import com.offbytwo.jenkins.client.util.UrlUtils; import com.offbytwo.jenkins.helper.BuildConsoleStreamListener; import org.apache.http.Header; import org.apache.http.HttpResponse; diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java index d203aad5..c51480e1 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java @@ -13,6 +13,8 @@ import java.util.List; import java.util.Objects; +import com.offbytwo.jenkins.client.util.UrlUtils; +import lombok.Data; import org.apache.http.HttpStatus; import org.apache.http.client.HttpResponseException; @@ -59,6 +61,8 @@ public class JobWithDetails extends Job { private List downstreamProjects; private List upstreamProjects; + + private FolderJob folder; public String getDescription() { return description; @@ -120,10 +124,8 @@ public Build apply(Build from) { * Issue */ public List getAllBuilds() throws IOException { - String path = "/"; - try { - List builds = client.get(path + "job/" + EncodingUtils.encode(this.getName()) + List builds = client.get(UrlUtils.toJobBaseUrl(folder, this.getName()) + "?tree=allBuilds[number[*],url[*],queueId[*]]", AllBuilds.class).getAllBuilds(); if (builds == null) { @@ -205,6 +207,22 @@ private Build buildWithClient(Build from) { return ret; } + public List actions() throws IOException { + String path = this.getUrl() + "/promotion"; + return client.get(path, PromotedAction.class).getProcesses(); + } + + public ActionWithDetails actionDetails(String name) throws IOException { + return client.get(makePromotionUrl(name), ActionWithDetails.class); + } +// +// public String getPromotionXml(String name) throws IOException { +// return client.get(makePromotionUrl(name) + "/config.xml"); +// } +// + private String makePromotionUrl(String name) { + return UrlUtils.toJobBaseUrl(folder, this.getName()) + "/promotion/process/" + EncodingUtils.encode(name); + } /** * @return the first build which has been executed or * {@link Build#BUILD_HAS_NEVER_RUN} if the build has never been @@ -551,6 +569,7 @@ public int hashCode() { result = prime * result + nextBuildNumber; result = prime * result + ((queueItem == null) ? 0 : queueItem.hashCode()); result = prime * result + ((upstreamProjects == null) ? 0 : upstreamProjects.hashCode()); + result = prime * result + ((folder == null) ? 0 : folder.hashCode()); return result; } @@ -637,9 +656,18 @@ public boolean equals(Object obj) { if (upstreamProjects == null) { if (other.upstreamProjects != null) return false; - } else if (!upstreamProjects.equals(other.upstreamProjects)) + } else if (!upstreamProjects.equals(other.upstreamProjects)) { + return false; + } else if (folder == null) { + if (other.folder != null) + return false; + } else if (!folder.equals(other.folder)) { return false; + } return true; } + public void setFolder(FolderJob folder) { + this.folder = folder; + } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PromotedAction.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PromotedAction.java new file mode 100644 index 00000000..aec54d69 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PromotedAction.java @@ -0,0 +1,14 @@ +package com.offbytwo.jenkins.model; + +import lombok.Data; + +import java.util.List; + +/** + * Created by msdg on 2019/1/8. + * Look, there is a moon. + */ +@Data +public class PromotedAction extends BaseModel{ + private List processes; +}