From dce445d0a9a148c22cc3a305d3004d334e2ce2e4 Mon Sep 17 00:00:00 2001 From: Aidan Delaney Date: Thu, 6 Jun 2024 08:14:41 +0100 Subject: [PATCH] Document exec.d (#720) * Document exec.d Provide documentation and examples of how to use exec.d Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Update content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md Co-authored-by: Natalie Arellano Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Update content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md Co-authored-by: Natalie Arellano Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Update content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md Co-authored-by: Natalie Arellano Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Update content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md Co-authored-by: Natalie Arellano Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Update content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md Co-authored-by: Natalie Arellano Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Use the inherited file descriptor in exec.d examples Use the inherited file descriptor Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney * Update content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md Co-authored-by: Natalie Arellano Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney --------- Signed-off-by: Aidan Delaney Signed-off-by: Aidan Delaney Co-authored-by: Natalie Arellano --- .../how-to/write-buildpacks/use-exec.d.md | 79 ++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md b/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md index afd470e2c..794190660 100644 --- a/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md +++ b/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-exec.d.md @@ -5,6 +5,81 @@ weight=99 -This page is a stub! The CNB project is applying to [Google Season of Docs](https://developers.google.com/season-of-docs/docs/timeline) to receive support for improving our documentation. Please check back soon. +The [buildpacks `exec.d` interface](https://github.com/buildpacks/spec/blob/main/buildpack.md#execd) allows buildpack authors to execute custom scripts or binaries when the application image is started. This interface can be particularly useful for injecting dynamic behavior or environment variables into the runtime environment of an application. -If you are familiar with this content and would like to make a contribution, please feel free to open a PR :) +## Key Points: + + 1. Location and Naming: Scripts are placed in the `/exec.d/` directory within a launch layer and must be executable. They can have any name. + + 2. Script Behavior: + * **Inputs** + * A third open file descriptor (in addition to stdin and stdout). The third open file descriptor is inherited from the calling process. + * **Outputs** + * Valid TOML describing environment variables in the form of key=value pairs. These variables are added to the application's runtime environment. The content should be written to file descriptor 3 (see examples for how to do this). + * Exit Code: The scripts should exit with a status code of `0` to indicate success. A non-zero exit code will indicate an error and prevent the application from launching. + +## Use Cases: +* Dynamic Configuration: Inject configuration values that are determined at runtime. +* Service Bindings: Configure environment variables based on bound services. + +## Implementation Steps: +* Write Scripts: Create executable scripts within the `/exec.d/` directory. +* Set Permissions: Ensure scripts have the appropriate execute permissions (chmod +x). +* Environment Variables: Use scripts to print `key="value"` pairs to the third open file descriptor. + +### Examples + +`exec.d` executables can be written in any language. We provide examples in bash, Go and Python that inject the `EXAMPLE="test"` into the runtime environment. It is important that environment variables are written to the third file descriptor which is inherited by the `exec.d` binary. + +A `bash` example looks as follows: +```bash +#!/bin/bash + +# Use the third file descriptor +FD=&3 + +# Output the environment variable EXAMPLE="test" to the specified file descriptor +echo "EXAMPLE=\"test\"" >&$FD +``` + +And a `Go` example is: +```Go +package main + +import ( + "fmt" + "os" +) + +func main() { + // Open file descriptor 3 for writing + fd3 := os.NewFile(3, "fd3") + if fd3 == nil { + fmt.Println("Failed to open file descriptor 3") + return + } + + // Write the environment variable to file descriptor 3 + _, err := fd3.WriteString(`EXAMPLE="test"\n`) + if err != nil { + fmt.Println("Error writing to file descriptor 3:", err) + } +} +``` +Finally, we provide a short Python example: +```Python +import os +import sys + +def main(): + # Use file descriptor 3 + fd = 3 + + # Write the environment variable to the given file descriptor + os.write(fd, b'EXAMPLE="test"\n') + +if __name__ == "__main__": + main() +``` + +The `exec.d` interface provides a powerful mechanism for dynamically configuring runtime environments in a flexible and programmable manner, enhancing the customization capabilities available to application programmers using buildpacks. \ No newline at end of file