Packages

Gleam SDK for Dagger — type-safe pipelines via GraphQL codegen

Current section

Files

Jump to
dagger_gleam src dagger dsl container.gleam
Raw

src/dagger/dsl/container.gleam

// AUTO-GENERATED BY DAGGER_GLEAM - DO NOT EDIT
import dagger/types.{type Client, type Try} as types
import dagger/interpreter
import dagger/dsl/types as t
import gleam/dynamic/decode
import gleam/list
import gleam/option.{type Option, None, Some}
pub type ForWithMountedTemp
pub type ForWithExposedPort
pub type WithDirectoryFns {
WithDirectory
WithFile
WithFiles
WithMountedCache
WithMountedDirectory
WithMountedFile
WithMountedSecret
WithNewFile
WithUnixSocket
}
pub type ForImport
pub type ForExists
pub type AsTarballFns {
AsTarball
Export
ExportImage
Publish
}
pub type AsServiceFns {
AsService
Terminal
Up
WithDefaultTerminalCmd
WithExec
}
pub type ForContainer
pub opaque type Opts(tag_) {
Opts(
platform: Option(String),
args: Option(List(String)),
use_entrypoint: Option(Bool),
experimental_privileged_nesting: Option(Bool),
insecure_root_capabilities: Option(Bool),
expand: Option(Bool),
no_init: Option(Bool),
platform_variants: Option(List(t.Container)),
forced_compression: Option(t.ImageLayerCompression),
media_types: Option(t.ImageMediaTypes),
expected_type: Option(t.ExistsType),
do_not_follow_symlinks: Option(Bool),
tag: Option(String),
cmd: Option(List(String)),
random: Option(Bool),
ports: Option(List(t.PortForward)),
exclude: Option(List(String)),
include: Option(List(String)),
gitignore: Option(Bool),
owner: Option(String),
keep_default_args: Option(Bool),
stdin: Option(String),
redirect_stdin: Option(String),
redirect_stdout: Option(String),
redirect_stderr: Option(String),
expect: Option(t.ReturnType),
protocol: Option(t.NetworkProtocol),
description: Option(String),
experimental_skip_healthcheck: Option(Bool),
permissions: Option(Int),
source: Option(t.Directory),
sharing: Option(t.CacheSharingMode),
mode: Option(Int),
size: Option(Int),
)
}
fn defaults() -> Opts(a) {
Opts(
platform: None,
args: None,
use_entrypoint: None,
experimental_privileged_nesting: None,
insecure_root_capabilities: None,
expand: None,
no_init: None,
platform_variants: None,
forced_compression: None,
media_types: None,
expected_type: None,
do_not_follow_symlinks: None,
tag: None,
cmd: None,
random: None,
ports: None,
exclude: None,
include: None,
gitignore: None,
owner: None,
keep_default_args: None,
stdin: None,
redirect_stdin: None,
redirect_stdout: None,
redirect_stderr: None,
expect: None,
protocol: None,
description: None,
experimental_skip_healthcheck: None,
permissions: None,
source: None,
sharing: None,
mode: None,
size: None,
)
}
pub fn none(opts: Opts(a)) -> Opts(a) {
opts
}
pub fn opt_platform(opts: Opts(ForContainer), val: String) -> Opts(ForContainer) {
Opts(..opts, platform: Some(val))
}
pub fn opt_args(opts: Opts(AsServiceFns), val: List(String)) -> Opts(AsServiceFns) {
Opts(..opts, args: Some(val))
}
pub fn opt_use_entrypoint(opts: Opts(AsServiceFns), val: Bool) -> Opts(AsServiceFns) {
Opts(..opts, use_entrypoint: Some(val))
}
pub fn opt_experimental_privileged_nesting(opts: Opts(AsServiceFns), val: Bool) -> Opts(AsServiceFns) {
Opts(..opts, experimental_privileged_nesting: Some(val))
}
pub fn opt_insecure_root_capabilities(opts: Opts(AsServiceFns), val: Bool) -> Opts(AsServiceFns) {
Opts(..opts, insecure_root_capabilities: Some(val))
}
pub fn opt_expand(opts: Opts(a), val: Bool) -> Opts(a) {
Opts(..opts, expand: Some(val))
}
pub fn opt_no_init(opts: Opts(AsServiceFns), val: Bool) -> Opts(AsServiceFns) {
Opts(..opts, no_init: Some(val))
}
pub fn opt_platform_variants(opts: Opts(AsTarballFns), val: List(t.Container)) -> Opts(AsTarballFns) {
Opts(..opts, platform_variants: Some(val))
}
pub fn opt_forced_compression(opts: Opts(AsTarballFns), val: t.ImageLayerCompression) -> Opts(AsTarballFns) {
Opts(..opts, forced_compression: Some(val))
}
pub fn opt_media_types(opts: Opts(AsTarballFns), val: t.ImageMediaTypes) -> Opts(AsTarballFns) {
Opts(..opts, media_types: Some(val))
}
pub fn opt_expected_type(opts: Opts(ForExists), val: t.ExistsType) -> Opts(ForExists) {
Opts(..opts, expected_type: Some(val))
}
pub fn opt_do_not_follow_symlinks(opts: Opts(a), val: Bool) -> Opts(a) {
Opts(..opts, do_not_follow_symlinks: Some(val))
}
pub fn opt_tag(opts: Opts(ForImport), val: String) -> Opts(ForImport) {
Opts(..opts, tag: Some(val))
}
pub fn opt_cmd(opts: Opts(AsServiceFns), val: List(String)) -> Opts(AsServiceFns) {
Opts(..opts, cmd: Some(val))
}
pub fn opt_random(opts: Opts(AsServiceFns), val: Bool) -> Opts(AsServiceFns) {
Opts(..opts, random: Some(val))
}
pub fn opt_ports(opts: Opts(AsServiceFns), val: List(t.PortForward)) -> Opts(AsServiceFns) {
Opts(..opts, ports: Some(val))
}
pub fn opt_exclude(opts: Opts(WithDirectoryFns), val: List(String)) -> Opts(WithDirectoryFns) {
Opts(..opts, exclude: Some(val))
}
pub fn opt_include(opts: Opts(WithDirectoryFns), val: List(String)) -> Opts(WithDirectoryFns) {
Opts(..opts, include: Some(val))
}
pub fn opt_gitignore(opts: Opts(WithDirectoryFns), val: Bool) -> Opts(WithDirectoryFns) {
Opts(..opts, gitignore: Some(val))
}
pub fn opt_owner(opts: Opts(WithDirectoryFns), val: String) -> Opts(WithDirectoryFns) {
Opts(..opts, owner: Some(val))
}
pub fn opt_keep_default_args(opts: Opts(a), val: Bool) -> Opts(a) {
Opts(..opts, keep_default_args: Some(val))
}
pub fn opt_stdin(opts: Opts(AsServiceFns), val: String) -> Opts(AsServiceFns) {
Opts(..opts, stdin: Some(val))
}
pub fn opt_redirect_stdin(opts: Opts(AsServiceFns), val: String) -> Opts(AsServiceFns) {
Opts(..opts, redirect_stdin: Some(val))
}
pub fn opt_redirect_stdout(opts: Opts(AsServiceFns), val: String) -> Opts(AsServiceFns) {
Opts(..opts, redirect_stdout: Some(val))
}
pub fn opt_redirect_stderr(opts: Opts(AsServiceFns), val: String) -> Opts(AsServiceFns) {
Opts(..opts, redirect_stderr: Some(val))
}
pub fn opt_expect(opts: Opts(AsServiceFns), val: t.ReturnType) -> Opts(AsServiceFns) {
Opts(..opts, expect: Some(val))
}
pub fn opt_protocol(opts: Opts(a), val: t.NetworkProtocol) -> Opts(a) {
Opts(..opts, protocol: Some(val))
}
pub fn opt_description(opts: Opts(ForWithExposedPort), val: String) -> Opts(ForWithExposedPort) {
Opts(..opts, description: Some(val))
}
pub fn opt_experimental_skip_healthcheck(opts: Opts(ForWithExposedPort), val: Bool) -> Opts(ForWithExposedPort) {
Opts(..opts, experimental_skip_healthcheck: Some(val))
}
pub fn opt_permissions(opts: Opts(WithDirectoryFns), val: Int) -> Opts(WithDirectoryFns) {
Opts(..opts, permissions: Some(val))
}
pub fn opt_source(opts: Opts(WithDirectoryFns), val: t.Directory) -> Opts(WithDirectoryFns) {
Opts(..opts, source: Some(val))
}
pub fn opt_sharing(opts: Opts(WithDirectoryFns), val: t.CacheSharingMode) -> Opts(WithDirectoryFns) {
Opts(..opts, sharing: Some(val))
}
pub fn opt_mode(opts: Opts(WithDirectoryFns), val: Int) -> Opts(WithDirectoryFns) {
Opts(..opts, mode: Some(val))
}
pub fn opt_size(opts: Opts(ForWithMountedTemp), val: Int) -> Opts(ForWithMountedTemp) {
Opts(..opts, size: Some(val))
}
fn encode_container(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.platform {
Some(val) -> Ok(#("platform", types.GString(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
pub fn container(with with_fn: fn(Opts(ForContainer)) -> Opts(ForContainer)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "container", args: encode_container(opts), subfields: [])
t.Container(op: types.Pure([field]))
}
fn encode_as_service(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.args {
Some(val) -> Ok(#("args", types.GList(list.map(val, fn(x) { types.GString(x) }))))
None -> Error(Nil)
},
case opts.use_entrypoint {
Some(val) -> Ok(#("useEntrypoint", types.GBool(val)))
None -> Error(Nil)
},
case opts.experimental_privileged_nesting {
Some(val) -> Ok(#("experimentalPrivilegedNesting", types.GBool(val)))
None -> Error(Nil)
},
case opts.insecure_root_capabilities {
Some(val) -> Ok(#("insecureRootCapabilities", types.GBool(val)))
None -> Error(Nil)
},
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.no_init {
Some(val) -> Ok(#("noInit", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Turn the container into a Service.
/// Be sure to set any exposed ports before this conversion.
pub fn as_service(parent: t.Container, with with_fn: fn(Opts(AsServiceFns)) -> Opts(AsServiceFns)) -> t.Service {
let opts = with_fn(defaults())
let field = types.Field(name: "asService", args: encode_as_service(opts), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Service(op: new_op)
}
fn encode_as_tarball(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.platform_variants {
Some(val) -> Ok(#("platformVariants", types.GList(list.map(val, fn(x) { types.GDeferred(x.op) }))))
None -> Error(Nil)
},
case opts.forced_compression {
Some(val) -> Ok(#("forcedCompression", types.GString(t.image_layer_compression_to_json(val))))
None -> Error(Nil)
},
case opts.media_types {
Some(val) -> Ok(#("mediaTypes", types.GString(t.image_media_types_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Package the container state as an OCI image, and return it as a tar archive
pub fn as_tarball(parent: t.Container, with with_fn: fn(Opts(AsTarballFns)) -> Opts(AsTarballFns)) -> t.File {
let opts = with_fn(defaults())
let field = types.Field(name: "asTarball", args: encode_as_tarball(opts), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.File(op: new_op)
}
/// The combined buffered standard output and standard error stream of the last executed command
/// Returns an error if no command was executed
pub fn combined_output(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "combinedOutput", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("combinedOutput")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Return the container's default arguments.
pub fn default_args(parent: t.Container, client client: Client, then handler: fn(Try(List(String))) -> a) -> a {
let field = types.Field(name: "defaultArgs", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.list(decode.string))) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("defaultArgs")))
}
}
)
}
handler(interpreter.run(op, client))
}
fn encode_directory(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieve a directory from the container's root filesystem
/// Mounts are included.
pub fn directory(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Directory {
let opts = with_fn(defaults())
let field = types.Field(name: "directory", args: list.append([#("path", types.GString(path))], encode_directory(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Directory(op: new_op)
}
/// Return the container's OCI entrypoint.
pub fn entrypoint(parent: t.Container, client client: Client, then handler: fn(Try(List(String))) -> a) -> a {
let field = types.Field(name: "entrypoint", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.list(decode.string))) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("entrypoint")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves the value of the specified environment variable.
pub fn env_variable(parent: t.Container, name name: String, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "envVariable", args: [#("name", types.GString(name))], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("envVariable")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves the list of environment variables passed to commands.
pub fn env_variables(parent: t.Container, select select: fn(t.EnvVariable) -> List(types.Field), client client: Client, then handler: fn(Try(List(t.EnvVariable))) -> a) -> a {
let subfields = select(t.EnvVariable(op: types.Pure([])))
let field = types.Field(name: "envVariables", args: [], subfields: subfields)
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.list(decode.dynamic))) {
Ok(items) -> types.Pure(Ok(list.map(items, fn(_) { t.EnvVariable(op: types.Pure(full_query)) })))
Error(_) -> types.Pure(Error(types.DecodingError("envVariables")))
}
}
)
}
handler(interpreter.run(op, client))
}
fn encode_exists(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expected_type {
Some(val) -> Ok(#("expectedType", types.GString(t.exists_type_to_json(val))))
None -> Error(Nil)
},
case opts.do_not_follow_symlinks {
Some(val) -> Ok(#("doNotFollowSymlinks", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// check if a file or directory exists
pub fn exists(parent: t.Container, path path: String, with with_fn: fn(Opts(ForExists)) -> Opts(ForExists), client client: Client, then handler: fn(Try(Bool)) -> a) -> a {
let opts = with_fn(defaults())
let field = types.Field(name: "exists", args: list.append([#("path", types.GString(path))], encode_exists(opts)), subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.bool)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("exists")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// The exit code of the last executed command
/// Returns an error if no command was executed
pub fn exit_code(parent: t.Container, client client: Client, then handler: fn(Try(Int)) -> a) -> a {
let field = types.Field(name: "exitCode", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.int)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("exitCode")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// EXPERIMENTAL API! Subject to change/removal at any time.
/// Configures all available GPUs on the host to be accessible to this container.
/// This currently works for Nvidia devices only.
pub fn experimental_with_all_g_p_us(parent: t.Container) -> t.Container {
let field = types.Field(name: "experimentalWithAllGPUs", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// EXPERIMENTAL API! Subject to change/removal at any time.
/// Configures the provided list of devices to be accessible to this container.
/// This currently works for Nvidia devices only.
pub fn experimental_with_g_p_u(parent: t.Container, devices devices: List(String)) -> t.Container {
let field = types.Field(name: "experimentalWithGPU", args: [#("devices", types.GList(list.map(devices, fn(x) { types.GString(x) })))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_export(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.platform_variants {
Some(val) -> Ok(#("platformVariants", types.GList(list.map(val, fn(x) { types.GDeferred(x.op) }))))
None -> Error(Nil)
},
case opts.forced_compression {
Some(val) -> Ok(#("forcedCompression", types.GString(t.image_layer_compression_to_json(val))))
None -> Error(Nil)
},
case opts.media_types {
Some(val) -> Ok(#("mediaTypes", types.GString(t.image_media_types_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Writes the container as an OCI tarball to the destination file path on the host.
/// It can also export platform variants.
pub fn export(parent: t.Container, path path: String, with with_fn: fn(Opts(AsTarballFns)) -> Opts(AsTarballFns), client client: Client, then handler: fn(Try(String)) -> a) -> a {
let opts = with_fn(defaults())
let field = types.Field(name: "export", args: list.append([#("path", types.GString(path))], encode_export(opts)), subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("export")))
}
}
)
}
handler(interpreter.run(op, client))
}
fn encode_export_image(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.platform_variants {
Some(val) -> Ok(#("platformVariants", types.GList(list.map(val, fn(x) { types.GDeferred(x.op) }))))
None -> Error(Nil)
},
case opts.forced_compression {
Some(val) -> Ok(#("forcedCompression", types.GString(t.image_layer_compression_to_json(val))))
None -> Error(Nil)
},
case opts.media_types {
Some(val) -> Ok(#("mediaTypes", types.GString(t.image_media_types_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Exports the container as an image to the host's container image store.
pub fn export_image(parent: t.Container, name name: String, with with_fn: fn(Opts(AsTarballFns)) -> Opts(AsTarballFns), client client: Client, then handler: fn(Try(Nil)) -> a) -> a {
let opts = with_fn(defaults())
let field = types.Field(name: "exportImage", args: list.append([#("name", types.GString(name))], encode_export_image(opts)), subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.dynamic)) {
Ok(_) -> types.Pure(Ok(Nil))
Error(_) -> types.Pure(Error(types.DecodingError("exportImage")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves the list of exposed ports.
/// This includes ports already exposed by the image, even if not explicitly added with dagger.
pub fn exposed_ports(parent: t.Container, select select: fn(t.Port) -> List(types.Field), client client: Client, then handler: fn(Try(List(t.Port))) -> a) -> a {
let subfields = select(t.Port(op: types.Pure([])))
let field = types.Field(name: "exposedPorts", args: [], subfields: subfields)
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.list(decode.dynamic))) {
Ok(items) -> types.Pure(Ok(list.map(items, fn(_) { t.Port(op: types.Pure(full_query)) })))
Error(_) -> types.Pure(Error(types.DecodingError("exposedPorts")))
}
}
)
}
handler(interpreter.run(op, client))
}
fn encode_file(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves a file at the given path.
/// Mounts are included.
pub fn file(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.File {
let opts = with_fn(defaults())
let field = types.Field(name: "file", args: list.append([#("path", types.GString(path))], encode_file(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.File(op: new_op)
}
/// Download a container image, and apply it to the container state. All previous state will be lost.
pub fn from(parent: t.Container, address address: String) -> t.Container {
let field = types.Field(name: "from", args: [#("address", types.GString(address))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// A unique identifier for this Container.
pub fn id(parent: t.Container) -> t.Container {
let field = types.Field(name: "id", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// The unique image reference which can only be retrieved immediately after the 'Container.From' call.
pub fn image_ref(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "imageRef", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("imageRef")))
}
}
)
}
handler(interpreter.run(op, client))
}
fn encode_import_(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.tag {
Some(val) -> Ok(#("tag", types.GString(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Reads the container from an OCI tarball.
pub fn import_(parent: t.Container, source source: t.File, with with_fn: fn(Opts(ForImport)) -> Opts(ForImport)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "import", args: list.append([#("source", types.GDeferred(source.op))], encode_import_(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves the value of the specified label.
pub fn label(parent: t.Container, name name: String, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "label", args: [#("name", types.GString(name))], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("label")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves the list of labels passed to container.
pub fn labels(parent: t.Container, select select: fn(t.Label) -> List(types.Field), client client: Client, then handler: fn(Try(List(t.Label))) -> a) -> a {
let subfields = select(t.Label(op: types.Pure([])))
let field = types.Field(name: "labels", args: [], subfields: subfields)
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.list(decode.dynamic))) {
Ok(items) -> types.Pure(Ok(list.map(items, fn(_) { t.Label(op: types.Pure(full_query)) })))
Error(_) -> types.Pure(Error(types.DecodingError("labels")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves the list of paths where a directory is mounted.
pub fn mounts(parent: t.Container, client client: Client, then handler: fn(Try(List(String))) -> a) -> a {
let field = types.Field(name: "mounts", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.list(decode.string))) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("mounts")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// The platform this container executes and publishes as.
pub fn platform(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "platform", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("platform")))
}
}
)
}
handler(interpreter.run(op, client))
}
fn encode_publish(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.platform_variants {
Some(val) -> Ok(#("platformVariants", types.GList(list.map(val, fn(x) { types.GDeferred(x.op) }))))
None -> Error(Nil)
},
case opts.forced_compression {
Some(val) -> Ok(#("forcedCompression", types.GString(t.image_layer_compression_to_json(val))))
None -> Error(Nil)
},
case opts.media_types {
Some(val) -> Ok(#("mediaTypes", types.GString(t.image_media_types_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Package the container state as an OCI image, and publish it to a registry
/// Returns the fully qualified address of the published image, with digest
pub fn publish(parent: t.Container, address address: String, with with_fn: fn(Opts(AsTarballFns)) -> Opts(AsTarballFns), client client: Client, then handler: fn(Try(String)) -> a) -> a {
let opts = with_fn(defaults())
let field = types.Field(name: "publish", args: list.append([#("address", types.GString(address))], encode_publish(opts)), subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("publish")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Return a snapshot of the container's root filesystem. The snapshot can be modified then written back using withRootfs. Use that method for filesystem modifications.
pub fn rootfs(parent: t.Container) -> t.Directory {
let field = types.Field(name: "rootfs", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Directory(op: new_op)
}
fn encode_stat(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.do_not_follow_symlinks {
Some(val) -> Ok(#("doNotFollowSymlinks", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return file status
pub fn stat(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Stat {
let opts = with_fn(defaults())
let field = types.Field(name: "stat", args: list.append([#("path", types.GString(path))], encode_stat(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Stat(op: new_op)
}
/// The buffered standard error stream of the last executed command
/// Returns an error if no command was executed
pub fn stderr(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "stderr", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("stderr")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// The buffered standard output stream of the last executed command
/// Returns an error if no command was executed
pub fn stdout(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "stdout", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("stdout")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Forces evaluation of the pipeline in the engine.
/// It doesn't run the default command if no exec has been set.
pub fn sync(parent: t.Container) -> t.Container {
let field = types.Field(name: "sync", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_terminal(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.experimental_privileged_nesting {
Some(val) -> Ok(#("experimentalPrivilegedNesting", types.GBool(val)))
None -> Error(Nil)
},
case opts.insecure_root_capabilities {
Some(val) -> Ok(#("insecureRootCapabilities", types.GBool(val)))
None -> Error(Nil)
},
case opts.cmd {
Some(val) -> Ok(#("cmd", types.GList(list.map(val, fn(x) { types.GString(x) }))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Opens an interactive terminal for this container using its configured default terminal command if not overridden by args (or sh as a fallback default).
pub fn terminal(parent: t.Container, with with_fn: fn(Opts(AsServiceFns)) -> Opts(AsServiceFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "terminal", args: encode_terminal(opts), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_up(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.args {
Some(val) -> Ok(#("args", types.GList(list.map(val, fn(x) { types.GString(x) }))))
None -> Error(Nil)
},
case opts.use_entrypoint {
Some(val) -> Ok(#("useEntrypoint", types.GBool(val)))
None -> Error(Nil)
},
case opts.experimental_privileged_nesting {
Some(val) -> Ok(#("experimentalPrivilegedNesting", types.GBool(val)))
None -> Error(Nil)
},
case opts.insecure_root_capabilities {
Some(val) -> Ok(#("insecureRootCapabilities", types.GBool(val)))
None -> Error(Nil)
},
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.no_init {
Some(val) -> Ok(#("noInit", types.GBool(val)))
None -> Error(Nil)
},
case opts.random {
Some(val) -> Ok(#("random", types.GBool(val)))
None -> Error(Nil)
},
case opts.ports {
Some(val) -> Ok(#("ports", types.GList(list.map(val, fn(x) { types.GObject(t.port_forward_to_json(x)) }))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Starts a Service and creates a tunnel that forwards traffic from the caller's network to that service.
/// Be sure to set any exposed ports before calling this api.
pub fn up(parent: t.Container, with with_fn: fn(Opts(AsServiceFns)) -> Opts(AsServiceFns), client client: Client, then handler: fn(Try(Nil)) -> a) -> a {
let opts = with_fn(defaults())
let field = types.Field(name: "up", args: encode_up(opts), subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.dynamic)) {
Ok(_) -> types.Pure(Ok(Nil))
Error(_) -> types.Pure(Error(types.DecodingError("up")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves the user to be set for all commands.
pub fn user(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "user", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("user")))
}
}
)
}
handler(interpreter.run(op, client))
}
/// Retrieves this container plus the given OCI annotation.
pub fn with_annotation(parent: t.Container, name name: String, value value: String) -> t.Container {
let field = types.Field(name: "withAnnotation", args: [#("name", types.GString(name)), #("value", types.GString(value))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Configures default arguments for future commands. Like CMD in Dockerfile.
pub fn with_default_args(parent: t.Container, args args: List(String)) -> t.Container {
let field = types.Field(name: "withDefaultArgs", args: [#("args", types.GList(list.map(args, fn(x) { types.GString(x) })))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_default_terminal_cmd(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.experimental_privileged_nesting {
Some(val) -> Ok(#("experimentalPrivilegedNesting", types.GBool(val)))
None -> Error(Nil)
},
case opts.insecure_root_capabilities {
Some(val) -> Ok(#("insecureRootCapabilities", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Set the default command to invoke for the container's terminal API.
pub fn with_default_terminal_cmd(parent: t.Container, args args: List(String), with with_fn: fn(Opts(AsServiceFns)) -> Opts(AsServiceFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withDefaultTerminalCmd", args: list.append([#("args", types.GList(list.map(args, fn(x) { types.GString(x) })))], encode_with_default_terminal_cmd(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_directory(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.exclude {
Some(val) -> Ok(#("exclude", types.GList(list.map(val, fn(x) { types.GString(x) }))))
None -> Error(Nil)
},
case opts.include {
Some(val) -> Ok(#("include", types.GList(list.map(val, fn(x) { types.GString(x) }))))
None -> Error(Nil)
},
case opts.gitignore {
Some(val) -> Ok(#("gitignore", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return a new container snapshot, with a directory added to its filesystem
pub fn with_directory(parent: t.Container, path path: String, source source: t.Directory, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withDirectory", args: list.append([#("path", types.GString(path)), #("source", types.GDeferred(source.op))], encode_with_directory(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_entrypoint(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.keep_default_args {
Some(val) -> Ok(#("keepDefaultArgs", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Set an OCI-style entrypoint. It will be included in the container's OCI configuration. Note, withExec ignores the entrypoint by default.
pub fn with_entrypoint(parent: t.Container, args args: List(String), with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withEntrypoint", args: list.append([#("args", types.GList(list.map(args, fn(x) { types.GString(x) })))], encode_with_entrypoint(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Export environment variables from an env-file to the container.
pub fn with_env_file_variables(parent: t.Container, source source: t.EnvFile) -> t.Container {
let field = types.Field(name: "withEnvFileVariables", args: [#("source", types.GDeferred(source.op))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_env_variable(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Set a new environment variable in the container.
pub fn with_env_variable(parent: t.Container, name name: String, value value: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withEnvVariable", args: list.append([#("name", types.GString(name)), #("value", types.GString(value))], encode_with_env_variable(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Raise an error.
pub fn with_error(parent: t.Container, err err: String) -> t.Container {
let field = types.Field(name: "withError", args: [#("err", types.GString(err))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_exec(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.use_entrypoint {
Some(val) -> Ok(#("useEntrypoint", types.GBool(val)))
None -> Error(Nil)
},
case opts.experimental_privileged_nesting {
Some(val) -> Ok(#("experimentalPrivilegedNesting", types.GBool(val)))
None -> Error(Nil)
},
case opts.insecure_root_capabilities {
Some(val) -> Ok(#("insecureRootCapabilities", types.GBool(val)))
None -> Error(Nil)
},
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.no_init {
Some(val) -> Ok(#("noInit", types.GBool(val)))
None -> Error(Nil)
},
case opts.stdin {
Some(val) -> Ok(#("stdin", types.GString(val)))
None -> Error(Nil)
},
case opts.redirect_stdin {
Some(val) -> Ok(#("redirectStdin", types.GString(val)))
None -> Error(Nil)
},
case opts.redirect_stdout {
Some(val) -> Ok(#("redirectStdout", types.GString(val)))
None -> Error(Nil)
},
case opts.redirect_stderr {
Some(val) -> Ok(#("redirectStderr", types.GString(val)))
None -> Error(Nil)
},
case opts.expect {
Some(val) -> Ok(#("expect", types.GString(t.return_type_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Execute a command in the container, and return a new snapshot of the container state after execution.
pub fn with_exec(parent: t.Container, args args: List(String), with with_fn: fn(Opts(AsServiceFns)) -> Opts(AsServiceFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withExec", args: list.append([#("args", types.GList(list.map(args, fn(x) { types.GString(x) })))], encode_with_exec(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_exposed_port(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.protocol {
Some(val) -> Ok(#("protocol", types.GString(t.network_protocol_to_json(val))))
None -> Error(Nil)
},
case opts.description {
Some(val) -> Ok(#("description", types.GString(val)))
None -> Error(Nil)
},
case opts.experimental_skip_healthcheck {
Some(val) -> Ok(#("experimentalSkipHealthcheck", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Expose a network port. Like EXPOSE in Dockerfile (but with healthcheck support)
/// Exposed ports serve two purposes:
/// - For health checks and introspection, when running services
/// - For setting the EXPOSE OCI field when publishing the container
pub fn with_exposed_port(parent: t.Container, port port: Int, with with_fn: fn(Opts(ForWithExposedPort)) -> Opts(ForWithExposedPort)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withExposedPort", args: list.append([#("port", types.GInt(port))], encode_with_exposed_port(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_file(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
},
case opts.permissions {
Some(val) -> Ok(#("permissions", types.GInt(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return a container snapshot with a file added
pub fn with_file(parent: t.Container, path path: String, source source: t.File, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withFile", args: list.append([#("path", types.GString(path)), #("source", types.GDeferred(source.op))], encode_with_file(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_files(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
},
case opts.permissions {
Some(val) -> Ok(#("permissions", types.GInt(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus the contents of the given files copied to the given path.
pub fn with_files(parent: t.Container, path path: String, sources sources: List(t.File), with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withFiles", args: list.append([#("path", types.GString(path)), #("sources", types.GList(list.map(sources, fn(x) { types.GDeferred(x.op) })))], encode_with_files(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container plus the given label.
pub fn with_label(parent: t.Container, name name: String, value value: String) -> t.Container {
let field = types.Field(name: "withLabel", args: [#("name", types.GString(name)), #("value", types.GString(value))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_mounted_cache(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
},
case opts.source {
Some(val) -> Ok(#("source", types.GDeferred(val.op)))
None -> Error(Nil)
},
case opts.sharing {
Some(val) -> Ok(#("sharing", types.GString(t.cache_sharing_mode_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus a cache volume mounted at the given path.
pub fn with_mounted_cache(parent: t.Container, path path: String, cache cache: t.CacheVolume, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withMountedCache", args: list.append([#("path", types.GString(path)), #("cache", types.GDeferred(cache.op))], encode_with_mounted_cache(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_mounted_directory(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus a directory mounted at the given path.
pub fn with_mounted_directory(parent: t.Container, path path: String, source source: t.Directory, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withMountedDirectory", args: list.append([#("path", types.GString(path)), #("source", types.GDeferred(source.op))], encode_with_mounted_directory(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_mounted_file(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus a file mounted at the given path.
pub fn with_mounted_file(parent: t.Container, path path: String, source source: t.File, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withMountedFile", args: list.append([#("path", types.GString(path)), #("source", types.GDeferred(source.op))], encode_with_mounted_file(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_mounted_secret(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
},
case opts.mode {
Some(val) -> Ok(#("mode", types.GInt(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus a secret mounted into a file at the given path.
pub fn with_mounted_secret(parent: t.Container, path path: String, source source: t.Secret, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withMountedSecret", args: list.append([#("path", types.GString(path)), #("source", types.GDeferred(source.op))], encode_with_mounted_secret(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_mounted_temp(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.size {
Some(val) -> Ok(#("size", types.GInt(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus a temporary directory mounted at the given path. Any writes will be ephemeral to a single withExec call; they will not be persisted to subsequent withExecs.
pub fn with_mounted_temp(parent: t.Container, path path: String, with with_fn: fn(Opts(ForWithMountedTemp)) -> Opts(ForWithMountedTemp)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withMountedTemp", args: list.append([#("path", types.GString(path))], encode_with_mounted_temp(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_new_file(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
},
case opts.permissions {
Some(val) -> Ok(#("permissions", types.GInt(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return a new container snapshot, with a file added to its filesystem with text content
pub fn with_new_file(parent: t.Container, path path: String, contents contents: String, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withNewFile", args: list.append([#("path", types.GString(path)), #("contents", types.GString(contents))], encode_with_new_file(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Attach credentials for future publishing to a registry. Use in combination with publish
pub fn with_registry_auth(parent: t.Container, address address: String, username username: String, secret secret: t.Secret) -> t.Container {
let field = types.Field(name: "withRegistryAuth", args: [#("address", types.GString(address)), #("username", types.GString(username)), #("secret", types.GDeferred(secret.op))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Change the container's root filesystem. The previous root filesystem will be lost.
pub fn with_rootfs(parent: t.Container, directory directory: t.Directory) -> t.Container {
let field = types.Field(name: "withRootfs", args: [#("directory", types.GDeferred(directory.op))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Set a new environment variable, using a secret value
pub fn with_secret_variable(parent: t.Container, name name: String, secret secret: t.Secret) -> t.Container {
let field = types.Field(name: "withSecretVariable", args: [#("name", types.GString(name)), #("secret", types.GDeferred(secret.op))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Establish a runtime dependency from a container to a network service.
/// The service will be started automatically when needed and detached when it is no longer needed, executing the default command if none is set.
/// The service will be reachable from the container via the provided hostname alias.
/// The service dependency will also convey to any files or directories produced by the container.
pub fn with_service_binding(parent: t.Container, alias alias: String, service service: t.Service) -> t.Container {
let field = types.Field(name: "withServiceBinding", args: [#("alias", types.GString(alias)), #("service", types.GDeferred(service.op))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_symlink(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return a snapshot with a symlink
pub fn with_symlink(parent: t.Container, target target: String, link_name link_name: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withSymlink", args: list.append([#("target", types.GString(target)), #("linkName", types.GString(link_name))], encode_with_symlink(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_unix_socket(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
},
case opts.owner {
Some(val) -> Ok(#("owner", types.GString(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container plus a socket forwarded to the given Unix socket path.
pub fn with_unix_socket(parent: t.Container, path path: String, source source: t.Socket, with with_fn: fn(Opts(WithDirectoryFns)) -> Opts(WithDirectoryFns)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withUnixSocket", args: list.append([#("path", types.GString(path)), #("source", types.GDeferred(source.op))], encode_with_unix_socket(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container with a different command user.
pub fn with_user(parent: t.Container, name name: String) -> t.Container {
let field = types.Field(name: "withUser", args: [#("name", types.GString(name))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_with_workdir(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Change the container's working directory. Like WORKDIR in Dockerfile.
pub fn with_workdir(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withWorkdir", args: list.append([#("path", types.GString(path))], encode_with_workdir(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container minus the given OCI annotation.
pub fn without_annotation(parent: t.Container, name name: String) -> t.Container {
let field = types.Field(name: "withoutAnnotation", args: [#("name", types.GString(name))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Remove the container's default arguments.
pub fn without_default_args(parent: t.Container) -> t.Container {
let field = types.Field(name: "withoutDefaultArgs", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_directory(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return a new container snapshot, with a directory removed from its filesystem
pub fn without_directory(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutDirectory", args: list.append([#("path", types.GString(path))], encode_without_directory(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_entrypoint(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.keep_default_args {
Some(val) -> Ok(#("keepDefaultArgs", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Reset the container's OCI entrypoint.
pub fn without_entrypoint(parent: t.Container, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutEntrypoint", args: encode_without_entrypoint(opts), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container minus the given environment variable.
pub fn without_env_variable(parent: t.Container, name name: String) -> t.Container {
let field = types.Field(name: "withoutEnvVariable", args: [#("name", types.GString(name))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_exposed_port(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.protocol {
Some(val) -> Ok(#("protocol", types.GString(t.network_protocol_to_json(val))))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Unexpose a previously exposed port.
pub fn without_exposed_port(parent: t.Container, port port: Int, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutExposedPort", args: list.append([#("port", types.GInt(port))], encode_without_exposed_port(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_file(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container with the file at the given path removed.
pub fn without_file(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutFile", args: list.append([#("path", types.GString(path))], encode_without_file(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_files(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Return a new container spanshot with specified files removed
pub fn without_files(parent: t.Container, paths paths: List(String), with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutFiles", args: list.append([#("paths", types.GList(list.map(paths, fn(x) { types.GString(x) })))], encode_without_files(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container minus the given environment label.
pub fn without_label(parent: t.Container, name name: String) -> t.Container {
let field = types.Field(name: "withoutLabel", args: [#("name", types.GString(name))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_mount(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container after unmounting everything at the given path.
pub fn without_mount(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutMount", args: list.append([#("path", types.GString(path))], encode_without_mount(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container without the registry authentication of a given address.
pub fn without_registry_auth(parent: t.Container, address address: String) -> t.Container {
let field = types.Field(name: "withoutRegistryAuth", args: [#("address", types.GString(address))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container minus the given environment variable containing the secret.
pub fn without_secret_variable(parent: t.Container, name name: String) -> t.Container {
let field = types.Field(name: "withoutSecretVariable", args: [#("name", types.GString(name))], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
fn encode_without_unix_socket(opts: Opts(tag_)) -> List(#(String, types.Value)) {
list.filter_map([
case opts.expand {
Some(val) -> Ok(#("expand", types.GBool(val)))
None -> Error(Nil)
}
], fn(x) { x })
}
/// Retrieves this container with a previously added Unix socket removed.
pub fn without_unix_socket(parent: t.Container, path path: String, with with_fn: fn(Opts(a)) -> Opts(a)) -> t.Container {
let opts = with_fn(defaults())
let field = types.Field(name: "withoutUnixSocket", args: list.append([#("path", types.GString(path))], encode_without_unix_socket(opts)), subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves this container with an unset command user.
/// Should default to root.
pub fn without_user(parent: t.Container) -> t.Container {
let field = types.Field(name: "withoutUser", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Unset the container's working directory.
/// Should default to "/".
pub fn without_workdir(parent: t.Container) -> t.Container {
let field = types.Field(name: "withoutWorkdir", args: [], subfields: [])
let new_op = {
use q <- types.bind(parent.op)
types.Pure(list.append(q, [field]))
}
t.Container(op: new_op)
}
/// Retrieves the working directory for all commands.
pub fn workdir(parent: t.Container, client client: Client, then handler: fn(Try(String)) -> a) -> a {
let field = types.Field(name: "workdir", args: [], subfields: [])
let op = {
use q <- types.bind(parent.op)
let full_query = list.append(q, [field])
types.Fetch(
fields: full_query,
decoder: decode.dynamic,
next: fn(dyn) {
let path = types.make_path(full_query)
case decode.run(dyn, decode.at(path, decode.string)) {
Ok(val) -> types.Pure(Ok(val))
Error(_) -> types.Pure(Error(types.DecodingError("workdir")))
}
}
)
}
handler(interpreter.run(op, client))
}