Files
gvisor/runsc/metricserver/metricserver_lifecycle.go
Ayush RanjanandgVisor bot f62a4a77d5 Update go branch to Go 1.21.
Starting with Go 1.21, build tags select the language version. We currently
have several `go:build go1.1` tags, which were intended to act as "true" tags.
But that will break with 1.21. So replace them with "!false".

Fixes #9568.

PiperOrigin-RevId: 576020779
2023-10-23 22:09:47 -07:00

105 lines
2.8 KiB
Go

// Copyright 2023 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !false
// +build !false
package metricserver
import (
"context"
"os"
"time"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/runsc/container"
)
// verifyLoopInterval is the interval at which we check whether there are any sandboxes we need
// to serve metrics for.
const verifyLoopInterval = 20 * time.Second
// sandboxData contains additional per-sandbox data.
type sandboxData struct{}
// load loads additional per-sandbox data.
func (s *sandboxData) load(*servedSandbox) error {
return nil
}
// serverData contains additional server-wide data.
type serverData struct{}
// verify is one iteration of verifyLoop.
// It runs in a loop in the background which checks all sandboxes for liveness, tries to load
// their metadata if that hasn't been loaded yet, and tries to pick up new sandboxes that
// failed to register for whatever reason.
func (m *metricServer) verify(ctx context.Context) {
_, err := container.ListSandboxes(m.rootDir)
m.mu.Lock()
defer m.mu.Unlock()
if err != nil {
if !m.allowUnknownRoot {
log.Warningf("Cannot list sandboxes in root directory %s, it has likely gone away: %v. Server shutting down.", m.rootDir, err)
m.shutdownLocked(ctx)
}
return
}
m.refreshSandboxesLocked()
}
// startVerifyLoop runs in the background and periodically calls verify.
func (m *metricServer) startVerifyLoop(ctx context.Context) error {
go func() {
ticker := time.NewTicker(verifyLoopInterval)
defer ticker.Stop()
for ctx.Err() == nil {
select {
case <-ctx.Done():
return
case <-m.shutdownCh:
log.Infof("Received interrupt signal, shutting down server.")
m.mu.Lock()
m.shutdownLocked(ctx)
m.mu.Unlock()
return
case <-ticker.C:
m.verify(ctx)
}
}
}()
return nil
}
// shutdownLocked shuts down the server. It assumes mu is held.
func (m *metricServer) shutdownLocked(ctx context.Context) {
log.Infof("Server shutting down.")
m.shuttingDown = true
if m.udsPath != "" {
if err := os.Remove(m.udsPath); err != nil {
log.Warningf("Cannot remove UDS at %s: %v", m.udsPath, err)
} else {
m.udsPath = ""
}
}
if m.pidFile != "" {
if err := os.Remove(m.pidFile); err != nil {
log.Warningf("Cannot remove PID file at %s: %v", m.pidFile, err)
} else {
m.pidFile = ""
}
}
m.srv.Shutdown(ctx)
}