Skip to content

Commit ab266a8

Browse files
Merge pull request #179 from basecamp/force-deploy
Force deploy
2 parents 6f6316b + 78af154 commit ab266a8

File tree

8 files changed

+102
-92
lines changed

8 files changed

+102
-92
lines changed

internal/cmd/deploy.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ func newDeployCommand() *deployCommand {
4141
deployCommand.cmd.Flags().BoolVar(&deployCommand.args.ServiceOptions.TLSRedirect, "tls-redirect", true, "Redirect HTTP traffic to HTTPS")
4242
deployCommand.cmd.Flags().StringVar(&deployCommand.args.ServiceOptions.CanonicalHost, "canonical-host", "", "Redirect all requests to this host (e.g., force root or www)")
4343

44-
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.DeployTimeout, "deploy-timeout", server.DefaultDeployTimeout, "Maximum time to wait for the new target to become healthy")
45-
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.DrainTimeout, "drain-timeout", server.DefaultDrainTimeout, "Maximum time to allow existing connections to drain before removing old target")
44+
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.DeploymentOptions.DeployTimeout, "deploy-timeout", server.DefaultDeployTimeout, "Maximum time to wait for the new target to become healthy")
45+
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.DeploymentOptions.DrainTimeout, "drain-timeout", server.DefaultDrainTimeout, "Maximum time to allow existing connections to drain before removing old target")
46+
deployCommand.cmd.Flags().BoolVar(&deployCommand.args.DeploymentOptions.Force, "force", false, "Skip health checks and force deployment")
4647
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.TargetOptions.HealthCheckConfig.Interval, "health-check-interval", server.DefaultHealthCheckInterval, "Interval between health checks")
4748
deployCommand.cmd.Flags().DurationVar(&deployCommand.args.TargetOptions.HealthCheckConfig.Timeout, "health-check-timeout", server.DefaultHealthCheckTimeout, "Time each health check must complete in")
4849
deployCommand.cmd.Flags().StringVar(&deployCommand.args.TargetOptions.HealthCheckConfig.Path, "health-check-path", server.DefaultHealthCheckPath, "Path to check for health")

