Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ ADDLICENSE_IGNORES = -ignore "**/.tools/**/*" \
-ignore "**/docs/**/*" \
-ignore "**/*.md" \
-ignore "**/testdata/*" \
-ignore "**/testdata/**/*" \
-ignore "**/golden/*" \
-ignore "**/google-built-opentelemetry-collector/*" \
-ignore "**/otelopscol/*" \
Expand Down
33 changes: 27 additions & 6 deletions cmd/distrogen/distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type BuildContainerOption string

const (
Alpine BuildContainerOption = "alpine"
Ubuntu BuildContainerOption = "ubuntu"
Debian BuildContainerOption = "debian"
)

// DistributionSpec is the specification for a new OpenTelemetry Collector distribution.
Expand All @@ -55,13 +55,16 @@ type DistributionSpec struct {
GoVersion string `yaml:"go_version"`
BinaryName string `yaml:"binary_name"`
BuildTags string `yaml:"build_tags"`
CollectorCGO bool `yaml:"collector_cgo"`
BoringCrypto bool `yaml:"boringcrypto"`
DockerRepo string `yaml:"docker_repo"`
Components *DistributionComponents `yaml:"components"`
Replaces ComponentReplaces `yaml:"replaces,omitempty"`
CustomValues map[string]any `yaml:"custom_values,omitempty"`
FeatureGates FeatureGates `yaml:"feature_gates"`
GoProxy string `yaml:"go_proxy,omitempty"`

// CollectorCGO determines whether the Collector will be built with CGO.
CollectorCGO bool `yaml:"collector_cgo,omitempty"`
}

// Diff will compare two different DistributionSpecs.
Expand Down Expand Up @@ -99,23 +102,41 @@ func (s *DistributionSpec) Query(field string) (string, error) {
return "", fmt.Errorf("field '%s': %w", field, ErrQueryValueNotFound)
}

var (
ErrSpecValidationBoringCryptoWithoutCGO = errors.New("boringcrypto build is not possible with collector_cgo turned off")
ErrSpecValidationBoringCryptoWithoutDebian = errors.New("boringcrypto is only possible with the debian build container")
)

// NewDistributionSpec loads the DistributionSpec from a yaml file.
func NewDistributionSpec(path string) (*DistributionSpec, error) {
spec, err := yamlUnmarshalFromFile[DistributionSpec](path)
if err != nil {
return nil, err
}

if spec.BuildContainer == "" {
spec.BuildContainer = Debian
}

// If BoringCrypto is set, CGO must be enabled and only the debian
// build container can be used.
if spec.BoringCrypto {
// If CGO was manually set to false in the config, return a validation error.
if !spec.CollectorCGO {
return nil, ErrSpecValidationBoringCryptoWithoutCGO
}
// If build container is manually set to something other than debian, return a validation error.
if spec.BuildContainer != Debian {
return nil, fmt.Errorf("%w, build_container was set to %s", ErrSpecValidationBoringCryptoWithoutDebian, spec.BuildContainer)
}
}

// It is a rare case where the contrib version falls out of sync with
// the canonical OpenTelemetry version, most of the time it is the same.
if spec.OpenTelemetryContribVersion == "" {
spec.OpenTelemetryContribVersion = spec.OpenTelemetryVersion
}

if spec.BuildContainer == "" {
spec.BuildContainer = Alpine
}

return spec, nil
}

Expand Down
26 changes: 26 additions & 0 deletions cmd/distrogen/distribution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,32 @@ func filesInDirAsSet(dir string) (map[string]bool, error) {
return fileSet, err
}

