Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make RFS runnable as Container #550

Merged
merged 3 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ __pycache__
.python-version
logs
test/opensearch-cluster-cdk/
RFS/.gradle/
RFS/build/
opensearch-cluster-cdk/
5 changes: 5 additions & 0 deletions RFS/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build
51 changes: 46 additions & 5 deletions RFS/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
plugins {
id 'application'
id 'java'
id "com.avast.gradle.docker-compose" version "0.17.4"
id 'com.bmuschko.docker-remote-api'
}

sourceCompatibility = '11'
targetCompatibility = '11'
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage

java.sourceCompatibility = JavaVersion.VERSION_11
java.targetCompatibility = JavaVersion.VERSION_11

repositories {
mavenCentral()
Expand All @@ -29,7 +33,44 @@ application {
mainClassName = 'com.rfs.ReindexFromSnapshot'
}

task demoPrintOutSnapshot(type: JavaExec) {
// Cleanup additional docker build directory
clean.doFirst {
delete project.file("./docker/build")
}

task demoPrintOutSnapshot (type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'com.rfs.DemoPrintOutSnapshot'
}
mainClass = 'com.rfs.DemoPrintOutSnapshot'
}

task copyDockerRuntimeJars (type: Copy) {
description = 'Copy runtime JARs and app jar to docker build directory'

// Define the destination directory
def buildDir = project.file("./docker/build/runtimeJars")
into buildDir

// Add all the required runtime JARs to be copied
from configurations.runtimeClasspath
from tasks.named('jar')
include '*.jar'
}

// ./gradlew composeUp
// ./gradlew composeDown
dockerCompose {
useComposeFiles = ['docker/docker-compose.yml']
projectName = 'rfs-compose'
}

// ./gradlew buildDockerImages
task buildDockerImages (type: DockerBuildImage) {
dependsOn copyDockerRuntimeJars
def dockerImageName = "reindex_from_snapshot"
inputDir = project.file("./docker")
images.add("migrations/${dockerImageName}:${version}")
images.add("migrations/${dockerImageName}:latest")
}

tasks.getByName('composeUp')
.dependsOn(tasks.getByName('buildDockerImages'))
27 changes: 27 additions & 0 deletions RFS/buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file was generated by the Gradle 'init' task.
*/

plugins {
// Support convention plugins written in Groovy. Convention plugins are build scripts in 'src/main' that automatically become available as plugins in the main build.
id 'groovy-gradle-plugin'
id 'org.owasp.dependencycheck' version '8.2.1'
}

repositories {
// Use the plugin portal to apply community plugins in convention plugins.
gradlePluginPortal()
mavenCentral()
}

dependencies {
implementation 'com.bmuschko:gradle-docker-plugin:9.3.1'
}

tasks.withType(Tar){
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

tasks.withType(Zip){
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
7 changes: 7 additions & 0 deletions RFS/buildSrc/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This settings file is used to specify which projects to include in your build-logic build.
*/

rootProject.name = 'buildSrc'
21 changes: 21 additions & 0 deletions RFS/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Build jars on container
#FROM amazoncorretto:11-alpine-jdk AS builder
#COPY /gradle /rfs-build/gradle
#COPY build.gradle /rfs-build
#COPY gradlew /rfs-build
#COPY settings.gradle /rfs-build
#COPY gradle.properties /rfs-build
#COPY /src /rfs-build/src
#COPY /buildSrc /rfs-build/buildSrc
#WORKDIR /rfs-build
#RUN ./gradlew copyRuntimeJars
lewijacn marked this conversation as resolved.
Show resolved Hide resolved

# Using same base image as other Java containers in this repo
FROM openjdk:11-jre
#COPY --from=builder /rfs-build/build/runtimeJars /rfs-app/jars
lewijacn marked this conversation as resolved.
Show resolved Hide resolved
# Requires Gradle to genearte runtime jars initially
COPY ./build/runtimeJars /rfs-app/jars
WORKDIR /rfs-app
RUN printf "#!/bin/sh\njava -XX:MaxRAMPercentage=80.0 -cp /rfs-app/jars/*:. \"\$@\" " > /rfs-app/runJavaWithClasspath.sh
RUN chmod +x /rfs-app/runJavaWithClasspath.sh
CMD ["tail", "-f", "/dev/null"]
39 changes: 39 additions & 0 deletions RFS/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: '3.7'
services:

# TODO: Sync gradle for RFS and C&R
# Temporarily this requires the user to first build the elasticsearch image from the TrafficCapture gradle project
# directory using a command like ./gradlew buildDockerImages
elasticsearchsource:
image: 'migrations/elasticsearch_searchguard:latest'
networks:
- migrations
environment:
- discovery.type=single-node
ports:
- '19200:9200'

# TODO: Add example command users can run to kickoff RFS after data is loaded on source
reindex-from-snapshot:
image: 'migrations/reindex_from_snapshot:latest'
depends_on:
elasticsearchsource:
condition: service_started
opensearchtarget:
condition: service_started
networks:
- migrations

opensearchtarget:
image: 'opensearchproject/opensearch:2.11.1'
environment:
- discovery.type=single-node
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=myStrongPassword123!
networks:
- migrations
ports:
- "29200:9200"

networks:
migrations:
driver: bridge
32 changes: 26 additions & 6 deletions RFS/src/main/java/com/rfs/ReindexFromSnapshot.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
Expand Down Expand Up @@ -59,18 +61,27 @@ public static class Args {
@Parameter(names = {"--movement-type"}, description = "What you want to move - everything, metadata, or data. Default: 'everything'", required = false, converter = MovementType.ArgsConverter.class)
public MovementType movementType = MovementType.EVERYTHING;

@Parameter(names = {"--index-template-whitelist"}, description = "List of index template names to migrate (e.g. 'posts_index_template1, posts_index_template2')", required = false)
public List<String> indexTemplateWhitelist;

@Parameter(names = {"--component-template-whitelist"}, description = "List of component template names to migrate (e.g. 'posts_template1, posts_template2')", required = false)
public List<String> componentTemplateWhitelist;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, this is actually more potentially confusing than I thought originally. Per our convo, before ES 7.8, there was only templates, so if you use the script to migrate a 6.8 cluster you wouldn't see an appropriate option.

Would you mind changing --index-template-whitelist to --templates-whitelist and updating the description to indicate it refers to legacy templates for ES 6.8 and index templates for 7.10? Not a perfect fix long term, but probably enough for the moment.

TBH, this argument list is getting pretty long an gnarly. Not sure what to do about it right now, but we should think about ways to make it easier to navigate the many different use-cases it's trying to address.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, we'll also want a check so that --component-templates aren't supplied to a ES 6.8 migration.

I'm wondering if we want different wrapper scripts for different source versions, or something...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a follow-up JIRA for this: https://opensearch.atlassian.net/browse/MIGRATIONS-1646

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated as per comment for now. Need to think about this more but having a pattern for handling different arguments for different versions could be nice


@Parameter(names = {"--enable-persistent-run"}, description = "If enabled, the java process will continue in an idle mode after the migration is completed. Default: false", arity=0, required = false)
public boolean enablePersistentRun;

@Parameter(names = {"--log-level"}, description = "What log level you want. Default: 'info'", required = false, converter = Logging.ArgsConverter.class)
public Level logLevel = Level.INFO;
}

public static void main(String[] args) {
public static void main(String[] args) throws InterruptedException {
// Grab out args
Args arguments = new Args();
JCommander.newBuilder()
.addObject(arguments)
.build()
.parse(args);

String snapshotName = arguments.snapshotName;
Path snapshotDirPath = (arguments.snapshotDirPath != null) ? Paths.get(arguments.snapshotDirPath) : null;
Path s3LocalDirPath = (arguments.s3LocalDirPath != null) ? Paths.get(arguments.s3LocalDirPath) : null;
Expand All @@ -82,6 +93,8 @@ public static void main(String[] args) {
String targetPass = arguments.targetPass;
ClusterVersion sourceVersion = arguments.sourceVersion;
ClusterVersion targetVersion = arguments.targetVersion;
List<String> indexTemplateWhitelist = arguments.indexTemplateWhitelist;
List<String> componentTemplateWhitelist = arguments.componentTemplateWhitelist;
MovementType movementType = arguments.movementType;
Level logLevel = arguments.logLevel;

Expand All @@ -90,8 +103,6 @@ public static void main(String[] args) {
ConnectionDetails targetConnection = new ConnectionDetails(targetHost, targetUser, targetPass);

// Should probably be passed in as an arguments
String[] templateWhitelist = {"posts_index_template"};
String[] componentTemplateWhitelist = {"posts_template"};
int awarenessAttributeDimensionality = 3; // https://opensearch.org/docs/2.11/api-reference/cluster-api/cluster-awareness/

// Sanity checks
Expand Down Expand Up @@ -191,11 +202,11 @@ public static void main(String[] args) {
if (sourceVersion == ClusterVersion.ES_6_8) {
ObjectNode root = globalMetadata.toObjectNode();
ObjectNode transformedRoot = transformer.transformGlobalMetadata(root);
GlobalMetadataCreator_OS_2_11.create(transformedRoot, targetConnection, new String[0], templateWhitelist);
GlobalMetadataCreator_OS_2_11.create(transformedRoot, targetConnection, Collections.emptyList(), indexTemplateWhitelist);
} else if (sourceVersion == ClusterVersion.ES_7_10) {
ObjectNode root = globalMetadata.toObjectNode();
ObjectNode transformedRoot = transformer.transformGlobalMetadata(root);
GlobalMetadataCreator_OS_2_11.create(transformedRoot, targetConnection, componentTemplateWhitelist, templateWhitelist);
GlobalMetadataCreator_OS_2_11.create(transformedRoot, targetConnection, componentTemplateWhitelist, indexTemplateWhitelist);
}
}

Expand Down Expand Up @@ -294,5 +305,14 @@ public static void main(String[] args) {
} catch (Exception e) {
e.printStackTrace();
}

// Optional temporary persistent runtime flag to continue Java process after steps have completed. This should get
// replaced as this app develops and becomes aware of determining work to be completed
if (arguments.enablePersistentRun) {
while (true) {
logger.info("Process is in idle mode, to retry migration please restart this app.");
Thread.sleep(TimeUnit.MINUTES.toMillis(5));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class GlobalMetadataCreator_OS_2_11 {
private static final Logger logger = LogManager.getLogger(GlobalMetadataCreator_OS_2_11.class);

public static void create(ObjectNode root, ConnectionDetails connectionDetails, String[] componentTemplateWhitelist, String[] indexTemplateWhitelist) throws Exception {
public static void create(ObjectNode root, ConnectionDetails connectionDetails, List<String> componentTemplateWhitelist, List<String> indexTemplateWhitelist) throws Exception {
logger.info("Setting Global Metadata");

GlobalMetadataData_OS_2_11 globalMetadata = new GlobalMetadataData_OS_2_11(root);
Expand All @@ -23,7 +23,7 @@ public static void create(ObjectNode root, ConnectionDetails connectionDetails,
createIndexTemplates(globalMetadata, connectionDetails, indexTemplateWhitelist);
}

public static void createTemplates(GlobalMetadataData_OS_2_11 globalMetadata, ConnectionDetails connectionDetails, String[] indexTemplateWhitelist) throws Exception {
public static void createTemplates(GlobalMetadataData_OS_2_11 globalMetadata, ConnectionDetails connectionDetails, List<String> indexTemplateWhitelist) throws Exception {
logger.info("Setting Legacy Templates");
ObjectNode templates = globalMetadata.getTemplates();

Expand Down Expand Up @@ -59,7 +59,7 @@ public static void createTemplates(GlobalMetadataData_OS_2_11 globalMetadata, Co
}
}

public static void createComponentTemplates(GlobalMetadataData_OS_2_11 globalMetadata, ConnectionDetails connectionDetails, String[] indexTemplateWhitelist) throws Exception {
public static void createComponentTemplates(GlobalMetadataData_OS_2_11 globalMetadata, ConnectionDetails connectionDetails, List<String> indexTemplateWhitelist) throws Exception {
logger.info("Setting Component Templates");
ObjectNode templates = globalMetadata.getComponentTemplates();

Expand Down Expand Up @@ -95,7 +95,7 @@ public static void createComponentTemplates(GlobalMetadataData_OS_2_11 globalMet
}
}

public static void createIndexTemplates(GlobalMetadataData_OS_2_11 globalMetadata, ConnectionDetails connectionDetails, String[] indexTemplateWhitelist) throws Exception {
public static void createIndexTemplates(GlobalMetadataData_OS_2_11 globalMetadata, ConnectionDetails connectionDetails, List<String> indexTemplateWhitelist) throws Exception {
logger.info("Setting Index Templates");
ObjectNode templates = globalMetadata.getIndexTemplates();

Expand Down