Skip to content

Commit 388d37b

Browse files
committed
feat: Add events recording
1 parent 5b01921 commit 388d37b

12 files changed

Lines changed: 154 additions & 29 deletions

File tree

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ COPY --from=manager-builder /workspace/manager .
4747
COPY --from=console-builder /workspace/console/dist ./console
4848
USER 65532:65532
4949

50+
ENV DEPLOYER_API_URL=https://deploy.wandb.ai/api
51+
5052
ENTRYPOINT ["/manager"]

controllers/config.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,55 @@ import (
66

77
apiv1 "github.com/wandb/operator/api/v1"
88
"github.com/wandb/operator/pkg/wandb/cdk8s/release"
9+
"github.com/wandb/operator/pkg/wandb/status"
10+
corev1 "k8s.io/api/core/v1"
911
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
1012
)
1113

1214
func (r *WeightsAndBiasesReconciler) applyConfig(
1315
ctx context.Context,
1416
wandb *apiv1.WeightsAndBiases,
17+
statusManager *status.Manager,
1518
rel release.Release,
1619
cfg map[string]interface{},
1720
) error {
1821
log := ctrllog.FromContext(ctx)
1922

23+
statusManager.Set(status.Downloading)
24+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "Downloading", "Downloading "+rel.Version())
2025
log.Info("Downloading release", "version", rel.Version())
2126
if err := rel.Download(); err != nil {
2227
log.Error(err, "Failed to download release")
2328
return err
2429
}
2530

31+
statusManager.Set(status.Installing)
32+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "Installing", "Installing "+rel.Version())
2633
log.Info("Install upgrade release", "version", rel.Version())
2734
if err := rel.Install(); err != nil {
2835
fmt.Println(err)
2936
log.Error(err, "Failed to install release")
3037
return err
3138
}
3239

40+
statusManager.Set(status.Generating)
41+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "Generating", "Generating manifests "+rel.Version())
3342
log.Info("Generating upgrade", "version", rel.Version())
3443
if err := rel.Generate(cfg); err != nil {
3544
fmt.Println(err)
3645
log.Error(err, "Failed to generate release")
3746
return err
3847
}
3948

49+
statusManager.Set(status.Applying)
50+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "Applying", "Applying manifests "+rel.Version())
4051
if err := rel.Apply(ctx, r.Client, wandb, r.Scheme); err != nil {
4152
fmt.Println(err)
4253
log.Error(err, "Failed to apply config")
4354
return err
4455
}
4556

57+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "AppliedSuccessfully", "Successfully applied "+rel.Version())
58+
4659
return nil
4760
}

controllers/weightsandbiases_controller.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ package controllers
1818

1919
import (
2020
"context"
21+
"reflect"
2122

2223
"k8s.io/apimachinery/pkg/runtime"
24+
"k8s.io/client-go/tools/record"
2325
ctrl "sigs.k8s.io/controller-runtime"
2426
"sigs.k8s.io/controller-runtime/pkg/builder"
2527
"sigs.k8s.io/controller-runtime/pkg/client"
28+
"sigs.k8s.io/controller-runtime/pkg/event"
2629
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
2730
"sigs.k8s.io/controller-runtime/pkg/predicate"
2831

@@ -39,7 +42,8 @@ import (
3942
// WeightsAndBiasesReconciler reconciles a WeightsAndBiases object
4043
type WeightsAndBiasesReconciler struct {
4144
client.Client
42-
Scheme *runtime.Scheme
45+
Scheme *runtime.Scheme
46+
Recorder record.EventRecorder
4347
}
4448

4549
//+kubebuilder:rbac:groups=apps.wandb.com,resources=weightsandbiases,verbs=get;list;watch;create;update;patch;delete
@@ -77,7 +81,8 @@ func (r *WeightsAndBiasesReconciler) Reconcile(ctx context.Context, req ctrl.Req
7781
log.Error(err, "Failed to set status")
7882
}
7983

80-
statusManager.Set(status.Loading)
84+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "Reconciling", "Reconciling")
85+
8186
configManager := config.NewManager(ctx, r.Client, wandb, r.Scheme)
8287
usersConfig, err := configManager.GetDesiredState()
8388

@@ -93,22 +98,25 @@ func (r *WeightsAndBiasesReconciler) Reconcile(ctx context.Context, req ctrl.Req
9398
license = wandb.Spec.License
9499
}
95100

101+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "LoadingConfig", "Loading desired configuration")
96102
// Apply configs in least to most priority order
97103
desiredState := config.Merge(
98104
usersConfig,
99105
cdk8s.Github(),
100-
cdk8s.Deployment(license),
106+
cdk8s.Deployer(license),
101107
cdk8s.Operator(wandb, r.Scheme),
102108
)
103109

