Merge dagger.io/dagger/engine into dagger.io/dagger

Signed-off-by: Solomon Hykes <solomon@dagger.io>
This commit is contained in:
Solomon Hykes
2022-02-16 18:37:16 +00:00
parent bf6d463833
commit c2766c265b
116 changed files with 658 additions and 750 deletions

View File

@@ -1,41 +0,0 @@
# Europa Core packages
## About this directory
`stdlib/europa/` holds the development version of the Core packages for the upcoming [Europa release](https://github.com/dagger/dagger/issues/1088).
Once Europa is released, `stdlib/europa` will become the new `stdlib/`
## What are Dagger core packages?
Dagger core packages are CUE packages released alongside the Dagger engine, to allow developers to access its features.
### Dagger Core API: `dagger.io/dagger`
*Development import path: `alpha.dagger.io/europa/dagger`*
The Dagger Core API defines core types and utilities for programming Dagger:
* `#Plan`: a complete configuration executable by `dagger up`
* `#FS` to reference filesystem state
* `#Secret` to (securely) reference external secrets
* `#Service` to reference network service endpoints
* `#Stream` to reference byte streams
### Low-level Engine API: `dagger.io/dagger/engine`
* *Development import path (implemented subset): `alpha.dagger.io/europa/dagger/engine`*
* *Development import path (full spec): `alpha.dagger.io/dagger/europa/dagger/engine/spec/engine`*
`engine` is a low-level API for accessing the raw capabilities of the Dagger Engine. Most developers should use the Dagger Core API instead (`dagger.io/dagger`), but experts and framework developers can target the engine API directly for maximum control.
This API prioritizes robustness, consistency, and feature completeness. It does NOT prioritize developer convenience or leveraging Cue for composition.
In Europa, `engine` will deprecate the following implicit API:
* Low-level operations defined in `alpha.dagger.io/dagger/op`
* Imperative DSL to assemble Dockerfile-like arrays as Cue arrays
* Convention to embed pipelines in the Cue lattice with the special nested definition `#up`
* Convention to reference filesystem state from the Cue lattice with `@dagger(artifact)`
* Convention to reference external secrets from the Cue lattice with `@dagger(secret)`
* Convention to reference external network endpoints from the Cue lattice with `@dagger(stream)`
* Convention that some operations (specifically `op.#Local`) are meant to be generated at runtime rather than authored manually.

1
pkg/dagger.io/README.md Symbolic link
View File

@@ -0,0 +1 @@
../../docs/learn/1213-api.md

View File

@@ -1,156 +0,0 @@
package engine
// A special kind of program which `dagger` can execute.
#Plan: {
// Receive inputs from the client
inputs: {
// Receive directories
directories: [name=string]: _#inputDirectory
// Securely receive secrets
secrets: [name=string]: _#inputSecret
// Receive runtime parameters
params: [name=string]: _
}
// Send outputs to the client
outputs: {
// Export an #FS to the client
directories: [name=string]: _#outputDirectory
// Export a string to a file
files: [name=string]: _#outputFile
}
// Forward network services to and from the client
proxy: [endpoint=string]: _#proxyEndpoint
// Configure platform execution
platform?: string
// Execute actions in containers
actions: {
...
}
}
_#inputDirectory: {
// FIXME: rename to "InputDirectory" for consistency
$dagger: task: _name: "InputDirectory"
// Import from this path ON THE CLIENT MACHINE
// Example: "/Users/Alice/dev/todoapp/src"
path: string
// Filename patterns to include
// Example: ["*.go", "Dockerfile"]
include?: [...string]
// Filename patterns to exclude
// Example: ["node_modules"]
exclude?: [...string]
// Imported filesystem contents
// Use this as input for actions requiring an #FS field
contents: #FS
}
// Securely receive a secret from the client
_#inputSecret: {
_#inputSecretEnv | _#inputSecretFile | _#inputSecretExec
// Reference to the secret contents
// Use this by securely mounting it into a container.
// See universe.dagger.io/docker.#Run.mounts
// FIXME: `contents` field name causes confusion (not actually the secret contents..)
contents: #Secret
// Whether to trim leading and trailing space characters from secret value
trimSpace: *true | false
}
// Read secret from an environment variable ON THE CLIENT MACHINE
_#inputSecretEnv: {
$dagger: task: _name: "InputSecretEnv"
envvar: string
contents: #Secret
}
// Read secret from a file ON THE CLIENT MACHINE
_#inputSecretFile: {
$dagger: task: _name: "InputSecretFile"
path: string
contents: #Secret
}
// Get secret by executing a command ON THE CLIENT MACHINE
_#inputSecretExec: {
$dagger: task: _name: "InputSecretExec"
command: {
name: string
args: [...string]
interactive: true | *false @dagger(notimplemented) // FIXME: https://github.com/dagger/dagger/issues/1268
}
contents: #Secret
}
_#outputDirectory: {
$dagger: task: _name: "OutputDirectory"
// Filesystem contents to export
// Reference an #FS field produced by an action
contents: #FS
// Export to this path ON THE CLIENT MACHINE
dest: string
}
_#outputFile: {
$dagger: task: _name: "OutputFile"
// File contents to export
contents: string
// Export to this path ON THE CLIENT MACHINE
dest: string
// Permissions of the file (defaults to 0o644)
permissions?: int
}
// Forward a network endpoint to and from the client
_#proxyEndpoint: {
$dagger: task: _name: "ProxyEndpoint"
// Service endpoint can be proxied to action containers as unix sockets
// FIXME: should #Service be renamed to #ServiceEndpoint or #Endpoint? Naming things is hard...
// FIXME: should be endpoint
service: #Service
endpoint: service
{
// FIXME: reconcile with spec
unix: string
} | {
// FIXME: reconcile with spec
npipe: string
} | {
// Listen for connections ON THE CLIENT MACHINE, proxy to actions
listen: #Address @dagger(notimplemented)
} | {
// Connect to a remote endpoint FROM THE CLIENT MACHINE, proxy to actions
connect: #Address @dagger(notimplemented)
} | {
// Proxy to/from the contents of a file ON THE CLIENT MACHINE
filepath: string @dagger(notimplemented)
} | {
// Proxy to/from standard input and output of a command ON THE CLIENT MACHINE
command: [string, ...string] | string @dagger(notimplemented)
}
}
// A network service address
#Address: string & =~"^(tcp://|unix://|udp://).*"

