bash.#Run: new and improved

* Script is written to filesystem, not inlined as argument
* Pass script either as string, or directory+filename

Signed-off-by: Solomon Hykes <solomon@dagger.io>
This commit is contained in:
Solomon Hykes 2022-02-08 17:54:42 +00:00
parent 4944bead44
commit 013900c2a2
8 changed files with 171 additions and 75 deletions

View File

@ -2,25 +2,59 @@
package bash package bash
import ( import (
"dagger.io/dagger"
"dagger.io/dagger/engine"
"universe.dagger.io/docker" "universe.dagger.io/docker"
) )
// Run a bash command or script in a container // Run a bash script in a Docker container
// Since this is a thin wrapper over docker.#Run, we embed it.
// Whether to embed or wrap is a case-by-case decision, like in Go.
#Run: { #Run: {
// Contents of the bash script // The script to execute
script: string script: {
// A directory containing one or more bash scripts
directory: dagger.#FS
// Name of the file to execute
filename: string
_directory: directory
_filename: filename
} | {
// Script contents
contents: string
_filename: "run.sh"
_write: engine.#WriteFile & {
input: engine.#Scratch
path: _filename
"contents": contents
}
_directory: _write.output
}
// Arguments to the script
args: [...string]
// Where in the container to mount the scripts directory
_mountpoint: "/bash/scripts"
// FIXME: don't pass the script as argument: write to filesystme instead
docker.#Run & { docker.#Run & {
command: { command: {
name: "bash" name: "bash"
"args": ["\(_mountpoint)/\(script._filename)"] + args
// FIXME: make default flags overrideable
flags: { flags: {
"-c": script
"--noprofile": true
"--norc": true "--norc": true
"-e": true "-e": true
"-o": "pipefail" "-o": "pipefail"
} }
} }
mounts: "Bash scripts": {
contents: script._directory
dest: _mountpoint
}
} }
} }

View File

@ -0,0 +1,10 @@
setup() {
load '../../bats_helpers'
common_setup
}
@test "bash.#Run" {
dagger up ./run-simple
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
echo Hello, world > /out.txt

View File

@ -0,0 +1,87 @@
package bash
import (
"dagger.io/dagger"
"universe.dagger.io/docker"
"universe.dagger.io/alpine"
)
dagger.#DAG & {
actions: {
"Run from source directory": {
build: alpine.#Build & {
packages: bash: _
}
run: #Run & {
image: build.output
script: {
directory: loadScripts.output
filename: "hello.sh"
}
export: files: "/out.txt": _
}
output: run.export.files."/out.txt".contents & "Hello, world\n"
}
"Run from source directory with custom image": {
debian: docker.#Pull & {
source: "index.docker.io/debian"
}
run: #Run & {
image: debian.output
export: files: "/out.txt": _
script: {
directory: loadScripts.output
filename: "hello.sh"
}
}
output: run.export.files."/out.txt".contents & "Hello, world\n"
}
"Run from string": {
run: #Run & {
script: contents: "echo 'Hello, inlined world!' > /output.txt"
export: files: "/output.txt": _
}
output: run.export.files."/output.txt".contents & "Hello, inlined world!\n"
}
"Run from string with custom image": {
debian: docker.#Pull & {
source: "index.docker.io/debian"
}
run: #Run & {
image: debian.output
export: files: "/output.txt": _
script: contents: "echo 'Hello, inlined world!' > /output.txt"
}
output: run.export.files."/output.txt".contents & "Hello, inlined world!\n"
}
// Same thing but without bash.#Run
control: {
run: docker.#Run & {
image: base.output
command: {
name: "sh"
args: ["/bash/scripts/hello.sh"]
}
mounts: scripts: {
contents: loadScripts.output
dest: "/bash/scripts"
}
export: files: "/out.txt": _
}
output: run.export.files."/out.txt".contents & "Hello, world\n"
base: docker.#Pull & {
source: "alpine"
}
}
loadScripts: dagger.#Source & {
path: "."
include: ["*.sh"]
}
}
}

View File