104110
if err != nil {
105111
if errors.IsNotFound(err) {
112+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "CreatingConfig", "Creating config")
106113
log.Info("No config found. Creating config...", "name", configManager.LatestConfigName())
107114
usersConfig, err = configManager.CreateLatest(
108115
desiredState.Release,
109116
map[string]interface{}{},
110117
)
111118
if err != nil {
119+
statusManager.Set(status.InvalidConfig)
112120
log.Error(err, "Failed to create config")
113121
return ctrlqueue.Requeue(err)
114122
}
@@ -118,24 +126,29 @@ func (r *WeightsAndBiasesReconciler) Reconcile(ctx context.Context, req ctrl.Req
118126
}
119127
}
120128

129+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "ConfigBackup", "Creating a copy of config")
121130
configManager.BackupLatest()
122131

123132
log.Info("Config values:", "version", desiredState.Release.Version(), "config", desiredState.Config)
124133
if err != nil {
134+
statusManager.Set(status.InvalidConfig)
125135
log.Error(err, "Failed to get config")
126136
return ctrlqueue.Requeue(err)
127137
}
128138

129139
statusManager.Set(status.Loading)
130140
log.Info("Applying config changes...", "version", usersConfig.Release.Version())
131-
if err := r.applyConfig(ctx, wandb, usersConfig.Release, desiredState.Config); err != nil {
141+
if err := r.applyConfig(ctx, wandb, statusManager, usersConfig.Release, desiredState.Config); err != nil {
142+
statusManager.Set(status.InvalidConfig)
143+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "ApplyFailed", "Valid to apply config changes")
132144
// TODO: Implement rollback
133145
log.Error(err, "Failed to apply config changes.")
134146
return ctrlqueue.DoNotRequeue()
135147
}
136148
log.Info("Successfully applied config", "version", usersConfig.Release.Version())
137149

