influxdb/.circleci/config.yml

444 lines
16 KiB
YAML
Raw Normal View History

# CI Overview
# -----------
#
# Each night:
#
# A build image is created (ci_image) from `docker/Dockerfile.ci` and is
# pushed to `quay.io/influxdb/rust:ci`. This build image is then used to run
# the CI tasks for the day.
#
# Every commit:
#
# The CI for every PR and merge to main runs tests, fmt, lints and compiles debug binaries
#
# On main if all these checks pass it will then additionally compile in "release" mode and
# publish a docker image to quay.io/influxdb/iox:$COMMIT_SHA
#
# Manual CI Image:
#
# It is possible to manually trigger a rebuild of the image used in CI. To do this, navigate to
# https://app.circleci.com/pipelines/github/influxdata/influxdb_iox?branch=main (overriding the
# branch name if desired). Then:
# - Click "Run Pipeline" in the top-right
# - Expand "Add Parameters"
# - Add a "boolean" parameter called "ci_image" with the value true
# - Click "Run Pipeline"
#
# If you refresh the page you should see a newly running ci_image workflow
2021-03-29 16:55:50 +00:00
#
version: 2.1
commands:
2021-04-20 19:29:14 +00:00
rust_components:
description: Verify installed components
2021-04-20 15:17:05 +00:00
steps:
- run:
name: Verify installed components
command: |
rustup --version
rustup show
cargo fmt --version
cargo clippy --version
2021-04-20 19:29:14 +00:00
2021-03-29 16:55:50 +00:00
cache_restore:
description: Restore Cargo Cache
steps:
- restore_cache:
name: Restoring Cargo Cache
keys:
- cargo-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Cargo.lock" }}
- cargo-cache-{{ arch }}-{{ .Branch }}
- cargo-cache
cache_save:
description: Save Cargo Cache
steps:
- save_cache:
name: Save Cargo Cache
paths:
- /usr/local/cargo/registry
key: cargo-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Cargo.lock" }}
2020-06-05 21:45:44 +00:00
jobs:
fmt:
docker:
- image: quay.io/influxdb/rust:ci
2021-03-29 16:55:50 +00:00
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
steps:
- checkout
2021-04-20 19:29:14 +00:00
- rust_components
2021-03-29 16:55:50 +00:00
- cache_restore
- run:
name: Rust fmt
2020-02-14 13:01:39 +00:00
command: cargo fmt --all -- --check
2021-03-29 16:55:50 +00:00
- cache_save
lint:
docker:
- image: quay.io/influxdb/rust:ci
2021-03-29 16:55:50 +00:00
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
steps:
- checkout
2021-04-20 19:29:14 +00:00
- rust_components
2021-03-29 16:55:50 +00:00
- cache_restore
- run:
name: Clippy
command: cargo clippy --all-targets --all-features --workspace -- -D warnings
2021-03-29 16:55:50 +00:00
- cache_save
cargo_audit:
docker:
- image: quay.io/influxdb/rust:ci
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
steps:
- checkout
- rust_components
- cache_restore
- run:
name: Install Cargo Audit
command: cargo install --force cargo-audit
- run:
name: Cargo Audit
command: cargo audit
- cache_save
doc:
docker:
- image: quay.io/influxdb/rust:ci
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
steps:
- checkout
- rust_components
- cache_restore
- run:
name: Cargo doc
# excluding datafusion because it's effectively a dependency masqueraded as workspace crate.
command: cargo doc --document-private-items --no-deps --workspace --exclude datafusion
- cache_save
- run:
name: Compress Docs
command: tar -cvzf rustdoc.tar.gz target/doc/
- store_artifacts:
path: rustdoc.tar.gz
test:
docker:
- image: quay.io/influxdb/rust:ci
resource_class: xlarge # use of a smaller executor tends crashes on link
2021-03-29 16:55:50 +00:00
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
RUST_BACKTRACE: "1"
# Run integration tests
TEST_INTEGRATION: 1
INFLUXDB_IOX_INTEGRATION_LOCAL: 1
KAFKA_CONNECT: "localhost:9092"
steps:
- run:
name: Run Kafka
# Sudo needed because data directory owned by root but container runs as unprivileged user
command: sudo rpk redpanda start
background: true
- checkout
2021-04-20 19:29:14 +00:00
- rust_components
2021-03-29 16:55:50 +00:00
- cache_restore
- run:
name: Cargo test
command: cargo test --workspace
2021-03-29 16:55:50 +00:00
- cache_save
2021-08-13 13:20:08 +00:00
# end to end tests with Heappy (heap profiling enabled)
test_heappy:
docker:
- image: quay.io/influxdb/rust:ci
resource_class: xlarge # use of a smaller executor tends crashes on link
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
RUST_BACKTRACE: "1"
2021-08-13 13:20:08 +00:00
steps:
- checkout
- rust_components
- cache_restore
- run:
name: End to end tests (with heappy)
command: cargo test --no-default-features --features=heappy end_to_end
2021-08-13 13:20:08 +00:00
- cache_save
test_perf:
machine:
image: ubuntu-2004:202107-02
resource_class: xlarge
2021-09-13 23:11:59 +00:00
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
RUST_BACKTRACE: "1"
steps:
- run: sudo apt update
- run:
name: Install required compile tools
command: sudo apt install curl clang lld pkg-config libssl-dev --yes --no-install-recommends
- checkout
- run:
name: Install rustup
command: scripts/install_rustup.sh
- run:
name: Install perf.py dependencies
command: python3 -m pip install -r perf/requirements.txt
- restore_cache:
keys:
- cargo-lock-{{ checksum "Cargo.lock" }}
- run:
name: Prime Rust build cache
2021-09-13 23:11:59 +00:00
command: cargo build --package influxdb_iox --bin influxdb_iox --package iox_data_generator --bin iox_data_generator
- save_cache:
key: cargo-lock-{{ checksum "Cargo.lock" }}
paths:
- target
- run:
name: Run basic perf test to ensure that perf.py works
command: |
trap "cat perf/logs/test.log" ERR
perf/perf.py --debug --no-volumes --object-store memory battery-0
# Build a dev binary.
#
# Compiles a binary with the default ("dev") cargo profile from the iox source
# using the latest ci_image.
build:
docker:
- image: quay.io/influxdb/rust:ci
2021-03-29 16:55:50 +00:00
resource_class: xlarge # use of a smaller executor tends crashes on link
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# Disable full debug symbol generation to speed up CI build
# "1" means line tables only, which is useful for panic tracebacks.
RUSTFLAGS: "-C debuginfo=1"
steps:
- checkout
2021-04-20 19:29:14 +00:00
- rust_components
2021-03-29 16:55:50 +00:00
- cache_restore
- run:
name: Cargo build
command: cargo build --workspace
2021-03-29 16:55:50 +00:00
- run:
name: Build benches
command: cargo test --workspace --benches --no-run
- run:
name: Build with object store + exporter support + HEAP profiling
command: cargo build --no-default-features --features="aws,gcp,azure,heappy,pprof"
2021-03-29 16:55:50 +00:00
- cache_save
# Lint protobufs.
protobuf-lint:
docker:
- image: bufbuild/buf:0.40.0
environment:
# Value to look for to skip breaking changes check
SKIP_LABEL: "https://api.github.com/repos/influxdata/influxdb_iox/labels/incompatible%20protobuf"
2021-03-29 16:55:50 +00:00
steps:
- checkout
- run:
name: buf lint
command: buf lint
- run:
name: buf breaking changes
command: |
echo "If you want to make changes forbidden by this lint, please"
echo "coordinate with the conductor team, add the 'incompatible protobuf' label"
echo "to the PR, and rerun this test"
# Check if label is present using github API:
# Inspired by https://discuss.circleci.com/t/tag-label-filter/11158
if wget -O - https://api.github.com/repos/influxdata/influxdb_iox/issues/$(echo $CIRCLE_PULL_REQUEST | grep -oE "[^/pull]+$") | grep "$SKIP_LABEL" ; then echo "SKIPPING (FOUND LABEL)" && exit ; else echo "CHECKING (NO LABEL FOUND)"; fi
git fetch origin main
# compare against only changes in this branch (not against
# other stuff that may have been added to main since last merge)
MERGE_BASE=$(git merge-base origin/main $CIRCLE_BRANCH) sh -c 'buf breaking --against ".git#ref=$MERGE_BASE"'
2021-03-29 16:55:50 +00:00
# Compile a cargo "release" profile binary for branches that end in `/perf`
#
# Uses the latest ci_image (influxdb/rust below) to build a release binary and
# copies it to a minimal container image based upon `rust:slim-buster`. This
# minimal image is then pushed to `quay.io/influxdb/iox:${BRANCH}` with '/'
# repaced by '.' - as an example:
#
2021-03-29 16:55:50 +00:00
# git branch: dom/my-awesome-feature/perf
# container: quay.io/influxdb/iox:dom.my-awesome-feature.perf
#
# Subsequent CI runs will overwrite the tag if you push more changes, so watch
# out for parallel CI runs!
#
# To change the contents of the build container, modify docker/Dockerfile.ci
2021-02-25 15:05:54 +00:00
# To change the final release container, modify docker/Dockerfile.iox
perf_image:
docker:
- image: quay.io/influxdb/rust:ci
resource_class: xlarge # use of a smaller executor tends crashes on link
2021-03-29 16:55:50 +00:00
environment:
# Disable incremental compilation to avoid overhead. We are not preserving these files anyway.
CARGO_INCREMENTAL: "0"
# We keep the debug symbols (Enabled in Cargo.toml as debug = true)
# workaround dynamic CPU detection bug in croaring
# https://github.com/influxdata/influxdb_iox/pull/2119
ROARING_ARCH: "haswell"
# Use avx512 instructions to take full advantage of the CPUs instruction set
RUSTFLAGS: "-C target-feature=+avx2"
steps:
- checkout
2021-04-20 19:29:14 +00:00
- rust_components
2021-03-29 16:55:50 +00:00
- cache_restore
- run:
name: Cargo release build with target arch set for CRoaring
command: cargo build --release --no-default-features --features="aws,gcp,azure,jemalloc_replacing_malloc"
chore: faster and smaller IOx binaries Use `codegen-units = 1`, thin-LTO and debug section compression to make our binary smaller (which is good for deploy and test times) and faster. # Summary The binary size of `influxdb_iox` after building with: ```console $ cargo build --release --no-default-features --features="aws,gcp,azure,jemalloc_replacing_malloc" ``` The profile was: ```toml [profile.release] debug = true ``` The commit was: ```text 89ece8b493c924d05ebfa75d6661be5462eaeefa ``` The size results are: | Method | Size | | ------------------------------------------ | ----- | | baseline | 833MB | | baseline + dbg compression | 222MB | | baseline + strip | 49MB | | codegen-units | 520MB | | codegen-units + strip | 40MB | | codegen-units + dbg compression | 143MB | | thin LTO | 715MB | | thin LTO + strip | 49MB | | thin LTO + dbg compression | 199MB | | codegen-units + thin LTO | 449MB | | codegen-units + thin LTO + strip | 40MB | | codegen-units + thin LTO + dbg compression | 130MB | For the methods that were successfully measured I couldn't really see any compile time differences on my laptop. # Methods ## Strip Remove debug symbols. We don't really want this, so this is just to get an idea of the size ```console $ strip baseline ``` ## Debug Sections compression Debug sections make a large amount of our binary size (a stripped executable is 49MB instead of 833MB). Since we like to have debug symbols we cannot just strip them. However these symbols are only used for: - backtrace generation (something went wrong, not BAU) - profiling - debugging So in normal operation and most test scenarios, we're just wasting memory. So we could compress them: ```console $ objcopy --compress-debug-sections baseline baseline-dbg_compressed ``` There is also elfutils: ```console $ eu-elfcompress test ``` Elfutils nearly ends up with the same size (220MB instead of 222MB that objcopy achieves), but takes more time and is probably not worth it. Note that compressed debug sections exist since many years. The Rust ecosystem supports reading them since over a year, see: - <https://github.com/gimli-rs/gimli/issues/195> - <https://github.com/rust-lang/backtrace-rs/issues/342> ## Codegen Units The rust compiler parallelizes codegen work. This split into units however means that optimizations are somewhat limited. This can be change by: ```toml [profile.release] ... codegen-units = 1 ``` As a nice side effect this should also make our code faster. ## Thin LTO Get LLVM to run "thin" Link Time Optimization: ```toml [profile.release] ... lto = "thin" ``` As a nice side effect this should also make our code faster. ## Fat LTO Get LLVM to run "fat" Link Time Optimization: ```toml [profile.release] ... lto = "fat" ``` There are no results for this because this took a massive amount of memory and CPU time and did not finish on my system.
2021-11-10 14:47:18 +00:00
- run:
name: Compress debug symbols
command: objcopy --compress-debug-sections target/release/influxdb_iox
2021-04-26 10:51:33 +00:00
- run: |
chore: faster and smaller IOx binaries Use `codegen-units = 1`, thin-LTO and debug section compression to make our binary smaller (which is good for deploy and test times) and faster. # Summary The binary size of `influxdb_iox` after building with: ```console $ cargo build --release --no-default-features --features="aws,gcp,azure,jemalloc_replacing_malloc" ``` The profile was: ```toml [profile.release] debug = true ``` The commit was: ```text 89ece8b493c924d05ebfa75d6661be5462eaeefa ``` The size results are: | Method | Size | | ------------------------------------------ | ----- | | baseline | 833MB | | baseline + dbg compression | 222MB | | baseline + strip | 49MB | | codegen-units | 520MB | | codegen-units + strip | 40MB | | codegen-units + dbg compression | 143MB | | thin LTO | 715MB | | thin LTO + strip | 49MB | | thin LTO + dbg compression | 199MB | | codegen-units + thin LTO | 449MB | | codegen-units + thin LTO + strip | 40MB | | codegen-units + thin LTO + dbg compression | 130MB | For the methods that were successfully measured I couldn't really see any compile time differences on my laptop. # Methods ## Strip Remove debug symbols. We don't really want this, so this is just to get an idea of the size ```console $ strip baseline ``` ## Debug Sections compression Debug sections make a large amount of our binary size (a stripped executable is 49MB instead of 833MB). Since we like to have debug symbols we cannot just strip them. However these symbols are only used for: - backtrace generation (something went wrong, not BAU) - profiling - debugging So in normal operation and most test scenarios, we're just wasting memory. So we could compress them: ```console $ objcopy --compress-debug-sections baseline baseline-dbg_compressed ``` There is also elfutils: ```console $ eu-elfcompress test ``` Elfutils nearly ends up with the same size (220MB instead of 222MB that objcopy achieves), but takes more time and is probably not worth it. Note that compressed debug sections exist since many years. The Rust ecosystem supports reading them since over a year, see: - <https://github.com/gimli-rs/gimli/issues/195> - <https://github.com/rust-lang/backtrace-rs/issues/342> ## Codegen Units The rust compiler parallelizes codegen work. This split into units however means that optimizations are somewhat limited. This can be change by: ```toml [profile.release] ... codegen-units = 1 ``` As a nice side effect this should also make our code faster. ## Thin LTO Get LLVM to run "thin" Link Time Optimization: ```toml [profile.release] ... lto = "thin" ``` As a nice side effect this should also make our code faster. ## Fat LTO Get LLVM to run "fat" Link Time Optimization: ```toml [profile.release] ... lto = "fat" ``` There are no results for this because this took a massive amount of memory and CPU time and did not finish on my system.
2021-11-10 14:47:18 +00:00
echo "binary sha256sum after build is (not to be confused w/ the GIT SHA and the resulting image SHA!)"
2021-04-26 10:51:33 +00:00
sha256sum target/release/influxdb_iox
- run:
name: Print rustc target CPU options
command: target/release/influxdb_iox debug print-cpu
- setup_remote_docker:
# There seems to be a cache invalidation bug in docker
# or in the way that circleci implements layer caching.
# Disabling for now, and tracked further investigations
# in https://github.com/influxdata/k8s-idpe/issues/3038
docker_layer_caching: false
version: 20.10.7
- run: |
sudo apt-get update
sudo apt-get install -y docker.io
docker --version
- run: |
echo "$QUAY_INFLUXDB_IOX_PASS" | docker login quay.io --username $QUAY_INFLUXDB_IOX_USER --password-stdin
- run:
# Docker has functionality to support per-Dockerfile .dockerignore
# This was added in https://github.com/moby/buildkit/pull/901
# And included in 19.03 - https://docs.docker.com/engine/release-notes/19.03/#19030
# Unfortunately CircleCI only seems to understand a root-level .dockerignore
# So we need to move it into position for it to not send ~10GB of build context
name: Fudge CircleCI Docker Context
command: mv docker/Dockerfile.iox.dockerignore .dockerignore
- run: |
BRANCH=$(git rev-parse --abbrev-ref HEAD | tr '/' '.')
COMMIT_SHA=$(git rev-parse --short HEAD)
docker build -t quay.io/influxdb/iox:$COMMIT_SHA -t quay.io/influxdb/iox:main -f docker/Dockerfile.iox .
docker push --all-tags quay.io/influxdb/iox
echo "export COMMIT_SHA=${COMMIT_SHA}" >> $BASH_ENV
- run:
name: Deploy tags
command: |
echo "$QUAY_PASS" | docker login quay.io --username $QUAY_USER --password-stdin
./.circleci/get-deploy-tags.sh "${COMMIT_SHA}"
2021-03-29 16:55:50 +00:00
- cache_save
# Prepare the CI image used for other tasks.
#
# A nightly job (scheduled below in the `workflows` section) to build the CI
# image (influxdb/rust) used for the rest of the checks.
#
# To modify the contents of the CI image, update docker/Dockerfile.ci
ci_image:
machine:
image: ubuntu-2004:202107-02
resource_class: xlarge
steps:
- checkout
- run: |
echo "$QUAY_PASS" | docker login quay.io --username $QUAY_USER --password-stdin
- run: |
COMMIT_SHA=$(git rev-parse --short HEAD)
RUST_VERSION=$(sed -E -ne 's/channel = "(.*)"/\1/p' rust-toolchain.toml)
docker --version
docker build -t quay.io/influxdb/rust:$COMMIT_SHA -t quay.io/influxdb/rust:ci -f docker/Dockerfile.ci --build-arg RUST_VERSION=$RUST_VERSION .
docker push --all-tags quay.io/influxdb/rust
parameters:
# Trigger build of CI image
ci_image:
type: boolean
default: false
workflows:
version: 2
2021-03-29 16:55:50 +00:00
# CI for all pull requests.
ci:
when:
not: << pipeline.parameters.ci_image >>
2021-03-29 16:55:50 +00:00
jobs:
- fmt
- lint
- cargo_audit
2021-03-29 16:55:50 +00:00
- protobuf-lint
- test
2021-08-13 13:20:08 +00:00
- test_heappy
- test_perf
2021-03-29 16:55:50 +00:00
- build
- doc
- perf_image:
filters:
branches:
only: main
requires: # Only do a release build if all tests have passed
- fmt
- lint
- cargo_audit
- protobuf-lint
- test
- test_heappy
- test_perf
- build
- doc
2021-03-29 16:55:50 +00:00
# Manual build of CI image
ci_image:
when: << pipeline.parameters.ci_image >>
jobs:
- ci_image
# Nightly rebuild of the build container
ci_image_nightly:
triggers:
- schedule:
cron: "0 5 * * *"
filters:
branches:
only:
- main
jobs:
- ci_image