@ -4,9 +4,11 @@ package netlify
import ( import (
"dagger.io/dagger" "dagger.io/dagger"
"dagger.io/dagger/engine"
"universe.dagger.io/alpine" "universe.dagger.io/alpine"
"universe.dagger.io/docker" "universe.dagger.io/docker"
"universe.dagger.io/bash"
) )
// Deploy a site to Netlify // Deploy a site to Netlify
@ -34,12 +36,7 @@ import (
// Create the site if it doesn't exist // Create the site if it doesn't exist
create: *true | false create: *true | false
// Source code of the Netlify package // Build a docker image to run the netlify client
_source: dagger.#Source & {
path: "."
include: ["*.sh"]
}
_build: docker.#Build & { _build: docker.#Build & {
steps: [ steps: [
alpine.#Build & { alpine.#Build & {
@ -50,45 +47,26 @@ import (
yarn: {} yarn: {}
} }
}, },
// FIXME: make this an alpine custom package, that would be so cool.
docker.#Run & { docker.#Run & {
command: { command: {
name: "yarn" name: "yarn"
args: ["global", "add", "netlify-cli@8.6.21"] args: ["global", "add", "netlify-cli@8.6.21"]
} }
}, },
docker.#Copy & {
contents: _source.output
dest: "/app"
},
] ]
} }
// Execute `netlify deploy` in a container // Run the netlify client in a container
command: docker.#Run & { container: bash.#Run & {
// FIXME: custom base image not supported script: {
// Container image. `netlify` must be available in the execution path _load: engine.#Source & {
// *{ path: "."
// _buildDefaultImage: docker.#Build & { include: ["*.sh"]
// input: alpine.#Build & { }
// bash: version: "=~5.1" directory: _load.output
// jq: version: "=~1.6" filename: "deploy.sh"
// curl: {} }
// yarn: version: "=~1.22"
// }
// steps: [{
// run: command: {
// name: "sh"
// flags: "-c": "yarn global add netlify-cli@3.38.10"
// }
// }]
// }
// // No nested tasks, boo hoo hoo
// image: _buildDefaultImage.output
// env: CUSTOM_IMAGE: "0"
// } | {
// env: CUSTOM_IMAGE: "1"
// }
image: _build.output image: _build.output
@ -114,7 +92,6 @@ import (
contents: token contents: token
} }
} }
command: name: "/app/deploy.sh"
export: files: { export: files: {
"/netlify/url": _ "/netlify/url": _
@ -124,11 +101,11 @@ import (
} }
// URL of the deployed site // URL of the deployed site
url: command.export.files."/netlify/url".contents url: container.export.files."/netlify/url".contents
// URL of the latest deployment // URL of the latest deployment
deployUrl: command.export.files."/netlify/deployUrl".contents deployUrl: container.export.files."/netlify/deployUrl".contents
// URL for logs of the latest deployment // URL for logs of the latest deployment
logsUrl: command.export.files."/netlify/logsUrl".contents logsUrl: container.export.files."/netlify/logsUrl".contents
} }

View File

@ -48,7 +48,7 @@ dagger.#Plan & {
// Check if the website was deployed // Check if the website was deployed
verify: bash.#Run & { verify: bash.#Run & {
input: image.output input: image.output
script: #""" script: contents: #"""
test "$(curl \#(deploy.deployUrl))" = "\#(marker)" test "$(curl \#(deploy.deployUrl))" = "\#(marker)"
"""# """#
} }

View File

@ -33,7 +33,7 @@ dagger.#Plan & {
dest: "/build" dest: "/build"
contents: pkg.output contents: pkg.output
} }
script: #""" script: contents: #"""
test "$(cat /build/test)" = "output" test "$(cat /build/test)" = "output"
"""# """#
} }

View File

@ -48,33 +48,19 @@ import (
// yarnVersion: *"=~1.22" | string // yarnVersion: *"=~1.22" | string
// FIXME: custom base image not supported // FIXME: custom base image not supported
image: alpine.#Build & { _buildImage: alpine.#Build & {
packages: { packages: {
bash: {} bash: {}
yarn: {} yarn: {}
} }
} }
// Run yarn in a containerized build environment // Run yarn in a docker container
command: bash.#Run & { container: bash.#Run & {
// FIXME: not working? image: _buildImage.output
// *{
// _image: alpine.#Build & {
// packages: {
// bash: version: "=~5.1"
// yarn: version: yarnVersion
// }
// }
// image: _image.output // FIXME: move shell script to its own file
// env: CUSTOM_IMAGE: "0" script: contents: #"""
// } | {
// env: CUSTOM_IMAGE: "1"
// }
"image": image.output
script: #"""
# Create $ENVFILE_NAME file if set # Create $ENVFILE_NAME file if set
[ -n "$ENVFILE_NAME" ] && echo "$ENVFILE" > "$ENVFILE_NAME" [ -n "$ENVFILE_NAME" ] && echo "$ENVFILE" > "$ENVFILE_NAME"
@ -94,7 +80,6 @@ import (
dest: "/src" dest: "/src"
contents: source contents: source
} }
// FIXME: mount secrets
} }
export: directories: "/build": _ export: directories: "/build": _
@ -115,5 +100,5 @@ import (
} }
// The final contents of the package after build // The final contents of the package after build
output: command.export.directories."/build".contents output: container.export.directories."/build".contents
} }