Add new Client API
Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
This commit is contained in:
190
docs/core-concepts/1203-client.md
Normal file
190
docs/core-concepts/1203-client.md
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
slug: /1203/client
|
||||
displayed_sidebar: europa
|
||||
---
|
||||
|
||||
# Interacting with the client
|
||||
|
||||
`dagger.#Plan` has a `client` field that allows interaction with the local machine where the `dagger` command line client is run. You can:
|
||||
|
||||
- Read and write files and directories;
|
||||
- Use local sockets;
|
||||
- Load environment variables;
|
||||
- Run commands;
|
||||
- Get current platform.
|
||||
|
||||
## Accessing the file system
|
||||
|
||||
You may need to load a local directory as a `dagger.#FS` type in your plan:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
// Path may be absolute, or relative to current working directory
|
||||
client: filesystem: ".": read: {
|
||||
// CUE type defines expected content
|
||||
contents: dagger.#FS
|
||||
exclude: ["node_modules"]
|
||||
}
|
||||
actions: {
|
||||
...
|
||||
copy: docker.Copy & {
|
||||
contents: client.filesystem.".".read.contents
|
||||
}
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It’s also easy to write a file locally:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: filesystem: "config.yaml": write: {
|
||||
contents: yaml.Marshal(actions.pull.output.config)
|
||||
}
|
||||
actions: {
|
||||
pull: docker.#Pull & {
|
||||
source: "alpine"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Using a local socket
|
||||
|
||||
You can use a local socket in an action:
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs defaultValue="unix" groupId="client-env">
|
||||
|
||||
<TabItem value="unix" label="Linux/macOS">
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: filesystem: "/var/run/docker.sock": read: {
|
||||
contents: dagger.#Service
|
||||
}
|
||||
|
||||
actions: {
|
||||
image: alpine.#Build & {
|
||||
packages: "docker-cli": {}
|
||||
}
|
||||
run: docker.#Run & {
|
||||
input: image.output
|
||||
mounts: docker: {
|
||||
dest: "/var/run/docker.sock"
|
||||
contents: client.filesystem."/var/run/docker.sock".read.contents
|
||||
}
|
||||
command: {
|
||||
name: "docker"
|
||||
args: ["info"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="windows" label="Windows">
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: filesystem: "//./pipe/docker_engine": read: {
|
||||
contents: dagger.#Service
|
||||
type: "npipe"
|
||||
}
|
||||
|
||||
actions: {
|
||||
image: alpine.#Build & {
|
||||
packages: "docker-cli": {}
|
||||
}
|
||||
run: docker.#Run & {
|
||||
input: image.output
|
||||
mounts: docker: {
|
||||
dest: "/var/run/docker.sock"
|
||||
contents: client.filesystem."//./pipe/docker_engine".read.contents
|
||||
}
|
||||
command: {
|
||||
name: "docker"
|
||||
args: ["info"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Environment variables
|
||||
|
||||
Environment variables can be read from the local machine as strings or secrets, just specify the type:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: env: {
|
||||
GITLAB_USER: string
|
||||
GITLAB_TOKEN: dagger.#Secret
|
||||
}
|
||||
actions: {
|
||||
pull: docker.#Pull & {
|
||||
source: "registry.gitlab.com/myuser/myrepo"
|
||||
auth: {
|
||||
username: client.env.GITLAB_USR
|
||||
secret: client.env.GITLAB_TOKEN
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Running commands
|
||||
|
||||
Sometimes you need something more advanced that only a local command can give you:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: commands: {
|
||||
os: {
|
||||
name: "uname"
|
||||
args: ["-s"]
|
||||
}
|
||||
arch: {
|
||||
name: "uname"
|
||||
args: ["-m"]
|
||||
}
|
||||
}
|
||||
actions: {
|
||||
build: docker.#Run & {
|
||||
env: {
|
||||
CLIENT_OS: client.commands.os.stdout
|
||||
CLIENT_ARCH: client.commands.arch.stdout
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also capture `stderr` for errors and provide `stdin` for input.
|
||||
|
||||
## Platform
|
||||
|
||||
If you need the current platform though, there’s a more portable way than running `uname` like in the previous example:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: platform: _
|
||||
|
||||
actions: {
|
||||
build: docker.#Run & {
|
||||
env: {
|
||||
CLIENT_OS: client.platform.os
|
||||
CLIENT_ARCH: client.platform.arch
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@@ -1,6 +0,0 @@
|
||||
---
|
||||
slug: /1203/inputs
|
||||
displayed_sidebar: europa
|
||||
---
|
||||
|
||||
# Configuring inputs
|
@@ -4,3 +4,85 @@ displayed_sidebar: europa
|
||||
---
|
||||
|
||||
# How to use secrets
|
||||
|
||||
Most operations in `client` support handling secrets (see [Interacting with the client](./1203-client.md)). More specifically, you can:
|
||||
|
||||
- Write a secret to a file;
|
||||
- Read a secret from a file;
|
||||
- Read a secret from an environment variable;
|
||||
- Read a secret from the output of a command;
|
||||
- Use a secret as the input of a command.
|
||||
|
||||
## Environmnet
|
||||
|
||||
The simplest use case is reading from an environment variable:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
client: env: GITHUB_TOKEN: dagger.#Secret
|
||||
}
|
||||
```
|
||||
|
||||
## File
|
||||
|
||||
You may need to trim the whitespace, especially when reading from a file:
|
||||
|
||||
```cue
|
||||
dagger.#Plan & {
|
||||
// Path may be absolute, or relative to current working directory
|
||||
client: filesystem: ".registry": read: {
|
||||
// CUE type defines expected content
|
||||
contents: dagger.#Secret
|
||||
}
|
||||
actions: {
|
||||
registry: dagger.#TrimSecret & {
|
||||
input: client.filesystem.".registry".read.contents
|
||||
}
|
||||
pull: docker.#Pull & {
|
||||
source: "myprivate/image"
|
||||
auth: {
|
||||
username: "_token_"
|
||||
secret: registry.output
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SOPS
|
||||
|
||||
There’s many ways to store encrypted secrets in your git repository. If you use [SOPS](https://github.com/mozilla/sops), here's a simple example where you can access keys from an encrypted yaml file:
|
||||
|
||||
```yaml title="secrets.yaml"
|
||||
myToken: ENC[AES256_GCM,data:AlUz7g==,iv:lq3mHi4GDLfAssqhPcuUIHMm5eVzJ/EpM+q7RHGCROU=,tag:dzbT5dEGhMnHbiRTu4bHdg==,type:str]
|
||||
sops:
|
||||
...
|
||||
```
|
||||
|
||||
```cue title="main.cue"
|
||||
dagger.#Plan & {
|
||||
client: commands: sops: {
|
||||
name: "sops"
|
||||
args: ["-d", "./secrets.yaml"]
|
||||
stdout: dagger.#Secret
|
||||
}
|
||||
|
||||
actions: {
|
||||
// Makes the yaml keys easily accessible
|
||||
secrets: dagger.#DecodeSecret & {
|
||||
input: client.commands.sops.stdout
|
||||
format: "yaml"
|
||||
}
|
||||
|
||||
run: docker.#Run & {
|
||||
mounts: secret: {
|
||||
dest: "/run/secrets/token"
|
||||
contents: secrets.output.myToken
|
||||
}
|
||||
// Do something with `/run/secrets/token`
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
Reference in New Issue
Block a user