MCPcopy Index your code
hub / github.com/coder/coder / Close

Method Close

agent/agent.go:2192–2332  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

2190}
2191
2192func (a *agent) Close() error {
2193 a.closeMutex.Lock()
2194 network := a.network
2195 coordDisconnected := a.coordDisconnected
2196 a.closing = true
2197 a.closeMutex.Unlock()
2198 if a.isClosed() {
2199 return nil
2200 }
2201
2202 a.logger.Info(a.hardCtx, "shutting down agent")
2203 a.setLifecycle(codersdk.WorkspaceAgentLifecycleShuttingDown)
2204
2205 // Attempt to gracefully shut down all active SSH connections and
2206 // stop accepting new ones. If all processes have not exited after 5
2207 // seconds, we just log it and move on as it's more important to run
2208 // the shutdown scripts. A typical shutdown time for containers is
2209 // 10 seconds, so this still leaves a bit of time to run the
2210 // shutdown scripts in the worst-case.
2211 sshShutdownCtx, sshShutdownCancel := context.WithTimeout(a.hardCtx, 5*time.Second)
2212 defer sshShutdownCancel()
2213 err := a.sshServer.Shutdown(sshShutdownCtx)
2214 if err != nil {
2215 if errors.Is(err, context.DeadlineExceeded) {
2216 a.logger.Warn(sshShutdownCtx, "ssh server shutdown timeout", slog.Error(err))
2217 } else {
2218 a.logger.Error(sshShutdownCtx, "ssh server shutdown", slog.Error(err))
2219 }
2220 }
2221
2222 // wait for SSH to shut down before the general graceful cancel, because
2223 // this triggers a disconnect in the tailnet layer, telling all clients to
2224 // shut down their wireguard tunnels to us. If SSH sessions are still up,
2225 // they might hang instead of being closed.
2226 a.gracefulCancel()
2227
2228 lifecycleState := codersdk.WorkspaceAgentLifecycleOff
2229 err = a.scriptRunner.Execute(a.hardCtx, agentscripts.ExecuteStopScripts)
2230 if err != nil {
2231 a.logger.Warn(a.hardCtx, "shutdown script(s) failed", slog.Error(err))
2232 if errors.Is(err, agentscripts.ErrTimeout) {
2233 lifecycleState = codersdk.WorkspaceAgentLifecycleShutdownTimeout
2234 } else {
2235 lifecycleState = codersdk.WorkspaceAgentLifecycleShutdownError
2236 }
2237 }
2238
2239 a.setLifecycle(lifecycleState)
2240
2241 err = a.scriptRunner.Close()
2242 if err != nil {
2243 a.logger.Error(a.hardCtx, "script runner close", slog.Error(err))
2244 }
2245
2246 if a.socketServer != nil {
2247 if err := a.socketServer.Close(); err != nil {
2248 a.logger.Error(a.hardCtx, "socket server close", slog.Error(err))
2249 }

Callers

nothing calls this directly

Calls 15

isClosedMethod · 0.95
setLifecycleMethod · 0.95
SlogDisconnectDetailFunction · 0.92
SlogExpectedFieldMethod · 0.80
WaitUntilEmptyMethod · 0.80
ShutdownMethod · 0.65
ExecuteMethod · 0.65
CloseMethod · 0.65
WaitMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45
InfoMethod · 0.45

Tested by

no test coverage detected