Skip to content

Commit 739d245

Browse files
committed
Fix blue-green deployment for Kubernetes apps
1 parent 550518c commit 739d245

30 files changed

Lines changed: 2758 additions & 244 deletions

docs/content/docs/Container/Config.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ container.show_logs_for_failure = true
3030

3131
# Kubernetes related settings
3232
kubernetes.default_volume_size = "10Gi"
33-
kubernetes.strict_version_check = true
3433
kubernetes.scaling_threshold_cpu = 80
3534
```
3635

docs/content/docs/Container/Kubernetes.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,4 @@ OpenRun is installed as a Kubernetes Deployment, with a Service for routing API
105105

106106
All Kubernetes resources are created lazily, on the first API call to the app. If app is running version 1, and a code/config change is done which updates it to version 2, the deployment update will happen on the next API call to the app. The API call is blocked, the container image is rebuild if required and the deployment is updated using Server Side Apply API calls.
107107

108-
By default, OpenRun will wait to ensure that the app is running pods with only the new version, before processing further API calls. This behavior can be relaxed by setting
109-
110-
```toml {filename="openrun.toml"}
111-
[app_config]
112-
kubernetes.strict_version_check = false
113-
```
114-
115-
in which case OpenRun just makes sure that the new version started successfully,
108+
OpenRun waits until Kubernetes reports the expected new version rollout is complete before processing further API calls.

internal/app/app.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func NewApp(sourceFS *appfs.SourceFs, workFS *appfs.WorkFs, logger *types.Logger
176176
func (a *App) Initialize(ctx context.Context, dryRun types.DryRun) error {
177177
var reloaded bool
178178
var err error
179-
if reloaded, err = a.Reload(ctx, false, true, dryRun, true); err != nil {
179+
if reloaded, err = a.Reload(ctx, false, true, dryRun, ReloadOptions{ReloadContainer: true, Verify: false}); err != nil {
180180
return err
181181
}
182182

@@ -235,7 +235,20 @@ func (a *App) ResetFS() {
235235
a.sourceFS.Reset()
236236
}
237237

238-
func (a *App) Reload(ctx context.Context, force, immediate bool, dryRun types.DryRun, reloadContainer bool) (bool, error) {
238+
// ReloadOptions controls how App.Reload handles the prod container.
239+
type ReloadOptions struct {
240+
// ReloadContainer, when true, (re)loads the prod container (rebuild/restart
241+
// as needed). It is true for reload and initialize operations; only the
242+
// metadata-only paths leave it false. Image-spec apps always reload.
243+
ReloadContainer bool
244+
// Verify indicates the caller wants a verified, rollback-capable update.
245+
// For in-place container managers (Kubernetes) this makes a missing
246+
// rollback snapshot a fatal error rather than proceeding with an
247+
// irreversible in-place update.
248+
Verify bool
249+
}
250+
251+
func (a *App) Reload(ctx context.Context, force, immediate bool, dryRun types.DryRun, opts ReloadOptions) (bool, error) {
239252
requestTime := time.Now()
240253

241254
a.initMutex.Lock()
@@ -301,7 +314,7 @@ func (a *App) Reload(ctx context.Context, force, immediate bool, dryRun types.Dr
301314
}
302315

303316
// Load Starlark config, AppConfig is updated with the settings contents
304-
if err = a.loadStarlarkConfig(ctx, dryRun, reloadContainer); err != nil {
317+
if err = a.loadStarlarkConfig(ctx, dryRun, opts); err != nil {
305318
return false, fmt.Errorf("error during initial setup: %w", err)
306319
}
307320
a.Metadata.Name = a.Name
@@ -775,7 +788,7 @@ func (a *App) startWatcher() error {
775788

776789
inReload.Store(true)
777790
defer inReload.Store(false)
778-
_, err := a.Reload(context.Background(), true, false, types.DryRun(false), true)
791+
_, err := a.Reload(context.Background(), true, false, types.DryRun(false), ReloadOptions{ReloadContainer: true, Verify: false})
779792
a.reloadError = err
780793
if err != nil {
781794
a.Error().Err(err).Msg("Error reloading app")

0 commit comments

Comments
 (0)