Cleanup inputs, outputs and proxy

Superceded by Client API.

Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
This commit is contained in:
Helder Correia 2022-03-08 20:45:28 -01:00
parent 2a6962ddc8
commit 24d3f82fc7
No known key found for this signature in database
GPG Key ID: C6490D872EF1DCA7
54 changed files with 101 additions and 1083 deletions

View File

@ -33,27 +33,6 @@ package dagger
platform: _#clientPlatform
}
// 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
@ -117,9 +96,20 @@ _#clientFilesystemWrite: {
_#clientCommand: {
$dagger: task: _name: "ClientCommand"
// Name of the command to execute
// Examples: "ls", "/bin/bash"
name: string
// Positional arguments to the command
// Examples: ["/tmp"]
args: [...string]
// Command-line flags represented in a civilized form
// Example: {"-l": true, "-c": "echo hello world"}
flags: [string]: bool | string
// Environment variables
// Example: {"DEBUG": "1"}
env: [string]: string | #Secret
// Capture standard output (as a string or secret)
@ -140,123 +130,3 @@ _#clientPlatform: {
// Hardware architecture of the client machine
arch: string
}
_#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

@ -7,15 +7,16 @@ import (
)
dagger.#Plan & {
inputs: secrets: sops: command: {
client: commands: sops: {
name: "sops"
args: ["-d", "--extract", "[\"AWS\"]", "../../../secrets_sops.yaml"]
stdout: dagger.#Secret
}
actions: {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
getCallerIdentity: cli.#Command & {

View File

@ -7,27 +7,27 @@ import (
)
dagger.#Plan & {
inputs: {
directories: awsConfig: {
path: "./"
client: {
filesystem: ".": read: {
contents: dagger.#FS
include: ["config"]
}
secrets: sops: command: {
commands: sops: {
name: "sops"
args: ["-d", "--extract", "[\"AWS\"]", "../../secrets_sops.yaml"]
stdout: dagger.#Secret
}
}
actions: {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
getCallerIdentity: aws.#Container & {
always: true
configFile: inputs.directories.awsConfig.contents
configFile: client.filesystem.".".read.contents
credentials: aws.#Credentials & {
accessKeyId: sopsSecrets.output.AWS_ACCESS_KEY_ID.contents

View File

@ -7,15 +7,16 @@ import (
)
dagger.#Plan & {
inputs: secrets: sops: command: {
client: commands: sops: {
name: "sops"
args: ["-d", "--extract", "[\"AWS\"]", "../../secrets_sops.yaml"]
stdout: dagger.#Secret
}
actions: {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
getCallerIdentity: aws.#Container & {

View File

@ -8,14 +8,14 @@ import (
)
dagger.#Plan & {
inputs: directories: testhello: path: "./data/hello"
client: filesystem: "./data/hello": read: contents: dagger.#FS
actions: tests: build: {
_baseImage: alpine.#Build
simple: {
build: go.#Build & {
source: inputs.directories.testhello.contents
source: client.filesystem."./data/hello".read.contents
}
exec: docker.#Run & {

View File

@ -5,6 +5,8 @@ setup() {
}
@test "bash" {
dagger up
dagger up ./build.cue
dagger up ./container.cue
dagger up ./image.cue
dagger up ./test.cue
}

View File

@ -6,10 +6,10 @@ import (
)
dagger.#Plan & {
inputs: directories: testhello: path: "./data/hello"
client: filesystem: "./data/hello": read: contents: dagger.#FS
actions: tests: test: simple: go.#Test & {
source: inputs.directories.testhello.contents
source: client.filesystem."./data/hello".read.contents
package: "./greeting"
}
}

View File

@ -10,9 +10,10 @@ import (
)
dagger.#Plan & {
inputs: secrets: test: command: {
client: commands: sops: {
name: "sops"
args: ["-d", "../../test_secrets.yaml"]
stdout: dagger.#Secret
}
actions: tests: {
@ -20,7 +21,7 @@ dagger.#Plan & {
// Configuration common to all tests
common: {
testSecrets: dagger.#DecodeSecret & {
input: inputs.secrets.test.contents
input: client.commands.sops.stdout
format: "yaml"
}

View File

@ -8,16 +8,16 @@ import (
)
dagger.#Plan & {
inputs: directories: {
testdata: path: "./data/foo"
testdata2: path: "./data/bar"
client: filesystem: {
"./data/foo": read: contents: dagger.#FS
"./data/bar": read: contents: dagger.#FS
}
actions: tests: {
// Configuration for all tests
common: {
data: inputs.directories.testdata.contents
data: client.filesystem."./data/foo".read.contents
}
// Run yarn.#Build

View File

@ -1,98 +0,0 @@
package task
import (
"context"
"errors"
"fmt"
"os"
"github.com/moby/buildkit/client/llb"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("InputDirectory", func() Task { return &inputDirectoryTask{} })
}
type inputDirectoryTask struct {
}
func (c *inputDirectoryTask) PreRun(ctx context.Context, pctx *plancontext.Context, v *compiler.Value) error {
path, err := v.Lookup("path").AbsPath()
if err != nil {
return err
}
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("path %q does not exist", path)
}
pctx.LocalDirs.Add(path)
return nil
}
func (c *inputDirectoryTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
path, err := v.Lookup("path").AbsPath()
if err != nil {
return nil, err
}
var dir struct {
Include []string
Exclude []string
}
if err := v.Decode(&dir); err != nil {
return nil, err
}
lg := log.Ctx(ctx)
lg.Debug().Str("path", path).Msg("loading local directory")
opts := []llb.LocalOption{
withCustomName(v, "Local %s", path),
// Without hint, multiple `llb.Local` operations on the
// same path get a different digest.
llb.SessionID(s.SessionID()),
llb.SharedKeyHint(path),
}
if len(dir.Include) > 0 {
opts = append(opts, llb.IncludePatterns(dir.Include))
}
// Excludes .dagger directory by default
excludePatterns := []string{"**/.dagger/"}
if len(dir.Exclude) > 0 {
excludePatterns = dir.Exclude
}
opts = append(opts, llb.ExcludePatterns(excludePatterns))
// FIXME: Remove the `Copy` and use `Local` directly.
//
// Copy'ing is a costly operation which should be unnecessary.
// However, using llb.Local directly breaks caching sometimes for unknown reasons.
st := llb.Scratch().File(
llb.Copy(
llb.Local(
path,
opts...,
),
"/",
"/",
),
withCustomName(v, "Local %s [copy]", path),
)
result, err := s.Solve(ctx, st, pctx.Platform.Get())
if err != nil {
return nil, err
}
fs := pctx.FS.New(result)
return compiler.NewValue().FillFields(map[string]interface{}{
"contents": fs.MarshalCUE(),
})
}

View File

@ -1,49 +0,0 @@
package task
import (
"context"
"fmt"
"os"
"strings"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("InputSecretEnv", func() Task { return &inputSecretEnvTask{} })
}
type inputSecretEnvTask struct {
}
func (c *inputSecretEnvTask) Run(ctx context.Context, pctx *plancontext.Context, _ solver.Solver, v *compiler.Value) (*compiler.Value, error) {
lg := log.Ctx(ctx)
var secretEnv struct {
Envvar string
TrimSpace bool
}
if err := v.Decode(&secretEnv); err != nil {
return nil, err
}
lg.Debug().Str("envvar", secretEnv.Envvar).Str("trimSpace", fmt.Sprintf("%t", secretEnv.TrimSpace)).Msg("loading secret")
env := os.Getenv(secretEnv.Envvar)
if env == "" {
return nil, fmt.Errorf("environment variable %q not set", secretEnv.Envvar)
}
if secretEnv.TrimSpace {
env = strings.TrimSpace(env)
}
secret := pctx.Secrets.New(env)
return compiler.NewValue().FillFields(map[string]interface{}{
"contents": secret.MarshalCUE(),
})
}

View File

@ -1,70 +0,0 @@
package task
import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"strings"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("InputSecretExec", func() Task { return &inputSecretExecTask{} })
}
type inputSecretExecTask struct {
}
func (c *inputSecretExecTask) Run(ctx context.Context, pctx *plancontext.Context, _ solver.Solver, v *compiler.Value) (*compiler.Value, error) {
var secretExec struct {
Command struct {
Name string
Args []string
}
TrimSpace bool
}
if err := v.Decode(&secretExec); err != nil {
return nil, err
}
lg := log.Ctx(ctx)
lg.Debug().Str("name", secretExec.Command.Name).Str("args", strings.Join(secretExec.Command.Args, " ")).Str("trimSpace", fmt.Sprintf("%t", secretExec.TrimSpace)).Msg("loading secret")
var err error
//#nosec G204: sec audited by @aluzzardi and @mrjones
cmd := exec.CommandContext(ctx, secretExec.Command.Name, secretExec.Command.Args...)
cmd.Env = os.Environ()
cmd.Dir, err = v.Lookup("command.name").Dirname()
if err != nil {
return nil, err
}
// sec audited by @aluzzardi and @mrjones
out, err := cmd.Output()
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
lg.Err(err).Msg(string(exitErr.Stderr))
}
return nil, err
}
plaintext := string(out)
if secretExec.TrimSpace {
plaintext = strings.TrimSpace(plaintext)
}
secret := pctx.Secrets.New(plaintext)
return compiler.NewValue().FillFields(map[string]interface{}{
"contents": secret.MarshalCUE(),
})
}

View File

@ -1,49 +0,0 @@
package task
import (
"context"
"os"
"strings"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("InputSecretFile", func() Task { return &inputSecretFileTask{} })
}
type inputSecretFileTask struct {
}
func (c *inputSecretFileTask) Run(ctx context.Context, pctx *plancontext.Context, _ solver.Solver, v *compiler.Value) (*compiler.Value, error) {
lg := log.Ctx(ctx)
path, err := v.Lookup("path").AbsPath()
if err != nil {
return nil, err
}
lg.Debug().Str("path", path).Msg("loading secret")
fileBytes, err := os.ReadFile(path)
if err != nil {
return nil, err
}
plaintext := string(fileBytes)
trimSpace, err := v.Lookup("trimSpace").Bool()
if err != nil {
return nil, err
}
if trimSpace {
plaintext = strings.TrimSpace(plaintext)
}
secret := pctx.Secrets.New(plaintext)
return compiler.NewValue().FillFields(map[string]interface{}{
"contents": secret.MarshalCUE(),
})
}

View File

@ -1,43 +0,0 @@
package task
import (
"context"
bk "github.com/moby/buildkit/client"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("OutputDirectory", func() Task { return &outputDirectoryTask{} })
}
type outputDirectoryTask struct {
}
func (c outputDirectoryTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
contents, err := pctx.FS.FromValue(v.Lookup("contents"))
if err != nil {
return nil, err
}
dest, err := v.Lookup("dest").AbsPath()
if err != nil {
return nil, err
}
st, err := contents.State()
if err != nil {
return nil, err
}
_, err = s.Export(ctx, st, nil, bk.ExportEntry{
Type: bk.ExporterLocal,
OutputDir: dest,
}, pctx.Platform.Get())
if err != nil {
return nil, err
}
return compiler.NewValue(), nil
}

View File

@ -1,63 +0,0 @@
package task
import (
"context"
"fmt"
"io/fs"
"os"
"cuelang.org/go/cue"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("OutputFile", func() Task { return &outputFileTask{} })
}
type outputFileTask struct {
}
func (c outputFileTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
var contents []byte
var err error
switch kind := v.Lookup("contents").Kind(); kind {
case cue.StringKind:
var str string
str, err = v.Lookup("contents").String()
if err == nil {
contents = []byte(str)
}
case cue.BottomKind:
err = fmt.Errorf("contents is not set")
default:
err = fmt.Errorf("unhandled data type in contents: %s", kind)
}
if err != nil {
return nil, err
}
dest, err := v.Lookup("dest").AbsPath()
if err != nil {
return nil, err
}
perm := fs.FileMode(0644) // default permission
if v.Lookup("permissions").Exists() {
permissions, err := v.Lookup("permissions").Int64()
if err != nil {
return nil, err
}
perm = fs.FileMode(permissions)
}
err = os.WriteFile(dest, contents, perm)
if err != nil {
return nil, err
}
return compiler.NewValue(), nil
}

View File

@ -1,58 +0,0 @@
package task
import (
"context"
"errors"
"cuelang.org/go/cue"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/compiler"
"go.dagger.io/dagger/plancontext"
"go.dagger.io/dagger/solver"
)
func init() {
Register("ProxyEndpoint", func() Task { return &proxyEndpointTask{} })
}
type proxyEndpointTask struct {
}
func (c *proxyEndpointTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
var unix, npipe string
var stringErr error
unixV := v.Lookup("unix")
npipeV := v.Lookup("npipe")
if unixV.Exists() && unixV.IsConcrete() {
unix, stringErr = unixV.String()
}
if npipeV.Exists() && npipeV.IsConcrete() {
npipe, stringErr = npipeV.String()
}
if stringErr != nil {
return nil, stringErr
}
if unix == "" && npipe == "" {
return nil, errors.New("invalid service")
}
lg := log.Ctx(ctx)
if unix != "" {
lg.Debug().Str("unix", unix).Msg("loading service")
} else if npipe != "" {
lg.Debug().Str("npipe", npipe).Msg("loading service")
}
service := pctx.Services.New(unix, npipe)
out := compiler.NewValue()
if err := out.FillPath(cue.ParsePath("service"), service.MarshalCUE()); err != nil {
return nil, err
}
return out, nil
}

View File

@ -146,68 +146,12 @@ setup() {
assert_output --partial 'exec: "foobar": executable file not found'
}
@test "plan/proxy invalid schema" {
cd "$TESTDIR"
run "$DAGGER" "do" -p ./plan/proxy/invalid_schema.cue verify
assert_failure
}
@test "plan/proxy invalid value" {
cd "$TESTDIR"
run "$DAGGER" "do" -p ./plan/proxy/invalid_value.cue verify
assert_failure
}
@test "plan/proxy incomplete unix" {
cd "$TESTDIR"
run "$DAGGER" "do" -p ./plan/proxy/incomplete_unix.cue verify
assert_failure
}
@test "plan/proxy incomplete service" {
cd "$TESTDIR"
run "$DAGGER" "do" -p ./plan/proxy/incomplete_service.cue verify
assert_output --partial 'mount "docker" is not concrete'
}
@test "plan/proxy unix" {
cd "$TESTDIR"
"$DAGGER" "do" -p ./plan/proxy/unix.cue verify
}
@test "plan/inputs/directories" {
cd "$TESTDIR"
"$DAGGER" "do" -p ./plan/inputs/directories/valid exists
run "$DAGGER" "do" -p ./plan/inputs/directories/invalid notExists
assert_failure
assert_output --partial 'fasdfsdfs" does not exist'
run "$DAGGER" "do" -p ./plan/inputs/directories/valid conflictingValues
assert_failure
assert_output --partial 'conflicting values "local directory" and "local dfsadf"'
}
@test "plan/inputs/secrets" {
cd "$TESTDIR"
"$DAGGER" "do" -p ./plan/inputs/secrets test valid
"$DAGGER" "do" -p ./plan/inputs/secrets test relative
run "$DAGGER" "do" -p ./plan/inputs/secrets test badCommand
assert_failure
assert_output --partial 'failed: exec: "rtyet": executable file not found'
run "$DAGGER" "do" -p ./plan/inputs/secrets test badArgs
assert_failure
assert_output --partial 'option'
}
@test "plan/with" {
cd "$TESTDIR"
"$DAGGER" "do" --with 'inputs: params: foo:"bar"' -p ./plan/with test params
"$DAGGER" "do" --with 'actions: params: foo:"bar"' -p ./plan/with test params
"$DAGGER" "do" --with 'actions: test: direct: env: FOO: "bar"' -p ./plan/with test direct
run "$DAGGER" "do" --with 'inputs: params: foo:1' -p ./plan/with test params
run "$DAGGER" "do" --with 'actions: params: foo:1' -p ./plan/with test params
assert_failure
assert_output --partial "conflicting values string and 1"

View File

@ -31,11 +31,6 @@ dagger.#Plan & {
input: write.output
path: "out.txt"
}
// FIXME: hack until we can do outputs with `dagger do`
verify: dagger.#Exec & {
input: image.output
args: ["echo", client.filesystem."test.txt".write.contents]
}
}
}
}

View File

@ -19,18 +19,11 @@ dagger.#Plan & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
test: {
fs: {
data: dagger.#WriteFile & {
fs: data: dagger.#WriteFile & {
input: dagger.#Scratch
path: "/test"
contents: "foobar"
}
// FIXME: hack until we can do outputs with `dagger do`
verify: dagger.#ReadFile & {
input: client.filesystem."out_fs".write.contents
path: "test"
}
}
file: {
// Only using contents for reference in client
data: dagger.#WriteFile & {
@ -38,11 +31,6 @@ dagger.#Plan & {
path: "/test"
contents: "foobaz"
}
// FIXME: hack until we can do outputs with `dagger do`
verify: dagger.#Exec & {
input: image.output
args: ["echo", "-c", client.filesystem."out_files/test.txt".write.contents]
}
}
secret: {
create: dagger.#WriteFile & {
@ -54,15 +42,6 @@ dagger.#Plan & {
input: create.output
path: "/test"
}
// FIXME: hack until we can do outputs with `dagger do`
verify: dagger.#Exec & {
input: image.output
mounts: secret: {
dest: "/run/secrets/test"
contents: client.filesystem."out_files/secret.txt".write.contents
}
args: ["id"]
}
}
}
}

