From e540bd27161785da8eb21d394e09d4ea57e2d000 Mon Sep 17 00:00:00 2001 From: Tom Chauveau Date: Fri, 11 Jun 2021 09:50:27 +0200 Subject: [PATCH] Replace docker.#Client with docker.#Command definition It's a simple wrapper that will expose an interface to run any docker or docker-compose commands You can configure : - ssh - environments - mount volumes - command to execute - package to install Signed-off-by: Tom Chauveau --- stdlib/docker/client.cue | 16 ---- stdlib/docker/command.cue | 178 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 16 deletions(-) delete mode 100644 stdlib/docker/client.cue create mode 100644 stdlib/docker/command.cue diff --git a/stdlib/docker/client.cue b/stdlib/docker/client.cue deleted file mode 100644 index 1810efd4..00000000 --- a/stdlib/docker/client.cue +++ /dev/null @@ -1,16 +0,0 @@ -package docker - -import ( - "dagger.io/alpine" -) - -// A container image to run the Docker client -#Client: alpine.#Image & { - package: { - bash: true - jq: true - curl: true - "openssh-client": true - "docker-cli": true - } -} diff --git a/stdlib/docker/command.cue b/stdlib/docker/command.cue new file mode 100644 index 00000000..00e6e11d --- /dev/null +++ b/stdlib/docker/command.cue @@ -0,0 +1,178 @@ +package docker + +import ( + "strconv" + + "dagger.io/alpine" + "dagger.io/dagger" + "dagger.io/dagger/op" +) + +// A container image that can run any docker command +#Command: { + ssh?: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + // Command to execute + command: string @dagger(input) + + // Environment variables shared by all commands + env: { + [string]: string @dagger(input) + } + + // Mount content from other artifacts + mount: { + [string]: { + from: dagger.#Artifact + } | { + secret: dagger.#Secret + } @dagger(input) + } + + // Mount persistent cache directories + cache: [string]: true @dagger(input) + + // Mount temporary directories + tmpfs: [string]: true @dagger(input) + + // Additional packages to install + package: [string]: true | false | string @dagger(input) + + // Setup docker client and then execute the user command + #code: #""" + # Setup ssh + if [ -n "$DOCKER_HOSTNAME" ]; then + export DOCKER_HOST="ssh://$DOCKER_USERNAME@$DOCKER_HOSTNAME:$DOCKER_PORT" + + # Start ssh-agent + eval $(ssh-agent) > /dev/null + + # Add key + if [ -f "/key" ]; then + message="$(ssh-keygen -y -f /key < /dev/null 2>&1)" || { + >&2 echo "$message" + exit 1 + } + + # Save key + ssh-add /key > /dev/null + if [ "$?" != 0 ]; then + exit 1 + fi + fi + + if [[ ! -z $FINGERPRINT ]]; then + mkdir -p "$HOME"/.ssh + + # Add user's fingerprint to known hosts + echo "$FINGERPRINT" >> "$HOME"/.ssh/known_hosts + else + # Add host to known hosts + ssh -i /key -o "UserKnownHostsFile "$HOME"/.ssh/known_hosts" -o "StrictHostKeyChecking accept-new" -p "$DOCKER_PORT" "$DOCKER_USERNAME"@"$DOCKER_HOSTNAME" /bin/true > /dev/null 2>&1 + fi + fi + + # Execute entrypoint + /bin/bash /entrypoint.sh + """# + + #up: [ + op.#Load & { + from: alpine.#Image & { + package: { + bash: true + "openssh-client": true + "docker-cli": true + } + } + }, + + if ssh.keyPassphrase != _|_ { + op.#WriteFile & { + content: #""" + #!/bin/bash + cat /keyPassphrase + """# + dest: "/get_keyPassphrase" + mode: 0o500 + } + }, + + // Write wrapper + op.#WriteFile & { + content: #code + dest: "/setup.sh" + }, + + // Write entrypoint + op.#WriteFile & { + content: command + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/setup.sh", + ] + "env": { + env + + if ssh != _|_ { + DOCKER_HOSTNAME: ssh.host + DOCKER_USERNAME: ssh.user + DOCKER_PORT: strconv.FormatInt(ssh.port, 10) + if ssh.keyPassphrase != _|_ { + SSH_ASKPASS: "/get_keyPassphrase" + DISPLAY: "1" + } + if ssh.fingerprint != _|_ { + FINGERPRINT: ssh.fingerprint + } + } + } + "mount": { + if ssh != _|_ { + if ssh.key != _|_ { + "/key": secret: ssh.key + } + if ssh.keyPassphrase != _|_ { + "/keyPassphrase": secret: ssh.keyPassphrase + } + } + for dest, o in mount { + "\(dest)": o + } + for dest, _ in cache { + "\(dest)": "cache" + } + for dest, _ in tmpfs { + "\(dest)": "tmpfs" + } + } + }, + ] +} \ No newline at end of file