138150
if desiredState.Release.Version() != usersConfig.Release.Version() {
151+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "VersionChangeDetected", "Version change detected ("+usersConfig.Release.Version()+" -> "+desiredState.Release.Version()+")")
139152
log.Info(
140153
"Version changed. Applying...",
141154
"current", usersConfig.Release.Version(),
@@ -145,13 +158,15 @@ func (r *WeightsAndBiasesReconciler) Reconcile(ctx context.Context, req ctrl.Req
145158
statusManager.Set(status.Loading)
146159
usersConfig.SetRelease(desiredState.Release)
147160

148-
if err := r.applyConfig(ctx, wandb, usersConfig.Release, desiredState.Config); err != nil {
161+
if err := r.applyConfig(ctx, wandb, statusManager, usersConfig.Release, desiredState.Config); err != nil {
162+
statusManager.Set(status.InvalidVersion)
163+
r.Recorder.Event(wandb, corev1.EventTypeNormal, "VersionApplyFailed", "Valid to apply version changes")
149164
// TODO: Implement rollback
150165
log.Error(err, "Failed to upgrade to new version.")
151166
return ctrlqueue.DoNotRequeue()
152167
}
153168

154-
// Only if succesful do we save the state to a config map.
169+
// Only if successful do we save the state to a config map.
155170
if err := configManager.SetDesiredState(usersConfig); err != nil {
156171
log.Error(err, "Failed to set desired state")
157172
return ctrlqueue.DoNotRequeue()
@@ -168,9 +183,25 @@ func (r *WeightsAndBiasesReconciler) SetupWithManager(mgr ctrl.Manager) error {
168183
builder := ctrl.NewControllerManagedBy(mgr).
169184
For(
170185
&apiv1.WeightsAndBiases{},
171-
builder.WithPredicates(predicate.GenerationChangedPredicate{}),
186+
builder.WithPredicates(annotationChangedPredicate{}),
172187
).
173188
Owns(&corev1.Secret{}).
174189
Owns(&corev1.ConfigMap{})
175190
return builder.Complete(r)
176191
}
192+
193+
// annotationChangedPredicate implements the Predicate interface. It is used to
194+
// watch changes in the annotation of the Custom Resource.
195+
type annotationChangedPredicate struct {
196+
predicate.Funcs
197+
}
198+
199+
// It checks if there is an update event and only returns true if the
200+
// annotations have changed. We use annotations to trigger a reconcile
201+
// functions.
202+
func (a annotationChangedPredicate) Update(e event.UpdateEvent) bool {
203+
return !reflect.DeepEqual(
204+
e.ObjectOld.GetAnnotations(),
205+
e.ObjectNew.GetAnnotations(),
206+
)
207+
}

main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ func main() {
9191
}
9292

9393
if err = (&controllers.WeightsAndBiasesReconciler{
94-
Client: mgr.GetClient(),
95-
Scheme: mgr.GetScheme(),
94+
Recorder: mgr.GetEventRecorderFor("weightsandbiases"),
95+
Client: mgr.GetClient(),
96+
Scheme: mgr.GetScheme(),
9697
}).SetupWithManager(mgr); err != nil {
9798
setupLog.Error(err, "unable to create controller", "controller", "WeightsAndBiases")
9899
os.Exit(1)

pkg/utils/envs.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package utils
2+
3+
import "os"
4+
5+
func Getenv(key string, defaultValue string) string {
6+
value := os.Getenv(key)
7+
if value == "" {
8+
return defaultValue
9+
}
10+
return value
11+
}

pkg/wandb/cdk8s/config/modifier.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
package config
22

3+
// Modifier is used to override or recommend a config for the user. It will
4+
// modify or add defaults to the users config.
35
type Modifier interface {
4-
Recommend() *Config
5-
Override() *Config
6+
// Recommend will return a config that will be applied for the users config.
7+
// This means the user can override any values set here cfg is the current
8+
// state of the config before applying these changes
9+
Recommend(cfg *Config) *Config
10+
// Override will return a config that will be applied and override the users
11+
// specified config. cfg is the current state of the config before applying
12+
// these changes
13+
Override(cfg *Config) *Config
614
}
715

816
// Merge will combine all the configs from the channels passed in. Last channel
9-
// will take precedent. If a channel returns nil for recommend or override, it will be skipped
17+
// will take precedent. If a channel returns nil for recommend or override, it
18+
// will be skipped
1019
func Merge(inputConfig *Config, providers ...Modifier) *Config {
1120
cfg := &Config{Config: map[string]interface{}{}}
1221

1322
for _, channel := range providers {
1423
if channel == nil {
1524
continue
1625
}
17-
if c := channel.Recommend(); c != nil {
26+
if c := channel.Recommend(cfg); c != nil {
1827
cfg.Merge(c)
1928
}
2029
}
@@ -27,7 +36,7 @@ func Merge(inputConfig *Config, providers ...Modifier) *Config {
2736
if channel == nil {
2837
continue
2938
}
30-
if c := channel.Override(); c != nil {
39+
if c := channel.Override(cfg); c != nil {
3140
cfg.Merge(c)
3241
}
3342
}

pkg/wandb/cdk8s/deployer.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,24 @@ import (
44
"github.com/wandb/operator/pkg/wandb/cdk8s/config"
55
)
66

7-
// Deployment returns the config suggested by deployer
8-
func Deployment(license string) config.Modifier {
9-
return nil
7+
// Deployer returns the config suggested by deployer
8+
func Deployer(license string) config.Modifier {
9+
return &deployerChannel{}
10+
}
11+
12+
type deployerResponse struct {
13+
recommend *config.Config
14+
override *config.Config
15+
}
16+
17+
type deployerChannel struct {
18+
response deployerResponse
19+
}
20+
21+
func (c deployerChannel) Recommend(_ *config.Config) *config.Config {
22+
return c.response.recommend
23+
}
24+
25+
func (c deployerChannel) Override(_ *config.Config) *config.Config {
26+
return c.response.override
1027
}

pkg/wandb/cdk8s/operator.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type operatorChannel struct {
1313
scheme *runtime.Scheme
1414
}
1515

16-
func (c operatorChannel) Recommend() *config.Config {
16+
func (c operatorChannel) Recommend(_ *config.Config) *config.Config {
1717
gvk, _ := apiutil.GVKForObject(c.wandb, c.scheme)
1818
return &config.Config{
1919
Config: map[string]interface{}{
@@ -39,7 +39,7 @@ func (c operatorChannel) Recommend() *config.Config {
3939
}
4040
}
4141

42-
func (c operatorChannel) Override() *config.Config {
42+
func (c operatorChannel) Override(_ *config.Config) *config.Config {
4343
cfg := &config.Config{}
4444

4545
cfg.SetConfig(c.wandb.Spec.Config.Object)

0 commit comments

Comments
 (0)