diff --git a/.github/workflows/base-goreleaser-ci.yaml b/.github/workflows/base-goreleaser-ci.yaml new file mode 100644 index 0000000..34c4245 --- /dev/null +++ b/.github/workflows/base-goreleaser-ci.yaml @@ -0,0 +1,43 @@ +name: Reusable GoReleaser CI workflow + +on: + workflow_call: + inputs: + distribution: + required: true + type: string + +jobs: + check-goreleaser: + name: Check GoReleaser Configuration for ${{ inputs.distribution }} + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64,ppc64le + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.21 + + - uses: anchore/sbom-action/download-syft@v0.15.10 + + - name: Generate the sources + run: make generate-sources + + - name: Run GoReleaser for ${{ inputs.distribution }} + uses: goreleaser/goreleaser-action@v5 + with: + workdir: distributions/${{ inputs.distribution }} + version: latest + args: --snapshot --rm-dist --timeout 2h diff --git a/.github/workflows/base-release.yaml b/.github/workflows/base-release.yaml new file mode 100644 index 0000000..5418e0c --- /dev/null +++ b/.github/workflows/base-release.yaml @@ -0,0 +1,54 @@ +name: Reusable release workflow + +on: + workflow_call: + inputs: + distribution: + required: true + type: string + +jobs: + release: + name: Release ${{ inputs.distribution }} + environment: release + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64,ppc64le + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 1.21 + + - uses: anchore/sbom-action/download-syft@v0.15.10 + + - name: Generate distribution sources + run: make generate-sources + + - name: Login to GitHub Package Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + version: latest + workdir: distributions/${{ inputs.distribution }} + args: release --clean --timeout 2h + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci-loadbalancing.yaml b/.github/workflows/ci-loadbalancing.yaml new file mode 100644 index 0000000..9d340c7 --- /dev/null +++ b/.github/workflows/ci-loadbalancing.yaml @@ -0,0 +1,15 @@ +name: Continuous Integration - load-balancing + +on: + workflow_run: + workflows: [Continuous Integration] + types: + - completed + +jobs: + release: + name: Continuous Integration - loadbalancing - GoReleaser + uses: ./.github/workflows/base-goreleaser-ci.yaml + with: + distribution: loadbalancing + secrets: inherit diff --git a/.github/workflows/ci-sidecar.yaml b/.github/workflows/ci-sidecar.yaml new file mode 100644 index 0000000..522256f --- /dev/null +++ b/.github/workflows/ci-sidecar.yaml @@ -0,0 +1,15 @@ +name: Continuous Integration - sidecar + +on: + workflow_run: + workflows: [Continuous Integration] + types: + - completed + +jobs: + release: + name: Continuous Integration - sidecar - GoReleaser + uses: ./.github/workflows/base-goreleaser-ci.yaml + with: + distribution: sidecar + secrets: inherit diff --git a/.github/workflows/ci-tracing.yaml b/.github/workflows/ci-tracing.yaml new file mode 100644 index 0000000..34b7d90 --- /dev/null +++ b/.github/workflows/ci-tracing.yaml @@ -0,0 +1,15 @@ +name: Continuous Integration - tracing + +on: + workflow_run: + workflows: [Continuous Integration] + types: + - completed + +jobs: + release: + name: Continuous Integration - sidecar - GoReleaser + uses: ./.github/workflows/base-goreleaser-ci.yaml + with: + distribution: tracing + secrets: inherit diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..102c31c --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,25 @@ +name: Continuous Integration + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build: + name: Build + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.21 + + - name: Verify + run: make ci diff --git a/.github/workflows/release-loadbalancing.yaml b/.github/workflows/release-loadbalancing.yaml new file mode 100644 index 0000000..2893090 --- /dev/null +++ b/.github/workflows/release-loadbalancing.yaml @@ -0,0 +1,14 @@ +name: Release loadbalancing + +on: + release: + types: [published] + +jobs: + release: + name: Release loadbalancing + uses: ./.github/workflows/base-release.yaml + with: + distribution: loadbalancing + secrets: inherit + permissions: write-all diff --git a/.github/workflows/release-sidecar.yaml b/.github/workflows/release-sidecar.yaml new file mode 100644 index 0000000..314ed74 --- /dev/null +++ b/.github/workflows/release-sidecar.yaml @@ -0,0 +1,14 @@ +name: Release sidecar + +on: + release: + types: [published] + +jobs: + release: + name: Release sidecar + uses: ./.github/workflows/base-release.yaml + with: + distribution: sidecar + secrets: inherit + permissions: write-all diff --git a/.github/workflows/release-tracing.yaml b/.github/workflows/release-tracing.yaml new file mode 100644 index 0000000..e2af6ff --- /dev/null +++ b/.github/workflows/release-tracing.yaml @@ -0,0 +1,14 @@ +name: Release tracing + +on: + release: + types: [published] + +jobs: + release: + name: Release tracing + uses: ./.github/workflows/base-release.yaml + with: + distribution: tracing + secrets: inherit + permissions: write-all \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..819c5b9 --- /dev/null +++ b/Makefile @@ -0,0 +1,52 @@ +GO ?= go + +OTELCOL_BUILDER_VERSION ?= 0.97.0 +OTELCOL_BUILDER_DIR ?= ${HOME}/bin +OTELCOL_BUILDER ?= ${OTELCOL_BUILDER_DIR}/ocb + +DISTRIBUTIONS ?= $(shell echo $(notdir $(wildcard ./distributions/*)) | tr " " ",") # outputs comma separated directories names + +ci: check build +check: test + +build: go ocb + @./scripts/build.sh -d "${DISTRIBUTIONS}" -b ${OTELCOL_BUILDER} -g ${GO} + +test: build + @./test/test-all.sh -d "${DISTRIBUTIONS}" + +generate: generate-sources generate-goreleaser + +generate-goreleaser: go + @./scripts/generate-goreleaser.sh -d "${DISTRIBUTIONS}" -g ${GO} + +generate-sources: go ocb + @./scripts/build.sh -d "${DISTRIBUTIONS}" -s true -b ${OTELCOL_BUILDER} -g ${GO} + +.PHONY: ocb +ocb: +ifeq (, $(shell command -v ocb 2>/dev/null)) + @{ \ + [ ! -x '$(OTELCOL_BUILDER)' ] || exit 0; \ + set -e ;\ + os=$$(uname | tr A-Z a-z) ;\ + machine=$$(uname -m) ;\ + [ "$${machine}" != x86 ] || machine=386 ;\ + [ "$${machine}" != x86_64 ] || machine=amd64 ;\ + echo "Installing ocb ($${os}/$${machine}) at $(OTELCOL_BUILDER_DIR)";\ + mkdir -p $(OTELCOL_BUILDER_DIR) ;\ + curl -sLo $(OTELCOL_BUILDER) "https://github.com/open-telemetry/opentelemetry-collector/releases/download/cmd%2Fbuilder%2Fv$(OTELCOL_BUILDER_VERSION)/ocb_$(OTELCOL_BUILDER_VERSION)_$${os}_$${machine}" ;\ + chmod +x $(OTELCOL_BUILDER) ;\ + } +else +OTELCOL_BUILDER=$(shell command -v ocb) +endif + +.PHONY: go +go: + @{ \ + if ! command -v '$(GO)' >/dev/null 2>/dev/null; then \ + echo >&2 '$(GO) command not found. Please install golang. https://go.dev/doc/install'; \ + exit 1; \ + fi \ + } diff --git a/README.md b/README.md new file mode 100644 index 0000000..00242b5 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# OpenTelemetry Collector distributions by jpkrohling + +This repository has a personal collection of OpenTelemetry Collector distributions curated by [@jpkrohling](https://github.com/jpkrohling). + +At every new version of the Collector, distributions are updated and published. + +## Adding a new distribution + +To add a new distribution to this repository: + +1) create a directory under `distributions` and place the `manifest.yaml` there +2) add `./github/workflows/ci-.yaml` and `./github/workflows/release-.yaml` files based on one of the existing distributions + +You can test your new distribution with: + +```console +./test/test.sh -d YOUR_DISTRIBUTION +``` + +Or, to run everything the CI would run: + +```console +make ci +``` diff --git a/distributions/delta-to-cumulative/Dockerfile b/distributions/delta-to-cumulative/Dockerfile new file mode 100644 index 0000000..db912dd --- /dev/null +++ b/distributions/delta-to-cumulative/Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:latest + +ARG USER_UID=10001 +USER ${USER_UID} + +COPY delta-to-cumulative /delta-to-cumulative +COPY otelcol.yaml /etc/delta-to-cumulative/config.yaml +ENTRYPOINT ["/delta-to-cumulative"] +CMD ["--config", "/etc/delta-to-cumulative/config.yaml"] +EXPOSE 4317 diff --git a/distributions/delta-to-cumulative/delta-to-cumulative.conf b/distributions/delta-to-cumulative/delta-to-cumulative.conf new file mode 100644 index 0000000..b6f8af7 --- /dev/null +++ b/distributions/delta-to-cumulative/delta-to-cumulative.conf @@ -0,0 +1,5 @@ +# Systemd environment file for the delta-to-cumulative service + +# Command-line options for the delta-to-cumulative service. +# Run `/usr/bin/delta-to-cumulative --help` to see all available options. +OTELCOL_OPTIONS="--config=/etc/delta-to-cumulative/config.yaml" \ No newline at end of file diff --git a/distributions/delta-to-cumulative/delta-to-cumulative.service b/distributions/delta-to-cumulative/delta-to-cumulative.service new file mode 100644 index 0000000..487922c --- /dev/null +++ b/distributions/delta-to-cumulative/delta-to-cumulative.service @@ -0,0 +1,15 @@ +[Unit] +Description=Delta to cummulative distribution of the OpenTelemetry Collector +After=network.target + +[Service] +EnvironmentFile=/etc/delta-to-cumulative/delta-to-cumulative.conf +ExecStart=/usr/bin/delta-to-cumulative $OTELCOL_OPTIONS +KillMode=mixed +Restart=on-failure +Type=simple +User=delta-to-cumulative +Group=delta-to-cumulative + +[Install] +WantedBy=multi-user.target diff --git a/distributions/delta-to-cumulative/manifest.yaml b/distributions/delta-to-cumulative/manifest.yaml new file mode 100644 index 0000000..a088af1 --- /dev/null +++ b/distributions/delta-to-cumulative/manifest.yaml @@ -0,0 +1,16 @@ +dist: + module: github.com/grafana/opentelemetry-collector-components/delta-to-cumulative + name: otelcol + description: Delta to cumulative distribution of the OpenTelemetry Collector + version: 0.97.0 + output_path: ./_build + otelcol_version: 0.97.0 + +extensions: + - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.97.0 +receivers: + - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.97.0 +exporters: + - gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.97.0 +processors: + - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.97.0 diff --git a/distributions/delta-to-cumulative/otelcol-test.yaml b/distributions/delta-to-cumulative/otelcol-test.yaml new file mode 100644 index 0000000..9ec5665 --- /dev/null +++ b/distributions/delta-to-cumulative/otelcol-test.yaml @@ -0,0 +1,25 @@ +extensions: + health_check: + +receivers: + otlp: + protocols: + grpc: + +processors: + deltatocumulative: + +exporters: + otlp: + endpoint: example.com:4317 + +service: + extensions: [health_check] + pipelines: + metrics: + receivers: + - otlp + processors: + - deltatocumulative + exporters: + - otlp diff --git a/distributions/delta-to-cumulative/otelcol.yaml b/distributions/delta-to-cumulative/otelcol.yaml new file mode 100644 index 0000000..9ec5665 --- /dev/null +++ b/distributions/delta-to-cumulative/otelcol.yaml @@ -0,0 +1,25 @@ +extensions: + health_check: + +receivers: + otlp: + protocols: + grpc: + +processors: + deltatocumulative: + +exporters: + otlp: + endpoint: example.com:4317 + +service: + extensions: [health_check] + pipelines: + metrics: + receivers: + - otlp + processors: + - deltatocumulative + exporters: + - otlp diff --git a/distributions/delta-to-cumulative/postinstall.sh b/distributions/delta-to-cumulative/postinstall.sh new file mode 100644 index 0000000..57cde5f --- /dev/null +++ b/distributions/delta-to-cumulative/postinstall.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# Copyright The OpenTelemetry Authors +# +# Licensed 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. + +if command -v systemctl >/dev/null 2>&1; then + systemctl enable delta-to-cumulative.service + if [ -f /etc/delta-to-cumulative/config.yaml ]; then + systemctl start delta-to-cumulative.service + fi +fi diff --git a/distributions/delta-to-cumulative/preinstall.sh b/distributions/delta-to-cumulative/preinstall.sh new file mode 100644 index 0000000..c19dcf7 --- /dev/null +++ b/distributions/delta-to-cumulative/preinstall.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# Copyright The OpenTelemetry Authors +# +# Licensed 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. + +getent passwd delta-to-cumulative >/dev/null || useradd --system --user-group --no-create-home --shell /sbin/nologin delta-to-cumulative diff --git a/distributions/delta-to-cumulative/preremove.sh b/distributions/delta-to-cumulative/preremove.sh new file mode 100644 index 0000000..0554f70 --- /dev/null +++ b/distributions/delta-to-cumulative/preremove.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# Copyright The OpenTelemetry Authors +# +# Licensed 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. + +if command -v systemctl >/dev/null 2>&1; then + systemctl stop delta-to-cumulative.service + systemctl disable delta-to-cumulative.service +fi diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..fb95192 --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module github.com/grafana/opentelemetry-collector-components + +go 1.21 + +toolchain go1.21.4 + +require ( + github.com/goreleaser/goreleaser v1.24.0 + github.com/goreleaser/nfpm/v2 v2.35.3 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/goreleaser/fileglob v1.3.0 // indirect + github.com/invopop/jsonschema v0.12.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c5c355b --- /dev/null +++ b/go.sum @@ -0,0 +1,52 @@ +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/caarlos0/testfs v0.4.4 h1:3PHvzHi5Lt+g332CiShwS8ogTgS3HjrmzZxCm6JCDr8= +github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTliBy+1DMk= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I= +github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= +github.com/goreleaser/goreleaser v1.21.2 h1:dgYtIS7aZlQuRMUMLCjDCOs4lWss85Oh60RDSO0rbWU= +github.com/goreleaser/goreleaser v1.21.2/go.mod h1:aldhx+J6NRthWY25GIZztFwfzug50IveIz/UNrCNIuk= +github.com/goreleaser/goreleaser v1.23.0/go.mod h1:6Dn+HZ03ifWg5Q2d1bRNAXGw66VudFLQeJ4g3KXTTOo= +github.com/goreleaser/goreleaser v1.24.0/go.mod h1:iEWoXoWy8y5AvqRhHPwXINHLYyyJCz5qkGzooCdRrGo= +github.com/goreleaser/nfpm/v2 v2.33.1 h1:EkdAzZyVhAI9JC1vjmjjbmnNzyH1J6Cu4JCsA7YcQuc= +github.com/goreleaser/nfpm/v2 v2.33.1/go.mod h1:8wwWWvJWmn84xo/Sqiv0aMvEGTHlHZTXTEuVSgQpkIM= +github.com/goreleaser/nfpm/v2 v2.35.1/go.mod h1:KeO5wxOHyU1nPFO5siSfw6Ds5dKyy0E6y89/ypM7+ZI= +github.com/goreleaser/nfpm/v2 v2.35.2/go.mod h1:gORhkEMuO8zSHn0k4WCBAaXxRa+jOLDJv3QByQVWE1M= +github.com/goreleaser/nfpm/v2 v2.35.3/go.mod h1:eyKRLSdXPCV1GgJ0tDNe4SqcZD0Fr5cezRwcuLjpxyM= +github.com/invopop/jsonschema v0.9.0 h1:m1Fe5PN4X9V7P1TCF+pA8Xly3Vj3pY905klC++8oOpM= +github.com/invopop/jsonschema v0.9.0/go.mod h1:uMhbTEOXoPcOKzdYRfk914W6UTGA/cVcgEQxXh1MJ7g= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/goreleaser/main.go b/goreleaser/main.go new file mode 100644 index 0000000..18e567e --- /dev/null +++ b/goreleaser/main.go @@ -0,0 +1,197 @@ +//go:build releaser + +package main + +// This file is a script which generates the .goreleaser.yaml file for all +// supported OpenTelemetry Collector distributions. +// +// Run it with `make generate-goreleaser`. + +import ( + "flag" + "fmt" + "log" + "os" + "path" + + "github.com/goreleaser/goreleaser/pkg/config" + "github.com/goreleaser/nfpm/v2/files" + "gopkg.in/yaml.v3" +) + +var ( + ImagePrefixes = []string{"ghcr.io/grafana/opentelemetry-collector-components"} + Architectures = []string{"386", "amd64", "arm64", "ppc64le"} + + distFlag = flag.String("d", "", "Single distribution to build") +) + +func main() { + flag.Parse() + + if len(*distFlag) == 0 { + log.Fatal("no distribution to build") + } + + project := Generate(ImagePrefixes, *distFlag) + if err := yaml.NewEncoder(os.Stdout).Encode(&project); err != nil { + log.Fatal(err) + } +} + +func Generate(imagePrefixes []string, dist string) config.Project { + return config.Project{ + ProjectName: dist, + Checksum: config.Checksum{ + NameTemplate: "{{ .ProjectName }}_checksums.txt", + }, + + Builds: []config.Build{Build(dist)}, + Archives: []config.Archive{Archive(dist)}, + NFPMs: []config.NFPM{Package(dist)}, + Dockers: DockerImages(imagePrefixes, dist), + DockerManifests: DockerManifest(imagePrefixes, dist), + SBOMs: []config.SBOM{ + { + ID: "archive", + Artifacts: "archive", + }, + { + ID: "package", + Artifacts: "package", + }, + }, + } +} + +// Build configures a goreleaser build. +// https://goreleaser.com/customization/build/ +func Build(dist string) config.Build { + return config.Build{ + ID: dist, + Dir: "_build", + Binary: dist, + BuildDetails: config.BuildDetails{ + Env: []string{"CGO_ENABLED=0"}, + Flags: []string{"-trimpath"}, + Ldflags: []string{"-s", "-w"}, + }, + Goos: []string{"darwin", "linux", "windows"}, + Goarch: Architectures, + Ignore: []config.IgnoredBuild{ + {Goos: "darwin", Goarch: "386"}, + {Goos: "windows", Goarch: "arm64"}, + }, + } +} + +// Archive configures a goreleaser archive (tarball). +// https://goreleaser.com/customization/archive/ +func Archive(dist string) config.Archive { + return config.Archive{ + ID: dist, + NameTemplate: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}", + Builds: []string{dist}, + } +} + +// Package configures goreleaser to build a system package. +// https://goreleaser.com/customization/nfpm/ +func Package(dist string) config.NFPM { + return config.NFPM{ + ID: dist, + Builds: []string{dist}, + Formats: []string{"apk", "deb", "rpm"}, + + License: "Apache 2.0", + Description: fmt.Sprintf("%s distribution of the OpenTelemetry Collector", dist), + Maintainer: "Juraci Paixão Kröhling ", + + NFPMOverridables: config.NFPMOverridables{ + PackageName: dist, + Scripts: config.NFPMScripts{ + PreInstall: "preinstall.sh", + PostInstall: "postinstall.sh", + PreRemove: "preremove.sh", + }, + Contents: files.Contents{ + { + Source: fmt.Sprintf("%s.service", dist), + Destination: path.Join("/lib", "systemd", "system", fmt.Sprintf("%s.service", dist)), + }, + { + Source: fmt.Sprintf("%s.conf", dist), + Destination: path.Join("/etc", dist, fmt.Sprintf("%s.conf", dist)), + Type: "config|noreplace", + }, + { + Source: "otelcol.yaml", + Destination: path.Join("/etc", dist, "config.yaml"), + Type: "config", + }, + }, + }, + } +} + +func DockerImages(imagePrefixes []string, dist string) (r []config.Docker) { + for _, arch := range Architectures { + r = append(r, DockerImage(imagePrefixes, dist, arch)) + } + return +} + +// DockerImage configures goreleaser to build a container image. +// https://goreleaser.com/customization/docker/ +func DockerImage(imagePrefixes []string, dist, arch string) config.Docker { + var imageTemplates []string + for _, prefix := range imagePrefixes { + imageTemplates = append( + imageTemplates, + fmt.Sprintf("%s/%s:{{ .Version }}-%s", prefix, dist, arch), + ) + } + + label := func(name, template string) string { + return fmt.Sprintf("--label=org.opencontainers.image.%s={{%s}}", name, template) + } + + return config.Docker{ + ImageTemplates: imageTemplates, + Dockerfile: "Dockerfile", + + Use: "buildx", + BuildFlagTemplates: []string{ + "--pull", + fmt.Sprintf("--platform=linux/%s", arch), + label("created", ".Date"), + label("name", ".ProjectName"), + label("revision", ".FullCommit"), + label("version", ".Version"), + label("source", ".GitURL"), + }, + Files: []string{"otelcol.yaml"}, + Goos: "linux", + Goarch: arch, + } +} + +// DockerManifest configures goreleaser to build a multi-arch container image manifest. +// https://goreleaser.com/customization/docker_manifest/ +func DockerManifest(imagePrefixes []string, dist string) (manifests []config.DockerManifest) { + for _, prefix := range imagePrefixes { + var imageTemplates []string + for _, arch := range Architectures { + imageTemplates = append( + imageTemplates, + fmt.Sprintf("%s/%s:{{ .Version }}-%s", prefix, dist, arch), + ) + } + + manifests = append(manifests, config.DockerManifest{ + NameTemplate: fmt.Sprintf("%s/%s:{{ .Version }}", prefix, dist), + ImageTemplates: imageTemplates, + }) + } + return +} diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..9b0ec25 --- /dev/null +++ b/renovate.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "ocb": { + "fileMatch": [ + "^distributions\\/.*manifest\\.ya?ml$" + ] + }, + "packageRules": [ + { + "matchSourceUrls": [ + "https://github.com/open-telemetry/opentelemetry-collector", + "https://github.com/open-telemetry/opentelemetry-collector-contrib" + ], + "groupName": "otel-collector upstream dependencies" + } + ], + "customManagers": [ + { + "description": "version field and OTELCOL_BUILDER_VERSION should follow upstream", + "fileMatch": [ + "^distributions\\/.*manifest\\.ya?ml$", + "^Makefile$" + ], + "matchStrings": [ + "\\sversion:\\s+(?\\S+)", + "OTELCOL_BUILDER_VERSION\\s*\\?=\\s*(?\\S+)" + ], + "depNameTemplate": "open-telemetry/opentelemetry-collector", + "datasourceTemplate": "github-releases", + "extractVersionTemplate": "^v(?.*)$" + } + ] +} diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..d8e2e62 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +REPO_DIR="$( cd "$(dirname $( dirname "${BASH_SOURCE[0]}" ))" &> /dev/null && pwd )" +BUILDER='' +GO='' + +# default values +skipcompilation=false + +while getopts d:s:b:g: flag +do + case "${flag}" in + d) distributions=${OPTARG};; + s) skipcompilation=${OPTARG};; + b) BUILDER=${OPTARG};; + g) GO=${OPTARG};; + esac +done + +[[ -n "$BUILDER" ]] || BUILDER='ocb' +[[ -n "$GO" ]] || GO='go' + +if [[ -z $distributions ]]; then + echo "List of distributions to build not provided. Use '-d' to specify the names of the distributions to build. Ex.:" + echo "$0 -d tracing" + exit 1 +fi + +if [[ "$skipcompilation" = true ]]; then + echo "Skipping the compilation, we'll only generate the sources." +fi + +echo "Distributions to build: $distributions"; + +for distribution in $(echo "$distributions" | tr "," "\n") +do + pushd "${REPO_DIR}/distributions/${distribution}" > /dev/null + mkdir -p _build + + echo "Building: $distribution" + echo "Using Builder: $(command -v "$BUILDER")" + echo "Using Go: $(command -v "$GO")" + + if "$BUILDER" --skip-compilation=${skipcompilation} --go "$GO" --config manifest.yaml > _build/build.log 2>&1; then + echo "✅ SUCCESS: distribution '${distribution}' built." + else + echo "❌ ERROR: failed to build the distribution '${distribution}'." + echo "🪵 Build logs for '${distribution}'" + echo "----------------------" + cat _build/build.log + echo "----------------------" + exit 1 + fi + + popd > /dev/null +done diff --git a/scripts/generate-goreleaser.sh b/scripts/generate-goreleaser.sh new file mode 100755 index 0000000..16d5681 --- /dev/null +++ b/scripts/generate-goreleaser.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +GO='' + +while getopts d:g: flag +do + case "${flag}" in + d) distributions=${OPTARG};; + g) GO=${OPTARG};; + esac +done + +[[ -n "$GO" ]] || GO='go' + +if [[ -z $distributions ]]; then + echo "List of distributions to generate the goreleaser not provided. Use '-d' to specify the names of the distributions use. Ex.:" + echo "$0 -d tracing" + exit 1 +fi + +echo "Distributions to generate: $distributions"; + +for distribution in $(echo "$distributions" | tr "," "\n") +do + ${GO} run -tags releaser goreleaser/main.go -d "${distribution}" > ./distributions/${distribution}/.goreleaser.yaml +done diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..0695229 --- /dev/null +++ b/test/README.md @@ -0,0 +1,13 @@ +# Tests + +The tests are a bunch of shell scripts that, for each distribution: + +- prepare the environment, such as installing tools like `tracegen` +- start the distribution +- create a data point (a trace, for now) +- check whether the data point was received +- stop the distribution + +In the future, we might add more scenarios to the tests. + +In the output, pay attention to the general outcome of each distribution's test. While you might see warnings or errors in the logs, they are not indicative of a failure. If you see a "PASS: sidecar", it means that the tests (eventually) passed. If you do NOT see this, check the logs for clues. diff --git a/test/check-trace.sh b/test/check-trace.sh new file mode 100755 index 0000000..05a7907 --- /dev/null +++ b/test/check-trace.sh @@ -0,0 +1,2 @@ +#!/bin/bash + diff --git a/test/generate-trace.sh b/test/generate-trace.sh new file mode 100755 index 0000000..db461b8 --- /dev/null +++ b/test/generate-trace.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +while getopts d:s:b:g: flag +do + case "${flag}" in + d) distribution=${OPTARG};; + esac +done +if [[ -z $distribution ]]; then + echo "Distribution to test not provided. Use '-d' to specify the names of the distribution to test. Ex.:" + echo "$0 -d tracing" + exit 1 +fi + +tracegen -otlp-endpoint localhost:4317 -otlp-insecure -service e2e-test &>> ./test/logs/tracegen-${distribution}.log +if [ $? != 0 ]; then + echo "Failed to generate a trace." + exit 1 +fi + +echo "✅ Traces generated." diff --git a/test/install-tracegen.sh b/test/install-tracegen.sh new file mode 100755 index 0000000..83e8906 --- /dev/null +++ b/test/install-tracegen.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +go install "github.com/open-telemetry/opentelemetry-collector-contrib/tracegen@v0.46.0" diff --git a/test/start-otelcol.sh b/test/start-otelcol.sh new file mode 100755 index 0000000..78ba1a8 --- /dev/null +++ b/test/start-otelcol.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +while getopts d:s:b:g: flag +do + case "${flag}" in + d) distribution=${OPTARG};; + esac +done +if [[ -z $distribution ]]; then + echo "Distribution to test not provided. Use '-d' to specify the names of the distribution to test. Ex.:" + echo "$0 -d tracing" + exit 1 +fi + +max_retries=50 + +# start the distribution +mkdir -p ./test/logs +./distributions/${distribution}/_build/otelcol --config ./distributions/${distribution}/otelcol-test.yaml > ./test/logs/otelcol-${distribution}.log 2>&1 & +pid=$! +echo "${pid}" > "otelcol-${distribution}.pid" + +retries=0 +while true +do + kill -0 "${pid}" >/dev/null 2>&1 + if [ $? != 0 ]; then + echo "❌ FAIL. The '${distribution}' distribution of the OpenTelemetry Collector isn't running. Startup log:" + failed=true + exit 1 + fi + + curl -s localhost:13133 | grep "Server available" > /dev/null + if [ $? == 0 ]; then + echo "✅ The '${distribution}' distribution of the OpenTelemetry Collector started." + break + fi + + echo "Server still unavailable" >> ./test/logs/test-${distribution}.log + + let "retries++" + if [ "$retries" -gt "$max_retries" ]; then + echo "❌ FAIL. Server wasn't up after about 5s." + exit 16 + fi + sleep 0.1s +done diff --git a/test/stop-otelcol.sh b/test/stop-otelcol.sh new file mode 100755 index 0000000..6125265 --- /dev/null +++ b/test/stop-otelcol.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +while getopts d:s:b:g: flag +do + case "${flag}" in + d) distribution=${OPTARG};; + esac +done +if [[ -z $distribution ]]; then + echo "Distribution to test not provided. Use '-d' to specify the names of the distribution to test. Ex.:" + echo "$0 -d tracing" + exit 1 +fi + +pid=$(cat otelcol-${distribution}.pid) +if [[ -z $pid ]]; then + echo "No Collectors running. Nothing to stop." + exit 0 +fi + +kill "${pid}" +if [ $? != 0 ]; then + echo "Failed to stop the running instance. Return code: $? . Skipping tests." + exit 2 +fi + +while kill -0 "${pid}" >/dev/null 2>&1 +do + sleep 0.1s +done + +rm "otelcol-${distribution}.pid" +echo "✅ '${distribution}' distribution of the OpenTelemetry Collector stopped." \ No newline at end of file diff --git a/test/test-all.sh b/test/test-all.sh new file mode 100755 index 0000000..8ec7fa8 --- /dev/null +++ b/test/test-all.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +while getopts d:s:b:g: flag +do + case "${flag}" in + d) distributions=${OPTARG};; + esac +done + +if [[ -z $distributions ]]; then + echo "List of distributions to test not provided. Use '-d' to specify the names of the distributions to test. Ex.:" + echo "$0 -d sidecar,tracing" + exit 1 +fi + +echo "Distributions to test: $distributions"; + +for distribution in $(echo "$distributions" | tr "," "\n") +do + ./test/test.sh -d "${distribution}" + rc=$? + if [ $rc != 0 ]; then + echo "❌ FAIL. Test failed for '${distribution}' distribution." + exit $rc + fi +done diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..834552a --- /dev/null +++ b/test/test.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +while getopts d:s:b:g: flag +do + case "${flag}" in + d) distribution=${OPTARG};; + esac +done +if [[ -z $distribution ]]; then + echo "Distribution to test not provided. Use '-d' to specify the names of the distribution to test. Ex.:" + echo "$0 -d tracing" + exit 1 +fi + +# register the teardown function before we can use it in the trap +function teardown { + ## tear down + echo "🔧 Tearing down..." + ./test/stop-otelcol.sh -d ${distribution} + + mkdir -p ./test/logs + + echo "🪵 '${distribution}' distribution of the OpenTelemetry Collector logs" + cat ./test/logs/otelcol-${distribution}.log + + echo "🪵 Test logs" + cat ./test/logs/test-${distribution}.log +} + +## setup +echo "🔧 Setting up..." +for st in ./test/install-tracegen.sh +do + ./${st} + rc=$? + if [ $rc != 0 ]; then + exit $rc + fi +done + +# from this point and on, we run the teardown before we exit +trap teardown EXIT + +## test +echo "🔧 Starting '${distribution}' distribution of the OpenTelemetry Collector..." +./test/start-otelcol.sh -d ${distribution} +rc=$? +if [ $rc != 0 ]; then + exit $rc +fi + +## generate a trace +echo "🔧 Generating trace..." +./test/generate-trace.sh -d ${distribution} +rc=$? +if [ $rc != 0 ]; then + exit $rc +fi + +## check that a trace was received +echo "🔧 Checking for existence of a trace..." +./test/check-trace.sh -d ${distribution} +rc=$? +if [ $rc != 0 ]; then + exit $rc +fi + +echo "✅ PASS: '${distribution}'" +exit 0