mirror of
https://github.com/containers/podman.git
synced 2025-06-29 15:08:09 +08:00
Merge pull request #11927 from jwhonce/issues/11921
Fix CI flake on time of shutdown for API service
This commit is contained in:
@ -93,7 +93,7 @@ func restService(flags *pflag.FlagSet, cfg *entities.PodmanConfig, opts entities
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := server.Shutdown(false); err != nil {
|
if err := server.Shutdown(true); err != nil {
|
||||||
logrus.Warnf("Error when stopping API service: %s", err)
|
logrus.Warnf("Error when stopping API service: %s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -5,9 +5,10 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
logrusImport "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -25,6 +26,7 @@ var (
|
|||||||
// Ordering that on-shutdown handlers will be invoked.
|
// Ordering that on-shutdown handlers will be invoked.
|
||||||
handlerOrder []string
|
handlerOrder []string
|
||||||
shutdownInhibit sync.RWMutex
|
shutdownInhibit sync.RWMutex
|
||||||
|
logrus = logrusImport.WithField("PID", os.Getpid())
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start begins handling SIGTERM and SIGINT and will run the given on-signal
|
// Start begins handling SIGTERM and SIGINT and will run the given on-signal
|
||||||
@ -44,25 +46,31 @@ func Start() error {
|
|||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-cancelChan:
|
case <-cancelChan:
|
||||||
|
logrus.Infof("Received shutdown.Stop(), terminating!")
|
||||||
signal.Stop(sigChan)
|
signal.Stop(sigChan)
|
||||||
close(sigChan)
|
close(sigChan)
|
||||||
close(cancelChan)
|
close(cancelChan)
|
||||||
stopped = true
|
stopped = true
|
||||||
return
|
return
|
||||||
case sig := <-sigChan:
|
case sig := <-sigChan:
|
||||||
logrus.Infof("Received shutdown signal %v, terminating!", sig)
|
logrus.Infof("Received shutdown signal %q, terminating!", sig.String())
|
||||||
shutdownInhibit.Lock()
|
shutdownInhibit.Lock()
|
||||||
handlerLock.Lock()
|
handlerLock.Lock()
|
||||||
|
|
||||||
for _, name := range handlerOrder {
|
for _, name := range handlerOrder {
|
||||||
handler, ok := handlers[name]
|
handler, ok := handlers[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
logrus.Errorf("Shutdown handler %s definition not found!", name)
|
logrus.Errorf("Shutdown handler %q definition not found!", name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
logrus.Infof("Invoking shutdown handler %s", name)
|
|
||||||
|
logrus.Infof("Invoking shutdown handler %q", name)
|
||||||
|
start := time.Now()
|
||||||
if err := handler(sig); err != nil {
|
if err := handler(sig); err != nil {
|
||||||
logrus.Errorf("Running shutdown handler %s: %v", name, err)
|
logrus.Errorf("Running shutdown handler %q: %v", name, err)
|
||||||
}
|
}
|
||||||
|
logrus.Debugf("Completed shutdown handler %q, duration %v", name,
|
||||||
|
time.Since(start).Round(time.Second))
|
||||||
}
|
}
|
||||||
handlerLock.Unlock()
|
handlerLock.Unlock()
|
||||||
shutdownInhibit.Unlock()
|
shutdownInhibit.Unlock()
|
||||||
|
@ -207,7 +207,7 @@ func (s *APIServer) setupSystemd() {
|
|||||||
func (s *APIServer) Serve() error {
|
func (s *APIServer) Serve() error {
|
||||||
s.setupPprof()
|
s.setupPprof()
|
||||||
|
|
||||||
if err := shutdown.Register("server", func(sig os.Signal) error {
|
if err := shutdown.Register("service", func(sig os.Signal) error {
|
||||||
return s.Shutdown(true)
|
return s.Shutdown(true)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -272,20 +272,24 @@ func (s *APIServer) setupPprof() {
|
|||||||
|
|
||||||
// Shutdown is a clean shutdown waiting on existing clients
|
// Shutdown is a clean shutdown waiting on existing clients
|
||||||
func (s *APIServer) Shutdown(halt bool) error {
|
func (s *APIServer) Shutdown(halt bool) error {
|
||||||
if s.idleTracker.Duration == UnlimitedServiceDuration && !halt {
|
switch {
|
||||||
logrus.Debug("API service shutdown request ignored as Duration is UnlimitedService")
|
case halt:
|
||||||
|
logrus.Debug("API service forced shutdown, ignoring timeout Duration")
|
||||||
|
case s.idleTracker.Duration == UnlimitedServiceDuration:
|
||||||
|
logrus.Debug("API service shutdown request ignored as timeout Duration is UnlimitedService")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdownOnce.Do(func() {
|
shutdownOnce.Do(func() {
|
||||||
if logrus.IsLevelEnabled(logrus.DebugLevel) {
|
logrus.Debugf("API service shutdown, %d/%d connection(s)",
|
||||||
_, file, line, _ := runtime.Caller(1)
|
s.idleTracker.ActiveConnections(), s.idleTracker.TotalConnections())
|
||||||
logrus.Debugf("API service shutdown by %s:%d, %d/%d connection(s)",
|
|
||||||
file, line, s.idleTracker.ActiveConnections(), s.idleTracker.TotalConnections())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gracefully shutdown server(s), duration of wait same as idle window
|
// Gracefully shutdown server(s), duration of wait same as idle window
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), s.idleTracker.Duration)
|
deadline := 1 * time.Second
|
||||||
|
if s.idleTracker.Duration > 0 {
|
||||||
|
deadline = s.idleTracker.Duration
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), deadline)
|
||||||
go func() {
|
go func() {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
@ -296,7 +300,6 @@ func (s *APIServer) Shutdown(halt bool) error {
|
|||||||
}()
|
}()
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ var _ = Describe("podman system service", func() {
|
|||||||
|
|
||||||
pprofPort := randomPort()
|
pprofPort := randomPort()
|
||||||
session := podmanTest.Podman([]string{
|
session := podmanTest.Podman([]string{
|
||||||
"system", "service", "--log-level=info", "--time=0",
|
"system", "service", "--log-level=debug", "--time=0",
|
||||||
"--pprof-address=localhost:" + pprofPort, address.String(),
|
"--pprof-address=localhost:" + pprofPort, address.String(),
|
||||||
})
|
})
|
||||||
defer session.Kill()
|
defer session.Kill()
|
||||||
@ -91,7 +91,7 @@ var _ = Describe("podman system service", func() {
|
|||||||
Expect(body).ShouldNot(BeEmpty())
|
Expect(body).ShouldNot(BeEmpty())
|
||||||
|
|
||||||
session.Interrupt().Wait(2 * time.Second)
|
session.Interrupt().Wait(2 * time.Second)
|
||||||
Eventually(session, 2).Should(Exit(1))
|
Eventually(session).Should(Exit(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("are not available", func() {
|
It("are not available", func() {
|
||||||
@ -103,7 +103,7 @@ var _ = Describe("podman system service", func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
session := podmanTest.Podman([]string{
|
session := podmanTest.Podman([]string{
|
||||||
"system", "service", "--log-level=info", "--time=0", address.String(),
|
"system", "service", "--log-level=debug", "--time=0", address.String(),
|
||||||
})
|
})
|
||||||
defer session.Kill()
|
defer session.Kill()
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ var _ = Describe("podman system service", func() {
|
|||||||
Expect(session.Err.Contents()).ShouldNot(ContainSubstring(magicComment))
|
Expect(session.Err.Contents()).ShouldNot(ContainSubstring(magicComment))
|
||||||
|
|
||||||
session.Interrupt().Wait(2 * time.Second)
|
session.Interrupt().Wait(2 * time.Second)
|
||||||
Eventually(session, 2).Should(Exit(1))
|
Eventually(session).Should(Exit(1))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user