Skip to main content

When to use core.#Source?

The #Source core action seems to do the same as client: filesystem: ...: read: contents: dagger.#FS, although there's important differences.

Purpose

The purpose of core.#Source is to enable including files with reusable packages in a secure way.

The most common example of this is writing scripts in their own file extensions, and importing in an action instead of inlining the contents of the script (see Don't inline scripts).

For example, here's how the netlify package imports the deploy.sh script:

pkg/universe.dagger.io/netlify/netlify.cue
// Deploy a site to Netlify
#Deploy: {
...
container: bash.#Run & {
...
script: {
_load: core.#Source & {
path: "."
include: ["*.sh"]
}
directory: _load.output
filename: "deploy.sh"
}
...
}
...
}

You can include all sorts of files this way, with your reusable packages.

Path is relative to the file where it's defined

Notice in the example above that the path to deploy.sh is relative to the file where core.#Source is being used (netfily/netlify.cue), unlike in Client API where paths are relative to where the dagger client is being run (current working directory).

This means that no matter where you run dagger from, the path in core.#Source will mean the same thing. You can use it in your plan directly if this is advantageous. A common example of that is when making integration test plans, for adding test data that is scoped to each plan.

Scoped to the directory where it's defined

For security reasons, you can't access files outside of this directory. You need to use client: filesystem for that, which can use any path, even absolute ones.

Remember, the purpose of core.#Source is to enable including files in packages in a secure way. Any other access to files in the host where the dagger client is being run, must be explicitly declared with the Client API.

~/projects/test/dagger.cue
ssh: core.#Source & {
// This won't work
// You can only reference files in ~/projects/test or deeper
path: "~/.ssh"
}
foobar: core.#Source & {
// Also won't work
path: "../foobar"
}