feat: introduce signoz-standalone and fix systemdcasting (#80)

#### Features   
- Add standalone Docker image (docs/standalone/): single container
running all SigNoz components via systemd
  casting
- Add SQLite metastore support in systemd casting (enricher, signoz
molding, forge, cast)
- Add Restart=on-failure with RestartSec=5 to migrator, ingester, and
signoz service templates to remove job readiness checks with
`After`/`Wants`/`Requires`
#### Fixes
                                                                     
- Enable all services before starting any (fixes Unit not found during
start)
- Use --no-block for systemctl start (prevents cast from blocking on
oneshot services)
 #### Refactors                                                 
- Remove inter-service dependency coupling (After=/Requires=/Wants=)
from all service templates; services manage their own readiness via
restart policies and readiness checks
- Move config material paths from configs/<component>/ to
<component>/<kind>/
- Move IsEnabled() checks to forgeCasting dispatcher instead of
individual forge methods
- Simplify discoverAndPrepareServices and startAllService, remove
service categorization map
- Render environment variables (Spec.Env) and ClickHouse DSN in
ingester, migrator, and telemetrystore templates
Related: https://github.com/SigNoz/platform-pod/issues/1522
This commit is contained in:
Nageshbansal
2026-03-26 23:51:57 +05:30
committed by GitHub
parent 4a049ac81d
commit 812d676792
29 changed files with 531 additions and 251 deletions
+16
View File
@@ -0,0 +1,16 @@
#### Auto generated by make docker-version-debian. DO NOT EDIT! ####
amd64=8af0e5095f9964007f5ebd11191dfe52dcb51bf3afa2c07f055fc5451b78ba0e
unknown=aa26de2aeba103c4f2232de5efe83d2b4522c26fec20c5848c9f16f2aa244b3f
arm=159390659db54d341957fe78ef829de76e5549d0f9fcbb777287bcfc6f6da2f8
unknown=83be97aab0d6eb03517006eea2cd7ecece54c20d3acbfe312d0ff4505dd4c344
arm=0a52c3389a9a13dbeb3f3183578c15dfd712e17dad4feacbe55d224d0f459afa
unknown=728313602cf4214e7e5fd2ab88fa68f2f9a8e11118ec24b04f9f05e93fd443f0
arm64=ee5473f786ff8a4e03409277c276b459b29afa55a84268bef55342c4f705b7ad
unknown=35e1cb927bb44a86ca8799cfe3d482a9e54e31a3995c28887c28bed9c0338bdd
386=02274f94f52336abd6ab4a8471ea09966613910ebaeed622429dc7b4b780e804
unknown=3cc496e7c7df2b166481306e36070238a7644af6b230646688ca3c6f675995a2
mips64le=b5bfd550af6266602aaef6c249baebf2c9835a2d0984013a23471cd8954503ff
ppc64le=8e69db6097e3efc0901fc84af17ea906710ae90b5842d919723eda3518ea6811
unknown=d1dc187105900becbeca525ab9ef08efa3c71cdb4b8c67a2151e3aadc1f57a48
s390x=a54db69bf6707382949f777f5fb8d0651d34a1b8602111a41eee7533e4ce07d8
unknown=57ae880cf756c23f9afd4ef46b418eaae9232ea48f7c994b5c81215b58f226a7
+4
View File
@@ -77,6 +77,10 @@ docker compose -f pours/deployment/compose.yaml logs -f signoz
cd pours/deployment && docker compose down
```
> [!NOTE]
> - `foundryctl cast` detects whether `docker compose` (v2 plugin) or `docker-compose` (legacy standalone) is available and uses whichever it finds, preferring the v2 plugin.
> - The `metadata.name` is used as the Compose project name (`-p` flag).
## Customization
Override component images, replicas, or environment variables in the casting spec. For platform-level changes to the generated `compose.yaml` (memory limits, networks, volumes), use [patches](../../concepts/patches.md).
@@ -57,6 +57,9 @@ Run the full pipeline (generate Terraform files and apply):
foundryctl cast -f casting.yaml
```
> [!NOTE]
> `foundryctl cast` runs `terraform init` followed by `terraform apply -auto-approve`. If you prefer to review the plan before applying, use the step-by-step approach below.
Step-by-step alternative:
```bash
+6
View File
@@ -40,10 +40,16 @@ Or step by step:
# Generate values.yaml
foundryctl forge -f casting.yaml
# Add the SigNoz Helm repo
helm repo add signoz https://charts.signoz.io
# Install with Helm
helm install signoz signoz/signoz -f pours/deployment/values.yaml -n signoz --create-namespace
```
> [!NOTE]
> `foundryctl cast` is idempotent. It detects whether a Helm release already exists and runs `helm upgrade` instead of `helm install` accordingly.
## Generated output
```text
@@ -39,10 +39,19 @@ Or step by step:
# Generate manifests
foundryctl forge -f casting.yaml
# Apply CRDs first (cast does this automatically)
kubectl apply -f https://raw.githubusercontent.com/Altinity/clickhouse-operator/0.25.3/deploy/operatorhub/0.25.3/clickhouseinstallations.clickhouse.altinity.com.crd.yaml
kubectl apply -f https://raw.githubusercontent.com/Altinity/clickhouse-operator/0.25.3/deploy/operatorhub/0.25.3/clickhouseinstallationtemplates.clickhouse.altinity.com.crd.yaml
kubectl apply -f https://raw.githubusercontent.com/Altinity/clickhouse-operator/0.25.3/deploy/operatorhub/0.25.3/clickhouseoperatorconfigurations.clickhouse.altinity.com.crd.yaml
kubectl apply -f https://raw.githubusercontent.com/Altinity/clickhouse-operator/0.25.3/deploy/operatorhub/0.25.3/clickhousekeeperinstallations.clickhouse-keeper.altinity.com.crd.yaml
# Apply with kubectl
kubectl apply -k pours/deployment/
```
> [!NOTE]
> `foundryctl cast` automatically fetches and applies the four Altinity ClickHouse Operator CRDs (v0.25.3) from GitHub before running `kubectl apply -k`. If you apply manually, you must install the CRDs first or the ClickHouseInstallation and ClickHouseKeeperInstallation resources will fail to create.
## Generated output
```text
@@ -103,3 +112,67 @@ Open `http://localhost:8080` to access the SigNoz UI.
## Customization
To set resource limits, storage classes, or scheduling constraints on the generated manifests, use [patches](../../concepts/patches.md). See the [kustomize-patches](../kustomize-patches/) example for a complete working configuration.
### Native Kustomize patches
Since Foundry generates standard Kustomize bases, you can also use native Kustomize patches on the generated `kustomization.yaml`. This lets you use strategic merge patches or overlays for environment-specific customization without re-forging.
Use a Foundry patch to inject a `patches` block into the root `kustomization.yaml`:
```yaml
apiVersion: v1alpha1
metadata:
name: signoz
spec:
deployment:
flavor: kustomize
mode: kubernetes
patches:
- target: "deployment/kustomization.yaml"
operations:
- op: add
path: /patches
value:
- target:
kind: StatefulSet
name: signoz-signoz
patch: |-
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: signoz-signoz
spec:
template:
spec:
nodeSelector:
node-role.kubernetes.io/observability: ""
```
Or create an overlay directory that references the generated base:
```
my-deployment/
├── base/ # Copy of pours/deployment/
│ └── ...
└── overlays/
└── prod/
├── kustomization.yaml
└── increase-resources.yaml
```
```yaml
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: increase-resources.yaml
target:
kind: StatefulSet
name: signoz-clickhouse
```
```bash
kubectl apply -k overlays/prod/
```
+3
View File
@@ -45,6 +45,9 @@ Run the full pipeline (validate prerequisites, generate files, install and start
sudo foundryctl cast -f casting.yaml
```
> [!NOTE]
> `foundryctl cast` requires `sudo` because it manages systemd services, creates system users, and writes to system directories.
Step-by-step alternative:
```bash
@@ -142,6 +142,8 @@ spec:
opamp.yaml: |
server_endpoint: ws://localhost:4320/v1/opamp
enabled: true
env:
SIGNOZ_OTEL_COLLECTOR_TIMEOUT: 10m
image: signoz/signoz-otel-collector:latest
version: latest
status:
@@ -276,6 +278,8 @@ spec:
- signozclickhousemeter
opamp.yaml: |
server_endpoint: ws://localhost:4320/v1/opamp
env:
SIGNOZ_OTEL_COLLECTOR_TIMEOUT: 10m
metastore:
kind: postgres
spec:
@@ -2,15 +2,17 @@
WantedBy=multi-user.target
[Service]
ExecStart=/opt/ingester/bin/signoz-otel-collector --config=%Y/configs/ingester/ingester.yaml --manager-config=%Y/configs/ingester/opamp.yaml --copy-path=/var/lib/ingester/ingester.yaml
Environment=SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://localhost:9000
Environment=SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
ExecStart=/opt/ingester/bin/signoz-otel-collector --config=%Y/ingester/ingester.yaml --manager-config=%Y/ingester/opamp.yaml --copy-path=/var/lib/ingester/ingester.yaml
ExecStartPre=/opt/ingester/bin/signoz-otel-collector migrate sync check
Group=signoz
KillMode=mixed
Restart=on-failure
RestartSec=5
Type=simple
User=signoz
[Unit]
After=signoz-telemetrystore-clickhouse-0-0 signoz-telemetrystore-migrator
Description=SigNoz OTel Collector
Documentation=https://signoz.io/docs
Requires=signoz-telemetrystore-migrator
@@ -11,12 +11,11 @@ ExecStart=/opt/signoz/bin/signoz server
Group=signoz
KillMode=mixed
Restart=on-failure
RestartSec=5
Type=simple
User=signoz
WorkingDirectory=/opt/signoz
[Unit]
After=signoz-telemetrystore-clickhouse-0-0 signoz-metastore-postgres signoz-telemetrystore-migrator
Description=SigNoz
Documentation=https://signoz.io/docs
Requires=signoz-telemetrystore-migrator
@@ -14,7 +14,7 @@ Type=simple
User=clickhouse
[Unit]
After=time-sync.target network-online.target signoz-telemetrykeeper-clickhousekeeper-0.service
After=time-sync.target network-online.target
Description=ClickHouse Server (v25.5.6)
Requires=network-online.target
Wants=time-sync.target signoz-telemetrykeeper-clickhousekeeper-0.service
Wants=time-sync.target
@@ -2,14 +2,17 @@
WantedBy=multi-user.target
[Service]
ExecStart=/bin/bash -c '/opt/ingester/bin/signoz-otel-collector migrate bootstrap --clickhouse-dsn=tcp://localhost:9000 && /opt/ingester/bin/signoz-otel-collector migrate sync up --clickhouse-dsn=tcp://localhost:9000 && /opt/ingester/bin/signoz-otel-collector migrate async up --clickhouse-dsn=tcp://localhost:9000'
Environment=SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://localhost:9000
Environment=SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
ExecStart=/bin/bash -c '/opt/ingester/bin/signoz-otel-collector migrate bootstrap && /opt/ingester/bin/signoz-otel-collector migrate sync up && /opt/ingester/bin/signoz-otel-collector migrate async up'
ExecStartPre=/opt/ingester/bin/signoz-otel-collector migrate ready
Group=signoz
RemainAfterExit=yes
Restart=on-failure
RestartSec=5
Type=oneshot
User=signoz
[Unit]
After=signoz-telemetrystore-clickhouse-0-0
Description=SigNoz Schema Migrator
Description=SigNoz TelemetryStore Migrator
Documentation=https://signoz.io/docs
Requires=signoz-telemetrystore-clickhouse-0-0
+74
View File
@@ -0,0 +1,74 @@
ARG DEBIAN_SHA="pass-a-valid-docker-sha-otherwise-this-will-fail"
FROM debian@sha256:${DEBIAN_SHA}
LABEL maintainer="signoz"
ARG OS="linux"
ARG ARCH
ARG SIGNOZ_VERSION=latest
ARG INGESTER_VERSION=latest
ARG FOUNDRY_VERSION=latest
# Install systemd
RUN apt-get update && apt-get install -y --no-install-recommends \
systemd \
systemd-sysv \
ca-certificates \
curl \
tar \
gnupg && \
rm -f /lib/systemd/system/multi-user.target.wants/* \
/etc/systemd/system/*.wants/* \
/lib/systemd/system/local-fs.target.wants/* \
/lib/systemd/system/sockets.target.wants/*udev* \
/lib/systemd/system/sockets.target.wants/*initctl* \
/lib/systemd/system/sysinit.target.wants/systemd-tmpfiles-setup* \
/lib/systemd/system/systemd-update-utmp*
# SigNoz
RUN mkdir -p /opt/signoz && \
curl -fsSL "https://github.com/SigNoz/signoz/releases/${SIGNOZ_VERSION}/download/signoz_${OS}_${ARCH}.tar.gz" | \
tar -xz --strip-components=1 -C /opt/signoz && \
chmod +x /opt/signoz/bin/signoz
# OTel Collector (ingester)
RUN mkdir -p /opt/ingester && \
curl -fsSL "https://github.com/SigNoz/signoz-otel-collector/releases/${INGESTER_VERSION}/download/signoz-otel-collector_${OS}_${ARCH}.tar.gz" | \
tar -xz --strip-components=1 -C /opt/ingester && \
chmod +x /opt/ingester/bin/signoz-otel-collector
# Foundry
RUN mkdir -p /usr/local/bin && \
curl -fsSL "https://github.com/SigNoz/foundry/releases/${FOUNDRY_VERSION}/download/foundry_${OS}_${ARCH}.tar.gz" | \
tar -xz --strip-components=1 -C /tmp && \
mv /tmp/bin/foundryctl /usr/local/bin/foundryctl && \
chmod +x /usr/local/bin/foundryctl
# Install ClickHouse from apt repo
RUN curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | \
gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg && \
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb stable main" \
> /etc/apt/sources.list.d/clickhouse.list && \
apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
clickhouse-server \
clickhouse-client && \
systemctl disable clickhouse-server || true
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
RUN useradd -r -m -d /opt/signoz -s /bin/false signoz && \
mkdir -p /var/lib/signoz /var/lib/ingester /etc/foundry /opt/signoz/web && \
chown signoz:signoz /var/lib/signoz /var/lib/ingester /opt/signoz
COPY docs/standalone/casting.yaml /etc/foundry/casting.yaml
COPY docs/standalone/foundry-setup.service /etc/systemd/system/foundry-setup.service
RUN mkdir -p /var/lib/foundry && systemctl enable foundry-setup.service
EXPOSE 8080 4317 4318
VOLUME ["/var/lib/clickhouse", "/var/lib/signoz"]
STOPSIGNAL SIGRTMIN+3
CMD ["/sbin/init"]
+86
View File
@@ -0,0 +1,86 @@
# Standalone Docker Image
| | |
| --- | --- |
| **Casting** | `systemd` / `binary` |
| **Use Case** | Single Docker image for quick testing, development, and CI |
## Overview
An OpenTelemetry-native observability backend in a single Docker image. The standalone image bundles all SigNoz components into one container for development, demo, and testing environments.
**Included components:**
- **SigNoz** - query engine and UI
- **OpenTelemetry Collector** - telemetry ingestion
- **ClickHouse** - telemetry storage
- **SQLite** - metadata storage
- **[Foundry](https://github.com/SigNoz/foundry)** - deployment orchestration via `foundryctl`
Applications can send telemetry using OpenTelemetry's standard defaults (OTLP gRPC/HTTP) without additional configuration. On first boot, Foundry generates all service configs and starts components via systemd.
## Prerequisites
- Docker Engine 20.10+
## Deploy
```bash
docker run -d --name signoz --privileged \
-p 8080:8080 \
-p 4317:4317 \
-p 4318:4318 \
signoz/signoz-standalone:latest
```
Access SigNoz UI at `http://localhost:8080`.
Send telemetry to:
- OTLP gRPC: `localhost:4317`
- OTLP HTTP: `localhost:4318`
## Customization
To customize the deployment, mount your own `casting.yaml` into the container:
```bash
docker run -d --name signoz --privileged \
-p 8080:8080 \
-p 4317:4317 \
-p 4318:4318 \
-v ./casting.yaml:/etc/foundry/casting.yaml \
signoz/signoz-standalone:latest
```
See the default [casting.yaml](casting.yaml) for the full config structure.
## Persist Data
```bash
docker run -d --name signoz --privileged \
-p 8080:8080 \
-p 4317:4317 \
-p 4318:4318 \
-v signoz-clickhouse:/var/lib/clickhouse \
-v signoz-data:/var/lib/signoz \
signoz/signoz-standalone:latest
```
## After deployment
```bash
# View logs for all services
docker exec signoz journalctl -f
# View logs for a specific service
docker exec signoz journalctl -u signoz-signoz.service -f
docker exec signoz journalctl -u signoz-ingester.service -f
docker exec signoz journalctl -u signoz-telemetrystore-clickhouse-0-0.service -f
```
## Limitations
- Requires `--privileged` flag (systemd needs cgroup access)
- `docker logs` is empty - use `journalctl` inside the container
- Single-node only (no clustering)
+12
View File
@@ -0,0 +1,12 @@
apiVersion: v1alpha1
metadata:
name: signoz
annotations:
foundry.signoz.io/signoz-binary-path: /opt/signoz/bin/signoz
foundry.signoz.io/ingester-binary-path: /opt/ingester/bin/signoz-otel-collector
spec:
deployment:
flavor: binary
mode: systemd
metastore:
kind: sqlite
+13
View File
@@ -0,0 +1,13 @@
[Unit]
Description=Foundry Setup - SigNoz Standalone
After=multi-user.target
ConditionPathExists=!/var/lib/foundry/.initialized
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/foundryctl cast -f /etc/foundry/casting.yaml -p /etc/foundry/pours --no-gauge
ExecStartPost=/bin/touch /var/lib/foundry/.initialized
[Install]
WantedBy=multi-user.target
+140 -175
View File
@@ -22,10 +22,6 @@ import (
const svcSuffix = ".service"
const (
serviceStartTimeout = 2 * time.Minute
)
var _ rootcasting.Casting = (*systemdCasting)(nil)
type systemdCasting struct {
@@ -54,7 +50,7 @@ func (c *systemdCasting) Enricher(ctx context.Context, config *v1alpha1.Casting)
func (c *systemdCasting) Forge(ctx context.Context, cfg v1alpha1.Casting, poursPath string) ([]types.Material, error) {
var materials []types.Material
for _, tmpl := range c.castings {
m, err := c.forgeCasting(tmpl, &cfg, poursPath)
m, err := c.forgeCasting(tmpl, &cfg)
if err != nil {
return nil, fmt.Errorf("failed to forge: %w", err)
}
@@ -70,11 +66,11 @@ func (c *systemdCasting) Cast(ctx context.Context, config v1alpha1.Casting, pour
defer cancel()
// Discover and prepare services
serviceMap, err := c.discoverAndPrepareServices(runctx, poursPath)
services, err := c.discoverAndPrepareServices(runctx, poursPath)
if err != nil {
return err
}
if serviceMap == nil {
if len(services) == 0 {
c.logger.WarnContext(runctx, "No service files found in pours directory")
return nil
}
@@ -85,13 +81,21 @@ func (c *systemdCasting) Cast(ctx context.Context, config v1alpha1.Casting, pour
}
if config.Spec.MetaStore.Spec.IsEnabled() {
if err := c.initializePostgres(ctx, &config); err != nil {
return err
switch config.Spec.MetaStore.Kind {
case v1alpha1.MetaStoreKindPostgres:
if err := c.initializePostgres(ctx, &config); err != nil {
return err
}
case v1alpha1.MetaStoreKindSQLite:
if err := os.MkdirAll("/var/lib/signoz", 0755); err != nil {
return fmt.Errorf("failed to create sqlite data directory: %w", err)
}
_ = c.execCommand(ctx, "chown", "-R", "signoz:signoz", "/var/lib/signoz")
}
}
// Start all services - systemd dependencies handle ordering
if err := c.startAllServices(runctx, serviceMap); err != nil {
if err := c.startAllServices(runctx, services); err != nil {
return err
}
@@ -99,115 +103,113 @@ func (c *systemdCasting) Cast(ctx context.Context, config v1alpha1.Casting, pour
return nil
}
func (c *systemdCasting) forgeCasting(tmpl *types.Template, cfg *v1alpha1.Casting, poursPath string) ([]types.Material, error) {
func (c *systemdCasting) forgeCasting(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
switch tmpl {
case signozServiceTemplate:
if !cfg.Spec.Signoz.Spec.IsEnabled() {
return nil, nil
}
return c.forgeSignoz(tmpl, cfg)
case metaStoreServiceTemplate:
return c.forgeMetaStore(tmpl, cfg, poursPath)
if !cfg.Spec.MetaStore.Spec.IsEnabled() {
return nil, nil
}
return c.forgeMetaStore(tmpl, cfg)
case ingesterServiceTemplate:
return c.forgeIngester(tmpl, cfg, poursPath)
if !cfg.Spec.Ingester.Spec.IsEnabled() {
return nil, nil
}
return c.forgeIngester(tmpl, cfg)
case telemetryStoreServiceTemplate:
return c.forgeTelemetryStore(tmpl, cfg, poursPath)
if !cfg.Spec.TelemetryStore.Spec.IsEnabled() {
return nil, nil
}
return c.forgeTelemetryStore(tmpl, cfg)
case telemetryKeeperServiceTemplate:
return c.forgeTelemetryKeeper(tmpl, cfg, poursPath)
if !cfg.Spec.TelemetryKeeper.Spec.IsEnabled() {
return nil, nil
}
return c.forgeTelemetryKeeper(tmpl, cfg)
case telemetryStoreMigratorServiceTemplate:
if !cfg.Spec.TelemetryStore.Spec.IsEnabled() {
return nil, nil
}
return c.forgeMigrator(tmpl, cfg)
default:
return nil, nil
}
}
// --- Forge Handlers ---
func (c *systemdCasting) forgeIngester(tmpl *types.Template, cfg *v1alpha1.Casting, poursPath string) ([]types.Material, error) {
func (c *systemdCasting) forgeIngester(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
spec := &cfg.Spec.Ingester
if !spec.Spec.IsEnabled() {
return nil, nil
}
if spec.Status.Config.Data == nil {
return nil, fmt.Errorf("no config molded for %s", v1alpha1.MoldingKindIngester)
}
// Initialize status extras
if spec.Status.Extras == nil {
spec.Status.Extras = make(map[string]string)
}
// Create config materials
mats, err := c.configMaterials(spec.Status.Config.Data, "ingester")
if err != nil {
return nil, err
}
// Set extras for template
spec.Status.Extras["cfgPath"] = "configs/ingester/ingester.yaml"
spec.Status.Extras["cfgOpampPath"] = "configs/ingester/opamp.yaml"
spec.Status.Extras["cfgPath"] = filepath.Join("ingester", "ingester.yaml")
spec.Status.Extras["cfgOpampPath"] = filepath.Join("ingester", "opamp.yaml")
spec.Status.Extras["workingDir"] = "/opt/ingester"
// Create service material
var materials []types.Material
svcMat, err := c.renderTemplate(tmpl, cfg, cfg.Metadata.Name+"-ingester"+svcSuffix)
if err != nil {
return nil, err
}
return append(mats, svcMat), nil
materials = append(materials, svcMat)
cfgMats, err := c.configMaterials(spec.Spec.Config.Data, "ingester", "")
if err != nil {
return nil, err
}
materials = append(materials, cfgMats...)
return materials, nil
}
func (c *systemdCasting) forgeSignoz(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
spec := &cfg.Spec.Signoz
if !spec.Spec.IsEnabled() {
return nil, nil
}
// Initialize status maps
if spec.Status.Extras == nil {
spec.Status.Extras = make(map[string]string)
}
// Create env material
prefix := cfg.Metadata.Name + "-signoz"
spec.Status.Extras["workingDir"] = "/opt/signoz"
// Create service material
svcMat, err := c.renderTemplate(tmpl, cfg, prefix+svcSuffix)
var materials []types.Material
svcMat, err := c.renderTemplate(tmpl, cfg, cfg.Metadata.Name+"-signoz"+svcSuffix)
if err != nil {
return nil, err
}
return []types.Material{svcMat}, nil
materials = append(materials, svcMat)
return materials, nil
}
func (c *systemdCasting) forgeMetaStore(tmpl *types.Template, cfg *v1alpha1.Casting, poursPath string) ([]types.Material, error) {
func (c *systemdCasting) forgeMetaStore(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
spec := &cfg.Spec.MetaStore
if !spec.Spec.IsEnabled() {
return nil, nil
}
// Initialize status extras
if spec.Status.Extras == nil {
spec.Status.Extras = make(map[string]string)
}
// Create env material
prefix := fmt.Sprintf("%s-metastore-%s", cfg.Metadata.Name, spec.Kind.String())
// Create service material
svcMat, err := c.renderTemplate(tmpl, cfg, prefix+svcSuffix)
if err != nil {
return nil, err
var materials []types.Material
switch spec.Kind {
case v1alpha1.MetaStoreKindPostgres:
svcMat, err := c.renderTemplate(tmpl, cfg, fmt.Sprintf("%s-metastore-%s%s", cfg.Metadata.Name, spec.Kind.String(), svcSuffix))
if err != nil {
return nil, err
}
materials = append(materials, svcMat)
}
return []types.Material{svcMat}, nil
return materials, nil
}
func (c *systemdCasting) forgeTelemetryStore(tmpl *types.Template, cfg *v1alpha1.Casting, poursPath string) ([]types.Material, error) {
func (c *systemdCasting) forgeTelemetryStore(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
spec := &cfg.Spec.TelemetryStore
if !spec.Spec.IsEnabled() {
return nil, nil
}
if spec.Status.Config.Data == nil {
return nil, fmt.Errorf("no config molded for %s", v1alpha1.MoldingKindTelemetryStore)
}
// Initialize status extras
if spec.Status.Extras == nil {
spec.Status.Extras = make(map[string]string)
}
@@ -216,36 +218,30 @@ func (c *systemdCasting) forgeTelemetryStore(tmpl *types.Template, cfg *v1alpha1
reps := max(1, *spec.Spec.Cluster.Replicas+1)
shards := max(1, *spec.Spec.Cluster.Shards)
// Create config materials
mats, err := c.configMaterials(spec.Status.Config.Data, "telemetrystore")
if err != nil {
return nil, err
}
var materials []types.Material
// Create service materials for each shard/replica
for s := range shards {
for r := range reps {
svcName := fmt.Sprintf("%s-telemetrystore-%s-%d-%d%s", cfg.Metadata.Name, kind, s, r, svcSuffix)
svcMat, err := c.renderTemplate(tmpl, cfg, svcName)
svcMat, err := c.renderTemplate(tmpl, cfg, fmt.Sprintf("%s-telemetrystore-%s-%d-%d%s", cfg.Metadata.Name, kind, s, r, svcSuffix))
if err != nil {
return nil, err
}
mats = append(mats, svcMat)
materials = append(materials, svcMat)
}
}
return mats, nil
cfgMats, err := c.configMaterials(spec.Spec.Config.Data, "telemetrystore", kind)
if err != nil {
return nil, err
}
materials = append(materials, cfgMats...)
return materials, nil
}
func (c *systemdCasting) forgeTelemetryKeeper(tmpl *types.Template, cfg *v1alpha1.Casting, poursPath string) ([]types.Material, error) {
func (c *systemdCasting) forgeTelemetryKeeper(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
spec := &cfg.Spec.TelemetryKeeper
if !spec.Spec.IsEnabled() {
return nil, nil
}
if spec.Status.Config.Data == nil {
return nil, fmt.Errorf("no config molded for %s", v1alpha1.MoldingKindTelemetryKeeper)
}
// Initialize status extras
if spec.Status.Extras == nil {
spec.Status.Extras = make(map[string]string)
}
@@ -253,42 +249,53 @@ func (c *systemdCasting) forgeTelemetryKeeper(tmpl *types.Template, cfg *v1alpha
kind := spec.Kind.String()
reps := max(1, *spec.Spec.Cluster.Replicas)
// Create config materials
mats, err := c.configMaterials(spec.Status.Config.Data, "telemetrykeeper")
// Config materials are created first because cfgPath extra is derived from them
cfgMats, err := c.configMaterials(spec.Spec.Config.Data, "telemetrykeeper", kind)
if err != nil {
return nil, err
}
if len(cfgMats) > 0 {
spec.Status.Extras["cfgPath"] = filepath.Join("/etc/clickhouse-keeper/", filepath.Base(cfgMats[0].Path()))
}
// Set config path for template
spec.Status.Extras["cfgPath"] = filepath.Join("/etc/clickhouse-keeper/", filepath.Base(mats[0].Path()))
var materials []types.Material
// Create service materials for each replica
for r := range reps {
svcName := fmt.Sprintf("%s-telemetrykeeper-%s-%d%s", cfg.Metadata.Name, kind, r, svcSuffix)
svcMat, err := c.renderTemplate(tmpl, cfg, svcName)
svcMat, err := c.renderTemplate(tmpl, cfg, fmt.Sprintf("%s-telemetrykeeper-%s-%d%s", cfg.Metadata.Name, kind, r, svcSuffix))
if err != nil {
return nil, err
}
mats = append(mats, svcMat)
materials = append(materials, svcMat)
}
return mats, nil
materials = append(materials, cfgMats...)
return materials, nil
}
func (c *systemdCasting) forgeMigrator(tmpl *types.Template, cfg *v1alpha1.Casting) ([]types.Material, error) {
spec := &cfg.Spec.TelemetryStore
if !spec.Spec.IsEnabled() {
return nil, nil
}
var materials []types.Material
// Create service material
svcMat, err := c.renderTemplate(tmpl, cfg, cfg.Metadata.Name+"-telemetrystore-migrator"+svcSuffix)
if err != nil {
return nil, err
}
return []types.Material{svcMat}, nil
materials = append(materials, svcMat)
return materials, nil
}
// --- Material Helpers ---
func (c *systemdCasting) configMaterials(data map[string]string, component string, kind string) ([]types.Material, error) {
mats := make([]types.Material, 0, len(data))
for filename, content := range data {
m, err := types.NewYAMLMaterial([]byte(content), filepath.Join(rootcasting.DeploymentDir, component, kind, filename))
if err != nil {
return nil, fmt.Errorf("failed to create %s config material %s: %w", component, filename, err)
}
mats = append(mats, m)
}
return mats, nil
}
func (c *systemdCasting) renderTemplate(tmpl *types.Template, cfg *v1alpha1.Casting, path string) (types.Material, error) {
var buf bytes.Buffer
@@ -298,18 +305,6 @@ func (c *systemdCasting) renderTemplate(tmpl *types.Template, cfg *v1alpha1.Cast
return types.NewINIMaterial(buf.Bytes(), filepath.Join(rootcasting.DeploymentDir, path))
}
func (c *systemdCasting) configMaterials(data map[string]string, path string) ([]types.Material, error) {
mats := make([]types.Material, 0, len(data))
for file, content := range data {
m, err := types.NewYAMLMaterial([]byte(content), filepath.Join(rootcasting.DeploymentDir, "configs/", path, file))
if err != nil {
return nil, fmt.Errorf("failed to create config material %s: %w", file, err)
}
mats = append(mats, m)
}
return mats, nil
}
// execCommand executes a command and returns an error if it fails.
func (c *systemdCasting) execCommand(ctx context.Context, name string, args ...string) error {
cmd := exec.CommandContext(ctx, name, args...)
@@ -318,61 +313,33 @@ func (c *systemdCasting) execCommand(ctx context.Context, name string, args ...s
return cmd.Run()
}
// discoverAndPrepareServices discovers service files, categorizes them, and prepares systemd.
// Returns nil serviceMap if no services found.
func (c *systemdCasting) discoverAndPrepareServices(ctx context.Context, poursPath string) (map[string][]string, error) {
// discoverAndPrepareServices discovers service files in the pours directory and reloads systemd.
func (c *systemdCasting) discoverAndPrepareServices(ctx context.Context, poursPath string) ([]string, error) {
deploymentPath := filepath.Join(poursPath, rootcasting.DeploymentDir)
entries, err := os.ReadDir(deploymentPath)
if err != nil {
return nil, fmt.Errorf("failed to read directory %s: %w", deploymentPath, err)
}
serviceMap := map[string][]string{"keeper": {}, "store": {}, "postgres": {}, "signoz": {}, "ingester": {}, "migrator": {}}
var services []string
for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".service") {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), svcSuffix) {
continue
}
servicePath := filepath.Join(deploymentPath, entry.Name())
baseName := strings.TrimSuffix(entry.Name(), ".service")
switch {
case strings.HasSuffix(baseName, "-migrator"):
serviceMap["migrator"] = append(serviceMap["migrator"], servicePath)
case strings.Contains(baseName, "-telemetrykeeper-") && !strings.Contains(baseName, "-migrator"):
serviceMap["keeper"] = append(serviceMap["keeper"], servicePath)
case strings.Contains(baseName, "-telemetrystore-") && !strings.Contains(baseName, "-migrator"):
serviceMap["store"] = append(serviceMap["store"], servicePath)
case strings.Contains(baseName, "-metastore-postgres"):
serviceMap["postgres"] = append(serviceMap["postgres"], servicePath)
case strings.HasSuffix(baseName, "-signoz"):
serviceMap["signoz"] = append(serviceMap["signoz"], servicePath)
case strings.HasSuffix(baseName, "-ingester"):
serviceMap["ingester"] = append(serviceMap["ingester"], servicePath)
default:
c.logger.WarnContext(ctx, "Unknown service type, skipping", slog.String("service", servicePath))
}
services = append(services, filepath.Join(deploymentPath, entry.Name()))
}
// Check if any services were found
total := 0
for cat, svcs := range serviceMap {
if len(svcs) > 0 {
c.logger.DebugContext(ctx, "Found services", slog.String("category", cat), slog.Int("count", len(svcs)))
total += len(svcs)
}
}
if total == 0 {
return map[string][]string{}, nil
if len(services) == 0 {
return nil, nil
}
// Reload systemd to pick up new service files
c.logger.DebugContext(ctx, "Reloading systemd daemon")
c.logger.DebugContext(ctx, "Found services", slog.Int("count", len(services)))
if err := c.execCommand(ctx, "systemctl", "daemon-reload"); err != nil {
return nil, fmt.Errorf("systemd daemon-reload failed: %w", err)
}
return serviceMap, nil
return services, nil
}
// setupSystemEnvironment creates signoz user, directories, copies configs, and validates binaries.
@@ -394,12 +361,14 @@ func (c *systemdCasting) setupSystemEnvironment(ctx context.Context, config *v1a
// Copy clickhouse configs to standard locations
if config.Spec.TelemetryStore.Spec.IsEnabled() {
if err := c.copyDir(filepath.Join(poursPath, rootcasting.DeploymentDir, "configs", "telemetrystore"), "/etc/clickhouse-server/"); err != nil {
src := filepath.Join(poursPath, rootcasting.DeploymentDir, "telemetrystore", config.Spec.TelemetryStore.Kind.String())
if err := c.copyDir(src, "/etc/clickhouse-server/"); err != nil {
return fmt.Errorf("failed to copy clickhouse-server configs: %w", err)
}
}
if config.Spec.TelemetryKeeper.Spec.IsEnabled() {
if err := c.copyDir(filepath.Join(poursPath, rootcasting.DeploymentDir, "configs", "telemetrykeeper"), "/etc/clickhouse-keeper/"); err != nil {
src := filepath.Join(poursPath, rootcasting.DeploymentDir, "telemetrykeeper", config.Spec.TelemetryKeeper.Kind.String())
if err := c.copyDir(src, "/etc/clickhouse-keeper/"); err != nil {
return fmt.Errorf("failed to copy clickhouse-keeper configs: %w", err)
}
}
@@ -463,32 +432,28 @@ func (c *systemdCasting) validateBinaries(config *v1alpha1.Casting) error {
}
// startAllServices enables and starts all discovered services.
// Systemd dependencies ensure proper ordering.
func (c *systemdCasting) startAllServices(ctx context.Context, serviceMap map[string][]string) error {
// Collect all services
var allServices []string
for _, services := range serviceMap {
allServices = append(allServices, services...)
}
if len(allServices) == 0 {
return nil
}
// Enable and start all services - systemd will handle ordering via dependencies
for _, svc := range allServices {
// All services are enabled first so that dependency references resolve,
// then started — systemd handles ordering via After=/Requires=.
func (c *systemdCasting) startAllServices(ctx context.Context, services []string) error {
// Enable all services first so dependencies can be resolved
for _, svc := range services {
unitName := filepath.Base(svc)
c.logger.DebugContext(ctx, "Enabling service", slog.String("service", unitName), slog.String("path", svc))
// Use full path for enable - systemctl can work with paths to service files
c.logger.DebugContext(ctx, "Enabling service", slog.String("service", unitName))
if err := c.execCommand(ctx, "systemctl", "enable", svc); err != nil {
return fmt.Errorf("failed to enable service %s: %w", unitName, err)
}
}
// Reload systemd to pick up all enabled services
if err := c.execCommand(ctx, "systemctl", "daemon-reload"); err != nil {
return fmt.Errorf("systemd daemon-reload failed: %w", err)
}
// Start all services without blocking — systemd dependencies handle ordering
for _, svc := range services {
unitName := filepath.Base(svc)
c.logger.InfoContext(ctx, "Starting service", slog.String("service", unitName))
startCtx, cancel := context.WithTimeout(ctx, serviceStartTimeout)
// Use full path for start as well
err := c.execCommand(startCtx, "systemctl", "start", unitName)
cancel()
if err != nil {
if err := c.execCommand(ctx, "systemctl", "start", "--no-block", unitName); err != nil {
return fmt.Errorf("failed to start service %s: %w", unitName, err)
}
}
+20 -10
View File
@@ -97,20 +97,25 @@ func (e *linuxMoldingEnricher) enrichTelemetryKeeper(config *v1alpha1.Casting) e
}
func (e *linuxMoldingEnricher) enrichMetaStore(config *v1alpha1.Casting) error {
dsn := types.FormatAddress("postgres", "localhost", baseMetaStorePostgresPort)
config.Spec.MetaStore.Status.Addresses.DSN = []string{dsn}
switch config.Spec.MetaStore.Kind {
case v1alpha1.MetaStoreKindSQLite:
// SQLite — no addresses or binaries to enrich.
case v1alpha1.MetaStoreKindPostgres:
dsn := types.FormatAddress("postgres", "localhost", baseMetaStorePostgresPort)
config.Spec.MetaStore.Status.Addresses.DSN = []string{dsn}
// Get the annotation value
metastoreBin := config.Metadata.Annotations["foundry.signoz.io/metastore-postgres-binary-path"]
// Get the annotation value
metastoreBin := config.Metadata.Annotations["foundry.signoz.io/metastore-postgres-binary-path"]
// If it's missing, apply the default and write it back
if metastoreBin == "" {
metastoreBin = "/usr/bin/postgres"
// If it's missing, apply the default and write it back
if metastoreBin == "" {
metastoreBin = "/usr/bin/postgres"
if config.Metadata.Annotations == nil {
config.Metadata.Annotations = make(map[string]string)
if config.Metadata.Annotations == nil {
config.Metadata.Annotations = make(map[string]string)
}
config.Metadata.Annotations["foundry.signoz.io/metastore-postgres-binary-path"] = metastoreBin
}
config.Metadata.Annotations["foundry.signoz.io/metastore-postgres-binary-path"] = metastoreBin
}
return nil
}
@@ -157,5 +162,10 @@ func (e *linuxMoldingEnricher) enrichIngester(config *v1alpha1.Casting) error {
config.Metadata.Annotations["foundry.signoz.io/ingester-binary-path"] = ingesterBin
}
if config.Spec.Ingester.Status.Env == nil {
config.Spec.Ingester.Status.Env = make(map[string]string)
}
config.Spec.Ingester.Status.Env["SIGNOZ_OTEL_COLLECTOR_TIMEOUT"] = "10m"
return nil
}
@@ -1,9 +1,8 @@
[Unit]
Description=ClickHouse Server (v25.5.6)
Requires=network-online.target
After=time-sync.target network-online.target{{ if $.Spec.TelemetryKeeper.Spec.Enabled }} {{ $.Metadata.Name }}-telemetrykeeper-{{ $.Spec.TelemetryKeeper.Kind }}-0.service{{ end }}
Wants=time-sync.target{{ if $.Spec.TelemetryKeeper.Spec.Enabled }} {{ $.Metadata.Name }}-telemetrykeeper-{{ $.Spec.TelemetryKeeper.Kind }}-0.service{{ end }}
After=time-sync.target network-online.target
Wants=time-sync.target
[Service]
Type=simple
@@ -13,9 +12,12 @@ Restart=always
RestartSec=30
RuntimeDirectory=clickhouse
ExecStart=/usr/bin/clickhouse-server --config=/etc/clickhouse-server/config.yaml --pid-file=/run/clickhouse/clickhouse.pid
{{- range $key, $value := $.Spec.TelemetryStore.Spec.Env }}
Environment={{ $key }}={{ $value }}
{{- end }}
LimitCORE=infinity
LimitNOFILE=500000
CapabilityBoundingSet=CAP_NET_ADMIN CAP_IPC_LOCK CAP_SYS_NICE CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
@@ -11,9 +11,12 @@ Group=clickhouse
Restart=always
RestartSec=30
RuntimeDirectory=clickhouse-keeper
{{ if and $.Spec.TelemetryKeeper.Status.Extras (index $.Spec.TelemetryKeeper.Status.Extras "cfgPath") }}
{{- if and $.Spec.TelemetryKeeper.Status.Extras (index $.Spec.TelemetryKeeper.Status.Extras "cfgPath") }}
ExecStart=/usr/bin/clickhouse-keeper --config={{ index $.Spec.TelemetryKeeper.Status.Extras "cfgPath" }} --pid-file=/run/clickhouse-keeper/clickhouse-keeper.pid
{{ end }}
{{- end }}
{{- range $key, $value := $.Spec.TelemetryKeeper.Spec.Env }}
Environment={{ $key }}={{ $value }}
{{- end }}
LimitCORE=infinity
LimitNOFILE=500000
CapabilityBoundingSet=CAP_NET_ADMIN CAP_IPC_LOCK CAP_SYS_NICE CAP_NET_BIND_SERVICE
@@ -1,10 +1,6 @@
[Unit]
Description=SigNoz OTel Collector
Documentation=https://signoz.io/docs
After={{ $.Metadata.Name }}-telemetrystore-{{ $.Spec.TelemetryStore.Kind }}-0-0{{ if $.Spec.TelemetryStore.Spec.Enabled }} {{ $.Metadata.Name }}-telemetrystore-migrator{{ end }}
{{ if $.Spec.TelemetryStore.Spec.Enabled }}
Requires={{ $.Metadata.Name }}-telemetrystore-migrator
{{ end }}
[Service]
User=signoz
@@ -12,12 +8,20 @@ Group=signoz
Type=simple
KillMode=mixed
Restart=on-failure
{{/* Using Fragment specifier to get the config from pours directory */}}
RestartSec=5
{{- if and $.Metadata.Annotations (index $.Metadata.Annotations "foundry.signoz.io/ingester-binary-path") }}
{{- $ingesterBinaryPath := index $.Metadata.Annotations "foundry.signoz.io/ingester-binary-path" }}
{{ if and $.Spec.Ingester.Status.Extras (index $.Spec.Ingester.Status.Extras "cfgPath") (index $.Spec.Ingester.Status.Extras "cfgOpampPath") }}
{{- if and $.Spec.Ingester.Status.Extras (index $.Spec.Ingester.Status.Extras "cfgPath") (index $.Spec.Ingester.Status.Extras "cfgOpampPath") }}
ExecStartPre={{ $ingesterBinaryPath }} migrate sync check
ExecStart={{ $ingesterBinaryPath }} --config=%Y/{{ index $.Spec.Ingester.Status.Extras "cfgPath" }} --manager-config=%Y/{{ index $.Spec.Ingester.Status.Extras "cfgOpampPath" }} --copy-path=/var/lib/ingester/ingester.yaml
{{ end }}
{{- end }}
{{- end }}
{{- if and $.Spec.TelemetryStore.Spec.Enabled $.Spec.TelemetryStore.Status.Addresses.TCP (index $.Spec.TelemetryStore.Status.Addresses.TCP 0) }}
Environment=SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN={{ index $.Spec.TelemetryStore.Status.Addresses.TCP 0 }}
{{- end }}
{{- range $key, $value := $.Spec.Ingester.Spec.Env }}
Environment={{ $key }}={{ $value }}
{{- end }}
[Install]
WantedBy=multi-user.target
@@ -1,23 +1,24 @@
[Unit]
Description=SigNoz Schema Migrator
Description=SigNoz TelemetryStore Migrator
Documentation=https://signoz.io/docs
{{ if $.Spec.TelemetryStore.Spec.Enabled }}
{{ $firstStore := printf "%s-telemetrystore-%s-0-0" $.Metadata.Name $.Spec.TelemetryStore.Kind.String }}
After={{ $firstStore }}
Requires={{ $firstStore }}
{{ end }}
[Service]
Type=oneshot
RemainAfterExit=yes
Restart=on-failure
RestartSec=5
User=signoz
Group=signoz
{{- if and $.Metadata.Annotations (index $.Metadata.Annotations "foundry.signoz.io/ingester-binary-path") }}
{{- $migratorBinary := index $.Metadata.Annotations "foundry.signoz.io/ingester-binary-path" }}
{{ if and $.Spec.TelemetryStore.Spec.Enabled $.Spec.TelemetryStore.Status.Addresses.TCP (index $.Spec.TelemetryStore.Status.Addresses.TCP 0) }}
{{- $dsn := index $.Spec.TelemetryStore.Status.Addresses.TCP 0 }}
ExecStart=/bin/bash -c '{{ $migratorBinary }} migrate bootstrap --clickhouse-dsn={{ $dsn }} && {{ $migratorBinary }} migrate sync up --clickhouse-dsn={{ $dsn }} && {{ $migratorBinary }} migrate async up --clickhouse-dsn={{ $dsn }}'
{{ end }}
ExecStartPre={{ $migratorBinary }} migrate ready
ExecStart=/bin/bash -c '{{ $migratorBinary }} migrate bootstrap && {{ $migratorBinary }} migrate sync up && {{ $migratorBinary }} migrate async up'
{{- end }}
{{- if and $.Spec.TelemetryStore.Spec.Enabled $.Spec.TelemetryStore.Status.Addresses.TCP (index $.Spec.TelemetryStore.Status.Addresses.TCP 0) }}
Environment=SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN={{ index $.Spec.TelemetryStore.Status.Addresses.TCP 0 }}
{{- end }}
{{- range $key, $value := $.Spec.Ingester.Spec.Env }}
Environment={{ $key }}={{ $value }}
{{- end }}
[Install]
WantedBy=multi-user.target
@@ -7,11 +7,9 @@ After=network-online.target
[Service]
Type=notify
User=postgres
{{ if $.Spec.MetaStore.Spec.Env }}
{{ range $key, $value := $.Spec.MetaStore.Spec.Env }}
{{- range $key, $value := $.Spec.MetaStore.Spec.Env }}
Environment={{ $key }}={{ $value }}
{{ end }}
{{ end }}
{{- end }}
{{- if and $.Metadata.Annotations (index $.Metadata.Annotations "foundry.signoz.io/metastore-postgres-binary-path") }}
{{- $metastoreBinaryPath := index $.Metadata.Annotations "foundry.signoz.io/metastore-postgres-binary-path" }}
ExecStart={{ $metastoreBinaryPath }} -D /usr/local/pgsql/data
@@ -22,4 +20,4 @@ KillSignal=SIGINT
TimeoutSec=infinity
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target
@@ -1,10 +1,6 @@
[Unit]
Description=SigNoz
Documentation=https://signoz.io/docs
After={{ $.Metadata.Name }}-telemetrystore-{{ $.Spec.TelemetryStore.Kind }}-0-0 {{ $.Metadata.Name }}-metastore-{{ $.Spec.MetaStore.Kind }}{{ if $.Spec.TelemetryStore.Spec.Enabled }} {{ $.Metadata.Name }}-telemetrystore-migrator{{ end }}
{{ if $.Spec.TelemetryStore.Spec.Enabled }}
Requires={{ $.Metadata.Name }}-telemetrystore-migrator
{{ end }}
[Service]
User=signoz
@@ -12,18 +8,16 @@ Group=signoz
Type=simple
KillMode=mixed
Restart=on-failure
RestartSec=5
WorkingDirectory=/opt/signoz
{{- if and $.Metadata.Annotations (index $.Metadata.Annotations "foundry.signoz.io/signoz-binary-path") }}
{{- $signozBinaryPath := index $.Metadata.Annotations "foundry.signoz.io/signoz-binary-path" }}
ExecStart={{ $signozBinaryPath }} server
{{- end }}
Environment=SIGNOZ_WEB_DIRECTORY=/opt/signoz/web
{{ if $.Spec.Signoz.Spec.Env }}
{{ range $key, $value := $.Spec.Signoz.Spec.Env }}
{{- range $key, $value := $.Spec.Signoz.Spec.Env }}
Environment={{ $key }}={{ $value }}
{{ end }}
{{ end }}
{{ if and $.Spec.Signoz.Status.Extras (index $.Spec.Signoz.Status.Extras "envPath") }}
{{ end }}
{{- end }}
[Install]
WantedBy=multi-user.target
+22 -17
View File
@@ -48,24 +48,29 @@ func (molding *signoz) MoldV1Alpha1(ctx context.Context, config *v1alpha1.Castin
// Add metastore addresses
config.Spec.Signoz.Status.Env["SIGNOZ_SQLSTORE_PROVIDER"] = config.Spec.MetaStore.Kind.String()
if config.Spec.MetaStore.Status.Addresses.DSN != nil {
if val, ok := config.Spec.Signoz.Spec.Env["SIGNOZ_SQLSTORE_POSTGRES_DSN"]; ok {
molding.logger.WarnContext(ctx, "SIGNOZ_SQLSTORE_POSTGRES_DSN is going to be overridden", slog.String("value", val))
switch config.Spec.MetaStore.Kind {
case v1alpha1.MetaStoreKindSQLite:
config.Spec.Signoz.Status.Env["SIGNOZ_SQLSTORE_SQLITE_PATH"] = "/var/lib/signoz/signoz.db"
case v1alpha1.MetaStoreKindPostgres:
if config.Spec.MetaStore.Status.Addresses.DSN != nil {
if val, ok := config.Spec.Signoz.Spec.Env["SIGNOZ_SQLSTORE_POSTGRES_DSN"]; ok {
molding.logger.WarnContext(ctx, "SIGNOZ_SQLSTORE_POSTGRES_DSN is going to be overridden", slog.String("value", val))
}
// construct postgres dsn with user, password, host, port, and db
addrs, err := types.NewAddresses(config.Spec.MetaStore.Status.Addresses.DSN)
if err != nil {
return fmt.Errorf("failed to parse addresses: %w", err)
}
var dsns []string
user := config.Spec.MetaStore.Status.Env["POSTGRES_USER"]
password := config.Spec.MetaStore.Status.Env["POSTGRES_PASSWORD"]
db := config.Spec.MetaStore.Status.Env["POSTGRES_DB"]
for _, addr := range addrs {
dsn := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", user, password, addr.Host(), addr.Port(), db)
dsns = append(dsns, dsn)
}
config.Spec.Signoz.Status.Env["SIGNOZ_SQLSTORE_POSTGRES_DSN"] = strings.Join(dsns, ",")
}
// construct postgres dsn with user, password, host, port, and db
addrs, err := types.NewAddresses(config.Spec.MetaStore.Status.Addresses.DSN)
if err != nil {
return fmt.Errorf("failed to parse addresses: %w", err)
}
var dsns []string
user := config.Spec.MetaStore.Status.Env["POSTGRES_USER"]
password := config.Spec.MetaStore.Status.Env["POSTGRES_PASSWORD"]
db := config.Spec.MetaStore.Status.Env["POSTGRES_DB"]
for _, addr := range addrs {
dsn := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", user, password, addr.Host(), addr.Port(), db)
dsns = append(dsns, dsn)
}
config.Spec.Signoz.Status.Env["SIGNOZ_SQLSTORE_POSTGRES_DSN"] = strings.Join(dsns, ",")
}
return nil
}