View File

@@ -1,45 +0,0 @@
package engine
// Create a new a secret from a filesystem tree
#NewSecret: {
$dagger: task: _name: "NewSecret"
// Filesystem tree holding the secret
input: #FS
// Path of the secret to read
path: string
// Whether to trim leading and trailing space characters from secret value
trimSpace: *true | false
// Contents of the secret
output: #Secret
}
// Securely apply a CUE transformation on the contents of a secret
// FIXME: disabled due to data race associated with filling #function.input
// #TransformSecret: {
// $dagger: task: _name: "TransformSecret"
// // The original secret
// input: #Secret
// // A new secret or (map of secrets) with the transformation applied
// output: #Secret | {[string]: output}
// // Transformation function
// #function: {
// // Full contents of the input secret (only available to the function)
// input: string
// _functionOutput: string | {[string]: _functionOutput}
// // New contents of the output secret (must provided by the caller)
// output: _functionOutput
// }
// }
#DecodeSecret: {
$dagger: task: _name: "DecodeSecret"
// A #Secret whose plain text is a JSON or YAML string
input: #Secret
format: "json" | "yaml"
// A new secret or (map of secrets) derived from unmarshaling the input secret's plain text
output: #Secret | {[string]: output}
}

View File

@@ -1,29 +0,0 @@
package engine
// A reference to a filesystem tree.
// For example:
// - The root filesystem of a container
// - A source code repository
// - A directory containing binary artifacts
// Rule of thumb: if it fits in a tar archive, it fits in a #FS.
#FS: {
$dagger: fs: _id: string | null
}
// A reference to an external secret, for example:
// - A password
// - A SSH private key
// - An API token
// Secrets are never merged in the Cue tree. They can only be used
// by a special filesystem mount designed to minimize leak risk.
#Secret: {
$dagger: secret: _id: string
}
// A reference to a network service endpoint, for example:
// - A TCP or UDP port
// - A unix or npipe socket
// - An HTTPS endpoint
#Service: {
$dagger: service: _id: string
}