View File

@ -1,3 +0,0 @@
package main
inputs: directories: test: path: "./fasdfsdfs"

View File

@ -1,32 +0,0 @@
package main
import (
"dagger.io/dagger"
)
dagger.#Plan & {
inputs: directories: test: path: string
actions: {
// Test that file exists and contains correct content
exists: dagger.#ReadFile & {
input: inputs.directories.test.contents
path: "test.txt"
contents: "local directory"
}
// Test that file does NOT exist
notExists: dagger.#ReadFile & {
input: inputs.directories.test.contents
path: "test.txt"
contents: "local directory"
}
// Test that file exists and contains conflicting content
conflictingValues: dagger.#ReadFile & {
input: inputs.directories.test.contents
path: "test.txt"
contents: "local dfsadf"
}
}
}

View File

@ -1 +0,0 @@
local directory

View File

@ -1,3 +0,0 @@
package main
inputs: directories: test: path: "."

View File

@ -1,59 +0,0 @@
package main
import (
"dagger.io/dagger"
)
dagger.#Plan & {
inputs: secrets: {
echo: command: {
name: "echo"
args: ["hello europa"]
}
relative: command: {
name: "cat"
args: ["./test.txt"]
}
badCommand: command: {
name: "rtyet" // should fail because command doesn't exist
args: ["hello europa"]
}
badArgs: command: {
name: "cat"
args: ["--sfgjkhf"] // // should fail because invalid option
}
}
actions: {
_image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
test: {
[string]: dagger.#Exec & {
input: _image.output
mounts: secret: {
dest: "/run/secrets/test"
// contents: inputs.secrets.echo.contents
}
args: [
"sh", "-c",
#"""
test "$(cat /run/secrets/test)" = "hello europa"
ls -l /run/secrets/test | grep -- "-r--------"
"""#,
]
}
valid: mounts: secret: contents: inputs.secrets.echo.contents
relative: mounts: secret: contents: inputs.secrets.relative.contents
badCommand: mounts: secret: contents: inputs.secrets.badCommand.contents
badArgs: mounts: secret: contents: inputs.secrets.badArgs.contents
}
}
}

View File

@ -1 +0,0 @@
hello europa

View File

@ -1 +0,0 @@
out

View File

@ -1,19 +0,0 @@
package main
import (
"dagger.io/dagger"
)
dagger.#Plan & {
actions: data: dagger.#WriteFile & {
input: dagger.#Scratch
path: "/test_outputs"
permissions: 0o600
contents: "foobar"
}
outputs: directories: test_outputs: {
contents: actions.data.output
dest: "./out"
}
}

View File

@ -1,19 +0,0 @@
package main
import (
"dagger.io/dagger"
)
dagger.#Plan & {
actions: data: dagger.#WriteFile & {
input: dagger.#Scratch
path: "/test_relative"
permissions: 0o600
contents: "foobar"
}
outputs: directories: test_relative: {
contents: actions.data.output
dest: "./out"
}
}

View File

@ -1,10 +0,0 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: test: {
contents: "foobar"
dest: "./test_default_permissions"
}
}

View File

@ -1,7 +0,0 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: test: dest: "./test_no_contents"
}

View File

@ -1,15 +0,0 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: {
[path=string]: dest: path
test_relative: contents: """
#!/bin/bash
set -euo pipefail
echo "Hello World!"
"""
}
}

View File

@ -1,18 +0,0 @@
package main
import "dagger.io/dagger"
dagger.#Plan & {
outputs: files: {
[path=string]: dest: path
test_usage: {
contents: """
#!/bin/bash
set -euo pipefail
echo "Hello World!"
"""
permissions: 0o750
}
}
}

View File

@ -1,32 +0,0 @@
package main
import (
"dagger.io/dagger"
// "alpha.dagger.io/dagger/op"
// "alpha.dagger.io/alpine"
)
dagger.#Plan & {
// should fail due to incomplete service
proxy: dockerSocket: {}
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
imageWithDocker: dagger.#Exec & {
input: image.output
args: ["apk", "add", "--no-cache", "docker-cli"]
}
verify: dagger.#Exec & {
input: imageWithDocker.output
mounts: docker: {
dest: "/var/run/docker.sock"
contents: proxy.dockerSocket.service
}
args: ["docker", "info"]
}
}
}

View File

@ -1,32 +0,0 @@
package main
import (
"dagger.io/dagger"
// "alpha.dagger.io/dagger/op"
// "alpha.dagger.io/alpine"
)
dagger.#Plan & {
// should fail because incomplete value
proxy: dockerSocket: unix: string
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
imageWithDocker: dagger.#Exec & {
input: image.output
args: ["apk", "add", "--no-cache", "docker-cli"]
}
verify: dagger.#Exec & {
input: imageWithDocker.output
mounts: docker: {
dest: "/var/run/docker.sock"
contents: proxy.dockerSocket.service
}
args: ["docker", "info"]
}
}
}

View File

@ -1,32 +0,0 @@
package main
import (
"dagger.io/dagger"
// "alpha.dagger.io/dagger/op"
// "alpha.dagger.io/alpine"
)
dagger.#Plan & {
// should fail because of misspelled key
proxy: dockerSocket: unx: "/var/run/docker.sock"
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
imageWithDocker: dagger.#Exec & {
input: image.output
args: ["apk", "add", "--no-cache", "docker-cli"]
}
verify: dagger.#Exec & {
input: imageWithDocker.output
mounts: docker: {
dest: "/var/run/docker.sock"
contents: proxy.dockerSocket.service
}
args: ["docker", "info"]
}
}
}

View File

@ -1,32 +0,0 @@
package main
import (
"dagger.io/dagger"
// "alpha.dagger.io/dagger/op"
// "alpha.dagger.io/alpine"
)
dagger.#Plan & {
// should fail because of misspelled value
proxy: dockerSocket: unix: "/var/run/docker.soc"
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
imageWithDocker: dagger.#Exec & {
input: image.output
args: ["apk", "add", "--no-cache", "docker-cli"]
}
verify: dagger.#Exec & {
input: imageWithDocker.output
mounts: docker: {
dest: "/var/run/docker.sock"
contents: proxy.dockerSocket.service
}
args: ["docker", "info"]
}
}
}

View File

@ -1,32 +0,0 @@
package main
import (
"dagger.io/dagger"
// "alpha.dagger.io/dagger/op"
// "alpha.dagger.io/alpine"
)
dagger.#Plan & {
// should succeed
proxy: dockerSocket: unix: "/var/run/docker.sock"
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
imageWithDocker: dagger.#Exec & {
input: image.output
args: ["apk", "add", "--no-cache", "docker-cli"]
}
verify: dagger.#Exec & {
input: imageWithDocker.output
mounts: docker: {
dest: "/var/run/docker.sock"
contents: proxy.dockerSocket.service
}
args: ["docker", "info"]
}
}
}

View File

@ -5,9 +5,9 @@ import (
)
dagger.#Plan & {
inputs: params: foo: string
actions: {
params: foo: string
_image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
}
@ -25,7 +25,7 @@ dagger.#Plan & {
}
direct: {}
params: env: FOO: inputs.params.foo
"params": env: FOO: params.foo
}
}
}

View File

@ -5,10 +5,10 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: contents: """
FROM alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
ARG TEST=foo

View File

@ -5,22 +5,23 @@ import (
)
dagger.#Plan & {
inputs: {
directories: testdata: path: "./testdata"
secrets: sops: command: {
client: {
filesystem: testdata: read: contents: dagger.#FS
commands: sops: {
name: "sops"
args: ["-d", "../../secrets_sops.yaml"]
stdout: dagger.#Secret
}
}
actions: {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
auth: "daggerio/ci-test:private-pull": {
username: "daggertest"
secret: sopsSecrets.output.DOCKERHUB_TOKEN.contents

View File

@ -5,11 +5,11 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
}
verify: dagger.#Exec & {

View File

@ -5,11 +5,11 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: path: "./dockerfilepath/Dockerfile.custom"
}

View File

@ -5,12 +5,12 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
// FIXME: this doesn't test anything beside not crashing
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: contents: """
FROM alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
ENV test foobar

View File

@ -5,11 +5,11 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: contents: """
FROM alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
RUN echo foobar > /output

View File

@ -5,11 +5,11 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: contents: """
# syntax = docker/dockerfile:1.3
FROM alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d

View File

@ -5,12 +5,12 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
// FIXME: this doesn't test anything beside not crashing
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: contents: """
FROM alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
"""

View File

@ -5,12 +5,12 @@ import (
)
dagger.#Plan & {
inputs: directories: testdata: path: "./testdata"
client: filesystem: testdata: read: contents: dagger.#FS
actions: {
// FIXME: this doesn't test anything beside not crashing
build: dagger.#Dockerfile & {
source: inputs.directories.testdata.contents
source: client.filesystem.testdata.read.contents
dockerfile: contents: """
FROM alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
"""

View File

@ -5,7 +5,7 @@ import (
)
dagger.#Plan & {
inputs: secrets: testSecret: path: "secret.txt"
client: filesystem: "secret.txt": read: contents: dagger.#Secret
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
@ -13,7 +13,7 @@ dagger.#Plan & {
verify: dagger.#Exec & {
input: image.output
env: TEST: inputs.secrets.testSecret.contents
env: TEST: client.filesystem."secret.txt".read.contents
args: [
"sh", "-c",
#"""

View File

@ -5,7 +5,7 @@ import (
)
dagger.#Plan & {
inputs: secrets: testSecret: envvar: "TESTSECRET"
client: env: TESTSECRET: dagger.#Secret
actions: {
image: dagger.#Pull & {
source: "alpine:3.15.0@sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
@ -15,7 +15,7 @@ dagger.#Plan & {
input: image.output
mounts: secret: {
dest: "/run/secrets/test"
contents: inputs.secrets.testSecret.contents
contents: client.env.TESTSECRET
}
args: [
"sh", "-c",
@ -30,7 +30,7 @@ dagger.#Plan & {
input: image.output
mounts: secret: {
dest: "/run/secrets/test"
contents: inputs.secrets.testSecret.contents
contents: client.env.TESTSECRET
uid: 42
gid: 24
mask: 0o666

View File

@ -5,7 +5,7 @@ import (
)
dagger.#Plan & {
proxy: dockerSocket: unix: "/var/run/docker.sock"
client: filesystem: "/var/run/docker.sock": read: contents: dagger.#Service
actions: {
image: dagger.#Pull & {
@ -21,7 +21,7 @@ dagger.#Plan & {
input: imageWithDocker.output
mounts: docker: {
dest: "/var/run/docker.sock"
contents: proxy.dockerSocket.service
contents: client.filesystem."/var/run/docker.sock".read.contents
}
args: ["docker", "info"]
}

View File

@ -5,9 +5,10 @@ import (
)
dagger.#Plan & {
inputs: secrets: sops: command: {
client: commands: sops: {
name: "sops"
args: ["-d", "../../secrets_sops.yaml"]
args: ["-d", "secrets_sops.yaml"]
stdout: dagger.#Secret
}
actions: {
@ -18,7 +19,7 @@ dagger.#Plan & {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
testRepo: dagger.#GitPull & {

View File

@ -5,15 +5,16 @@ import (
)
dagger.#Plan & {
inputs: secrets: sops: command: {
client: commands: sops: {
name: "sops"
args: ["-d", "../../secrets_sops.yaml"]
args: ["-d", "secrets_sops.yaml"]
stdout: dagger.#Secret
}
actions: {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
pull: dagger.#Pull & {

View File

@ -6,9 +6,10 @@ import (
)
dagger.#Plan & {
inputs: secrets: sops: command: {
client: commands: sops: {
name: "sops"
args: ["-d", "../../secrets_sops.yaml"]
args: ["-d", "secrets_sops.yaml"]
stdout: dagger.#Secret
}
#auth: {
@ -17,10 +18,9 @@ dagger.#Plan & {
}
actions: {
sopsSecrets: dagger.#DecodeSecret & {
format: "yaml"
input: inputs.secrets.sops.contents
input: client.commands.sops.stdout
}
randomString: {