<aside> đźš§

This is a living document, and a work in progress. You’re going to see missing or incomplete pieces. It’s meant to be an easier way to progressively build the documentation for adding modules support to an SDK, until it’s ready to be committed and published in the dagger/dagger repo.

</aside>

<aside> <img src="/icons/info-alternate_blue.svg" alt="/icons/info-alternate_blue.svg" width="40px" />

You may see code samples written in Python, but they are meant to be pseudo-code.

</aside>

Overview

There’s two main parts for adding modules support:

  1. Create an executable (aka, runtime entrypoint) that knows how to read and execute user code
  2. Create a Dagger module, using Go, to interact with the Dagger engine

Technical decisions

There’s things that you need to figure out technically, which can be done before even starting with the runtime module. You’ll need to be able to:

Additionally, parsing the user’s code can be done either at:

The choice of parsing the code during run time or codegen time is a matter of performance, but also productivity. Python has the types readily available at runtime so there’s no noticeable overhead. Go, on the other hand, is a compiled language and uses lower level AST parsing that’s more wasteful to do every time. However, with the codegen path, you may get more cache invalidation during the codegen phase because any change in function signatures generates a different output. The code may also be harder to maintain. It pays to measure which approach is more worth it if not clear.

Example

Consider the following function, defined in a user module:

class MyModule:
		def echo(self, msg: str) -> str:
				return msg

To start, you can mock the API calls that will get the necessary inputs, and save the right output:

# Name of the object
parent_name = "MyModule"

# State of the object instance
parent = {}

# Name of the function to call
name = "echo"

# Function arguments
input_args = {
		"msg": "Hello!",
}

# Abstraction for finding and executing function
result = get_result(parent_name, parent, name, input_args)

assert result == "Hello!"