Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4ad4803
feat(runner): add runners and the owners they find workloads by
Nageshbansal Aug 20, 2026
2cc7bfa
feat(casting): thread runners and uncast through the castings
Nageshbansal Aug 20, 2026
c0532cd
feat(casting/compose): cast and uncast through the compose runner
Nageshbansal Aug 20, 2026
d56ffdd
feat(tooler): add the tool-interaction contract and its shared mechanics
Nageshbansal Aug 23, 2026
06f5dc4
feat(tooler): drive every tool through a tooler
Nageshbansal Aug 23, 2026
ef925e8
feat(casting/installation): cast and uncast through the toolers
Nageshbansal Aug 23, 2026
ee8c580
feat(casting/collectionagent): cast and uncast through the toolers
Nageshbansal Aug 23, 2026
421661d
refactor: rename uncast to melt
Nageshbansal Aug 24, 2026
72df731
chore: drop unrelated cosmetic changes from yamlconfig
Nageshbansal Aug 24, 2026
d819681
refactor: add tails to errors
Nageshbansal Aug 24, 2026
7a565ff
refactor(tooler): gauge per document and cut the tests that cannot fail
Nageshbansal Aug 24, 2026
f428989
refactor: let tools word be in the message itself than in tail
Nageshbansal Aug 24, 2026
900cf0b
refactor(tooler): derive the core, split exec from the shared contract
Nageshbansal Aug 26, 2026
d0fe6f2
refactor(tooler/kube): neutralize object semantics into the castings
Nageshbansal Aug 31, 2026
361d3a4
refactor: fixup the drift
Nageshbansal Aug 31, 2026
bf6cb76
fix(infrastructure): hand the planner the toolers its registry lists
Nageshbansal Sep 1, 2026
52024fb
refactor: trim down godoc for tooler
Nageshbansal Sep 3, 2026
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
5 changes: 5 additions & 0 deletions cmd/foundryctl/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/signoz/foundry/internal/domain"
"github.com/signoz/foundry/internal/errors"
"github.com/signoz/foundry/internal/foundry"
"github.com/signoz/foundry/internal/tooler"
"github.com/spf13/cobra"
)

