add feature for live-reload when configuration changed

Signed-off-by: x893675 <x893675@icloud.com>
This commit is contained in:
x893675
2022-02-07 16:47:43 +08:00
parent b8e1261989
commit 2a521bb157
20 changed files with 189 additions and 60 deletions

View File

@@ -19,6 +19,7 @@ package app
import (
"context"
"fmt"
"net/http"
"github.com/spf13/cobra"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@@ -37,7 +38,7 @@ func NewAPIServerCommand() *cobra.Command {
s := options.NewServerRunOptions()
// Load configuration from file
conf, err := apiserverconfig.TryLoadFromDisk()
conf, configCh, err := apiserverconfig.TryLoadFromDisk()
if err == nil {
s = &options.ServerRunOptions{
GenericServerRunOptions: s.GenericServerRunOptions,
@@ -56,8 +57,7 @@ cluster's shared state through which all other components interact.`,
if errs := s.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs)
}
return Run(s, signals.SetupSignalHandler())
return Run(s, configCh, signals.SetupSignalHandler())
},
SilenceUsage: true,
}
@@ -88,8 +88,38 @@ cluster's shared state through which all other components interact.`,
return cmd
}
func Run(s *options.ServerRunOptions, ctx context.Context) error {
func Run(s *options.ServerRunOptions, configCh <-chan apiserverconfig.Config, ctx context.Context) error {
ictx := apiserverconfig.Context{}
ictx.RenewContext(context.TODO())
errCh := make(chan error)
defer close(errCh)
go func() {
if err := run(s, ictx.GetContext()); err != nil {
errCh <- err
}
}()
for {
select {
case <-ctx.Done():
ictx.CancelContext()
return nil
case cfg := <-configCh:
ictx.CancelContext()
s.Config = &cfg
ictx.RenewContext(context.TODO())
go func() {
if err := run(s, ictx.GetContext()); err != nil {
errCh <- err
}
}()
case err := <-errCh:
return err
}
}
}
func run(s *options.ServerRunOptions, ctx context.Context) error {
apiserver, err := s.NewAPIServer(ctx.Done())
if err != nil {
return err
@@ -100,5 +130,9 @@ func Run(s *options.ServerRunOptions, ctx context.Context) error {
return err
}
return apiserver.Run(ctx)
err = apiserver.Run(ctx)
if err == http.ErrServerClosed {
return nil
}
return err
}