Skip to content
Snippets Groups Projects
Commit 4917896f authored by Benedikt Wetzel's avatar Benedikt Wetzel
Browse files

Merge upstream repository

parents 60064b67 d4ead8a5
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!97Restructuring to create the PatcherDefinition inside the TheodoliteExecutor,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus
This commit is part of merge request !97. Comments created here will be created in the context of that merge request.
Showing
with 248 additions and 21 deletions
......@@ -28,7 +28,7 @@ stages:
paths:
- .gradle
before_script:
- cd benchmarks
- cd theodolite-benchmarks
- export GRADLE_USER_HOME=`pwd`/.gradle
build-benchmarks:
......@@ -37,8 +37,8 @@ build-benchmarks:
script: ./gradlew --build-cache assemble
artifacts:
paths:
- "benchmarks/build/libs/*.jar"
- "benchmarks/*/build/distributions/*.tar"
- "theodolite-benchmarks/build/libs/*.jar"
- "theodolite-benchmarks/*/build/distributions/*.tar"
expire_in: 1 day
test-benchmarks:
......@@ -50,7 +50,7 @@ test-benchmarks:
artifacts:
reports:
junit:
- "benchmarks/**/build/test-results/test/TEST-*.xml"
- "theodolite-benchmarks/**/build/test-results/test/TEST-*.xml"
checkstyle-benchmarks:
stage: check
......@@ -61,7 +61,7 @@ checkstyle-benchmarks:
script: ./gradlew checkstyle --continue
artifacts:
paths:
- "benchmarks/*/build/reports/checkstyle/main.html"
- "theodolite-benchmarks/*/build/reports/checkstyle/main.html"
when: on_failure
expire_in: 1 day
......@@ -74,7 +74,7 @@ pmd-benchmarks:
script: ./gradlew pmd --continue
artifacts:
paths:
- "benchmarks/*/build/reports/pmd/*.html"
- "theodolite-benchmarks/*/build/reports/pmd/*.html"
when: on_failure
expire_in: 1 day
......@@ -87,7 +87,7 @@ spotbugs-benchmarks:
script: ./gradlew spotbugs --continue
artifacts:
paths:
- "benchmarks/*/build/reports/spotbugs/*.html"
- "theodolite-benchmarks/*/build/reports/spotbugs/*.html"
when: on_failure
expire_in: 1 day
......@@ -114,10 +114,10 @@ spotbugs-benchmarks:
- if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $IMAGE_NAME && $JAVA_PROJECT_NAME && $CI_COMMIT_TAG"
when: always
- changes:
- benchmarks/*
- benchmarks/$JAVA_PROJECT_NAME/**/*
- benchmarks/application-kafkastreams-commons/**/*
- benchmarks/workload-generator-commons/**/*
- theodolite-benchmarks/*
- theodolite-benchmarks/$JAVA_PROJECT_NAME/**/*
- theodolite-benchmarks/application-kafkastreams-commons/**/*
- theodolite-benchmarks/workload-generator-commons/**/*
if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $IMAGE_NAME && $JAVA_PROJECT_NAME"
when: always
- if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $IMAGE_NAME && $JAVA_PROJECT_NAME"
......@@ -176,7 +176,7 @@ deploy-uc4-load-generator:
# Theodolite Framework
.theodolite:
image: openjdk:11-jdk
image: ghcr.io/graalvm/graalvm-ce:java11-21.0.0.2
tags:
- exec-docker
variables:
......@@ -189,23 +189,33 @@ deploy-uc4-load-generator:
- cd theodolite-quarkus
- export GRADLE_USER_HOME=`pwd`/.gradle
build-theodolite:
build-theodolite-jvm:
stage: build
extends: .theodolite
# script: ./gradlew --build-cache assemble -Dquarkus.package.type=native
script: ./gradlew --build-cache assemble
artifacts:
paths:
- "theodolite-quarkus/build/lib/*"
- "theodolite-quarkus/build/*-runner.jar"
# - "theodolite-quarkus/build/*-runner" # For native image
expire_in: 1 day
build-theodolite-native:
stage: build
extends: .theodolite
script:
- gu install native-image # TODO move to image
- ./gradlew --build-cache assemble -Dquarkus.package.type=native
artifacts:
paths:
- "theodolite-quarkus/build/*-runner"
expire_in: 1 day
test-theodolite:
stage: test
extends: .theodolite
needs:
- build-theodolite
- build-theodolite-jvm
- build-theodolite-native
script: ./gradlew test --stacktrace
# Disabled for now
......@@ -213,7 +223,7 @@ test-theodolite:
stage: check
extends: .theodolite
needs:
- build-theodolite
- build-theodolite-jvm
- test-theodolite
script: ./gradlew ktlintCheck --continue
......@@ -222,7 +232,7 @@ test-theodolite:
stage: check
extends: .theodolite
needs:
- build-theodolite
- build-theodolite-jvm
- test-theodolite
script: ./gradlew detekt --continue
......@@ -232,12 +242,12 @@ deploy-theodolite:
- .theodolite
- .dind
needs:
- build-theodolite
- build-theodolite-native
- test-theodolite
script:
- DOCKER_TAG_NAME=$(echo $CI_COMMIT_REF_SLUG- | sed 's/^master-$//')
#- docker build -f src/main/docker/Dockerfile.native -t theodolite .
- docker build -f src/main/docker/Dockerfile.jvm -t theodolite .
- docker build -f src/main/docker/Dockerfile.native -t theodolite .
#- docker build -f src/main/docker/Dockerfile.jvm -t theodolite .
- "[ ! $CI_COMMIT_TAG ] && docker tag theodolite $CR_HOST/$CR_ORG/theodolite:${DOCKER_TAG_NAME}latest"
- "[ ! $CI_COMMIT_TAG ] && docker tag theodolite $CR_HOST/$CR_ORG/theodolite:$DOCKER_TAG_NAME$CI_COMMIT_SHORT_SHA"
- "[ $CI_COMMIT_TAG ] && docker tag theodolite $CR_HOST/$CR_ORG/theodolite:$CI_COMMIT_TAG"
......@@ -254,3 +264,30 @@ deploy-theodolite:
- if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW"
when: manual
allow_failure: true
# Theodolite Random Scheduler
deploy-random-scheduler:
stage: deploy
extends:
- .dind
script:
- DOCKER_TAG_NAME=$(echo $CI_COMMIT_REF_SLUG- | sed 's/^master-$//')
- docker build --pull -t theodolite-random-scheduler execution/infrastructure/random-scheduler
- "[ ! $CI_COMMIT_TAG ] && docker tag theodolite-random-scheduler $CR_HOST/$CR_ORG/theodolite-random-scheduler:${DOCKER_TAG_NAME}latest"
- "[ $CI_COMMIT_TAG ] && docker tag theodolite-random-scheduler $CR_HOST/$CR_ORG/theodolite-random-scheduler:$CI_COMMIT_TAG"
- echo $CR_PW | docker login $CR_HOST -u $CR_USER --password-stdin
- docker push $CR_HOST/$CR_ORG/theodolite-random-scheduler
- docker logout
rules:
- if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $CI_COMMIT_TAG"
when: always
- changes:
- execution/infrastructure/random-scheduler/**/*
if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW"
when: always
- if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW"
when: manual
allow_failure: true
\ No newline at end of file
FROM alpine:3.12
RUN apk update && apk add bash curl jq
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \
&& chmod +x ./kubectl \
&& mv ./kubectl /usr/local/bin/kubectl
ADD schedule.sh /bin/schedule
CMD /bin/schedule
# Theodolite Random Scheduler
This directory contains the Theodolite Random Scheduler that schedules pods on random nodes.
## Build and Push
Run the following commands
- `docker build -t theodolite-random-scheduler .`
- `docker tag theodolite-random-scheduler <user>/theodolite-random-scheduler`
- `docker push <user>/theodolite-random-scheduler`
## Deployment
Deploy the `deployment.yaml` file into Kubernetes. Note, that the `TARGET_NAMESPACE` environment variable specifies the operating namespace of the random scheduler.
apiVersion: apps/v1
kind: Deployment
metadata:
name: random-scheduler
labels:
app: random-scheduler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: random-scheduler
template:
metadata:
labels:
app: random-scheduler
spec:
serviceAccount: random-scheduler
containers:
- name: random-scheduler
image: ghcr.io/cau-se/theodolite-random-scheduler:latest
imagePullPolicy: Always
env:
- name: TARGET_NAMESPACE
value: default
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: kube-system
name: random-scheduler
labels:
app: random-scheduler
component: random-scheduler
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: random-scheduler
subjects:
- kind: ServiceAccount
name: random-scheduler
namespace: kube-system
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: system:kube-scheduler
\ No newline at end of file
#!/bin/bash
# use kubectl in proxy mode in order to allow curl requesting the k8's api server
kubectl proxy --port 8080 &
echo "Target Namespace: $TARGET_NAMESPACE"
while true;
do
for PODNAME in $(kubectl get pods -n $TARGET_NAMESPACE -o json | jq '.items[] | select(.spec.schedulerName == "random-scheduler") | select(.spec.nodeName == null) | .metadata.name' | tr -d '"');
do
NODES=($(kubectl get nodes -o json | jq '.items[].metadata.name' | tr -d '"'))
NUMNODES=${#NODES[@]}
CHOSEN=${NODES[$[$RANDOM % $NUMNODES]]}
curl --header "Content-Type:application/json" --request POST --data '{"apiVersion":"v1", "kind": "Binding", "metadata": {"name": "'$PODNAME'"}, "target": {"apiVersion": "v1", "kind": "Node", "name": "'$CHOSEN'"}}' localhost:8080/api/v1/namespaces/$TARGET_NAMESPACE/pods/$PODNAME/binding/
echo "Assigned $PODNAME to $CHOSEN"
done
sleep 1
done
\ No newline at end of file
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY ./app /app
\ No newline at end of file
# Lag Trend SLO Evaluator
## Execution
For development:
```sh
uvicorn main:app --reload
```
Build the docker image:
```sh
docker build . -t theodolite-evaluator
```
Run the Docker image:
```sh
docker run -p 80:80 theodolite-evaluator
```
## Configuration
You can set the `HOST` and the `PORT` (and a lot of more parameters) via environment variables. Default is `0.0.0.0:80`.
For more information see [here](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#advanced-usage).
from fastapi import FastAPI,Request
import trend_slope_computer as trend_slope_computer
import logging
import os
import pandas as pd
import json
import sys
app = FastAPI()
logging.basicConfig(stream=sys.stdout,
format="%(asctime)s %(levelname)s %(name)s: %(message)s")
logger = logging.getLogger("API")
if os.getenv('LOG_LEVEL') == 'INFO':
logger.setLevel(logging.INFO)
elif os.getenv('LOG_LEVEL') == 'WARNING':
logger.setLevel(logging.WARNING)
elif os.getenv('LOG_LEVEL') == 'DEBUG':
logger.setLevel((logging.DEBUG))
def execute(results, threshold, warmup):
d = []
for result in results:
group = result['metric']['group']
for value in result['values']:
d.append({'group': group, 'timestamp': int(
value[0]), 'value': int(value[1]) if value[1] != 'NaN' else 0})
df = pd.DataFrame(d)
logger.info(df)
try:
trend_slope = trend_slope_computer.compute(df, warmup)
except Exception as e:
err_msg = 'Computing trend slope failed'
logger.exception(err_msg)
logger.error('Mark this subexperiment as not successful and continue benchmark')
return False
logger.info("Trend Slope: %s", trend_slope)
return trend_slope < threshold
@app.post("/evaluate-slope",response_model=bool)
async def evaluate_slope(request: Request):
data = json.loads(await request.body())
return execute(data['total_lag'], data['threshold'], data['warmup'])
logger.info("Slope evaluator is online")
\ No newline at end of file
from sklearn.linear_model import LinearRegression
import pandas as pd
import os
def compute(x, warmup_sec):
input = x
input['sec_start'] = input.loc[0:, 'timestamp'] - input.iloc[0]['timestamp']
regress = input.loc[input['sec_start'] >= warmup_sec] # Warm-Up
X = regress.iloc[:, 2].values.reshape(-1, 1) # values converts it into a numpy array
Y = regress.iloc[:, 3].values.reshape(-1, 1) # -1 means that calculate the dimension of rows, but have 1 column
linear_regressor = LinearRegression() # create object for the class
linear_regressor.fit(X, Y) # perform linear regression
Y_pred = linear_regressor.predict(X) # make predictions
trend_slope = linear_regressor.coef_[0][0]
return trend_slope
fastapi==0.55.1
scikit-learn==0.20.3
pandas==1.0.3
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment