package docker import ( "strconv" "alpha.dagger.io/alpine" "alpha.dagger.io/dagger" "alpha.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) } // Connect via DOCKER_HOST, supports tcp:// // TODO: Consider refactoring to support ssh:// & even file:// host?: string @dagger(input) // Command to execute command: string // Environment variables shared by all commands env: { [string]: string } // Mount content from other artifacts mount: [string]: from: dagger.#Artifact // Mount secrets secret: [string]: dagger.#Secret // Mount persistent cache directories cache: { [string]: true } // Mount temporary directories tmpfs: { [string]: true } // Mount docker socket socket?: dagger.#Stream @dagger(input) // Additional packages to install package: { [string]: true | false | string } // Image registries registries: [...{ target?: string username: string secret: dagger.#Secret }] // Copy contents from other artifacts copy: [string]: from: dagger.#Artifact // Write file in the container files: [string]: string // 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" true > /dev/null 2>&1 fi fi # Execute entrypoint /bin/bash /entrypoint.sh """# #up: [ op.#Load & { from: alpine.#Image & { "package": { package bash: true "openssh-client": true "docker-cli": true } } }, for registry in registries { op.#Exec & { args: ["/bin/bash", "-c", #""" echo "$TARGER_HOST" | docker login --username "$DOCKER_USERNAME" --password-stdin "$(cat /password)" """#, ] env: { TARGET_HOST: registry.target DOCKER_USERNAME: registry.username } mount: "/password": secret: registry.secret } }, for dest, content in files { op.#WriteFile & { "content": content "dest": dest } }, for dest, src in copy { op.#Copy & { from: src.from "dest": dest } }, 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/bash", "--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 } } if host != _|_ && ssh == _|_ { DOCKER_HOST: host } } "mount": { if ssh != _|_ { if ssh.key != _|_ { "/key": secret: ssh.key } if ssh.keyPassphrase != _|_ { "/keyPassphrase": secret: ssh.keyPassphrase } } if socket != _|_ { "/var/run/docker.sock": stream: socket } for dest, o in mount { "\(dest)": o } for dest, s in secret { "\(dest)": secret: s } for dest, _ in cache { "\(dest)": "cache" } for dest, _ in tmpfs { "\(dest)": "tmpfs" } } }, ] }