Skip to content

Commit 03c801e

Browse files
pditommasoclaude
andcommitted
Add labels support to Seqera executor for cost tracking
Add configurable labels that are propagated to AWS resources (ECS tasks, capacity providers, EC2 instances) for cost tracking and resource organization. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
1 parent 8a58f9f commit 03c801e

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

plugins/nf-seqera/src/main/io/seqera/config/SeqeraConfig.groovy

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ class SeqeraConfig implements ConfigScope {
6767
""")
6868
final MachineRequirementOpts machineRequirement
6969

70+
@ConfigOption
71+
@Description("""
72+
Custom labels to apply to AWS resources for cost tracking and resource organization.
73+
Labels are propagated to ECS tasks, capacity providers, and EC2 instances.
74+
""")
75+
final Map<String, String> labels
76+
7077
/* required by config scope -- do not remove */
7178
SeqeraConfig() {}
7279

@@ -83,6 +90,8 @@ class SeqeraConfig implements ConfigScope {
8390
: Duration.of('1 sec')
8491
// machine requirement settings
8592
this.machineRequirement = new MachineRequirementOpts(opts.machineRequirement as Map ?: Map.of())
93+
// labels for cost tracking
94+
this.labels = opts.labels as Map<String, String>
8695
}
8796

8897
RetryOpts retryOpts() {
@@ -108,4 +117,8 @@ class SeqeraConfig implements ConfigScope {
108117
MachineRequirementOpts getMachineRequirement() {
109118
return machineRequirement
110119
}
120+
121+
Map<String, String> getLabels() {
122+
return labels
123+
}
111124
}

plugins/nf-seqera/src/main/io/seqera/executor/SeqeraExecutor.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ class SeqeraExecutor extends Executor implements ExtensionPoint {
8585

8686
protected void createSession() {
8787
final machineReq = MapperUtil.toMachineRequirement(seqeraConfig.machineRequirement)
88-
log.debug "[SEQERA] Creating session for workflow in region: ${seqeraConfig.region}, runName: ${session.runName}, machineRequirement: ${machineReq}"
89-
final response = client.createSession(seqeraConfig.region, session.runName, machineReq)
88+
final labels = seqeraConfig.labels
89+
log.debug "[SEQERA] Creating session for workflow in region: ${seqeraConfig.region}, runName: ${session.runName}, machineRequirement: ${machineReq}, labels: ${labels}"
90+
final response = client.createSession(seqeraConfig.region, session.runName, machineReq, labels)
9091
this.sessionId = response.getSessionId()
9192
log.debug "[SEQERA] Session created id: ${sessionId}"
9293
// Initialize and start batch submitter with error callback to abort session on fatal errors

plugins/nf-seqera/src/test/io/seqera/config/SeqeraConfigTest.groovy

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,40 @@ class SeqeraConfigTest extends Specification {
127127
config.machineRequirement.provisioning == 'spot'
128128
}
129129

130+
def 'should create config with labels' () {
131+
when:
132+
def config = new SeqeraConfig([
133+
endpoint: 'https://sched.example.com',
134+
labels: [
135+
project: 'genomics',
136+
team: 'research',
137+
costCenter: 'CC-1234'
138+
]
139+
])
140+
141+
then:
142+
config.labels == [project: 'genomics', team: 'research', costCenter: 'CC-1234']
143+
}
144+
145+
def 'should handle null labels' () {
146+
when:
147+
def config = new SeqeraConfig([
148+
endpoint: 'https://sched.example.com'
149+
])
150+
151+
then:
152+
config.labels == null
153+
}
154+
155+
def 'should handle empty labels' () {
156+
when:
157+
def config = new SeqeraConfig([
158+
endpoint: 'https://sched.example.com',
159+
labels: [:]
160+
])
161+
162+
then:
163+
config.labels == [:]
164+
}
165+
130166
}

0 commit comments

Comments
 (0)