View File

@@ -1,4 +1,4 @@
package engine
package dagger
// Execute a command in a container
#Exec: {

View File

@@ -1,4 +1,4 @@
package engine
package dagger
// Access the source directory for the current CUE package
// This may safely be called from any package
@@ -63,9 +63,6 @@ package engine
output: #FS
}
// Produce an empty directory
#Scratch: #FS & {$dagger: fs: _id: null}
// Copy files from one FS tree to another
#Copy: {
$dagger: task: _name: "Copy"
@@ -98,3 +95,24 @@ package engine
layers: [...#CopyInfo]
output: #FS
}
// Select a subdirectory from a filesystem tree
#Subdir: {
// Input tree
input: #FS
// Path of the subdirectory
// Example: "/build"
path: string
// Copy action
_copy: #Copy & {
"input": #Scratch
contents: input
source: path
dest: "/"
}
// Subdirectory tree
output: #FS & _copy.output
}

View File

@@ -1,4 +1,4 @@
package engine
package dagger
// Push a directory to a git remote
#GitPush: {

View File

@@ -1,4 +1,4 @@
package engine
package dagger
// HTTP operations

View File

@@ -1,4 +1,4 @@
package engine
package dagger
import (
"list"

View File

@@ -1,8 +1,153 @@
package dagger
import (
"dagger.io/dagger/engine"
)
// A special kind of program which `dagger` can execute.
#Plan: engine.#Plan
#Plan: {
// Receive inputs from the client
inputs: {
// Receive directories
directories: [name=string]: _#inputDirectory
// Securely receive secrets
secrets: [name=string]: _#inputSecret
// Receive runtime parameters
params: [name=string]: _
}
// Send outputs to the client
outputs: {
// Export an #FS to the client
directories: [name=string]: _#outputDirectory
// Export a string to a file
files: [name=string]: _#outputFile
}
// Forward network services to and from the client
proxy: [endpoint=string]: _#proxyEndpoint
// Configure platform execution
platform?: string
// Execute actions in containers
actions: {
...
}
}
_#inputDirectory: {
// FIXME: rename to "InputDirectory" for consistency
$dagger: task: _name: "InputDirectory"
// Import from this path ON THE CLIENT MACHINE
// Example: "/Users/Alice/dev/todoapp/src"
path: string
// Filename patterns to include
// Example: ["*.go", "Dockerfile"]
include?: [...string]
// Filename patterns to exclude
// Example: ["node_modules"]
exclude?: [...string]
// Imported filesystem contents
// Use this as input for actions requiring an #FS field
contents: #FS
}
// Securely receive a secret from the client
_#inputSecret: {
_#inputSecretEnv | _#inputSecretFile | _#inputSecretExec
// Reference to the secret contents
// Use this by securely mounting it into a container.
// See universe.io/docker.#Run.mounts
// FIXME: `contents` field name causes confusion (not actually the secret contents..)
contents: #Secret
// Whether to trim leading and trailing space characters from secret value
trimSpace: *true | false
}
// Read secret from an environment variable ON THE CLIENT MACHINE
_#inputSecretEnv: {
$dagger: task: _name: "InputSecretEnv"
envvar: string
contents: #Secret
}
// Read secret from a file ON THE CLIENT MACHINE
_#inputSecretFile: {
$dagger: task: _name: "InputSecretFile"
path: string
contents: #Secret
}
// Get secret by executing a command ON THE CLIENT MACHINE
_#inputSecretExec: {
$dagger: task: _name: "InputSecretExec"
command: {
name: string
args: [...string]
interactive: true | *false @dagger(notimplemented) // FIXME: https://github.com/dagger/dagger/issues/1268
}
contents: #Secret
}
_#outputDirectory: {
$dagger: task: _name: "OutputDirectory"
// Filesystem contents to export
// Reference an #FS field produced by an action
contents: #FS
// Export to this path ON THE CLIENT MACHINE
dest: string
}
_#outputFile: {
$dagger: task: _name: "OutputFile"
// File contents to export
contents: string
// Export to this path ON THE CLIENT MACHINE
dest: string
// Permissions of the file (defaults to 0o644)
permissions?: int
}
// Forward a network endpoint to and from the client
_#proxyEndpoint: {
$dagger: task: _name: "ProxyEndpoint"
// Service endpoint can be proxied to action containers as unix sockets
// FIXME: should #Service be renamed to #ServiceEndpoint or #Endpoint? Naming things is hard...
// FIXME: should be endpoint
service: #Service
endpoint: service
{
// FIXME: reconcile with spec
unix: string
} | {
// FIXME: reconcile with spec
npipe: string
} | {
// Listen for connections ON THE CLIENT MACHINE, proxy to actions
listen: #Address @dagger(notimplemented)
} | {
// Connect to a remote endpoint FROM THE CLIENT MACHINE, proxy to actions
connect: #Address @dagger(notimplemented)
} | {
// Proxy to/from the contents of a file ON THE CLIENT MACHINE
filepath: string @dagger(notimplemented)
} | {
// Proxy to/from standard input and output of a command ON THE CLIENT MACHINE
command: [string, ...string] | string @dagger(notimplemented)
}
}

