Skip to content

Commit eac5bae

Browse files
committed
experimental launcher
Signed-off-by: jose.vazquez <[email protected]>
1 parent 9430b0b commit eac5bae

File tree

10 files changed

+887
-26
lines changed

10 files changed

+887
-26
lines changed

Makefile

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ prepare-run: generate vet manifests run-kind install-crds install-credentials
552552
.PHONY: run
553553
run: prepare-run ## Run a freshly compiled manager against kind
554554
ifdef RUN_YAML
555-
kubectl apply -f $(RUN_YAML)
555+
kubectl apply -n $(OPERATOR_NAMESPACE) -f $(RUN_YAML)
556556
endif
557557
VERSION=$(NEXT_VERSION) \
558558
OPERATOR_POD_NAME=$(OPERATOR_POD_NAME) \
@@ -561,6 +561,29 @@ endif
561561
--atlas-domain=$(ATLAS_DOMAIN) \
562562
--global-api-secret-name=$(ATLAS_KEY_SECRET_NAME)
563563

564+
.PHONY: experimental-run
565+
experimental-run: prepare-run ## Run a freshly compiled manager & experimental controllers on kind
566+
kubectl apply -f internal/next-crds/*.yaml
567+
ifdef RUN_YAML
568+
kubectl apply -n $(OPERATOR_NAMESPACE) -f $(RUN_YAML)
569+
endif
570+
VERSION=$(NEXT_VERSION) \
571+
OPERATOR_POD_NAME=$(OPERATOR_POD_NAME) \
572+
OPERATOR_NAMESPACE=$(OPERATOR_NAMESPACE) \
573+
AKO_BINARY_PATH=./bin/manager \
574+
go run ./internal/cmd/nextako --object-deletion-protection=false --log-level=$(RUN_LOG_LEVEL) \
575+
--atlas-domain=$(ATLAS_DOMAIN) \
576+
--global-api-secret-name=$(ATLAS_KEY_SECRET_NAME)
577+
578+
.PHONY: experimental-generate
579+
experimental-generate: ## Generate experimental CRDs
580+
controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./internal/nextapi/v1/..."
581+
$(MAKE) fmt
582+
583+
.PHONY: experimental-manifests
584+
experimental-manifests: fmt ## Generate experimental CRDs
585+
controller-gen crd paths="./internal/nextapi/v1" output:crd:artifacts:config=internal/next-crds
586+
564587
.PHONY: local-docker-build
565588
local-docker-build:
566589
docker build -f fast.Dockerfile -t $(LOCAL_IMAGE) .

internal/cmd/nextako/main.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"log"
21+
"os"
22+
"os/exec"
23+
"os/signal"
24+
"syscall"
25+
26+
"github.com/go-logr/zapr"
27+
"go.uber.org/zap"
28+
corev1 "k8s.io/api/core/v1"
29+
"k8s.io/apimachinery/pkg/runtime"
30+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
31+
ctrl "sigs.k8s.io/controller-runtime"
32+
ctrlog "sigs.k8s.io/controller-runtime/pkg/log"
33+
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
34+
35+
akov2next "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/nextapi/v1"
36+
)
37+
38+
func main() {
39+
akoPath, ok := os.LookupEnv("AKO_BINARY_PATH")
40+
if !ok {
41+
log.Fatalf("AKO_BINARY_PATH must be set and point to the AKO binary path")
42+
}
43+
44+
ctx, cancel := context.WithCancel(context.Background())
45+
defer cancel()
46+
if err := startExperimentalControllers(cancel); err != nil {
47+
log.Fatalf("Failed to launch experimental controllers: %v", err)
48+
}
49+
50+
akoCmd, err := startAKO(akoPath)
51+
if err != nil {
52+
log.Fatalf("Failed to launch AKO binary %q: %v", akoPath, err)
53+
}
54+
55+
log.Println("Experimental launcher is running. AKO binary started.")
56+
57+
handleShutdown(ctx, cancel, akoCmd)
58+
}
59+
60+
func startExperimentalControllers(cancel context.CancelFunc) error {
61+
setupLog := ctrl.Log.WithName("experimental-launcher")
62+
setupLog.Info("Starting experimental controllers")
63+
64+
experimentalScheme := runtime.NewScheme()
65+
utilruntime.Must(corev1.AddToScheme(experimentalScheme))
66+
utilruntime.Must(akov2next.AddToScheme(experimentalScheme))
67+
68+
kubeCfg, err := ctrl.GetConfig()
69+
if err != nil {
70+
return fmt.Errorf("failed to get kube config (is cluster running?): %w", err)
71+
}
72+
73+
if err := setupControllerRuntimeLogger(); err != nil {
74+
return err
75+
}
76+
mgr, err := ctrl.NewManager(kubeCfg, ctrl.Options{
77+
Scheme: experimentalScheme,
78+
Metrics: metricsserver.Options{BindAddress: ":8090"},
79+
HealthProbeBindAddress: ":8091",
80+
})
81+
if err != nil {
82+
return fmt.Errorf("failed to start experimental controller manager: %w", err)
83+
}
84+
85+
for _, reconciler := range experimentalReconcilers {
86+
if err := reconciler.register(mgr); err != nil {
87+
return fmt.Errorf("failed to register experimental %s: %w", reconciler.name, err)
88+
}
89+
log.Printf("Experimental %s registered", reconciler.name)
90+
}
91+
92+
go func() {
93+
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
94+
setupLog.Error(err, "problem running experimental manager")
95+
cancel()
96+
}
97+
}()
98+
return nil
99+
}
100+
101+
func setupControllerRuntimeLogger() error {
102+
zapLog, err := zap.NewDevelopment()
103+
if err != nil {
104+
return fmt.Errorf("failed to initialize logger: %w", err)
105+
}
106+
ctrlog.SetLogger(zapr.NewLogger(zapLog))
107+
return nil
108+
}
109+
110+
func startAKO(akoPath string) (*exec.Cmd, error) {
111+
cmd := exec.Command(akoPath, os.Args[1:]...)
112+
cmd.Stdout = os.Stdout
113+
cmd.Stderr = os.Stderr
114+
115+
if err := cmd.Start(); err != nil {
116+
return nil, fmt.Errorf("failed to start AKO binary: %w", err)
117+
}
118+
return cmd, nil
119+
}
120+
121+
func handleShutdown(ctx context.Context, cancel context.CancelFunc, akoCmd *exec.Cmd) {
122+
signalCh := make(chan os.Signal, 1)
123+
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
124+
125+
select {
126+
case <-signalCh:
127+
log.Println("Received termination signal. Stopping everything...")
128+
cancel()
129+
if err := akoCmd.Process.Signal(syscall.SIGTERM); err != nil {
130+
log.Printf("Failed to terminate AKO subprocess: %v", err)
131+
}
132+
case <-ctx.Done():
133+
log.Println("Experimental controllers stopped. Terminating AKO subprocess...")
134+
if err := akoCmd.Process.Kill(); err != nil {
135+
log.Printf("Failed to force-kill AKO subprocess: %v", err)
136+
}
137+
}
138+
_ = akoCmd.Wait()
139+
log.Println("Experimental launcher shut down completely.")
140+
}

internal/cmd/nextako/registrations.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
ctrl "sigs.k8s.io/controller-runtime"
19+
20+
integrations "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/controller/atlasthirdpartyintegrations"
21+
)
22+
23+
type registerReconcilerFn func(ctrl.Manager) error
24+
25+
type experimentalReconcilerInitSpec struct {
26+
name string
27+
register registerReconcilerFn
28+
}
29+
30+
var experimentalReconcilers = []experimentalReconcilerInitSpec{
31+
{
32+
name: "AtlasThirdPartyIntegrationsReconciler",
33+
register: func(mgr ctrl.Manager) error {
34+
return integrations.NewAtlasThirdPartyIntegrationsReconciler().SetupWithManager(mgr)
35+
},
36+
},
37+
}

internal/controller/atlasthirdpartyintegrations/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (h *AtlasThirdPartyIntegrationHandler) HandleCreated(ctx context.Context, i
8484

8585
func (h *AtlasThirdPartyIntegrationHandler) handleIdle(ctx context.Context, integration *akov2next.AtlasThirdPartyIntegration) (ctrlstate.Result, error) {
8686
// TODO skew detection here
87-
87+
8888
return ctrlstate.Result{}, nil
8989
}
9090

0 commit comments

Comments
 (0)