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

List process container images in preview mode #4069

Merged
merged 71 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
cb555cb
Dump container image for each process during preview run
bentsherman Jun 30, 2023
e1640fb
Support any directives, save report to JSON file
bentsherman Jul 5, 2023
a84511a
Add -preview-report CLI option to enable preview report
bentsherman Jul 6, 2023
2a85e7a
Merge branch 'master' into 3340-preview-container-images
bentsherman Jul 27, 2023
181c8b3
Apply suggestions from review
bentsherman Jul 27, 2023
aef325e
Merge branch 'master' into 3340-preview-container-images
pditommaso Jul 30, 2023
b330461
Merge branch '3340-preview-container-images' of github.com:nextflow-i…
pditommaso Aug 2, 2023
05c8c58
Merge branch 'master' into 3340-preview-container-images
pditommaso Aug 2, 2023
0db293f
Rename to PreviewContainersObserver [ci fast]
pditommaso Aug 2, 2023
938c7f3
Fix minor type error [ci skip]
pditommaso Aug 2, 2023
6f72b30
Revert unrelated changes
bentsherman Aug 2, 2023
d8a704f
Format JSON as array of objects
bentsherman Aug 2, 2023
631f38b
Pushing missing log [ci skip]
pditommaso Aug 2, 2023
4f1642a
Replace file output with stdout, suppress console output
bentsherman Aug 4, 2023
050874b
Update Wave and Fusion docs (#4149)
bentsherman Aug 3, 2023
4838bfb
Fix strict mode docs (#4150)
bentsherman Aug 3, 2023
6f65591
Fix bug with K8s resource labels (#4147) [ci fast]
bentsherman Aug 3, 2023
b009ecf
Add `-value` option to `config` command (#4142)
afishman Aug 3, 2023
f738ec0
Fix Wave disable flag
pditommaso Aug 4, 2023
7be17d3
Restore Tower CacheManager for backward compatibility
pditommaso Aug 5, 2023
36d6de3
Increase Wave client max attempts
pditommaso Aug 5, 2023
dd7d922
Bump [email protected]
pditommaso Aug 5, 2023
3555e00
Bump [email protected]
pditommaso Aug 5, 2023
167de54
Bump [email protected]
pditommaso Aug 5, 2023
ac2c473
Bump [email protected]
pditommaso Aug 5, 2023
2954436
Update changelog
pditommaso Aug 5, 2023
a391a75
[release 23.08.0-edge] Update timestamp and build number [ci fast]
pditommaso Aug 5, 2023
822184f
Enable cloud cache based on environment variable (#4160)
bentsherman Aug 8, 2023
2079efc
Minor changes [ci fast]
pditommaso Aug 9, 2023
8f0fa99
Fix typos in source code comments (#4173) [ci fast]
mribeirodantas Aug 10, 2023
8482c35
Add 429 http status code to Wave retriable errors
pditommaso Aug 10, 2023
d5ec1f0
Update changelog
pditommaso Aug 11, 2023
bd026e5
Improve Conda build error report [ci fast]
pditommaso Aug 13, 2023
da6ceba
Fix Process hangs when using flatten and finish errorStrategy
pditommaso Aug 13, 2023
1eb5293
Fix Execution should fail if report or timeline file already exists
pditommaso Aug 13, 2023
901ceb7
Fix env output when changing task workdir
pditommaso Aug 13, 2023
41385fa
Improve handling of name-only container env variables
pditommaso Aug 13, 2023
3a3fbf0
Document error about trailing backslash with space (#4180)
bentsherman Aug 13, 2023
ce01de2
Update AWS instructions for creating a custom AMI [ci skip] (#4174)
manuelesimi Aug 13, 2023
df20ac4
Remove lock file from cloudcache (#4167)
bentsherman Aug 13, 2023
f04f62c
Fix checkpoint thread termination (#4166)
pditommaso Aug 13, 2023
333ea7e
Update tip about modifying maps (#4153) [ci skip]
bentsherman Aug 14, 2023
2b13235
Apply K8s Pod metadata to Job (#4057) [ci fast]
bentsherman Aug 14, 2023
694cff0
Remove dockerize launcher classpath file (#4191) [ci fast]
bentsherman Aug 15, 2023
cec558c
Fix `workflow.container` map resolution (#4190)
bentsherman Aug 15, 2023
062cb1c
Escape semicolons in paths (#4193)
bentsherman Aug 15, 2023
7a26e4a
Use root user in Wave container based on micromamba (#4038) [ci fast]
marcodelapierre Aug 15, 2023
109f3b1
FIx nested InvocationTargetException (#4192) [ci fast]
bentsherman Aug 15, 2023
8b2c276
Fix if-guard on log.trace in trask processor inner class [ci fast]
pditommaso Aug 16, 2023
42ea6c8
Add resource labels support for Azure Batch (#4178)
bentsherman Aug 17, 2023
eb38aea
Bump [email protected]
pditommaso Aug 17, 2023
8223dbe
Bump [email protected]
pditommaso Aug 17, 2023
a70ec26
Bump [email protected]
pditommaso Aug 17, 2023
24a695d
Bump [email protected]
pditommaso Aug 17, 2023
ac72bc9
Update changelog [ci fast]
pditommaso Aug 17, 2023
d7c4fc1
[release 23.08.1-edge] Update timestamp and build number [ci fast]
pditommaso Aug 17, 2023
d2ac7d6
Fix security deps in nf-azure plugin
pditommaso Aug 17, 2023
513e0d2
Add support for Wave native build for singularity
pditommaso Aug 20, 2023
8ee9cb2
Bump groovy 3.0.19
pditommaso Aug 23, 2023
e69ec67
Move containers preview to its own command
pditommaso Aug 23, 2023
006623d
Merge branch 'master' into 3340-preview-container-images
pditommaso Aug 23, 2023
d549a82
apply suggestions from review, minor edits
bentsherman Aug 23, 2023
544235b
Add tests [ci fast]
pditommaso Aug 23, 2023
0481202
Fix & more
pditommaso Aug 23, 2023
44614b4
Just a blank [ci skip]
pditommaso Aug 23, 2023
a6c12b2
remove extraneous tests
bentsherman Aug 23, 2023
314f348
Add tests [ci fast]
pditommaso Aug 24, 2023
7ec45eb
Add prompt confirmation [ci fast]
pditommaso Aug 24, 2023
8f0eb45
Restructure json result
pditommaso Aug 24, 2023
15659cf
Add Wave dry-run mode + inspect -concretize
pditommaso Aug 24, 2023
dfdeeb4
update docs [ci fast]
bentsherman Aug 23, 2023
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
21 changes: 13 additions & 8 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,12 @@ The `run` command is used to execute a local pipeline script or remote pipeline
`-preview`
: :::{versionadded} 22.06.0-edge
:::
: Run the workflow script skipping the execution of all processes
: Run the workflow script skipping the execution of all processes.

`-preview-containers` (`json`)
: :::{versionadded} 23.08.0-edge
:::
: Print a preview of the containers used for each process to stdout (implicitly enables `-preview`). An optional argument specifies the output format, can be `config` or `json`.
bentsherman marked this conversation as resolved.
Show resolved Hide resolved

`-process.<key>=<value>`
: Set process config options.
Expand Down Expand Up @@ -1106,7 +1111,7 @@ The `run` command is used to execute a local pipeline script or remote pipeline
`-with-conda`
: Use the specified Conda environment package or file (must end with `.yml` or `.yaml`)

`-with-dag` (`dag.dot`)
`-with-dag` (`dag-<timestamp>.dot`)
: Create pipeline DAG file.

`-with-docker`
Expand All @@ -1118,7 +1123,7 @@ The `run` command is used to execute a local pipeline script or remote pipeline
`-with-podman`
: Enable process execution in a Podman container.

`-with-report` (`report.html`)
`-with-report` (`report-<timestamp>.html`)
: Create workflow execution HTML report.

`-with-singularity`
Expand All @@ -1127,19 +1132,19 @@ The `run` command is used to execute a local pipeline script or remote pipeline
`-with-spack`
: Use the specified Spack environment package or file (must end with `.yaml`)

`-with-timeline` (`timeline.html`)
`-with-timeline` (`timeline-<timestamp>.html`)
: Create workflow execution timeline.

`-with-tower`
`-with-tower` (`https://api.tower.nf`)
: Monitor workflow execution with [Tower](https://cloud.tower.nf/).

`-with-trace` (`trace.txt`)
`-with-trace` (`trace-<timestamp>.txt`)
: Create workflow execution trace file.

`-with-wave`
`-with-wave` (`https://wave.seqera.io`)
: Enable the use of Wave containers.

`-with-weblog`
`-with-weblog` (`http://localhost`)
: Send workflow status messages via HTTP to target URL.

`-without-conda`
Expand Down
5 changes: 5 additions & 0 deletions modules/nextflow/src/main/groovy/nextflow/Session.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ class Session implements ISession {
*/
boolean disableRemoteBinDir

/**
* Suppress all output from pipeline script
*/
boolean quiet

/**
* Local path where script generated classes are saved
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package nextflow.cli

import com.beust.jcommander.DynamicParameter
import com.beust.jcommander.Parameter
import groovy.transform.PackageScope
import groovy.util.logging.Slf4j
import nextflow.exception.AbortOperationException
import org.fusesource.jansi.Ansi
Expand All @@ -30,6 +31,8 @@ import org.fusesource.jansi.Ansi
@Slf4j
class CliOptions {

static @PackageScope boolean quiteDefault = false
bentsherman marked this conversation as resolved.
Show resolved Hide resolved

/**
* The packages to debug
*/
Expand Down Expand Up @@ -73,7 +76,7 @@ class CliOptions {
boolean help

@Parameter(names = ['-q','-quiet'], description = 'Do not print information messages' )
boolean quiet
boolean quiet = quiteDefault

@Parameter(names = ['-bg'], description = 'Execute nextflow in background', arity = 0)
boolean background
Expand Down
88 changes: 88 additions & 0 deletions modules/nextflow/src/main/groovy/nextflow/cli/CmdInspect.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2013-2023, Seqera Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package nextflow.cli

import com.beust.jcommander.Parameter
import groovy.transform.CompileStatic
import nextflow.Session
import nextflow.container.inspect.ContainersInspector

/**
*
* @author Paolo Di Tommaso <[email protected]>
*/
@CompileStatic
class CmdInspect extends CmdBase {

@Override
String getName() {
return 'inspect'
}

@Parameter(names=['-profile'], description = 'Choose a configuration profile')
String profile

@Parameter(names=['-format'], description = "Inspect output format. Either 'json' or 'config'")
String format = 'json'

@Parameter(names=['-c','-config'], hidden = true )
List<String> runConfig

@Parameter(names=['-i'], description = 'Ignore error while inspecting the pipeline configuration' )
boolean ignoreErrors

@Parameter(names=['-w'], description = 'Await resources to be accessible' )
boolean awaitMode = false

@Parameter(description = 'Project name or repository url')
List<String> args

{
// enable quite by default
CliOptions.quiteDefault = true
}

@Override
void run() {
final target = new CmdRun()
target.launcher = this.launcher
target.args = args
target.profile = this.profile
target.runConfig = this.runConfig
target.preview = true
target.previewAction = this.&applyInspect
target.ansiLog = false
// run it
target.run()
}

protected void applyInspect(Session session) {
// disable wave await mode when running
if( session.config.wave instanceof Map )
configAwaitMode(session.config.wave as Map)
// run the inspector
new ContainersInspector(session.dag)
.withFormat(format)
.withIgnoreErrors(ignoreErrors)
.printContainers()
}

protected void configAwaitMode(Map waveConfig) {
waveConfig.awaitMode = awaitMode
}
}
4 changes: 3 additions & 1 deletion modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ class CmdRun extends CmdBase implements HubOptions {
: sysEnv.get('NXF_DISABLE_JOBS_CANCELLATION') as boolean
}

Closure<Void> previewAction

@Override
String getName() { NAME }

Expand Down Expand Up @@ -343,7 +345,7 @@ class CmdRun extends CmdBase implements HubOptions {
// -- create a new runner instance
final runner = new ScriptRunner(config)
runner.setScript(scriptFile)
runner.setPreview(this.preview)
runner.setPreview(this.preview, previewAction)
runner.session.profile = profile
runner.session.commandLine = launcher.cliString
runner.session.ansiLog = launcher.options.ansiLog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class Launcher {
new CmdHelp(),
new CmdSelfUpdate(),
new CmdPlugins(),
new CmdPlugin()
new CmdPlugin(),
new CmdInspect()
]

if(SecretsLoader.isEnabled())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2013-2023, Seqera Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package nextflow.container.inspect

import groovy.json.JsonBuilder
import groovy.json.JsonOutput
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import nextflow.dag.DAG
import org.codehaus.groovy.util.ListHashMap
/**
* Preview the list of containers used by a pipeline.
*
* @author Ben Sherman <[email protected]>
*/
@Slf4j
@CompileStatic
class ContainersInspector {

private DAG dag

private String format

private boolean ignoreErrors

ContainersInspector(DAG dag) {
this.dag = dag
}

ContainersInspector withFormat(String format) {
if( format !in ['config', 'json'] )
throw new IllegalArgumentException("Invalid format for container preview: '${format}' -- should be 'config' or 'json'")
this.format = format
return this
}

ContainersInspector withIgnoreErrors(boolean ignore) {
if( format !in ['config', 'json'] )
throw new IllegalArgumentException("Invalid format for container preview: '${format}' -- should be 'config' or 'json'")
bentsherman marked this conversation as resolved.
Show resolved Hide resolved
this.ignoreErrors = ignore
return this
}

String computeContainers() {
log.debug "Rendering container preview"
final containers = getContainers()
if( format == 'config' )
return renderConfig(containers)
if( format == 'json' )
bentsherman marked this conversation as resolved.
Show resolved Hide resolved
return renderJson(containers)
else
throw new IllegalStateException("Unknown containers preview format: $format")
}

void printContainers() {
final result = computeContainers()
if( result )
print result
}

protected Map<String,String> getContainers() {
final containers = new ListHashMap<String,String>()

for( def vertex : dag.vertices ) {
// skip nodes that are not processes
final process = vertex.process
if( !process )
continue

try {
// get container preview
containers[process.name] = process.inspectableTaskRun().getContainer()
}
catch (Exception e) {
if( ignoreErrors )
log.warn "Unable to inspect container for task `$process.name` - cause: ${e.message}"
else
throw e
}
}

return containers
}

protected String renderConfig(Map<String,String> containers) {
final result = new StringBuilder()
for( Map.Entry<String,String> entry : containers ) {
result.append("process { withName: '${entry.key}' { container = '${entry.value}' } }\n")
}

return result.toString()
}

protected String renderJson(Map<String,String> containers) {
final list = containers.collect( (k, v) -> [name: k, container: v] )
return JsonOutput.prettyPrint(new JsonBuilder(list).toString())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,23 @@ class TaskProcessor {

boolean hasErrors() { errorCount>0 }

/**
* Get a preview task config.
*/
TaskRun inspectableTaskRun() {
final task = new TaskRun(
processor: this,
type: scriptType,
config: config.createTaskConfig(),
context: new TaskContext(this)
)
task.config.context = task.context
task.config.process = task.processor.name
task.config.executor = task.processor.executor.name

return task
}

protected void checkWarn(String msg, Map opts=null) {
if( NF.isStrictMode() )
throw new ProcessUnrecoverableException(msg)
Expand Down
Loading