TNB supports multiple deployment strategies for OpenShift, each optimized for different use cases and workflows.
Overview
Deployment strategies are defined in the OpenshiftDeployStrategyType enum:
public enum OpenshiftDeployStrategyType {
JKUBE,
DEVFILE,
BINARY,
CUSTOM,
JKUBE_EXT_REPO
}
Selecting a strategy
Set the deployment strategy using the openshift.deploy.strategy system property:
-Dopenshift.deploy.strategy=JKUBE
If not specified, TNB selects a default strategy based on the product type.
Strategy types
JKube strategy
The Eclipse JKube Maven plugin strategy is the standard approach for OpenShift deployments.
Type
OpenshiftDeployStrategyType
JKUBE
How it works
Build the project
Runs Maven with clean install goals.
Deploy to OpenShift
Executes JKube’s openshift goal to create OpenShift resources and deploy.
Create TNB deployment
Optionally creates TNB-specific deployment resources.
Usage
import software.tnb.product.integration.builder.IntegrationBuilder;
IntegrationBuilder ib = new IntegrationBuilder("jkube-deployment")
.fromRouteBuilder(routeBuilder)
.dependencies("timer", "log");
product.createIntegration(ib);
Configuration
# System properties
-Dopenshift.deploy.strategy=JKUBE
-Dopenshift.url=https://api.openshift.example.com:6443
-Dopenshift.namespace=my-project
JKube with external repository
Similar to JKube but pushes the container image to an external registry.
Type
OpenshiftDeployStrategyType
JKUBE_EXT_REPO
Use case
When your OpenShift cluster requires images from a specific external registry (e.g., Quay.io, Docker Hub).
Configuration
-Dopenshift.deploy.strategy=JKUBE_EXT_REPO
-Dexternal.registry.url=quay.io/myorg
-Dexternal.registry.username=myuser
-Dexternal.registry.password=mypassword
Binary strategy
Uses OpenShift’s Binary Source-to-Image (S2I) builds.
Type
OpenshiftDeployStrategyType
BINARY
How it works
Copy resources
Copies resources to ocp/deployments/data directory.
Build JAR
Runs Maven clean package with openshift profile.
Copy JAR
Copies the generated JAR to ocp/deployments.
Create build config
Creates a new build using oc new-build --binary.
Start build
Starts the build with oc start-build --from-dir.
Create deployment
Creates the deployment with oc new-app.
Expose route
Exposes the service with oc expose svc.
Key implementation details
@AutoService(OpenshiftDeployStrategy.class)
public class BinaryStrategy extends OpenshiftBaseDeployer {
@Override
public void doDeploy() {
// Create new build
binary.execute("new-build", "--binary=true",
String.format("--name=%s", name),
String.format("--image=%s", SpringBootConfiguration.openshiftBaseImage()),
String.format("--labels=%s=%s", OpenshiftConfiguration.openshiftDeploymentLabel(), name)
);
// Start build
binary.execute("start-build", name,
String.format("--from-dir=%s", baseDirectory.resolve("ocp").toAbsolutePath()),
"--follow"
);
// Create deployment
binary.execute("new-app", name,
String.format("--labels=%s=%s", OpenshiftConfiguration.openshiftDeploymentLabel(), name),
String.format("--env=JAVA_OPTS_APPEND=%s", getPropertiesForJVM(integrationBuilder)),
"--allow-missing-imagestream-tags=true"
);
// Expose service
binary.execute("expose", String.format("svc/%s", name),
String.format("--labels=%s=%s", OpenshiftConfiguration.openshiftDeploymentLabel(), name)
);
}
}
Usage
-Dopenshift.deploy.strategy=BINARY
Devfile strategy
Uses OpenShift Dev Spaces / ODO with devfile-based deployments.
Type
OpenshiftDeployStrategyType
DEVFILE
How it works
Copy resources
Copies project resources to devfile-resources directory.
Copy devfile
Copies the devfile.yaml for Java Spring Boot UBI8.
Copy Dockerfile
Copies the Dockerfile for the build.
Configure ODO
Sets ODO preferences and environment variables.
Deploy with ODO
Executes odo deploy with configured variables.
Environment variables
The strategy configures several environment variables:
MAVEN_MIRROR_URL: Maven repository mirror
JAVA_OPTS_APPEND: JVM options from integration builder
MAVEN_ARGS_APPEND: Maven arguments
SUB_FOLDER: Subfolder for multi-module projects
APP: Application name
IMAGE_REGISTRY: Container registry URL
Usage
# Install ODO CLI
-Dodo.path=/usr/local/bin/odo
# Set strategy
-Dopenshift.deploy.strategy=DEVFILE
Key implementation details
@Override
public void doDeploy() {
try {
login();
List<String> envVars = new ArrayList<>();
// Set ephemeral preference
runOdoCmd(Arrays.asList("preference", "set", "Ephemeral", "true", "--force"), Phase.GENERATE);
// Configure Maven mirror
if (TestConfiguration.isMavenMirror()) {
envVars.addAll(
setEnvVar("MAVEN_MIRROR_URL",
StringUtils.substringBefore(TestConfiguration.mavenRepository(), "@mirrorOf"))
);
}
// Add JVM properties
envVars.addAll(setEnvVar("JAVA_OPTS_APPEND", getPropertiesForJVM(integrationBuilder)));
// Deploy
ArrayList<String> devCommand = new ArrayList<>(List.of("deploy"));
devCommand.addAll(envVars);
runOdoCmd(devCommand, Phase.DEPLOY);
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
Custom strategy
Implement your own deployment strategy for special requirements.
Type
OpenshiftDeployStrategyType
CUSTOM
All products (depends on implementation)
Creating a custom strategy
Implement OpenshiftCustomDeployer
Create a class implementing the OpenshiftCustomDeployer interface.
Define deployment logic
Implement preDeploy(), doDeploy(), and undeploy() methods.
Register with integration builder
Use useOcpCustomStrategy() to register your deployer.
Example
import software.tnb.product.deploystrategy.impl.custom.OpenshiftCustomDeployer;
import software.tnb.product.integration.builder.IntegrationBuilder;
public class MyCustomDeployer implements OpenshiftCustomDeployer {
@Override
public void preDeploy() {
// Pre-deployment setup
LOG.info("Preparing custom deployment");
}
@Override
public void doDeploy() {
// Main deployment logic
LOG.info("Executing custom deployment");
// ... your deployment code ...
}
@Override
public void undeploy() {
// Cleanup
LOG.info("Cleaning up custom deployment");
}
}
// Usage
IntegrationBuilder ib = new IntegrationBuilder("custom-deploy")
.fromRouteBuilder(routeBuilder)
.useOcpCustomStrategy(new MyCustomDeployer());
Deployment phases
All deployment strategies follow a common lifecycle:
Pre-deploy
preDeploy(): Preparation tasks like copying resources, building JARs.
Deploy
doDeploy(): Main deployment to OpenShift cluster.
Wait for ready
Application waits until pods are running and ready.
Test execution
Your tests run against the deployed integration.
Undeploy
undeploy(): Cleanup of OpenShift resources.
Strategy selection logic
The OpenshiftDeployStrategyFactory selects strategies based on:
- Explicit
openshift.deploy.strategy system property
- Product type compatibility
- Custom strategy from integration builder
- Default strategy for the product
public class OpenshiftDeployStrategyFactory {
public static OpenshiftDeployStrategy getStrategy(
ProductType productType,
OpenshiftDeployStrategyType strategyType
) {
// Find strategy matching product and type
return strategies.stream()
.filter(s -> Arrays.asList(s.products()).contains(productType))
.filter(s -> s.deployType() == strategyType)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
"No strategy found for product " + productType +
" and strategy " + strategyType
));
}
}
Logging and troubleshooting
Each strategy creates log files in the application location:
{integration-name}-build.log: Build phase logs
{integration-name}-deploy.log: Deployment phase logs
{integration-name}-undeploy.log: Undeployment phase logs
final BuildRequest.Builder requestBuilder = new BuildRequest.Builder()
.withBaseDirectory(baseDirectory)
.withArgs("clean", "package")
.withProfiles("openshift")
.withLogFile(TestConfiguration.appLocation().resolve(name + "-build.log"))
.withLogMarker(LogStream.marker(name, Phase.BUILD));
Best practices
Use JKube for standard deployments
JKube is the most common and well-supported strategy for most use cases.
Use Binary for quick iterations
Binary strategy is faster for development cycles as it skips some build steps.
Use Devfile for Dev Spaces
Devfile strategy integrates with OpenShift Dev Spaces for cloud-native development.
Implement Custom for special requirements
Only implement custom strategies when built-in strategies don’t meet your needs.
Check logs for failures
Always check the generated log files when deployments fail.
Clean up resources
Ensure proper cleanup in undeploy() to avoid resource leaks.
Configuration reference
Common system properties
OpenShift cluster API URLExample: https://api.openshift.example.com:6443
openshift.deploy.strategy
OpenshiftDeployStrategyType
Deployment strategy to useValues: JKUBE, BINARY, DEVFILE, CUSTOM, JKUBE_EXT_REPO
Target namespace/project for deploymentDefault: Current namespace from kubeconfig
Path to kubeconfig fileDefault: ~/.kube/config
openshift.deployment.label
Label applied to all created resourcesDefault: tnb-deployment
Strategy-specific properties
Path to ODO CLI binary (for Devfile strategy)Default: odo (from PATH)
External container registry URL (for JKUBE_EXT_REPO strategy)
external.registry.username
Registry username (for JKUBE_EXT_REPO strategy)
external.registry.password
Registry password (for JKUBE_EXT_REPO strategy)