Skip to content
Permalink
Browse files

JENKINS-23908 - Provide way to execute external liquibase

creation of liquibase installation class and available job config
  • Loading branch information
prospero238 committed Jul 23, 2014
1 parent d95b122 commit 4b64c5347c5a1e03d047f4f6a2e7f3852e8d8390
@@ -6,8 +6,10 @@
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.Result;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import hudson.tools.ToolInstallation;
import hudson.util.ArgumentListBuilder;
import liquibase.Contexts;
import liquibase.Liquibase;
@@ -24,6 +26,7 @@
import java.util.Properties;

import org.jenkinsci.plugins.liquibase.common.PropertiesParser;
import org.jenkinsci.plugins.liquibase.installation.LiquibaseInstallation;
import org.kohsuke.stapler.DataBoundConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -79,6 +82,11 @@

private String liquibasePropertiesPath;

private boolean invokeExternal;

private String installationName;


@DataBoundConstructor
public LiquibaseBuilder(String changeLogFile,
String username,
@@ -88,7 +96,9 @@ public LiquibaseBuilder(String changeLogFile,
String contexts,
String databaseEngine,
boolean testRollbacks,
String liquibasePropertiesPath) {
String liquibasePropertiesPath,
boolean invokeExternal,
String installationName) {
this.password = password;
this.defaultSchemaName = defaultSchemaName;
this.url = url;
@@ -101,7 +111,8 @@ public LiquibaseBuilder(String changeLogFile,
this.testRollbacks = testRollbacks;
this.liquibasePropertiesPath = liquibasePropertiesPath;


this.invokeExternal = invokeExternal;
this.installationName = installationName;
}

@Override
@@ -126,13 +137,13 @@ public boolean perform(final AbstractBuild<?, ?> build, Launcher launcher, Build
action.addFailed(changeSetOptional.get());
}
migrationException.printStackTrace(listener.getLogger());
throw new RuntimeException("Error executing liquibase liquibase database", migrationException);
build.setResult(Result.UNSTABLE);
} catch (DatabaseException e) {
e.printStackTrace(listener.getLogger());
throw new RuntimeException("Error creating liquibase database", e);
build.setResult(Result.FAILURE);
} catch (LiquibaseException e) {
e.printStackTrace(listener.getLogger());
throw new RuntimeException("Error executing liquibase liquibase database", e);
build.setResult(Result.FAILURE);
} finally {
if (liquibase.getDatabase() != null) {
try {
@@ -150,7 +161,6 @@ private Liquibase createLiquibase(AbstractBuild<?, ?> build,
ExecutedChangesetAction action,
Properties configProperties) {


Liquibase liquibase;
try {
Database databaseObject = CommandLineUtils.createDatabaseObject(getClass().getClassLoader(),
@@ -227,6 +237,10 @@ public String getUsername() {
return username;
}

public boolean isInvokeExternal() {
return invokeExternal;
}

public String getPassword() {
return password;
}
@@ -282,6 +296,7 @@ public void setDriverName(String driverName) {
public static class DescriptorImpl extends BuildStepDescriptor<Builder> {

private List<EmbeddedDriver> embeddedDrivers;
private LiquibaseInstallation[] installations;

@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
@@ -299,13 +314,25 @@ public String getDisplayName() {
}
return embeddedDrivers;
}
public LiquibaseInstallation.DescriptorImpl getToolDescriptor() {
return ToolInstallation.all().get(LiquibaseInstallation.DescriptorImpl.class);
}

private void initDriverList() {
embeddedDrivers = Lists.newArrayList(new EmbeddedDriver("MySQL", "com.mysql.jdbc.Driver"),
new EmbeddedDriver("PostgreSQL", "org.postgresql.Driver"),
new EmbeddedDriver("Hypersonic", "org.hsqldb.jdbcDriver"),
new EmbeddedDriver("H2", "org.h2.Driver"));
}

public LiquibaseInstallation[] getInstallations() {
return installations;
}

public void setInstallations(LiquibaseInstallation[] installations) {
this.installations = installations;
save();
}
}

}
@@ -0,0 +1,58 @@
package org.jenkinsci.plugins.liquibase.installation;

import hudson.EnvVars;
import hudson.Extension;
import hudson.model.EnvironmentSpecific;
import hudson.model.Node;
import hudson.model.TaskListener;
import hudson.slaves.NodeSpecific;
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolInstallation;
import hudson.tools.ToolProperty;
import jenkins.model.Jenkins;

import java.io.IOException;
import java.util.List;

import org.jenkinsci.plugins.liquibase.builder.LiquibaseBuilder;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Describes details of liquibase installation.
*/
public class LiquibaseInstallation extends ToolInstallation
implements NodeSpecific<LiquibaseInstallation>, EnvironmentSpecific<LiquibaseInstallation> {

@DataBoundConstructor
public LiquibaseInstallation(String name, String home, List<? extends ToolProperty<?>> properties) {
super(name, home, properties);
}

public LiquibaseInstallation forEnvironment(EnvVars environment) {
return new LiquibaseInstallation(getName(), getHome(), getProperties().toList());
}

public LiquibaseInstallation forNode(Node node, TaskListener log) throws IOException, InterruptedException {
return new LiquibaseInstallation(getName(), getHome(), getProperties().toList());
}


@Extension
public static class DescriptorImpl extends ToolDescriptor<LiquibaseInstallation> {
@Override
public String getDisplayName() {
return "Liquibase";
}

@Override
public LiquibaseInstallation[] getInstallations() {
return Jenkins.getInstance().getDescriptorByType(LiquibaseBuilder.DESCRIPTOR.getClass()).getInstallations();
}

@Override
public void setInstallations(LiquibaseInstallation... installations) {
Jenkins.getInstance().getDescriptorByType(LiquibaseBuilder.DESCRIPTOR.getClass())
.setInstallations(installations);
}
}
}
@@ -2,6 +2,21 @@
xmlns:f="/lib/form">


<f:radioBlock inline="true" name="invokeExternal" checked="${instance.invokeExternal}" value="false"
title="${%Use Existing Liquibase Installation}">
<f:entry title="${%Liquibase Version}" field="installationName">
<select class="setting-input" name="installationName">
<option>(Default)</option>
<j:forEach var="inst" items="${descriptor.installations}">
<f:option selected="${inst.name==instance.installationName}">${inst.name}</f:option>
</j:forEach>
</select>
</f:entry>
</f:radioBlock>
<f:radioBlock inline="true" name="invokeExternal" checked="${!instance.invokeExternal}" value="true"
title="${%Use Embedded Liquibase}">
</f:radioBlock>

<f:entry title="Change Log File" field="changeLogFile"
description="Root changeset file.">
<f:textbox value="${instance.changeLogFile}"/>
@@ -37,11 +52,13 @@
<f:entry title="Contexts" field="contexts" description="Comma separated list of liquibase contexts to execute.">
<f:textbox value="${instance.contexts}"/>
</f:entry>
<f:entry title="Defaults file" field="liquibasePropertiesPath" description="Properties file defining liquibase configuration. You can use this instead of defining above configuration.">
<f:entry title="Defaults file" field="liquibasePropertiesPath"
description="Properties file defining liquibase configuration. You can use this instead of defining above configuration.">
<f:textbox value="${instance.liquibasePropertiesPath}"/>
</f:entry>

<f:entry title="Test Rollbacks" field="testRollbacks" description="Executes any included rollback statements in addition to the changeset.">
<f:entry title="Test Rollbacks" field="testRollbacks"
description="Executes any included rollback statements in addition to the changeset.">
<f:checkbox checked="${instance.testRollbacks}"/>
</f:entry>

@@ -0,0 +1,9 @@
<j:jelly xmlns:j="jelly:core"
xmlns:f="/lib/form">
<f:entry title="${%name}" field="name">
<f:textbox/>
</f:entry>
<f:entry title="LIQUIBASE_HOME" field="home">
<f:textbox/>
</f:entry>
</j:jelly>

0 comments on commit 4b64c53

Please sign in to comment.
You can’t perform that action at this time.