Replies: 2 comments 1 reply
-
Overall I like it, it's more explicit (for instance: referencing the However we should be careful with root definitions: For example, instead of:
I would do:
Without it, |
Beta Was this translation helpful? Give feedback.
-
Given (Maybe it allows to differentiate 2 pipelines in cue by their list of Ops. Example: |
Beta Was this translation helpful? Give feedback.
-
Intro
In its current state, this is more of a brain dump with a straw man proposal rather than a full fledged proposal. Just enough to get some ideas bouncing.
Background
Currently, the concept of computation (e.g. a set of compute operations) and data (e.g. the resulting filesystem from the computation) are mixed together as a single concept,
dagger.#Artifact
with an open definition:Packages expecting data as input actually take a computational pipeline (in the form of an
#Artifact
with accompanying#up
instructions). At runtime, the artifact is computed and replaced by the resulting buildkit state (e.g. filesystem).For instance,
docker.#Build
is defined as such:If we were to pass a
git.#Repository
as thesource
argument, it would eventually CUE evaluate to something like this:As soon as
#Build
attempts to manipulatesource
(for instance, copying its content), dagger will compute the pipeline on the fly (i.e.#FetchGit
operation) and use the resulting filesystem.Access to local directories (e.g.
dagger input dir
) works in the same way and is "compiled" to an artifact:Problem
#Artifact
concept is not intuitive as it serves different purposes (compute and data).mount
takes an#Artifact
which itself providesmount
which itself provides an#Artifact
, ...) have caused various performance issues. This led to all#Artifact
references being replaced by_
as a workaround. Related performance issues keep coming up [reference needed -- @samalba @grouville?]{ ... _ }
) of#Artifact
causes problems. Since anything is technically an artifact, it confuses CUE's type system (e.g.if (source & string) != _|_
). Passing a wrong argument (or forgetting to provide it) causes hard to understand CUE errors [reference needed -- @samalba?]docker.#Load
as well). In a nutshell:always: true
which is re-computed at each reference Duplicate execution withalways: true
#42)Proposal
WIP
#Artifact
into computation (#Pipeline
?) and data (#Directory
?)source: #Directory
) rather than computation{ ... _}
)Directory (data)
id
field is there to help the runtime perform the mapping, it's an implementation detail#Directory
directly (e.g.source: dagger.#Directory
). This is true for built-in definitions as well (e.g.#Exec: { mount: [string]: dagger.#Directory }
)dagger input dir
) maps to a#Directory
. It's the job of the runtime to figure out how solve the mapping.Pipeline (computation)
WIP
#Artifact
s (e.g.#up
instructions are executed)fs
is the bridge with#Directory
... _
Example:
Exporting
WIP
Beside filesystem contents, computation pipelines are passed around for their exported values.
With the current
#Artifact
it looks like this:#Pipeline
to be closedfs
field (e.g. can't be both astring
and containfs
)One potential solution would be to adopt the pattern of
os.#Container
: there's no built-in export, exporting happens from the filesystem instead.Example:
User-facing Directories (integration with #1058)
Splitting computation and data breaks the current way of injecting user directories using
op.#Local
in an#Artifact
. It's a happy coincidence since that method doesn't play very nice with #1058 IMO (/cc @talentedmrjones).A better approach would be "declarative format" for directories:
context.directories
#Directory
(with theid
and such). No need for anop.#Local
context.directories
can be passed around in packagesThere are a couple alternative DX here:
Merging
Use the same
#Directory
definition both for "produced" directories and "user defined" directories. This is achieved by merging the base#Directory
fields with additional (optional) user-settable fields.Example definition:
Example of a plan:
#Directory
typepath
) which will be ignored if set outside ofcontext.directories
. Can be confusing to have fields which you're not supposed to set.Wrapping
Here we keep the original
#Directory
and add a new definition specifically meant to be used in context. This new definition wraps#Directory
Example definition:
Example of a plan:
#Directory
one is supposed to fill or not#LocalDirectory
we could have#SSHDirectory
with entirely different fields.dagger.#Secret
andcontext.#AWSVaultSecret
,context.#SOPSSecret
, ...) and services (e.g.dagger.#Stream
andcontext.#UnixSocket
,context.#TCPSocket
). Merging would require cramming every option into a single type.#LocalDirectory
) are only relevant to the runtime to compute a universal type (#Directory
). If a package uses an old version of#Directory
it shouldn't prevent the plan to use a new contextual type (e.g.#AWSVaultSecret
).context.directories.xxx.contents
is a bit cumbersomeEmbedding
I'm not sure if this would work.
This is a hybrid between merging and wrapping.
Example definition:
Example of a plan:
context.directories.xxx.contents
syntax (e.g.context.directories.xxx
works)Beta Was this translation helpful? Give feedback.
All reactions