Expand All @@ -19,6 +20,10 @@ func registerCastCmd(rootCmd *cobra.Command) {
RunE: recoverRunE(domain.EventCast, func(cmd *cobra.Command, args []string, report reporter) error {
ctx := cmd.Context()

if castCfg.Yes {
ctx = tooler.WithApproval(ctx)
}

// A document the inner stages pass is prepared, not cast, so
// only their failures report.
prepReport := reporter(func(props domain.Properties, err error) {
Expand Down
13 changes: 13 additions & 0 deletions cmd/foundryctl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ var (
// Stores cast configuration.
castCfg castConfig

// Stores melt configuration.
meltCfg meltConfig

// Stores catalog configuration.
catalogCfg catalogConfig
)
Expand Down Expand Up @@ -43,11 +46,21 @@ func (c *poursConfig) RegisterFlags(cmd *cobra.Command) {
type castConfig struct {
NoGauge bool
NoForge bool
Yes bool
}

type meltConfig struct {
Yes bool
}

func (c *meltConfig) RegisterFlags(cmd *cobra.Command) {
cmd.PersistentFlags().BoolVar(&c.Yes, "yes", false, "Confirm the verbs that change infrastructure.")
}

func (c *castConfig) RegisterFlags(cmd *cobra.Command) {
cmd.PersistentFlags().BoolVar(&c.NoGauge, "no-gauge", false, "Do not run gauge before forge and cast.")
cmd.PersistentFlags().BoolVar(&c.NoForge, "no-forge", false, "Do not run forge before cast.")
cmd.PersistentFlags().BoolVar(&c.Yes, "yes", false, "Confirm the verbs that change infrastructure.")
}

type catalogConfig struct {
Expand Down
19 changes: 18 additions & 1 deletion cmd/foundryctl/main.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package main

import (
"context"
"os"
"os/signal"
"syscall"

foundryerrors "github.com/signoz/foundry/internal/errors"
"github.com/signoz/foundry/internal/version"
"github.com/spf13/cobra"
)

func main() {

rootCmd := &cobra.Command{
Use: "foundryctl",
SilenceUsage: true,
Expand All @@ -26,11 +30,24 @@ func main() {
registerGaugeCmd(rootCmd)
registerForgeCmd(rootCmd)
registerCastCmd(rootCmd)
registerMeltCmd(rootCmd)
registerGenCmd(rootCmd)
registerCatalogCmd(rootCmd)
registerVersionCmd(rootCmd)

err := rootCmd.Execute()
// Foundry survives the interrupt to keep reading the tool's streams: dying
// here SIGPIPEs the tool mid-write. Exec'd tools get the kernel's copy
// directly; the cancelled context is the relay only for in-process SDK work.
// A second signal kills foundry by the OS default.
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

go func() {
<-ctx.Done()
stop()
}()

err := rootCmd.ExecuteContext(ctx)

if rootNotifier != nil {
rootNotifier.Finish(version.Info.Version(), os.Stderr)
Expand Down
65 changes: 65 additions & 0 deletions cmd/foundryctl/melt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package main

import (
"context"
"log/slog"
"path/filepath"
"slices"

"github.com/signoz/foundry/internal/domain"
foundryerrors "github.com/signoz/foundry/internal/errors"
"github.com/signoz/foundry/internal/foundry"
"github.com/signoz/foundry/internal/tooler"
"github.com/spf13/cobra"
)

func registerMeltCmd(rootCmd *cobra.Command) {
meltCmd := &cobra.Command{
Use: "melt",
Short: "Remove the cast deployment",
Long: "Remove the cast deployment from the target environment; data is never touched",
RunE: recoverRunE(domain.EventMelt, func(cmd *cobra.Command, args []string, report reporter) error {
ctx := cmd.Context()

if meltCfg.Yes {
ctx = tooler.WithApproval(ctx)
}

return runMelt(ctx, rootLogger, poursCfg.Path, commonCfg.File, report)
}),
}

rootCmd.AddCommand(meltCmd)
meltCfg.RegisterFlags(meltCmd)
}

func runMelt(ctx context.Context, logger *slog.Logger, poursPath string, configPath string, report reporter) error {
foundry, err := foundry.New(logger)
if err != nil {
return err
}

poursPath, err = filepath.Abs(poursPath)
if err != nil {
return foundryerrors.Wrapf(err, foundryerrors.TypeInternal, "failed to resolve pours path")
}

machineries, err := foundry.Config.GetV1Alpha1Lock(ctx, configPath)
if err != nil {
return err
}

// Backwards against the order the lock records, so a workload leaves
// before the substrate it runs on.
for _, machinery := range slices.Backward(machineries) {
if err := foundry.Melt(ctx, machinery, poursPath); err != nil {
report(machinery.TrackableProperties(), err)

return err
}

report(machinery.TrackableProperties(), nil)
}

return nil
}
32 changes: 32 additions & 0 deletions docs/examples/docker/compose-mcp/pours/deployment/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ services:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://signoz-telemetrystore-clickhouse-0-0:9000
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
image: signoz/signoz-otel-collector:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
signoz-network:
aliases:
Expand All @@ -36,6 +40,10 @@ services:
- SIGNOZ_URL=http://signoz-signoz-0:8080
- TRANSPORT_MODE=http
image: signoz/signoz-mcp-server:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
signoz-network:
aliases:
Expand All @@ -58,6 +66,10 @@ services:
- pg_isready -U signoz -d signoz
timeout: 10s
image: postgres:16
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: unless-stopped
Expand All @@ -82,6 +94,10 @@ services:
- http://localhost:8080/api/v1/health
timeout: 10s
image: signoz/signoz:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
ports:
Expand All @@ -107,6 +123,10 @@ services:
- ls
timeout: 10s
image: clickhouse/clickhouse-keeper:25.12.5
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: unless-stopped
Expand Down Expand Up @@ -135,6 +155,10 @@ services:
- http://localhost:8123/ping
timeout: 10s
image: clickhouse/clickhouse-server:25.12.5
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: unless-stopped
Expand All @@ -158,6 +182,10 @@ services:
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
container_name: signoz-telemetrystore-clickhouse-user-scripts
image: clickhouse/clickhouse-server:25.12.5
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: on-failure
Expand All @@ -178,6 +206,10 @@ services:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://signoz-telemetrystore-clickhouse-0-0:9000
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
image: signoz/signoz-otel-collector:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: on-failure
Expand Down
28 changes: 28 additions & 0 deletions docs/examples/docker/compose/pours/deployment/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ services:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://signoz-telemetrystore-clickhouse-0-0:9000
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
image: signoz/signoz-otel-collector:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
signoz-network:
aliases:
Expand All @@ -43,6 +47,10 @@ services:
- pg_isready -U signoz -d signoz
timeout: 10s
image: postgres:16
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: unless-stopped
Expand All @@ -67,6 +75,10 @@ services:
- http://localhost:8080/api/v1/health
timeout: 10s
image: signoz/signoz:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
ports:
Expand All @@ -92,6 +104,10 @@ services:
- ls
timeout: 10s
image: clickhouse/clickhouse-keeper:25.12.5
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: unless-stopped
Expand Down Expand Up @@ -120,6 +136,10 @@ services:
- http://localhost:8123/ping
timeout: 10s
image: clickhouse/clickhouse-server:25.12.5
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: unless-stopped
Expand All @@ -143,6 +163,10 @@ services:
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
container_name: signoz-telemetrystore-clickhouse-user-scripts
image: clickhouse/clickhouse-server:25.12.5
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: on-failure
Expand All @@ -163,6 +187,10 @@ services:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://signoz-telemetrystore-clickhouse-0-0:9000
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
image: signoz/signoz-otel-collector:latest
labels:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
networks:
- signoz-network
restart: on-failure
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
labels:
- includeSelectors: false
pairs:
foundry.signoz.io/kind: Installation
foundry.signoz.io/managed-by: foundry
foundry.signoz.io/name: signoz
namespace: signoz
resources:
- namespace.yaml
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ require (
github.com/tidwall/gjson v1.18.0
go.yaml.in/yaml/v3 v3.0.4
golang.org/x/mod v0.35.0
golang.org/x/oauth2 v0.36.0
gopkg.in/ini.v1 v1.67.1
helm.sh/helm/v3 v3.20.2
k8s.io/apimachinery v0.35.1
k8s.io/cli-runtime v0.35.1
k8s.io/client-go v0.35.1
sigs.k8s.io/kustomize/api v0.20.1
sigs.k8s.io/kustomize/kyaml v0.21.1
sigs.k8s.io/yaml v1.6.0
)
Expand Down Expand Up @@ -109,7 +113,6 @@ require (
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/crypto v0.52.0 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.45.0 // indirect
golang.org/x/term v0.43.0 // indirect
Expand All @@ -124,16 +127,13 @@ require (
k8s.io/api v0.35.1 // indirect
k8s.io/apiextensions-apiserver v0.35.1 // indirect
k8s.io/apiserver v0.35.1 // indirect
k8s.io/cli-runtime v0.35.1 // indirect
k8s.io/client-go v0.35.1 // indirect
k8s.io/component-base v0.35.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
k8s.io/kubectl v0.35.1 // indirect
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
oras.land/oras-go/v2 v2.6.2 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/kustomize/api v0.20.1 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)
10 changes: 8 additions & 2 deletions internal/casting/casting.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/signoz/foundry/api/v1alpha1/installation"
"github.com/signoz/foundry/internal/domain"
"github.com/signoz/foundry/internal/molding"
"github.com/signoz/foundry/internal/tooler"
)

// DeploymentDir is the subdirectory within the pours directory where
Expand All @@ -19,6 +20,11 @@ type Casting interface {
// Generates all the files needed for casting.
Forge(ctx context.Context, config installation.Casting, poursPath string) ([]domain.Material, error)

// Runs the forged files.
Cast(ctx context.Context, config installation.Casting, poursPath string) error
// Runs the forged files. Toolers are the tool interfaces the registry
// lists for this casting.
Cast(ctx context.Context, config installation.Casting, poursPath string, toolers []tooler.Tooler) error

// Removes what Cast deployed: definitions only, never data, never
// users, config stays.
Melt(ctx context.Context, config installation.Casting, poursPath string, toolers []tooler.Tooler) error
}
Loading