diff --git a/Dockerfile b/Dockerfile index 4af06ac..c198394 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,30 @@ # specific language governing permissions and limitations # under the License. -FROM python:3.8-slim-bookworm +# Builder stage - build the wheel +FROM ghcr.io/astral-sh/uv:debian AS builder + +# Install build dependencies +RUN apt-get update --assume-yes && \ + apt-get install -o 'Dpkg::Options::=--force-confnew' -y --force-yes -q \ + gcc \ + clang \ + build-essential \ + make \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /build + +# Copy source code +COPY . /build + +# Build the wheel using uv +RUN uv build --wheel + +# Runtime stage - install and run the package +FROM python:3.10-slim-bookworm AS runtime + # So that STDOUT/STDERR is printed ENV PYTHONUNBUFFERED="1" ARG UV_VERSION=0.8.3 @@ -29,24 +52,22 @@ RUN groupadd --gid 8192 otava && \ useradd --uid 8192 --shell /bin/false --create-home --no-log-init --gid otava otava && \ chown otava:otava ${OTAVA_HOME} -# First let's just get things updated. -# Install System dependencies + +# Install build dependencies needed for native extensions RUN apt-get update --assume-yes && \ apt-get install -o 'Dpkg::Options::=--force-confnew' -y --force-yes -q \ - git \ - openssh-client \ gcc \ - clang \ build-essential \ - make \ && rm -rf /var/lib/apt/lists/* -# Copy the rest of the program over -COPY --chown=otava:otava . ${OTAVA_HOME} +# Copy the wheel from builder stage +COPY --from=builder /build/dist/*.whl /tmp/ + +# Install the wheel using uv +RUN pip install /tmp/apache_otava-*.whl && rm /tmp/apache_otava-*.whl -ENV PATH="${OTAVA_HOME}/bin:$PATH" +# Switch to otava user +USER otava -RUN --mount=from=ghcr.io/astral-sh/uv,source=/uv,target=/bin/uv --mount=type=ssh \ - uv pip install --system -e ".[dev]" && \ - mkdir -p bin && \ - ln -s ../venv/bin/otava ${OTAVA_HOME}/bin +# The otava command should now be available in PATH via the installed package +ENTRYPOINT ["otava"] diff --git a/docs/CSV.md b/docs/CSV.md index 30305dc..8eb65b7 100644 --- a/docs/CSV.md +++ b/docs/CSV.md @@ -40,7 +40,7 @@ tests: ## Example ```bash -docker-compose -f examples/csv/docker-compose.yaml run --build otava bin/otava analyze local.sample +docker-compose -f examples/csv/docker-compose.yaml run --build otava analyze local.sample ``` Expected output: diff --git a/examples/csv/docker-compose.yaml b/examples/csv/docker-compose.yaml index a1e5f36..f3abcd3 100644 --- a/examples/csv/docker-compose.yaml +++ b/examples/csv/docker-compose.yaml @@ -22,6 +22,7 @@ services: dockerfile: Dockerfile container_name: otava environment: - OTAVA_CONFIG: examples/csv/otava.yaml + OTAVA_CONFIG: /config/otava.yaml volumes: - ./data:/data + - ./config:/config diff --git a/examples/csv/otava.yaml b/examples/csv/otava.yaml deleted file mode 100644 index d91f4ea..0000000 --- a/examples/csv/otava.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -tests: - local.sample: - type: csv - file: /data/local_sample.csv - time_column: time - attributes: [commit] - metrics: [metric1, metric2] - csv_options: - delimiter: "," - quotechar: "'" diff --git a/examples/graphite/docker-compose.yaml b/examples/graphite/docker-compose.yaml index a784ea1..06b0ec7 100644 --- a/examples/graphite/docker-compose.yaml +++ b/examples/graphite/docker-compose.yaml @@ -38,7 +38,7 @@ services: ports: - "3000:3000" volumes: - - ./grafana:/etc/grafana/provisioning + - ./grafana:/etc/grafana/provisioning networks: - otava-graphite @@ -65,15 +65,12 @@ services: GRAFANA_ADDRESS: http://grafana:3000/ GRAFANA_USER: admin GRAFANA_PASSWORD: admin - OTAVA_CONFIG: examples/graphite/otava.yaml + OTAVA_CONFIG: /config/otava.yaml networks: - otava-graphite + volumes: + - ./config:/config networks: otava-graphite: driver: bridge - - -# TODO: -# 3. make sure Otava can connect to graphite and query the data -# 4. make sure it annotates the dashboard correctly \ No newline at end of file diff --git a/examples/graphite/otava.yaml b/examples/graphite/otava.yaml deleted file mode 100644 index 09e07f9..0000000 --- a/examples/graphite/otava.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# External systems connectors configuration: -graphite: - url: ${GRAPHITE_ADDRESS} - -grafana: - url: ${GRAFANA_ADDRESS} - user: ${GRAFANA_USER} - password: ${GRAFANA_PASSWORD} - -# Define your tests here: -tests: - my-product.test: - type: graphite - prefix: performance-tests.daily.my-product - tags: [perf-test, daily, my-product] - metrics: - throughput: - suffix: client.throughput - direction: 1 # higher is better - scale: 1 - response_time: - suffix: client.p50 - direction: -1 # lower is better - scale: 1 - cpu_usage: - suffix: server.cpu - direction: -1 # lower is better - scale: 1 - - - diff --git a/examples/postgresql/docker-compose.yaml b/examples/postgresql/docker-compose.yaml index f4829da..151879e 100644 --- a/examples/postgresql/docker-compose.yaml +++ b/examples/postgresql/docker-compose.yaml @@ -14,9 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. - -version: "3.8" - services: postgres: image: postgres:latest @@ -45,10 +42,12 @@ services: POSTGRES_USERNAME: exampleuser POSTGRES_PASSWORD: examplepassword POSTGRES_DATABASE: benchmark_results - OTAVA_CONFIG: examples/postgresql/otava.yaml + OTAVA_CONFIG: /config/otava.yaml BRANCH: trunk networks: - otava-postgres + volumes: + - ./config:/config networks: otava-postgres: diff --git a/examples/postgresql/otava.yaml b/examples/postgresql/otava.yaml deleted file mode 100644 index bb52c15..0000000 --- a/examples/postgresql/otava.yaml +++ /dev/null @@ -1,94 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# External systems connectors configuration: -postgres: - hostname: ${POSTGRES_HOSTNAME} - port: ${POSTGRES_PORT} - username: ${POSTGRES_USERNAME} - password: ${POSTGRES_PASSWORD} - database: ${POSTGRES_DATABASE} - -# Templates define common bits shared between test definitions: -templates: - common: - type: postgres - time_column: commit_ts - attributes: [experiment_id, commit, config_id] - # required for --update-postgres to work - update_statement: | - UPDATE results - SET {metric}_rel_forward_change=%s, - {metric}_rel_backward_change=%s, - {metric}_p_value=%s - WHERE experiment_id = '{experiment_id}' AND config_id = {config_id} - metrics: - process_cumulative_rate_mean: - direction: 1 - scale: 1 - process_cumulative_rate_stderr: - direction: -1 - scale: 1 - process_cumulative_rate_diff: - direction: -1 - scale: 1 - -# Define your tests here: -tests: - aggregate_mem: - inherit: [ common ] # avoids repeating metrics definitions and postgres-related config - query: | - SELECT e.commit, - e.commit_ts, - r.process_cumulative_rate_mean, - r.process_cumulative_rate_stderr, - r.process_cumulative_rate_diff, - r.experiment_id, - r.config_id - FROM results r - INNER JOIN configs c ON r.config_id = c.id - INNER JOIN experiments e ON r.experiment_id = e.id - WHERE e.exclude_from_analysis = false AND - e.branch = '${BRANCH}' AND - e.username = 'ci' AND - c.store = 'MEM' AND - c.cache = true AND - c.benchmark = 'aggregate' AND - c.instance_type = 'ec2i3.large' - ORDER BY e.commit_ts ASC; - - aggregate_time_rocks: - inherit: [ common ] - query: | - SELECT e.commit, - e.commit_ts, - r.process_cumulative_rate_mean, - r.process_cumulative_rate_stderr, - r.process_cumulative_rate_diff, - r.experiment_id, - r.config_id - FROM results r - INNER JOIN configs c ON r.config_id = c.id - INNER JOIN experiments e ON r.experiment_id = e.id - WHERE e.exclude_from_analysis = false AND - e.branch = '${BRANCH}' AND - e.username = 'ci' AND - c.store = 'TIME_ROCKS' AND - c.cache = true AND - c.benchmark = 'aggregate' AND - c.instance_type = 'ec2i3.large' - ORDER BY e.commit_ts ASC; \ No newline at end of file