Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src(buildpack): add python #60

Merged
merged 5 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ GO_BUILDER_REPO := quay.io/boson/faas-go-builder
QUARKUS_JVM_BUILDER_REPO := quay.io/boson/faas-quarkus-jvm-builder
QUARKUS_NATIVE_BUILDER_REPO := quay.io/boson/faas-quarkus-native-builder
SPRINGBOOT_BUILDER_REPO := quay.io/boson/faas-springboot-builder
PYTHON_BUILDER_REPO := quay.io/boson/faas-python-builder

NODEJS_BUILDPACK_REPO := quay.io/boson/faas-nodejs-bp
GO_BUILDPACK_REPO := quay.io/boson/faas-go-bp
QUARKUS_JVM_BUILDPACK_REPO := quay.io/boson/faas-quarkus-jvm-bp
QUARKUS_NATIVE_BUILDPACK_REPO := quay.io/boson/faas-quarkus-native-bp
SPRINGBOOT_BUILDPACK_REPO := quay.io/boson/faas-springboot-bp
PYTHON_BUILDPACK_REPO := quay.io/boson/faas-python-bp


.PHONY: stacks buildpacks builders
Expand All @@ -32,13 +34,15 @@ stacks:
./stacks/build-stack.sh -v $(VERSION_TAG) stacks/quarkus-jvm
./stacks/build-stack.sh -v $(VERSION_TAG) stacks/quarkus-native
./stacks/build-stack.sh -v $(VERSION_TAG) stacks/springboot
./stacks/build-stack.sh -v $(VERSION_TAG) stacks/python

buildpacks:
$(PACK_CMD) package-buildpack $(NODEJS_BUILDPACK_REPO):$(VERSION_TAG) --config ./packages/nodejs/package.toml
$(PACK_CMD) package-buildpack $(GO_BUILDPACK_REPO):$(VERSION_TAG) --config ./packages/go/package.toml
$(PACK_CMD) package-buildpack $(QUARKUS_JVM_BUILDPACK_REPO):$(VERSION_TAG) --config ./packages/quarkus-jvm/package.toml
$(PACK_CMD) package-buildpack $(QUARKUS_NATIVE_BUILDPACK_REPO):$(VERSION_TAG) --config ./packages/quarkus-native/package.toml
$(PACK_CMD) package-buildpack $(SPRINGBOOT_BUILDPACK_REPO):$(VERSION_TAG) --config ./packages/springboot/package.toml
$(PACK_CMD) package-buildpack $(PYTHON_BUILDPACK_REPO):$(VERSION_TAG) --config ./packages/python/package.toml

builders:
TMP_BLDRS=$(shell mktemp -d) && \
Expand All @@ -47,11 +51,13 @@ builders:
sed "s/{{VERSION}}/$(VERSION_TAG)/g" ./builders/go/builder.toml > $$TMP_BLDRS/go.toml && \
sed "s/{{VERSION}}/$(VERSION_TAG)/g" ./builders/quarkus-jvm/builder.toml > $$TMP_BLDRS/quarkus-jvm.toml && \
sed "s/{{VERSION}}/$(VERSION_TAG)/g" ./builders/springboot/builder.toml > $$TMP_BLDRS/springboot.toml && \
sed "s/{{VERSION}}/$(VERSION_TAG)/g" ./builders/python/builder.toml > $$TMP_BLDRS/python.toml && \
$(PACK_CMD) create-builder --pull-policy=never $(NODEJS_BUILDER_REPO):$(VERSION_TAG) --config $$TMP_BLDRS/node.toml && \
$(PACK_CMD) create-builder --pull-policy=never $(GO_BUILDER_REPO):$(VERSION_TAG) --config $$TMP_BLDRS/go.toml && \
$(PACK_CMD) create-builder --pull-policy=never $(QUARKUS_JVM_BUILDER_REPO):$(VERSION_TAG) --config $$TMP_BLDRS/quarkus-jvm.toml && \
$(PACK_CMD) create-builder --pull-policy=never $(QUARKUS_NATIVE_BUILDER_REPO):$(VERSION_TAG) --config $$TMP_BLDRS/quarkus-native.toml && \
$(PACK_CMD) create-builder --pull-policy=never $(SPRINGBOOT_BUILDER_REPO):$(VERSION_TAG) --config $$TMP_BLDRS/springboot.toml -v && \
$(PACK_CMD) create-builder --pull-policy=never $(PYTHON_BUILDER_REPO):$(VERSION_TAG) --config $$TMP_BLDRS/python.toml -v && \
rm -fr $$TMP_BLDRS

publish:
Expand All @@ -63,7 +69,7 @@ publish:
docker push $(BUILD_REPO):$$i-$(VERSION_TAG); \
done

for img in $(QUARKUS_NATIVE_BUILDPACK_REPO) $(QUARKUS_JVM_BUILDPACK_REPO) $(QUARKUS_NATIVE_BUILDER_REPO) $(QUARKUS_JVM_BUILDER_REPO) $(NODEJS_BUILDPACK_REPO) $(GO_BUILDPACK_REPO) $(NODEJS_BUILDER_REPO) $(GO_BUILDER_REPO) $(SPRINGBOOT_BUILDPACK_REPO) $(SPRINGBOOT_BUILDER_REPO); do \
for img in $(QUARKUS_NATIVE_BUILDPACK_REPO) $(QUARKUS_JVM_BUILDPACK_REPO) $(QUARKUS_NATIVE_BUILDER_REPO) $(QUARKUS_JVM_BUILDER_REPO) $(NODEJS_BUILDPACK_REPO) $(GO_BUILDPACK_REPO) $(NODEJS_BUILDER_REPO) $(GO_BUILDER_REPO) $(SPRINGBOOT_BUILDPACK_REPO) $(SPRINGBOOT_BUILDER_REPO) $(PYTHON_BUILDPACK_REPO) $(PYTHON_BUILDER_REPO); do \
docker push $$img:$(VERSION_TAG); \
if [ "$(VERSION_TAG)" != "tip" ]; then \
docker tag $$img:$(VERSION_TAG) $$img:latest; \
Expand Down
16 changes: 16 additions & 0 deletions builders/python/builder.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Buildpacks to include in builder
[[buildpacks]]
id = "dev.boson.python"
image = "quay.io/boson/faas-python-bp:{{VERSION}}"

[[order]]
[[order.group]]
id = "dev.boson.python"

# Stack that will be used by the builder
[stack]
id = "dev.boson.stacks.python"
# This image is used at runtime
run-image = "quay.io/boson/faas-stack-run:python-{{VERSION}}"
# This image is used at build-time
build-image = "quay.io/boson/faas-stack-build:python-{{VERSION}}"
42 changes: 42 additions & 0 deletions buildpacks/python/bin/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -e
set -o pipefail

echo "---> Python Function Buildpack"

bp_dir=$(cd "$(dirname "$0")"/..; pwd)
build_dir=$(pwd)
layers_dir=$1

source "${bp_dir}/lib/build.sh"

app_layer=${layers_dir}/app
mkdir -p "${app_layer}"
cat > "$app_layer.toml" << TOML
launch = true
build = false
cache = false
TOML

# Install function
echo "---> Installing function"
ls -l ${build_dir}
cp -r ${build_dir}/* ${app_layer}

# Install invoker
echo "---> Installing invoker"
ls -l ${bp_dir}/runtime
cp -r ${bp_dir}/runtime ${app_layer}/.invoker

# Install or reuse dependencies
echo "---> Installing or reusing dependencies"
environments_layer="${layers_dir}/environments"
install_or_reuse_deps ${environments_layer}

# TODO: set up production using waitress

cat <<TOML > "${layers_dir}/launch.toml"
[[processes]]
type = "web"
command = "export FLASK_APP=server.py && source $environments_layer/functions/bin/activate && cd $app_layer/.invoker && flask run --host=0.0.0.0 --port=8080"
TOML
8 changes: 8 additions & 0 deletions buildpacks/python/bin/detect
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -eo pipefail

if [[ ! -d __pycache__ ]] ; then
if [[ ! -f func.py ]] ; then
exit 100
fi
fi
9 changes: 9 additions & 0 deletions buildpacks/python/buildpack.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
api = "0.2"

[buildpack]
id = "dev.boson.python"
version = "0.0.1"
name = "Python Function Buildpack"

[[stacks]]
id = "dev.boson.stacks.python"
32 changes: 32 additions & 0 deletions buildpacks/python/lib/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

set -e

install_or_reuse_deps() {
echo "Installing function invoker dependencies"
local layer_dir=$1
local env_dir="${layer_dir}/functions"

touch "${layer_dir}.toml"
mkdir -p ${layer_dir}

echo "Using python version $(python3 --version)"

if [[ ! -d ${env_dir} ]]; then
cd ${layer_dir}
echo "Installing virtualenv"
pip3 install --user virtualenv
echo "Creating function runtime environment"
python3 -m venv functions
echo "Initializing functions environment"
source functions/bin/activate
echo "Installing flask"
pip3 install flask
echo "Installing cloudevents"
pip3 install cloudevents
fi

echo "cache = true" > "${layer_dir}.toml"
echo "build = true" >> "${layer_dir}.toml"
echo "launch = true" >> "${layer_dir}.toml"
}
24 changes: 24 additions & 0 deletions buildpacks/python/runtime/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import sys
import os

from flask import Flask, request
from cloudevents.http import from_http

serverDir = os.path.dirname(__file__)
funcDir = os.path.realpath(os.path.join(serverDir, ".."))
sys.path.append(funcDir)

import func

app = Flask(__name__)

# create an endpoint at localhost:3000

@app.route("/", methods=["POST"])
def handler():
# create a CloudEvent
event = from_http(request.headers, request.get_data())
return func.main(event)

if __name__ == "__main__":
app.run(port=8080)
lance marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 2 additions & 0 deletions packages/python/package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[buildpack]
uri = "../../buildpacks/python"
16 changes: 16 additions & 0 deletions stacks/python/build/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ARG version=tip
FROM quay.io/boson/faas-stack-build:ubi8-${version}

ARG stack_id
ENV CNB_STACK_ID=${stack_id}
LABEL io.buildpacks.stack.id=${stack_id}

# Install Python 3, tar and a python functions virtual environment
USER root
ENV HOME /projects/python-function
COPY ./python.module /etc/dnf/modules.d
RUN dnf install --nodocs -y python3 tar

WORKDIR $HOME
RUN chown cnb:cnb $HOME
USER cnb
5 changes: 5 additions & 0 deletions stacks/python/build/python.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[python]
name=python
stream=3.8
profiles=
state=enabled
17 changes: 17 additions & 0 deletions stacks/python/run/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
ARG version=tip
FROM quay.io/boson/faas-stack-run:ubi8-minimal-${version}

ARG stack_id
ENV CNB_STACK_ID=${stack_id}
LABEL io.buildpacks.stack.id=${stack_id}

USER root
COPY ./python.module /etc/dnf/modules.d
RUN microdnf install --nodocs -y python3 tar

ENV HOME /projects/python-function
WORKDIR $HOME
RUN chown cnb:cnb $HOME
USER cnb

ENV PORT 8080
5 changes: 5 additions & 0 deletions stacks/python/run/python.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[python]
name=python
stream=3.8
profiles=
state=enabled