func TestSpecValidationError(t *testing.T) {
testCases := []struct {
name string
expectedErr error
}{
{
name: "boringcrypto_alpine_build_container",
expectedErr: ErrSpecValidationBoringCryptoWithoutDebian,
},
{
name: "boringcrypto_cgo_off",
expectedErr: ErrSpecValidationBoringCryptoWithoutCGO,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

testConfigPath := filepath.Join("testdata", "invalid", tc.name+".yaml")
_, err := NewDistributionSpec(testConfigPath)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}

func TestSpecQuery(t *testing.T) {
otelVer := "v0.124.0"
spec := &DistributionSpec{
Expand Down
14 changes: 11 additions & 3 deletions cmd/distrogen/templates/Dockerfile.build.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
# any custom components contained within your full project structure.
ARG PROJECT_ROOT="."
ARG CERT_CONTAINER="alpine:3"
{{ if eq .BuildContainer "ubuntu" -}}
ARG BUILD_CONTAINER="ubuntu:24.04"
{{ if eq .BuildContainer "debian" -}}
ARG BUILD_CONTAINER="debian"
FROM --platform=${BUILDPLATFORM:-linux/amd64} ${BUILD_CONTAINER} AS build

RUN apt-get update && apt-get install -y make curl{{ if .CollectorCGO }} build-essential{{ end }}

{{ else -}}
ARG BUILD_CONTAINER="alpine:3"
ARG BUILD_CONTAINER="alpine"
FROM --platform=${BUILDPLATFORM:-linux/amd64} ${BUILD_CONTAINER} AS build

RUN apk --update add make curl{{ if .CollectorCGO }} alpine-sdk{{ end }}
Expand All @@ -35,7 +35,15 @@ ARG BUILDARCH
ARG BUILDOS
ARG TARGETOS
ARG TARGETARCH
{{ if .CollectorCGO -}}
RUN if [ "${TARGETARCH}" = "arm64" ] && [ "${BUILDARCH}" != "arm64" ]; then \
apt-get install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross; \
CC=aarch64-linux-gnu-gcc; \
fi && \
CC=${CC} make build
{{ else -}}
RUN make build
{{ end -}}

FROM ${CERT_CONTAINER} AS certs
RUN apk --update add ca-certificates
Expand Down
11 changes: 9 additions & 2 deletions cmd/distrogen/templates/Dockerfile.goreleaser_releaser.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@
# The whole project is copied to the container in case you provide
# any custom components contained within your full project structure.
ARG PROJECT_ROOT="."
# Currently, this container has to be alpine based.
ARG BUILD_CONTAINER="alpine:3"
{{ if eq .BuildContainer "debian" -}}
ARG BUILD_CONTAINER="debian"
FROM ${BUILD_CONTAINER} AS build

RUN apt-get update && apt-get install -y make curl git{{ if .CollectorCGO }} build-essential{{ end }}

{{ else -}}
ARG BUILD_CONTAINER="alpine"
FROM ${BUILD_CONTAINER} AS build

RUN apk --update add make curl git{{ if .CollectorCGO }} alpine-sdk{{ end }}

{{ end -}}

ARG PROJECT_ROOT
COPY ${PROJECT_ROOT} /

Expand Down
3 changes: 3 additions & 0 deletions cmd/distrogen/templates/Makefile.go.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ ocb-generate: $(OCB_BIN)
$(COLLECTOR_BINARY_NAME): ocb-generate
cd $(COLLECTOR_BUILD_TEMP_DIR) && \
GOWORK=off \
{{ if .BoringCrypto -}}
GOEXPERIMENT=boringcrypto \
{{ end -}}
CGO_ENABLED=$(COLLECTOR_CGO) \
GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) \
$(GO_BIN) build \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
# any custom components contained within your full project structure.
ARG PROJECT_ROOT="."
ARG CERT_CONTAINER="alpine:3"
ARG BUILD_CONTAINER="alpine:3"
ARG BUILD_CONTAINER="debian"
FROM --platform=${BUILDPLATFORM:-linux/amd64} ${BUILD_CONTAINER} AS build

RUN apk --update add make curl
RUN apt-get update && apt-get install -y make curl

ARG PROJECT_ROOT
COPY ${PROJECT_ROOT} /
Expand All @@ -27,7 +27,6 @@ ARG BUILDOS
ARG TARGETOS
ARG TARGETARCH
RUN make build

FROM ${CERT_CONTAINER} AS certs
RUN apk --update add ca-certificates

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
# The whole project is copied to the container in case you provide
# any custom components contained within your full project structure.
ARG PROJECT_ROOT="."
# Currently, this container has to be alpine based.
ARG BUILD_CONTAINER="alpine:3"

ARG BUILD_CONTAINER="debian"
FROM ${BUILD_CONTAINER} AS build

RUN apk --update add make curl git
RUN apt-get update && apt-get install -y make curl git

ARG PROJECT_ROOT
COPY ${PROJECT_ROOT} /
Expand Down
4 changes: 2 additions & 2 deletions cmd/distrogen/testdata/generator/basic/golden/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module: ""
display_name: Basic OTel
description: A basic distribution of the OpenTelemetry Collector
blurb: A basic collector distro
build_container: alpine
build_container: debian
version: 0.121.0
opentelemetry_version: 0.121.0
opentelemetry_contrib_version: 0.121.0
opentelemetry_stable_version: 1.27.0
go_version: 1.24.0
binary_name: otelcol-basic
build_tags: ""
collector_cgo: false
boringcrypto: false
docker_repo: us-docker.pkg.dev/pretend-repo/otelcol-basic
components:
receivers:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
version: 2
project_name: opentelemetry-operations-collector

snapshot:
version_template: 0.121.0

env:
- LD_FLAGS=-s -w
- CGO_ENABLED=1
- BUILD_FLAGS=-trimpath
- GOWORK=off

builds:
- id: otelcol-basic-linux
goos:
- linux
goarch:
- amd64
- arm64
binary: otelcol-basic
dir: _build
ldflags:
- "-s -w"
flags:
- "-trimpath"
- "-buildvcs=false"

- id: otelcol-basic-windows
goos:
- windows
goarch:
- amd64
binary: otelcol-basic
dir: _build
ldflags:
- "-s -w"
flags:
- "-trimpath"
- "-buildvcs=false"

nfpms:
- package_name: otelcol-basic
contents:
- src: otelcol-basic.service
dst: /lib/systemd/system/otelcol-basic.service
- src: otelcol-basic.conf
dst: /etc/otelcol-basic/otelcol-basic.conf
type: config|noreplace
file_info:
mode: 0644
- src: config.yaml
dst: /etc/otelcol-basic/config.yaml
type: config|noreplace
file_info:
mode: 0644
scripts:
preinstall: preinstall.sh
postinstall: postinstall.sh
preremove: preremove.sh
overrides:
rpm:
dependencies:
- /bin/sh
ids:
- otelcol-basic-linux
formats:
- deb
- rpm
umask: 0
maintainer: Google Cloud Platform <[email protected]> # something better than this
description: A basic distribution of the OpenTelemetry Collector
license: Apache 2.0
15 changes: 15 additions & 0 deletions cmd/distrogen/testdata/generator/boringcrypto/golden/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# NOTE: File generated by distrogen. Do not manually edit.

FROM alpine:3.19 as certs
RUN apk --update add ca-certificates

FROM scratch

ARG USER_UID=10001
USER ${USER_UID}

COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --chmod=755 otelcol-basic /otelcol-basic
COPY config.yaml /etc/otelcol-basic/config.yaml
ENTRYPOINT ["/otelcol-basic", "--feature-gates=exporter.googlemanagedprometheus.intToDouble"]
CMD ["--config=/etc/otelcol-basic/config.yaml"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# NOTE: File generated by distrogen. Do not manually edit.

# This Dockerfile provides the same resulting container as
# the main Dockerfile, but it also performs the build within
# an earlier layer. The resulting container will be scratch and
# should be functionally identical.

# By default, this container should have the root of your project
# where all distributions are container. The generated version will
# use the respective distribution as the working directory for builds.
# The whole project is copied to the container in case you provide
# any custom components contained within your full project structure.
ARG PROJECT_ROOT="."
ARG CERT_CONTAINER="alpine:3"
ARG BUILD_CONTAINER="debian"
FROM --platform=${BUILDPLATFORM:-linux/amd64} ${BUILD_CONTAINER} AS build

RUN apt-get update && apt-get install -y make curl build-essential

ARG PROJECT_ROOT
COPY ${PROJECT_ROOT} /

WORKDIR /basic-distro

ARG BUILDARCH
ARG BUILDOS
ARG TARGETOS
ARG TARGETARCH
RUN if [ "${TARGETARCH}" = "arm64" ] && [ "${BUILDARCH}" != "arm64" ]; then \
apt-get install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross; \
CC=aarch64-linux-gnu-gcc; \
fi && \
CC=${CC} make build
FROM ${CERT_CONTAINER} AS certs
RUN apk --update add ca-certificates

FROM scratch

ARG USER_UID=10001
USER ${USER_UID}

COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build --chmod=755 /basic-distro/otelcol-basic /otelcol-basic
COPY --from=build --chmod=644 /basic-distro/config.yaml /etc/otelcol-basic/config.yaml

ENTRYPOINT ["/otelcol-basic", "--feature-gates=exporter.googlemanagedprometheus.intToDouble"]
CMD ["--config=/etc/otelcol-basic/config.yaml"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# NOTE: File generated by distrogen. Do not manually edit.

# This Dockerfile provides the same resulting container as
# the main Dockerfile, but it also performs the build within
# an earlier layer. The resulting container will be scratch and
# should be functionally identical.

# By default, this container should have the root of your project
# where all distributions are container. The generated version will
# use the respective distribution as the working directory for builds.
# The whole project is copied to the container in case you provide
# any custom components contained within your full project structure.
ARG PROJECT_ROOT="."
ARG BUILD_CONTAINER="debian"
FROM ${BUILD_CONTAINER} AS build

RUN apt-get update && apt-get install -y make curl git build-essential

ARG PROJECT_ROOT
COPY ${PROJECT_ROOT} /

WORKDIR /basic-distro
RUN make goreleaser-release
Loading