package net.serenitybdd.integration.jenkins.client; import com.google.common.base.Joiner; import net.serenitybdd.integration.jenkins.logging.ErrorWitness; import net.serenitybdd.integration.jenkins.logging.InfoWitness; import net.serenitybdd.integration.jenkins.logging.LoggerOutputStream; import net.serenitybdd.integration.jenkins.process.JenkinsProcess; import org.jdeferred.Promise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.regex.Matcher; import static java.lang.String.format; import static net.serenitybdd.integration.jenkins.process.JenkinsProcess.JENKINS_IS_FULLY_UP_AND_RUNNING; public class JenkinsClient { private static final Logger logger = LoggerFactory.getLogger(JenkinsClient.class); private static final int Max_Wait_Time = 5 * 60 * 1000; private final JenkinsProcess process; private final JenkinsClientExecutor executor; public JenkinsClient(JenkinsClientExecutor executor, JenkinsProcess process) { this.executor = executor; this.process = process; } // user accounts // https://gist.github.com/hayderimran7/50cb1244cc1e856873a4 // http://stackoverflow.com/questions/17716242/creating-user-in-jenkins-via-api public void registerAccount(String username, String password) { logger.info("Enabling Jenkins Security and registering account for '{}', identified by '{}'", username, password); Promise<Matcher, ?, ?> promise = process.promiseWhen("defining beans \\[authenticationManager\\]"); executeGroovy( "def instance = jenkins.model.Jenkins.getInstance()", "def usersCanRegister = true", "def realm = new hudson.security.HudsonPrivateSecurityRealm(usersCanRegister)", format("realm.createAccount(\"%s\",\"%s\")", username, password), "instance.setSecurityRealm(realm)", "instance.save()" ); try { promise.waitSafely(Max_Wait_Time); logger.info("Account for '{}' created", username); } catch (InterruptedException e) { throw new RuntimeException("Couldn't enable Jenkins Security", e); } } public void populateUpdateCenterCaches() { logger.info("FETCHING UPDATE CENTER"); Promise<Matcher, ?, ?> promise = process.promiseWhen("Obtained the latest update center data file for UpdateSource default"); executeGroovy( "def ucUrl = new URL('http://updates.jenkins-ci.org/update-center.json')", "def json = hudson.model.DownloadService.loadJSON(ucUrl)", "def site = jenkins.model.Jenkins.instance.updateCenter.getById('default')", "site.updateData(json, false)" ); try { promise.waitSafely(Max_Wait_Time); logger.info("UPDATE CENTER RELOADED"); } catch (InterruptedException e) { throw new RuntimeException("Couldn't update the Update Center caches.", e); } } public void installPlugin(String pluginName) { // http://stackoverflow.com/questions/7709993/how-can-i-update-jenkins-plugins-from-the-terminal executeCommand("install-plugin", pluginName, "-restart"); process.waitUntil(JENKINS_IS_FULLY_UP_AND_RUNNING); } public void installPlugins(List<String> plugins) { for (String pluginName : plugins) { executeCommand("install-plugin", pluginName); } safeRestart(); } public void safeRestart() { executeCommand("safe-restart"); process.waitUntil(JENKINS_IS_FULLY_UP_AND_RUNNING); } public void setExternalBuildResult(String projectName, String result) { executeCommand("set-external-build-result", "--job", projectName, "--result", result, "--log", format("%s finished with %s", projectName, result) ); } private int executeGroovy(String... groovyScriptLines) { String script = Joiner.on(";\n").join(groovyScriptLines); return executor.call("groovy", "=").execute(withInput(script), info(logger), error(logger)); } private int executeCommand(String... args) { return executor.call(args).execute(noManualInput(), info(logger), error(logger)); } private InputStream noManualInput() { return withInput(""); } private InputStream withInput(String text) { return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); } private OutputStream info(Logger logger) { return new LoggerOutputStream(new InfoWitness(logger)); } private OutputStream error(Logger logger) { return new LoggerOutputStream(new ErrorWitness(logger)); } }