2021-11-04 08:05:24 +01:00
|
|
|
package docker
|
|
|
|
|
|
|
|
import (
|
|
|
|
"list"
|
|
|
|
|
|
|
|
"dagger.io/dagger"
|
2022-03-26 16:09:21 +01:00
|
|
|
"dagger.io/dagger/core"
|
2021-11-04 08:05:24 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Run a command in a container
|
|
|
|
#Run: {
|
2022-02-09 07:16:13 +01:00
|
|
|
// Docker image to execute
|
|
|
|
input: #Image
|
2021-11-04 08:05:24 +01:00
|
|
|
|
|
|
|
always: bool | *false
|
|
|
|
|
|
|
|
// Filesystem mounts
|
2022-03-26 16:09:21 +01:00
|
|
|
mounts: [name=string]: core.#Mount
|
2021-11-04 08:05:24 +01:00
|
|
|
|
|
|
|
// Expose network ports
|
2021-12-14 23:33:11 +01:00
|
|
|
// FIXME: investigate feasibility
|
2021-11-04 08:05:24 +01:00
|
|
|
ports: [name=string]: {
|
2022-03-28 19:54:08 +02:00
|
|
|
frontend: dagger.#Socket
|
2021-11-04 08:05:24 +01:00
|
|
|
backend: {
|
|
|
|
protocol: *"tcp" | "udp"
|
|
|
|
address: string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-15 20:34:24 +01:00
|
|
|
// Entrypoint to prepend to command
|
|
|
|
entrypoint?: [...string]
|
|
|
|
|
2021-11-04 08:05:24 +01:00
|
|
|
// Command to execute
|
2022-02-08 02:35:51 +01:00
|
|
|
command?: {
|
2021-11-04 08:05:24 +01:00
|
|
|
// 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]: (string | true)
|
|
|
|
|
|
|
|
_flatFlags: list.FlattenN([
|
|
|
|
for k, v in flags {
|
|
|
|
if (v & bool) != _|_ {
|
|
|
|
[k]
|
|
|
|
}
|
|
|
|
if (v & string) != _|_ {
|
|
|
|
[k, v]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
], 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Environment variables
|
|
|
|
// Example: {"DEBUG": "1"}
|
2022-02-16 19:37:16 +01:00
|
|
|
env: [string]: string | dagger.#Secret
|
2021-11-04 08:05:24 +01:00
|
|
|
|
|
|
|
// Working directory for the command
|
|
|
|
// Example: "/src"
|
2022-01-27 21:21:08 +01:00
|
|
|
workdir: string
|
2021-11-04 08:05:24 +01:00
|
|
|
|
|
|
|
// Username or UID to ad
|
|
|
|
// User identity for this command
|
|
|
|
// Examples: "root", "0", "1002"
|
2022-01-27 20:15:32 +01:00
|
|
|
user: string
|
2021-11-04 08:05:24 +01:00
|
|
|
|
2022-03-15 20:34:24 +01:00
|
|
|
// Add defaults to image config
|
|
|
|
// This ensures these values are present
|
2022-03-26 16:09:21 +01:00
|
|
|
_defaults: core.#Set & {
|
2022-03-15 20:34:24 +01:00
|
|
|
"input": {
|
|
|
|
entrypoint: []
|
|
|
|
cmd: []
|
|
|
|
workdir: "/"
|
|
|
|
user: "root"
|
|
|
|
}
|
|
|
|
config: input.config
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override with user config
|
2022-03-26 16:09:21 +01:00
|
|
|
_config: core.#Set & {
|
2022-03-15 20:34:24 +01:00
|
|
|
input: _defaults.output
|
|
|
|
config: {
|
|
|
|
if entrypoint != _|_ {
|
|
|
|
"entrypoint": entrypoint
|
|
|
|
}
|
|
|
|
if command != _|_ {
|
|
|
|
cmd: [command.name] + command._flatFlags + command.args
|
|
|
|
}
|
|
|
|
if workdir != _|_ {
|
|
|
|
"workdir": workdir
|
|
|
|
}
|
|
|
|
if user != _|_ {
|
|
|
|
"user": user
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-04 08:05:24 +01:00
|
|
|
// Output fields
|
|
|
|
{
|
|
|
|
// Has the command completed?
|
|
|
|
completed: bool & (_exec.exit != _|_)
|
|
|
|
|
|
|
|
// Was completion successful?
|
|
|
|
success: bool & (_exec.exit == 0)
|
|
|
|
|
|
|
|
// Details on error, if any
|
|
|
|
error: {
|
|
|
|
// Error code
|
|
|
|
code: _exec.exit
|
|
|
|
|
|
|
|
// Error message
|
|
|
|
message: string | *null
|
|
|
|
}
|
|
|
|
|
2022-01-15 21:33:50 +01:00
|
|
|
export: {
|
|
|
|
rootfs: dagger.#FS & _exec.output
|
2022-02-11 17:31:36 +01:00
|
|
|
files: [path=string]: string
|
|
|
|
_files: {
|
|
|
|
for path, _ in files {
|
|
|
|
"\(path)": {
|
|
|
|
contents: string & _read.contents
|
2022-03-26 16:09:21 +01:00
|
|
|
_read: core.#ReadFile & {
|
2022-02-11 17:31:36 +01:00
|
|
|
input: _exec.output
|
|
|
|
"path": path
|
|
|
|
}
|
|
|
|
}
|
2021-11-04 08:05:24 +01:00
|
|
|
}
|
|
|
|
}
|
2022-02-11 17:31:36 +01:00
|
|
|
for path, output in _files {
|
|
|
|
files: "\(path)": output.contents
|
|
|
|
}
|
|
|
|
|
|
|
|
directories: [path=string]: dagger.#FS
|
|
|
|
_directories: {
|
|
|
|
for path, _ in directories {
|
|
|
|
"\(path)": {
|
|
|
|
contents: dagger.#FS & _subdir.output
|
2022-03-26 16:09:21 +01:00
|
|
|
_subdir: core.#Subdir & {
|
2022-02-11 17:31:36 +01:00
|
|
|
input: _exec.output
|
|
|
|
"path": path
|
|
|
|
}
|
|
|
|
}
|
2022-01-15 21:33:50 +01:00
|
|
|
}
|
2021-11-04 08:05:24 +01:00
|
|
|
}
|
2022-02-11 17:31:36 +01:00
|
|
|
for path, output in _directories {
|
|
|
|
directories: "\(path)": output.contents
|
|
|
|
}
|
2021-11-04 08:05:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-15 21:33:50 +01:00
|
|
|
// For compatibility with #Build
|
|
|
|
output: #Image & {
|
|
|
|
rootfs: _exec.output
|
2022-02-09 07:16:13 +01:00
|
|
|
config: input.config
|
2022-01-15 21:33:50 +01:00
|
|
|
}
|
|
|
|
|
2021-11-04 08:05:24 +01:00
|
|
|
// Actually execute the command
|
2022-03-26 16:09:21 +01:00
|
|
|
_exec: core.#Exec & {
|
2022-02-09 07:16:13 +01:00
|
|
|
"input": input.rootfs
|
2022-01-27 20:15:32 +01:00
|
|
|
"always": always
|
|
|
|
"mounts": mounts
|
2022-03-15 20:34:24 +01:00
|
|
|
args: _config.output.entrypoint + _config.output.cmd
|
|
|
|
workdir: _config.output.workdir
|
|
|
|
user: _config.output.user
|
|
|
|
"env": env
|
2022-03-26 16:09:21 +01:00
|
|
|
// env may contain secrets so we can't use core.#Set
|
2022-02-09 07:16:13 +01:00
|
|
|
if input.config.env != _|_ {
|
|
|
|
for key, val in input.config.env {
|
2022-01-28 19:15:44 +01:00
|
|
|
if env[key] == _|_ {
|
|
|
|
env: "\(key)": val
|
2022-01-27 20:15:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-04 08:05:24 +01:00
|
|
|
}
|
2022-02-25 02:48:18 +01:00
|
|
|
|
|
|
|
// Command exit code
|
|
|
|
exit: _exec.exit
|
2021-11-04 08:05:24 +01:00
|
|
|
}
|