Home > Software engineering >  Implement 'Entrypoint' like functionality in Cloud Native Buildpack
Implement 'Entrypoint' like functionality in Cloud Native Buildpack

Time:03-31

I have a multi-process web app. The processes are contributed by different buildpacks. The default process will start the web application. I have a use case in which a given shell script should be executed before the default process invocation.

I have tried the following approach;

  1. Create a custom-buildpack
  2. Create a script that needs to be executed and invoke the web process in it.
  3. Create a new process based on the above shell sciprt by specifying it in launch.toml definition
  4. Make the buildpack launchable

The entrypoint.sh

#!/usr/bin/env bash

# Some fancy stuff.. 

#Invoke the web process  
/cnb/process/web

Create lauch.toml from the build script of custom-buildpack. Make the entrypoint process the default one.

    cat > "$layers_dir/launch.toml" << EOL
    
    [[processes]]
    type = "entrypoint"
    command = "bash"
    args = ["$scriptlayer/bin/entrypoint.sh"]
    default = true
    
    EOL
    
    echo -e '[types]\nlaunch = true' > "$layers_dir/assembly-scripts.toml"

Truncated pack inspect-image output

Processes:
  TYPE                        SHELL        COMMAND          ARGS
  entrypoint (default)        bash         bash        /layers/gw_assembly-scripts/assembly-scripts/bin/entrypoint.sh
  task                                     bash             catalina.sh run
  tomcat                                   bash             catalina.sh run
  web                                      bash             catalina.sh run

Is there any better CNB native approach to achieve this use case?

CodePudding user response:

You have a couple of options here:

  1. The simplest option would be to add a .profile script to the root of your application. It's a bash script, so anything you can write in bash can be done there, however, it's primarily for initializing your app and setting additional env variables.

    This file runs prior to the command in your process type. I looked for documentation on this behavior, but only found it briefly mentioned in the buildpacks spec.

    As an example, if I put .profile in the root of my application and inside that file, I write echo 'Hello World!'. I'll see Hello World! printed before any of my process types execute.

  2. If you want to create a buildpack, you can achieve something similar to the .profile script by having your buildpack include an exec.d binary.

    This is a binary that's part of your launch image and gets run prior to any of your process types. It allows you to take actions to initialize an application and set additional environment variables dynamically before your application starts.

    This mechanism is often used by buildpack authors to provide dynamic behavior at runtime based on changes to environment variables or Kubernetes service bindings. For example, turning on/off features like APM tools, debugging, and metrics.

A few other miscellaneous notes.

  1. Neither of the options above allows you to change the actual process type. The process type that will be executed is selected prior to these options (.profile and exec.d) running and you cannot influence that from within. You can only use them to run things prior to the process type running.

  2. The buildpack spec does not allow for a buildpack to modify the process types for another buildpack. So you cannot create a buildpack that wraps or modifies process types set by another buildpack. That said, a buildpack can override the process types set by another buildpack. Buildpacks that are later in the order group will override earlier buildpacks.

    From the spec: A combined processes list derived from all launch.toml files such that process types from later buildpacks override identical process types from earlier buildpacks.

  3. With buildpacks, the entrypoint is always the launcher. The launcher is a process that runs and implements the application side of the buildpack specification. It runs .profile, exec.d binaries, sets up buildpack provide environment variables and eventually launch the specified process type.

    If you override the entrypoint for a container then the launcher won't run and none of the things it is supposed to do will happen. Sometimes this is desired, like if you're troubleshooting, but usually you want the launcher to be the entrypoint.

  • Related