Skip to content

Commit 8ca91ca

Browse files
committed
Unify nf-lang config scopes with runtime classes
Signed-off-by: Ben Sherman <bentshermann@gmail.com>
1 parent a468f8e commit 8ca91ca

File tree

248 files changed

+5341
-6728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

248 files changed

+5341
-6728
lines changed

docs/google.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
# Google Cloud
44

5+
(google-credentials)=
6+
57
## Credentials
68

79
Credentials for submitting requests to the Google Cloud Batch API are picked up from your environment using [Application Default Credentials](https://github.com/googleapis/google-auth-library-java#google-auth-library-oauth2-http). Application Default Credentials are designed to use the credentials most natural to the environment in which a tool runs.

docs/notifications.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,26 @@ mail {
189189
}
190190
```
191191

192+
:::{note}
193+
Some versions of Java (e.g. Java 11 Corretto) do not default to TLS v1.2, and as a result may have issues with 3rd party integrations that enforce TLS v1.2 (e.g. Azure Active Directory OIDC). This problem can be addressed by setting the following config option:
194+
195+
```groovy
196+
mail {
197+
smtp.ssl.protocols = 'TLSv1.2'
198+
}
199+
```
200+
:::
201+
192202
See the {ref}`mail scope <config-mail>` section to learn more the mail server configuration options.
193203

194204
### AWS SES configuration
195205

196206
:::{versionadded} 23.06.0-edge
197207
:::
198208

199-
Nextflow supports [AWS SES](https://aws.amazon.com/ses/) native API as an alternative
200-
provider to send emails in place of SMTP server.
209+
Nextflow supports the [AWS Simple Email Service](https://aws.amazon.com/ses/) API as an alternative provider to send emails in place of an SMTP server.
201210

202-
To enable this feature add the following environment variable in the launching environment:
211+
To enable this feature, set the following environment variable in the launch environment:
203212

204213
```bash
205214
export NXF_ENABLE_AWS_SES=true
@@ -211,6 +220,20 @@ Make also sure to add the following AWS IAM permission to the AWS user (or role)
211220
ses:SendRawEmail
212221
```
213222

223+
The following snippet shows how to configure Nextflow to send emails through SES:
224+
225+
```groovy
226+
mail {
227+
smtp.host = 'email-smtp.us-east-1.amazonaws.com'
228+
smtp.port = 587
229+
smtp.user = '<Your AWS SES access key>'
230+
smtp.password = '<Your AWS SES secret key>'
231+
smtp.auth = true
232+
smtp.starttls.enable = true
233+
smtp.starttls.required = true
234+
}
235+
```
236+
214237
## Mail notification
215238

216239
You can use the `sendMail` function with a {ref}`workflow completion handler <metadata-completion-handler>` to notify the completion of a workflow completion. For example:

docs/reference/config.md

Lines changed: 363 additions & 389 deletions
Large diffs are not rendered by default.

docs/spack.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,11 @@ profiles {
164164
}
165165
```
166166

167-
The above configuration snippet allows the execution either with Spack or Docker by specifying `-profile spack` or
168-
`-profile docker` when running the pipeline script.
167+
The above configuration snippet allows the execution either with Spack or Docker by specifying `-profile spack` or `-profile docker` when running the pipeline script.
168+
169+
:::{note}
170+
Nextflow does not allow for fine-grained configuration of the Spack package manager. Instead, this has to be performed directly on the host Spack installation. For more information see the [Spack documentation](https://spack.readthedocs.io).
171+
:::
169172

170173
## Advanced settings
171174

modules/nextflow/src/main/groovy/nextflow/Channel.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ class Channel {
673673
final linExt = Plugins.getExtension(LinExtension)
674674
if( !linExt )
675675
throw new IllegalStateException("Unable to load lineage extensions.")
676-
final future = CompletableFuture.runAsync(() -> linExt.fromLineage(session, channel, params))
676+
final future = CompletableFuture.runAsync(() -> linExt.fromLineage(session.config, channel, params))
677677
future.exceptionally(this.&handlerException)
678678
}
679679
}

modules/nextflow/src/main/groovy/nextflow/Nextflow.groovy

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,8 @@ class Nextflow {
348348
* - attach: One or more list attachment
349349
*/
350350
static void sendMail( Map params ) {
351-
352-
new Mailer()
353-
.setConfig(Global.session.config.mail as Map)
354-
.send(params)
355-
351+
final opts = Global.session.config.mail as Map ?: Collections.emptyMap()
352+
new Mailer(opts).send(params)
356353
}
357354

358355
/**
@@ -374,9 +371,8 @@ class Nextflow {
374371
* <code>
375372
*/
376373
static void sendMail( Closure params ) {
377-
new Mailer()
378-
.setConfig(Global.session.config.mail as Map)
379-
.send(params)
374+
final config = Global.session.config.mail as Map ?: Collections.emptyMap()
375+
new Mailer(config).send(params)
380376
}
381377

382378
/**

modules/nextflow/src/main/groovy/nextflow/Session.groovy

Lines changed: 30 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,14 @@ import nextflow.cache.CacheDB
3737
import nextflow.cache.CacheFactory
3838
import nextflow.conda.CondaConfig
3939
import nextflow.config.Manifest
40+
import nextflow.container.ApptainerConfig
41+
import nextflow.container.CharliecloudConfig
4042
import nextflow.container.ContainerConfig
43+
import nextflow.container.DockerConfig
44+
import nextflow.container.PodmanConfig
45+
import nextflow.container.SarusConfig
46+
import nextflow.container.ShifterConfig
47+
import nextflow.container.SingularityConfig
4148
import nextflow.dag.DAG
4249
import nextflow.exception.AbortOperationException
4350
import nextflow.exception.AbortSignalException
@@ -436,7 +443,7 @@ class Session implements ISession {
436443
}
437444

438445
// set the byte-code target directory
439-
this.disableRemoteBinDir = getExecConfigProp(null, 'disableRemoteBinDir', false)
446+
this.disableRemoteBinDir = (config.executor as Map)?.disableRemoteBinDir as boolean
440447
this.classesDir = FileHelper.createLocalDir()
441448
this.executorFactory = new ExecutorFactory(Plugins.manager)
442449
this.observersV2 = createObserversV2()
@@ -1176,14 +1183,14 @@ class Session implements ISession {
11761183

11771184
@Memoized
11781185
CondaConfig getCondaConfig() {
1179-
final cfg = config.conda as Map ?: Collections.emptyMap()
1180-
return new CondaConfig(cfg, getSystemEnv())
1186+
final opts = config.conda as Map ?: Collections.emptyMap()
1187+
return new CondaConfig(opts, getSystemEnv())
11811188
}
11821189

11831190
@Memoized
11841191
SpackConfig getSpackConfig() {
1185-
final cfg = config.spack as Map ?: Collections.emptyMap()
1186-
return new SpackConfig(cfg, getSystemEnv())
1192+
final opts = config.spack as Map ?: Collections.emptyMap()
1193+
return new SpackConfig(opts, getSystemEnv())
11871194
}
11881195

11891196
/**
@@ -1199,91 +1206,38 @@ class Session implements ISession {
11991206
@Memoized
12001207
ContainerConfig getContainerConfig(String engine) {
12011208

1202-
final allEngines = new LinkedList<Map>()
1203-
getContainerConfig0('docker', allEngines)
1204-
getContainerConfig0('podman', allEngines)
1205-
getContainerConfig0('sarus', allEngines)
1206-
getContainerConfig0('shifter', allEngines)
1207-
getContainerConfig0('udocker', allEngines)
1208-
getContainerConfig0('singularity', allEngines)
1209-
getContainerConfig0('apptainer', allEngines)
1210-
getContainerConfig0('charliecloud', allEngines)
1209+
final allConfigs = [
1210+
new DockerConfig(config.docker as Map ?: Collections.emptyMap()),
1211+
new PodmanConfig(config.podman as Map ?: Collections.emptyMap()),
1212+
new SarusConfig(config.sarus as Map ?: Collections.emptyMap()),
1213+
new ShifterConfig(config.shifter as Map ?: Collections.emptyMap()),
1214+
new SingularityConfig(config.singularity as Map ?: Collections.emptyMap()),
1215+
new ApptainerConfig(config.apptainer as Map ?: Collections.emptyMap()),
1216+
new CharliecloudConfig(config.charliecloud as Map ?: Collections.emptyMap()),
1217+
] as List<ContainerConfig>
12111218

12121219
if( engine ) {
1213-
final result = allEngines.find(it -> it.engine==engine) ?: [engine: engine]
1214-
return new ContainerConfig(result)
1220+
return allConfigs.find { it -> it.engine == engine }
12151221
}
12161222

1217-
final enabled = allEngines.findAll(it -> it.enabled?.toString() == 'true')
1218-
if( enabled.size() > 1 ) {
1219-
final names = enabled.collect(it -> it.engine)
1223+
final allEnabled = allConfigs.findAll { it -> it.enabled }
1224+
if( allEnabled.size() > 1 ) {
1225+
final names = allEnabled.collect { it -> it.engine }
12201226
throw new IllegalConfigException("Cannot enable more than one container engine -- Choose either one of: ${names.join(', ')}")
12211227
}
1222-
if( enabled ) {
1223-
return new ContainerConfig(enabled.get(0))
1228+
if( allEnabled ) {
1229+
return allEnabled.first()
12241230
}
1225-
if( allEngines ) {
1226-
return new ContainerConfig(allEngines.get(0))
1231+
if( allConfigs ) {
1232+
return allConfigs.first()
12271233
}
1228-
return new ContainerConfig(engine:'docker')
1234+
return new DockerConfig([:])
12291235
}
12301236

12311237
ContainerConfig getContainerConfig() {
12321238
return getContainerConfig(null)
12331239
}
12341240

1235-
private void getContainerConfig0(String engine, List<Map> drivers) {
1236-
assert engine
1237-
final entry = this.config?.get(engine)
1238-
if( entry instanceof Map ) {
1239-
final config0 = new LinkedHashMap()
1240-
config0.putAll((Map)entry)
1241-
config0.put('engine', engine)
1242-
drivers.add(config0)
1243-
}
1244-
else if( entry!=null ) {
1245-
log.warn "Malformed configuration for container engine '$engine' -- One or more attributes should be provided"
1246-
}
1247-
}
1248-
1249-
@Memoized
1250-
def getExecConfigProp( String execName, String name, Object defValue, Map env = null ) {
1251-
def result = ConfigHelper.getConfigProperty(config.executor, execName, name )
1252-
if( result != null )
1253-
return result
1254-
1255-
// -- try to fallback sys env
1256-
def key = "NXF_EXECUTOR_${name.toUpperCase().replaceAll(/\./,'_')}".toString()
1257-
if( env == null ) env = System.getenv()
1258-
return env.containsKey(key) ? env.get(key) : defValue
1259-
}
1260-
1261-
@Memoized
1262-
def getConfigAttribute(String name, defValue ) {
1263-
def result = getMap0(getConfig(),name,name)
1264-
if( result != null )
1265-
return result
1266-
1267-
def key = "NXF_${name.toUpperCase().replaceAll(/\./,'_')}".toString()
1268-
def env = getSystemEnv()
1269-
return (env.containsKey(key) ? env.get(key) : defValue)
1270-
}
1271-
1272-
private getMap0(Map map, String name, String fqn) {
1273-
def p=name.indexOf('.')
1274-
if( p == -1 )
1275-
return map.get(name)
1276-
else {
1277-
def k=name.substring(0,p)
1278-
def v=map.get(k)
1279-
if( v == null )
1280-
return null
1281-
if( v instanceof Map )
1282-
return getMap0(v,name.substring(p+1),fqn)
1283-
throw new IllegalArgumentException("Not a valid config attribute: $fqn -- Missing element: $k")
1284-
}
1285-
}
1286-
12871241
@Memoized
12881242
protected Map<String,String> getSystemEnv() {
12891243
new HashMap<String, String>(System.getenv())
@@ -1350,68 +1304,6 @@ class Session implements ISession {
13501304
return String.valueOf(val)
13511305
}
13521306

1353-
1354-
/**
1355-
* Defines the number of tasks the executor will handle in a parallel manner
1356-
*
1357-
* @param execName The executor name
1358-
* @param defValue The default value if setting is not defined in the configuration file
1359-
* @return The value of tasks to handle in parallel
1360-
*/
1361-
@Memoized
1362-
int getQueueSize( String execName, int defValue ) {
1363-
getExecConfigProp(execName, 'queueSize', defValue) as int
1364-
}
1365-
1366-
/**
1367-
* Determines how often a poll occurs to check for a process termination
1368-
*
1369-
* @param execName The executor name
1370-
* @param defValue The default value if setting is not defined in the configuration file
1371-
* @return A {@code Duration} object. Default '1 second'
1372-
*/
1373-
@Memoized
1374-
Duration getPollInterval( String execName, Duration defValue = Duration.of('1sec') ) {
1375-
getExecConfigProp( execName, 'pollInterval', defValue ) as Duration
1376-
}
1377-
1378-
/**
1379-
* Determines how long the executors waits before return an error status when a process is
1380-
* terminated but the exit file does not exist or it is empty. This setting is used only by grid executors
1381-
*
1382-
* @param execName The executor name
1383-
* @param defValue The default value if setting is not defined in the configuration file
1384-
* @return A {@code Duration} object. Default '90 second'
1385-
*/
1386-
@Memoized
1387-
Duration getExitReadTimeout( String execName, Duration defValue = Duration.of('90sec') ) {
1388-
getExecConfigProp( execName, 'exitReadTimeout', defValue ) as Duration
1389-
}
1390-
1391-
/**
1392-
* Determines how often the executor status is written in the application log file
1393-
*
1394-
* @param execName The executor name
1395-
* @param defValue The default value if setting is not defined in the configuration file
1396-
* @return A {@code Duration} object. Default '5 minutes'
1397-
*/
1398-
@Memoized
1399-
Duration getMonitorDumpInterval( String execName, Duration defValue = Duration.of('5min')) {
1400-
getExecConfigProp(execName, 'dumpInterval', defValue) as Duration
1401-
}
1402-
1403-
/**
1404-
* Determines how often the queue status is fetched from the cluster system. This setting is used only by grid executors
1405-
*
1406-
* @param execName The executor name
1407-
* @param defValue The default value if setting is not defined in the configuration file
1408-
* @return A {@code Duration} object. Default '1 minute'
1409-
*/
1410-
@Memoized
1411-
Duration getQueueStatInterval( String execName, Duration defValue = Duration.of('1min') ) {
1412-
getExecConfigProp(execName, 'queueStatInterval', defValue) as Duration
1413-
}
1414-
14151307
void printConsole(String str, boolean newLine=false) {
14161308
if( ansiLogObserver )
14171309
ansiLogObserver.appendInfo(str)

modules/nextflow/src/main/groovy/nextflow/cli/CmdLineage.groovy

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import com.beust.jcommander.Parameter
2323
import com.beust.jcommander.Parameters
2424
import groovy.transform.CompileStatic
2525
import nextflow.config.ConfigBuilder
26-
import nextflow.config.ConfigMap
2726
import nextflow.exception.AbortOperationException
2827
import nextflow.plugin.Plugins
2928
import org.pf4j.ExtensionPoint
@@ -40,12 +39,12 @@ class CmdLineage extends CmdBase implements UsageAware {
4039
private static final String NAME = 'lineage'
4140

4241
interface LinCommand extends ExtensionPoint {
43-
void list(ConfigMap config)
44-
void view(ConfigMap config, List<String> args)
45-
void render(ConfigMap config, List<String> args)
46-
void diff(ConfigMap config, List<String> args)
47-
void find(ConfigMap config, List<String> args)
48-
void check(ConfigMap config, List<String> args)
42+
void list(Map config)
43+
void view(Map config, List<String> args)
44+
void render(Map config, List<String> args)
45+
void diff(Map config, List<String> args)
46+
void find(Map config, List<String> args)
47+
void check(Map config, List<String> args)
4948
}
5049

5150
interface SubCmd {
@@ -59,7 +58,7 @@ class CmdLineage extends CmdBase implements UsageAware {
5958

6059
private LinCommand operation
6160

62-
private ConfigMap config
61+
private Map config
6362

6463
CmdLineage() {
6564
commands << new CmdList()

modules/nextflow/src/main/groovy/nextflow/conda/CondaCache.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import groovy.util.logging.Slf4j
2828
import groovyx.gpars.dataflow.DataflowVariable
2929
import groovyx.gpars.dataflow.LazyDataflowVariable
3030
import nextflow.Global
31+
import nextflow.SysEnv
3132
import nextflow.file.FileMutex
3233
import nextflow.util.CacheHelper
3334
import nextflow.util.Duration
@@ -56,7 +57,7 @@ class CondaCache {
5657
/**
5758
* Timeout after which the environment creation is aborted
5859
*/
59-
private Duration createTimeout = Duration.of('20min')
60+
private Duration createTimeout
6061

6162
private String createOptions
6263

@@ -72,7 +73,7 @@ class CondaCache {
7273

7374
@PackageScope Duration getCreateTimeout() { createTimeout }
7475

75-
@PackageScope Map<String,String> getEnv() { System.getenv() }
76+
@PackageScope Map<String,String> getEnv() { SysEnv.get() }
7677

7778
@PackageScope Path getConfigCacheDir0() { configCacheDir0 }
7879

0 commit comments

Comments
 (0)