Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions genie-docs/src/docs/asciidoc/_properties.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-featu
|genie.agent.launcher.titus.command-template
|The container command array, placeholder values are substituted at runtime
|[exec, --api-job, --launchInJobDirectory, --job-id, <JOB_ID>, --server-host, <SERVER_HOST>, --server-port, <SERVER_PORT>]
|no
|yes

|genie.agent.launcher.titus.container-attributes
|Map attributes to send to Titus specific to the container
Expand All @@ -215,7 +215,7 @@ https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-featu
|genie.agent.launcher.titus.entry-point-template
|The container entry point array, placeholder values are substituted at runtime
|[/bin/genie-agent]
|no
|yes

|genie.agent.launcher.titus.genie-server-host
|The hostname of the Genie server or cluster for the agent to connect to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,17 @@ private TitusBatchJobRequest createJobRequest(final ResolvedJob resolvedJob) thr

// Substitute all placeholders with their values for the container entry point and command
final List<String> entryPoint = REPLACE_PLACEHOLDERS.apply(
this.titusAgentLauncherProperties.getEntryPointTemplate(),
this.binder
.bind(
TitusAgentLauncherProperties.ENTRY_POINT_TEMPLATE,
Bindable.listOf(String.class))
.orElse(this.titusAgentLauncherProperties.getEntryPointTemplate()),
placeholdersMap
);
final List<String> command = REPLACE_PLACEHOLDERS.apply(
this.titusAgentLauncherProperties.getCommandTemplate(),
this.binder
.bind(TitusAgentLauncherProperties.COMMAND_TEMPLATE, Bindable.listOf(String.class))
.orElse(this.titusAgentLauncherProperties.getCommandTemplate()),
placeholdersMap
);
final Duration runtimeLimit = this.titusAgentLauncherProperties.getRuntimeLimit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public class TitusAgentLauncherProperties {
*/
public static final String CAPACITY_GROUP_PROPERTY = PREFIX + ".capacityGroup";

/**
* The container command template array, placeholder values are substituted at runtime.
*/
public static final String COMMAND_TEMPLATE = PREFIX + ".command-template";

/**
* Any attributes that should be added to the request specifically for the container.
*/
Expand All @@ -104,6 +109,11 @@ public class TitusAgentLauncherProperties {
*/
public static final String ENABLE_PROPERTY = PREFIX + ".enabled";

/**
* The container entry point template array, placeholder values are substituted at runtime.
*/
public static final String ENTRY_POINT_TEMPLATE = PREFIX + ".entry-point-template";

/**
* The name of the property that dictates which image to launch on Titus with.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,60 @@ class TitusAgentLauncherImplSpec extends Specification {
return new ObjectMapper().readValue(s, TitusBatchJobResponse.class)
}

def "Check container entrypoint and command resolution"() {
TitusBatchJobResponse response = toTitusResponse("{ \"id\" : \"" + TITUS_JOB_ID + "\" }")
TitusBatchJobRequest requestCapture

when:
Optional<JsonNode> launcherExt = launcher.launchAgent(resolvedJob, null)

then:
1 * restTemplate.postForObject(TITUS_ENDPOINT, _ as TitusBatchJobRequest, TitusBatchJobResponse.class) >> {
args ->
requestCapture = args[1] as TitusBatchJobRequest
return response
}
1 * adapter.modifyJobRequest(_ as TitusBatchJobRequest, resolvedJob)
1 * cache.put(JOB_ID, TITUS_JOB_ID)
launcherExt.isPresent()
requestCapture != null
requestCapture.getContainer().getEntryPoint() == ["/bin/genie-agent"]
requestCapture.getContainer().getCommand() == [
"exec",
"--api-job",
"--launchInJobDirectory",
"--job-id", JOB_ID,
"--server-host", launcherProperties.getGenieServerHost(),
"--server-port", launcherProperties.getGenieServerPort().toString()
]

when:
def entryPointTemplate = ["my", "entrypoint"]
def commandTemplate = ["my", "command"]
environment.withProperty(
Copy link

Choose a reason for hiding this comment

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

What happens if the property is malformed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In that case, the Titus container will still launch, but it will fail finally. This change is mainly intended to help with testing and rolling out changes related to the entry point or command. The default values are stored in property files like application.yml, so we don't anticipate needing a long-term fast property for this scenario.

TitusAgentLauncherProperties.ENTRY_POINT_TEMPLATE,
entryPointTemplate.join(",")
)
environment.withProperty(
TitusAgentLauncherProperties.COMMAND_TEMPLATE,
commandTemplate.join(",")
)
launcherExt = launcher.launchAgent(resolvedJob, null)

then:
1 * restTemplate.postForObject(TITUS_ENDPOINT, _ as TitusBatchJobRequest, TitusBatchJobResponse.class) >> {
args ->
requestCapture = args[1] as TitusBatchJobRequest
return response
}
1 * adapter.modifyJobRequest(_ as TitusBatchJobRequest, resolvedJob)
1 * cache.put(JOB_ID, TITUS_JOB_ID)
launcherExt.isPresent()
requestCapture != null
requestCapture.getContainer().getEntryPoint() == entryPointTemplate
requestCapture.getContainer().getCommand() == commandTemplate
}

@Unroll
def "Check memory allocation logic"() {
if (envMinimumMemory != null) {
Expand Down