internal/cmd/rollout_deploy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ func newRolloutDeployCommand() *rolloutDeployCommand {
2424

2525
rolloutDeployCommand.cmd.Flags().StringSliceVar(&rolloutDeployCommand.args.TargetURLs, "target", []string{}, "Target host(s) to deploy")
2626
rolloutDeployCommand.cmd.Flags().StringSliceVar(&rolloutDeployCommand.args.ReaderURLs, "read-target", []string{}, "Read-only target host(s) to deploy")
27-
rolloutDeployCommand.cmd.Flags().DurationVar(&rolloutDeployCommand.args.DeployTimeout, "deploy-timeout", server.DefaultDeployTimeout, "Maximum time to wait for the new target to become healthy")
28-
rolloutDeployCommand.cmd.Flags().DurationVar(&rolloutDeployCommand.args.DrainTimeout, "drain-timeout", server.DefaultDrainTimeout, "Maximum time to allow existing connections to drain before removing old target")
27+
rolloutDeployCommand.cmd.Flags().DurationVar(&rolloutDeployCommand.args.DeploymentOptions.DeployTimeout, "deploy-timeout", server.DefaultDeployTimeout, "Maximum time to wait for the new target to become healthy")
28+
rolloutDeployCommand.cmd.Flags().DurationVar(&rolloutDeployCommand.args.DeploymentOptions.DrainTimeout, "drain-timeout", server.DefaultDrainTimeout, "Maximum time to allow existing connections to drain before removing old target")
2929

3030
rolloutDeployCommand.cmd.MarkFlagRequired("target")
3131

internal/server/commands.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ type CommandHandler struct {
1717
}
1818

1919
type DeployArgs struct {
20-
Service string
21-
TargetURLs []string
22-
ReaderURLs []string
23-
DeployTimeout time.Duration
24-
DrainTimeout time.Duration
25-
ServiceOptions ServiceOptions
26-
TargetOptions TargetOptions
20+
Service string
21+
TargetURLs []string
22+
ReaderURLs []string
23+
DeploymentOptions DeploymentOptions
24+
ServiceOptions ServiceOptions
25+
TargetOptions TargetOptions
2726
}
2827

2928
type PauseArgs struct {
@@ -47,11 +46,10 @@ type RemoveArgs struct {
4746
}
4847

4948
type RolloutDeployArgs struct {
50-
Service string
51-
TargetURLs []string
52-
ReaderURLs []string
53-
DeployTimeout time.Duration
54-
DrainTimeout time.Duration
49+
Service string
50+
TargetURLs []string
51+
ReaderURLs []string
52+
DeploymentOptions DeploymentOptions
5553
}
5654

5755
type RolloutSetArgs struct {
@@ -115,7 +113,7 @@ func (h *CommandHandler) Close() error {
115113
}
116114

117115
func (h *CommandHandler) Deploy(args DeployArgs, reply *bool) error {
118-
return h.router.DeployService(args.Service, args.TargetURLs, args.ReaderURLs, args.ServiceOptions, args.TargetOptions, args.DeployTimeout, args.DrainTimeout)
116+
return h.router.DeployService(args.Service, args.TargetURLs, args.ReaderURLs, args.ServiceOptions, args.TargetOptions, args.DeploymentOptions)
119117
}
120118

121119
func (h *CommandHandler) Pause(args PauseArgs, reply *bool) error {
@@ -141,7 +139,7 @@ func (h *CommandHandler) List(args bool, reply *ListResponse) error {
141139
}
142140

143141
func (h *CommandHandler) RolloutDeploy(args RolloutDeployArgs, reply *bool) error {
144-
return h.router.SetRolloutTargets(args.Service, args.TargetURLs, args.ReaderURLs, args.DeployTimeout, args.DrainTimeout)
142+
return h.router.SetRolloutTargets(args.Service, args.TargetURLs, args.ReaderURLs, args.DeploymentOptions)
145143
}
146144

147145
func (h *CommandHandler) RolloutSet(args RolloutSetArgs, reply *bool) error {

internal/server/router.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
105105
service.ServeHTTP(w, req)
106106
}
107107

108-
func (r *Router) DeployService(name string, targetURLs, readerURLs []string, options ServiceOptions, targetOptions TargetOptions, deployTimeout time.Duration, drainTimeout time.Duration) error {
108+
func (r *Router) DeployService(name string, targetURLs, readerURLs []string, options ServiceOptions, targetOptions TargetOptions, deploymentOptions DeploymentOptions) error {
109109
options.Normalize()
110110
slog.Info("Deploying", "service", name, "targets", targetURLs, "hosts", options.Hosts, "paths", options.PathPrefixes, "tls", options.TLSEnabled)
111111

112-
lb, err := r.createLoadBalancer(targetURLs, readerURLs, options, targetOptions, deployTimeout)
112+
lb, err := r.createLoadBalancer(targetURLs, readerURLs, options, targetOptions, deploymentOptions)
113113
if err != nil {
114114
return err
115115
}
@@ -123,22 +123,22 @@ func (r *Router) DeployService(name string, targetURLs, readerURLs []string, opt
123123

124124
if replaced != nil {
125125
replaced.Dispose()
126-
replaced.DrainAll(drainTimeout)
126+
replaced.DrainAll(deploymentOptions.DrainTimeout)
127127
}
128128

129129
slog.Info("Deployed", "service", name, "targets", targetURLs, "hosts", options.Hosts, "paths", options.PathPrefixes, "tls", options.TLSEnabled)
130130
return nil
131131
}
132132

133-
func (r *Router) SetRolloutTargets(name string, targetURLs, readerURLs []string, deployTimeout time.Duration, drainTimeout time.Duration) error {
133+
func (r *Router) SetRolloutTargets(name string, targetURLs, readerURLs []string, deploymentOptions DeploymentOptions) error {
134134
service := r.serviceForName(name)
135135
if service == nil {
136136
return ErrorServiceNotFound
137137
}
138138

139139
slog.Info("Deploying for rollout", "service", name, "targets", targetURLs)
140140

141-
lb, err := r.createLoadBalancer(targetURLs, readerURLs, service.options, service.targetOptions, deployTimeout)
141+
lb, err := r.createLoadBalancer(targetURLs, readerURLs, service.options, service.targetOptions, deploymentOptions)
142142
if err != nil {
143143
return err
144144
}
@@ -152,7 +152,7 @@ func (r *Router) SetRolloutTargets(name string, targetURLs, readerURLs []string,
152152

153153
if replaced != nil {
154154
replaced.Dispose()
155-
replaced.DrainAll(drainTimeout)
155+
replaced.DrainAll(deploymentOptions.DrainTimeout)
156156
}
157157

158158
slog.Info("Deployed for rollout", "service", name, "targets", targetURLs)
@@ -297,17 +297,20 @@ func (r *Router) createOrUpdateService(name string, options ServiceOptions, targ
297297
return service, err
298298
}
299299

300-
func (r *Router) createLoadBalancer(targetURLs, readerURLs []string, options ServiceOptions, targetOptions TargetOptions, deployTimeout time.Duration) (*LoadBalancer, error) {
300+
func (r *Router) createLoadBalancer(targetURLs, readerURLs []string, options ServiceOptions, targetOptions TargetOptions, deploymentOptions DeploymentOptions) (*LoadBalancer, error) {
301301
tl, err := NewTargetList(targetURLs, readerURLs, targetOptions)
302302
if err != nil {
303303
return nil, err
304304
}
305305

306306
lb := NewLoadBalancer(tl, options.WriterAffinityTimeout, options.ReadTargetsAcceptWebsockets)
307-
err = lb.WaitUntilHealthy(deployTimeout)
308-
if err != nil {
309-
lb.Dispose()
310-
return nil, err
307+
308+
if !deploymentOptions.Force {
309+
err = lb.WaitUntilHealthy(deploymentOptions.DeployTimeout)
310+
if err != nil {
311+
lb.Dispose()
312+
return nil, err
313+
}
311314
}
312315

313316
return lb, nil

0 commit comments

Comments
 (0)