View File

@@ -0,0 +1,29 @@
package dagger
// Decode the contents of a secrets without leaking it.
// Supported formats: json, yaml
#DecodeSecret: {
$dagger: task: _name: "DecodeSecret"
// A #Secret whose plain text is a JSON or YAML string
input: #Secret
format: "json" | "yaml"
// A new secret or (map of secrets) derived from unmarshaling the input secret's plain text
output: #Secret | {[string]: output}
}
// Create a new a secret from a filesystem tree
#NewSecret: {
$dagger: task: _name: "NewSecret"
// Filesystem tree holding the secret
input: #FS
// Path of the secret to read
path: string
// Whether to trim leading and trailing space characters from secret value
trimSpace: *true | false
// Contents of the secret
output: #Secret
}

View File

@@ -1,16 +1,19 @@
package dagger
import (
"dagger.io/dagger/engine"
)
// A reference to a filesystem tree.
// For example:
// - The root filesystem of a container
// - A source code repository
// - A directory containing binary artifacts
// Rule of thumb: if it fits in a tar archive, it fits in a #FS.
#FS: engine.#FS
#FS: {
$dagger: fs: _id: string | null
}
// An empty directory
#Scratch: #FS & {
$dagger: fs: _id: null
}
// A reference to an external secret, for example:
// - A password
@@ -18,13 +21,17 @@ import (
// - An API token
// Secrets are never merged in the Cue tree. They can only be used
// by a special filesystem mount designed to minimize leak risk.
#Secret: engine.#Secret
#Secret: {
$dagger: secret: _id: string
}
// A reference to a network service endpoint, for example:
// - A TCP or UDP port
// - A unix socket
// - An HTTPS endpoint
#Service: engine.#Service
#Service: {
$dagger: service: _id: string
}
// A network service address
#Address: engine.#Address
#Address: string & =~"^(tcp://|unix://|udp://).*"

View File

@@ -1,61 +0,0 @@
package dagger
import (
// "encoding/json"
// "encoding/yaml"
"dagger.io/dagger/engine"
)
// Access the source directory for the current CUE package
// This may safely be called from any package
#Source: engine.#Source
// A (best effort) persistent cache dir
#CacheDir: engine.#CacheDir
// A temporary directory for command execution
#TempDir: engine.#TempDir
// Select a subdirectory from a filesystem tree
#Subdir: {
// Input tree
input: engine.#FS
// Path of the subdirectory
// Example: "/build"
path: string
// Copy action
_copy: engine.#Copy & {
"input": engine.#Scratch
contents: input
source: path
dest: "/"
}
// Subdirectory tree
output: engine.#FS & _copy.output
}
// DecodeSecret is a convenience wrapper around #TransformSecret. The plain text contents of input is expected to match the format
// #DecodeSecret: {
// {
// format: "json"
// engine.#TransformSecret & {
// #function: {
// input: _
// output: json.Unmarshal(input)
// }
// }
// } | {
// format: "yaml"
// engine.#TransformSecret & {
// #function: {
// input: _
// output: yaml.Unmarshal(input)
// }
// }
// }
// }
#DecodeSecret: engine.#DecodeSecret