Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,26 @@ jobs:
with:
lua-version: ${{ matrix.version }}
rockspec: ${{ matrix.package }}


hello-haproxy:
runs-on: ubuntu-latest
env:
LD_SDK_KEY: "foo"
steps:
- uses: actions/checkout@v4
- name: Build hello-haproxy image
run: |
docker build -t launchdarkly:hello-haproxy -f ./examples/hello-haproxy/Dockerfile .
- name: Run hello-haproxy container in background
# The sleep is to give haproxy some time to start-up.
run: |
docker run -dit --rm --name hello-haproxy -p 8123:8123 --env LD_SDK_KEY="$LD_SDK_KEY" launchdarkly:hello-haproxy
sleep 5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably fine, but if it ends up being a problem you could instead just use curl with something like --retry 10 --retry-connrefused --retry-delay 1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's probably more robust.

- name: Evaluate feature flag
run: |
curl -s -v http://localhost:8123 | tee response.txt
grep -F "Feature flag is false for this user" response.txt || (echo "Expected false evaluation!" && exit 1)
- name: Stop hello-haproxy container
run: |
docker stop hello-haproxy
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ Getting started
Refer to the [SDK documentation](https://docs.launchdarkly.com/sdk/server-side/lua#getting-started) for instructions on
getting started with using the SDK.

Runnable examples in this repo are available:

| Example | Purpose |
|-------------------------------------------------|-----------------------------------------------------------------------------------------------|
| [hello-lua-server](./examples/hello-lua-server) | Demonstrates basic example of Lua SDK usage from the command line. |
| [hello-haproxy](./examples/hello-haproxy) | Demonstrates usage of the Lua SDK as a [HAproxy](https://www.haproxy.org/) module via Docker. |


There are two paths to installing the SDK. In both cases, you must first install the native
[LaunchDarkly C++ Server-side SDK](https://github.com/launchdarkly/cpp-sdks).

Expand Down
41 changes: 41 additions & 0 deletions examples/hello-haproxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
curl luarocks lua5.3 lua5.3-dev \
haproxy apt-transport-https ca-certificates \
software-properties-common

RUN add-apt-repository ppa:mhier/libboost-latest && \
apt-get update && \
apt-get install -y boost1.81

RUN curl https://github.com/launchdarkly/cpp-sdks/releases/download/launchdarkly-cpp-server-v3.3.1/linux-gcc-x64-dynamic.zip -L -o /tmp/sdk.zip && \
mkdir ./cpp-sdk && \
unzip /tmp/sdk.zip -d ./cpp-sdk && \
rm /tmp/sdk.zip

COPY . .

RUN luarocks make launchdarkly-server-sdk-2.0.2-0.rockspec LD_DIR=./cpp-sdk/build-dynamic/release

COPY ./examples/hello-haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg
COPY ./examples/hello-haproxy/service.lua /service.lua

# The strategy for this Docker example is to download the C++ SDK release artifacts and use those instead of compiling
# from source. This is for example/CI purposes only; generally it's better to build from source to ensure all libraries
# are compatible.
#
# Since we require a newer version of boost than is available in Ubuntu 22.04, we grab it from a PPA (mhier/libboost-latest).
#
# The SDK dynamic libs expect the boost libs to follow a specific naming convention, which isn't what
# the libraries from the PPA follow ('-mt' suffix is added to indicate the libraries are built with multithreading support enabled.)
#
# It's not 100% clear if these libraries are multithread enabled (build logs in the PPA seem to indicate it),
# but even so, the C++ SDK is single-threaded.
#
# To workaround, add symlinks with the expected names.
RUN cd /usr/lib/x86_64-linux-gnu && \
ln -s libboost_json.so.1.81.0 libboost_json-mt-x64.so.1.81.0 && \
ln -s libboost_url.so.1.81.0 libboost_url-mt-x64.so.1.81.0

CMD haproxy -d -f /etc/haproxy/haproxy.cfg
16 changes: 16 additions & 0 deletions examples/hello-haproxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# LaunchDarkly Lua server-side SDK HAProxy example

We've built a minimal dockerized example of using the Lua SDK with [HAProxy](https://www.haproxy.org/). For more comprehensive instructions, you can visit the [Using the Lua SDK with HAProxy guide](https://docs.launchdarkly.com/guides/sdk/haproxy) or the [Lua reference guide](https://docs.launchdarkly.com/sdk/server-side/lua).

## Build instructions

1. On the command line from the root of the repo, build the image from this directory with `docker build -t hello-haproxy -f ./examples/hello-haproxy/Dockerfile .`.
2. Run the demo with:
```
docker run -it --rm --name hello-haproxy -p 8123:8123 --env LD_SDK_KEY="your-sdk-key" --env LD_FLAG_KEY="my-boolean-flag" hello-haproxy```
```
3. **Note:** the SDK key and flag key are passed with environment variables into the container. The `LD_FLAG_KEY` should be a boolean-type flag in your environment.
4. Open `localhost:8123` in your browser. Toggle the flag on to see a change in the page (refresh the page.)

You should receive the message:
> Feature flag is <true/false> for this user.
15 changes: 15 additions & 0 deletions examples/hello-haproxy/haproxy.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
global
lua-load /service.lua

defaults
mode http
timeout connect 10s
timeout client 30s
timeout server 30s

frontend proxy
bind 0.0.0.0:8123
use_backend default_backend

backend default_backend
http-request use-service lua.launchdarkly
50 changes: 50 additions & 0 deletions examples/hello-haproxy/service.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
print "loaded"

local os = require("os")
local ld = require("launchdarkly_server_sdk")


-- Set YOUR_SDK_KEY to your LaunchDarkly SDK key.
local YOUR_SDK_KEY = ""

-- Set YOUR_FEATURE_KEY to the feature flag key you want to evaluate.
local YOUR_FEATURE_KEY = "my-boolean-flag"


-- Allows the LaunchDarkly SDK key to be specified as an environment variable (LD_SDK_KEY)
-- or locally in this example code (YOUR_SDK_KEY).
function get_key_from_env_or(name, existing_key)
if existing_key ~= nil and existing_key ~= "" then
core.Debug("Using LaunchDarkly SDK key from service.lua file")
return existing_key
end

local env_key = os.getenv("LD_" .. name)
if env_key ~= nil and env_key ~= "" then
core.Debug("Using LaunchDarkly SDK key from LD_" .. name .. " environment variable")
return env_key
end

core.log(core.crit, "LaunchDarkly SDK key not provided! SDK won't be initialized.")
return ""
end

local config = {}
local client = ld.clientInit(get_key_from_env_or("SDK_KEY", YOUR_SDK_KEY), 1000, config)

core.register_service("launchdarkly", "http", function(applet)
applet:start_response()

local user = ld.makeContext({
user = {
key = "example-user-key",
name = "Sandy"
}
})

if client:boolVariation(user, get_key_from_env_or("FLAG_KEY", YOUR_FEATURE_KEY), false) then
applet:send("<p>Feature flag is true for this user</p>")
else
applet:send("<p>Feature flag is false for this user</p>")
end
end)