mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
rebase: add controller runtime dependency
this commits add the controller runtime and its dependency to the vendor. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
14700b89d1
commit
5af3fe5deb
21
vendor/sigs.k8s.io/controller-runtime/pkg/manager/doc.go
generated
vendored
Normal file
21
vendor/sigs.k8s.io/controller-runtime/pkg/manager/doc.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Package manager is required to create Controllers and provides shared dependencies such as clients, caches, schemes,
|
||||
etc. Controllers must be started by calling Manager.Start.
|
||||
*/
|
||||
package manager
|
586
vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go
generated
vendored
Normal file
586
vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go
generated
vendored
Normal file
@ -0,0 +1,586 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/client-go/tools/record"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||
"sigs.k8s.io/controller-runtime/pkg/recorder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
const (
|
||||
// Values taken from: https://github.com/kubernetes/apiserver/blob/master/pkg/apis/config/v1alpha1/defaults.go
|
||||
defaultLeaseDuration = 15 * time.Second
|
||||
defaultRenewDeadline = 10 * time.Second
|
||||
defaultRetryPeriod = 2 * time.Second
|
||||
|
||||
defaultReadinessEndpoint = "/readyz"
|
||||
defaultLivenessEndpoint = "/healthz"
|
||||
defaultMetricsEndpoint = "/metrics"
|
||||
)
|
||||
|
||||
var log = logf.RuntimeLog.WithName("manager")
|
||||
|
||||
type controllerManager struct {
|
||||
// config is the rest.config used to talk to the apiserver. Required.
|
||||
config *rest.Config
|
||||
|
||||
// scheme is the scheme injected into Controllers, EventHandlers, Sources and Predicates. Defaults
|
||||
// to scheme.scheme.
|
||||
scheme *runtime.Scheme
|
||||
|
||||
// leaderElectionRunnables is the set of Controllers that the controllerManager injects deps into and Starts.
|
||||
// These Runnables are managed by lead election.
|
||||
leaderElectionRunnables []Runnable
|
||||
// nonLeaderElectionRunnables is the set of webhook servers that the controllerManager injects deps into and Starts.
|
||||
// These Runnables will not be blocked by lead election.
|
||||
nonLeaderElectionRunnables []Runnable
|
||||
|
||||
cache cache.Cache
|
||||
|
||||
// TODO(directxman12): Provide an escape hatch to get individual indexers
|
||||
// client is the client injected into Controllers (and EventHandlers, Sources and Predicates).
|
||||
client client.Client
|
||||
|
||||
// apiReader is the reader that will make requests to the api server and not the cache.
|
||||
apiReader client.Reader
|
||||
|
||||
// fieldIndexes knows how to add field indexes over the Cache used by this controller,
|
||||
// which can later be consumed via field selectors from the injected client.
|
||||
fieldIndexes client.FieldIndexer
|
||||
|
||||
// recorderProvider is used to generate event recorders that will be injected into Controllers
|
||||
// (and EventHandlers, Sources and Predicates).
|
||||
recorderProvider recorder.Provider
|
||||
|
||||
// resourceLock forms the basis for leader election
|
||||
resourceLock resourcelock.Interface
|
||||
|
||||
// mapper is used to map resources to kind, and map kind and version.
|
||||
mapper meta.RESTMapper
|
||||
|
||||
// metricsListener is used to serve prometheus metrics
|
||||
metricsListener net.Listener
|
||||
|
||||
// metricsExtraHandlers contains extra handlers to register on http server that serves metrics.
|
||||
metricsExtraHandlers map[string]http.Handler
|
||||
|
||||
// healthProbeListener is used to serve liveness probe
|
||||
healthProbeListener net.Listener
|
||||
|
||||
// Readiness probe endpoint name
|
||||
readinessEndpointName string
|
||||
|
||||
// Liveness probe endpoint name
|
||||
livenessEndpointName string
|
||||
|
||||
// Readyz probe handler
|
||||
readyzHandler *healthz.Handler
|
||||
|
||||
// Healthz probe handler
|
||||
healthzHandler *healthz.Handler
|
||||
|
||||
mu sync.Mutex
|
||||
started bool
|
||||
startedLeader bool
|
||||
healthzStarted bool
|
||||
|
||||
// NB(directxman12): we don't just use an error channel here to avoid the situation where the
|
||||
// error channel is too small and we end up blocking some goroutines waiting to report their errors.
|
||||
// errSignal lets us track when we should stop because an error occurred
|
||||
errSignal *errSignaler
|
||||
|
||||
// internalStop is the stop channel *actually* used by everything involved
|
||||
// with the manager as a stop channel, so that we can pass a stop channel
|
||||
// to things that need it off the bat (like the Channel source). It can
|
||||
// be closed via `internalStopper` (by being the same underlying channel).
|
||||
internalStop <-chan struct{}
|
||||
|
||||
// internalStopper is the write side of the internal stop channel, allowing us to close it.
|
||||
// It and `internalStop` should point to the same channel.
|
||||
internalStopper chan<- struct{}
|
||||
|
||||
// elected is closed when this manager becomes the leader of a group of
|
||||
// managers, either because it won a leader election or because no leader
|
||||
// election was configured.
|
||||
elected chan struct{}
|
||||
|
||||
startCache func(stop <-chan struct{}) error
|
||||
|
||||
// port is the port that the webhook server serves at.
|
||||
port int
|
||||
// host is the hostname that the webhook server binds to.
|
||||
host string
|
||||
// CertDir is the directory that contains the server key and certificate.
|
||||
// if not set, webhook server would look up the server key and certificate in
|
||||
// {TempDir}/k8s-webhook-server/serving-certs
|
||||
certDir string
|
||||
|
||||
webhookServer *webhook.Server
|
||||
|
||||
// leaseDuration is the duration that non-leader candidates will
|
||||
// wait to force acquire leadership.
|
||||
leaseDuration time.Duration
|
||||
// renewDeadline is the duration that the acting master will retry
|
||||
// refreshing leadership before giving up.
|
||||
renewDeadline time.Duration
|
||||
// retryPeriod is the duration the LeaderElector clients should wait
|
||||
// between tries of actions.
|
||||
retryPeriod time.Duration
|
||||
}
|
||||
|
||||
type errSignaler struct {
|
||||
// errSignal indicates that an error occurred, when closed. It shouldn't
|
||||
// be written to.
|
||||
errSignal chan struct{}
|
||||
|
||||
// err is the received error
|
||||
err error
|
||||
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (r *errSignaler) SignalError(err error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if err == nil {
|
||||
// non-error, ignore
|
||||
log.Error(nil, "SignalError called without an (with a nil) error, which should never happen, ignoring")
|
||||
return
|
||||
}
|
||||
|
||||
if r.err != nil {
|
||||
// we already have an error, don't try again
|
||||
return
|
||||
}
|
||||
|
||||
// save the error and report it
|
||||
r.err = err
|
||||
close(r.errSignal)
|
||||
}
|
||||
|
||||
func (r *errSignaler) Error() error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
return r.err
|
||||
}
|
||||
|
||||
func (r *errSignaler) GotError() chan struct{} {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
return r.errSignal
|
||||
}
|
||||
|
||||
// Add sets dependencies on i, and adds it to the list of Runnables to start.
|
||||
func (cm *controllerManager) Add(r Runnable) error {
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
// Set dependencies on the object
|
||||
if err := cm.SetFields(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var shouldStart bool
|
||||
|
||||
// Add the runnable to the leader election or the non-leaderelection list
|
||||
if leRunnable, ok := r.(LeaderElectionRunnable); ok && !leRunnable.NeedLeaderElection() {
|
||||
shouldStart = cm.started
|
||||
cm.nonLeaderElectionRunnables = append(cm.nonLeaderElectionRunnables, r)
|
||||
} else {
|
||||
shouldStart = cm.startedLeader
|
||||
cm.leaderElectionRunnables = append(cm.leaderElectionRunnables, r)
|
||||
}
|
||||
|
||||
if shouldStart {
|
||||
// If already started, start the controller
|
||||
go func() {
|
||||
if err := r.Start(cm.internalStop); err != nil {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *controllerManager) SetFields(i interface{}) error {
|
||||
if _, err := inject.ConfigInto(cm.config, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.ClientInto(cm.client, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.APIReaderInto(cm.apiReader, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.SchemeInto(cm.scheme, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.CacheInto(cm.cache, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.InjectorInto(cm.SetFields, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.StopChannelInto(cm.internalStop, i); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := inject.MapperInto(cm.mapper, i); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddMetricsExtraHandler adds extra handler served on path to the http server that serves metrics.
|
||||
func (cm *controllerManager) AddMetricsExtraHandler(path string, handler http.Handler) error {
|
||||
if path == defaultMetricsEndpoint {
|
||||
return fmt.Errorf("overriding builtin %s endpoint is not allowed", defaultMetricsEndpoint)
|
||||
}
|
||||
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
_, found := cm.metricsExtraHandlers[path]
|
||||
if found {
|
||||
return fmt.Errorf("can't register extra handler by duplicate path %q on metrics http server", path)
|
||||
}
|
||||
|
||||
cm.metricsExtraHandlers[path] = handler
|
||||
log.V(2).Info("Registering metrics http server extra handler", "path", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddHealthzCheck allows you to add Healthz checker
|
||||
func (cm *controllerManager) AddHealthzCheck(name string, check healthz.Checker) error {
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
if cm.healthzStarted {
|
||||
return fmt.Errorf("unable to add new checker because healthz endpoint has already been created")
|
||||
}
|
||||
|
||||
if cm.healthzHandler == nil {
|
||||
cm.healthzHandler = &healthz.Handler{Checks: map[string]healthz.Checker{}}
|
||||
}
|
||||
|
||||
cm.healthzHandler.Checks[name] = check
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddReadyzCheck allows you to add Readyz checker
|
||||
func (cm *controllerManager) AddReadyzCheck(name string, check healthz.Checker) error {
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
if cm.healthzStarted {
|
||||
return fmt.Errorf("unable to add new checker because readyz endpoint has already been created")
|
||||
}
|
||||
|
||||
if cm.readyzHandler == nil {
|
||||
cm.readyzHandler = &healthz.Handler{Checks: map[string]healthz.Checker{}}
|
||||
}
|
||||
|
||||
cm.readyzHandler.Checks[name] = check
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetConfig() *rest.Config {
|
||||
return cm.config
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetClient() client.Client {
|
||||
return cm.client
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetScheme() *runtime.Scheme {
|
||||
return cm.scheme
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetFieldIndexer() client.FieldIndexer {
|
||||
return cm.fieldIndexes
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetCache() cache.Cache {
|
||||
return cm.cache
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetEventRecorderFor(name string) record.EventRecorder {
|
||||
return cm.recorderProvider.GetEventRecorderFor(name)
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetRESTMapper() meta.RESTMapper {
|
||||
return cm.mapper
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetAPIReader() client.Reader {
|
||||
return cm.apiReader
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetWebhookServer() *webhook.Server {
|
||||
if cm.webhookServer == nil {
|
||||
cm.webhookServer = &webhook.Server{
|
||||
Port: cm.port,
|
||||
Host: cm.host,
|
||||
CertDir: cm.certDir,
|
||||
}
|
||||
if err := cm.Add(cm.webhookServer); err != nil {
|
||||
panic("unable to add webhookServer to the controller manager")
|
||||
}
|
||||
}
|
||||
return cm.webhookServer
|
||||
}
|
||||
|
||||
func (cm *controllerManager) serveMetrics(stop <-chan struct{}) {
|
||||
handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{
|
||||
ErrorHandling: promhttp.HTTPErrorOnError,
|
||||
})
|
||||
// TODO(JoelSpeed): Use existing Kubernetes machinery for serving metrics
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle(defaultMetricsEndpoint, handler)
|
||||
|
||||
func() {
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
for path, extraHandler := range cm.metricsExtraHandlers {
|
||||
mux.Handle(path, extraHandler)
|
||||
}
|
||||
}()
|
||||
|
||||
server := http.Server{
|
||||
Handler: mux,
|
||||
}
|
||||
// Run the server
|
||||
go func() {
|
||||
log.Info("starting metrics server", "path", defaultMetricsEndpoint)
|
||||
if err := server.Serve(cm.metricsListener); err != nil && err != http.ErrServerClosed {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Shutdown the server when stop is closed
|
||||
<-stop
|
||||
if err := server.Shutdown(context.Background()); err != nil {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *controllerManager) serveHealthProbes(stop <-chan struct{}) {
|
||||
// TODO(hypnoglow): refactor locking to use anonymous func in the similar way
|
||||
// it's done in serveMetrics.
|
||||
cm.mu.Lock()
|
||||
mux := http.NewServeMux()
|
||||
|
||||
if cm.readyzHandler != nil {
|
||||
mux.Handle(cm.readinessEndpointName, http.StripPrefix(cm.readinessEndpointName, cm.readyzHandler))
|
||||
}
|
||||
if cm.healthzHandler != nil {
|
||||
mux.Handle(cm.livenessEndpointName, http.StripPrefix(cm.livenessEndpointName, cm.healthzHandler))
|
||||
}
|
||||
|
||||
server := http.Server{
|
||||
Handler: mux,
|
||||
}
|
||||
// Run server
|
||||
go func() {
|
||||
if err := server.Serve(cm.healthProbeListener); err != nil && err != http.ErrServerClosed {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
}()
|
||||
cm.healthzStarted = true
|
||||
cm.mu.Unlock()
|
||||
|
||||
// Shutdown the server when stop is closed
|
||||
<-stop
|
||||
if err := server.Shutdown(context.Background()); err != nil {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *controllerManager) Start(stop <-chan struct{}) error {
|
||||
// join the passed-in stop channel as an upstream feeding into cm.internalStopper
|
||||
defer close(cm.internalStopper)
|
||||
|
||||
// initialize this here so that we reset the signal channel state on every start
|
||||
cm.errSignal = &errSignaler{errSignal: make(chan struct{})}
|
||||
|
||||
// Metrics should be served whether the controller is leader or not.
|
||||
// (If we don't serve metrics for non-leaders, prometheus will still scrape
|
||||
// the pod but will get a connection refused)
|
||||
if cm.metricsListener != nil {
|
||||
go cm.serveMetrics(cm.internalStop)
|
||||
}
|
||||
|
||||
// Serve health probes
|
||||
if cm.healthProbeListener != nil {
|
||||
go cm.serveHealthProbes(cm.internalStop)
|
||||
}
|
||||
|
||||
go cm.startNonLeaderElectionRunnables()
|
||||
|
||||
if cm.resourceLock != nil {
|
||||
err := cm.startLeaderElection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Treat not having leader election enabled the same as being elected.
|
||||
close(cm.elected)
|
||||
go cm.startLeaderElectionRunnables()
|
||||
}
|
||||
|
||||
select {
|
||||
case <-stop:
|
||||
// We are done
|
||||
return nil
|
||||
case <-cm.errSignal.GotError():
|
||||
// Error starting a controller
|
||||
return cm.errSignal.Error()
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *controllerManager) startNonLeaderElectionRunnables() {
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
cm.waitForCache()
|
||||
|
||||
// Start the non-leaderelection Runnables after the cache has synced
|
||||
for _, c := range cm.nonLeaderElectionRunnables {
|
||||
// Controllers block, but we want to return an error if any have an error starting.
|
||||
// Write any Start errors to a channel so we can return them
|
||||
ctrl := c
|
||||
go func() {
|
||||
if err := ctrl.Start(cm.internalStop); err != nil {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
// we use %T here because we don't have a good stand-in for "name",
|
||||
// and the full runnable might not serialize (mutexes, etc)
|
||||
log.V(1).Info("non-leader-election runnable finished", "runnable type", fmt.Sprintf("%T", ctrl))
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *controllerManager) startLeaderElectionRunnables() {
|
||||
cm.mu.Lock()
|
||||
defer cm.mu.Unlock()
|
||||
|
||||
cm.waitForCache()
|
||||
|
||||
// Start the leader election Runnables after the cache has synced
|
||||
for _, c := range cm.leaderElectionRunnables {
|
||||
// Controllers block, but we want to return an error if any have an error starting.
|
||||
// Write any Start errors to a channel so we can return them
|
||||
ctrl := c
|
||||
go func() {
|
||||
if err := ctrl.Start(cm.internalStop); err != nil {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
// we use %T here because we don't have a good stand-in for "name",
|
||||
// and the full runnable might not serialize (mutexes, etc)
|
||||
log.V(1).Info("leader-election runnable finished", "runnable type", fmt.Sprintf("%T", ctrl))
|
||||
}()
|
||||
}
|
||||
|
||||
cm.startedLeader = true
|
||||
}
|
||||
|
||||
func (cm *controllerManager) waitForCache() {
|
||||
if cm.started {
|
||||
return
|
||||
}
|
||||
|
||||
// Start the Cache. Allow the function to start the cache to be mocked out for testing
|
||||
if cm.startCache == nil {
|
||||
cm.startCache = cm.cache.Start
|
||||
}
|
||||
go func() {
|
||||
if err := cm.startCache(cm.internalStop); err != nil {
|
||||
cm.errSignal.SignalError(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for the caches to sync.
|
||||
// TODO(community): Check the return value and write a test
|
||||
cm.cache.WaitForCacheSync(cm.internalStop)
|
||||
cm.started = true
|
||||
}
|
||||
|
||||
func (cm *controllerManager) startLeaderElection() (err error) {
|
||||
l, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
|
||||
Lock: cm.resourceLock,
|
||||
LeaseDuration: cm.leaseDuration,
|
||||
RenewDeadline: cm.renewDeadline,
|
||||
RetryPeriod: cm.retryPeriod,
|
||||
Callbacks: leaderelection.LeaderCallbacks{
|
||||
OnStartedLeading: func(_ context.Context) {
|
||||
close(cm.elected)
|
||||
cm.startLeaderElectionRunnables()
|
||||
},
|
||||
OnStoppedLeading: func() {
|
||||
// Most implementations of leader election log.Fatal() here.
|
||||
// Since Start is wrapped in log.Fatal when called, we can just return
|
||||
// an error here which will cause the program to exit.
|
||||
cm.errSignal.SignalError(fmt.Errorf("leader election lost"))
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
select {
|
||||
case <-cm.internalStop:
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
// Start the leader elector process
|
||||
go l.Run(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cm *controllerManager) Elected() <-chan struct{} {
|
||||
return cm.elected
|
||||
}
|
443
vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
generated
vendored
Normal file
443
vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
generated
vendored
Normal file
@ -0,0 +1,443 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
package manager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
internalrecorder "sigs.k8s.io/controller-runtime/pkg/internal/recorder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/leaderelection"
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||
"sigs.k8s.io/controller-runtime/pkg/recorder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
)
|
||||
|
||||
// Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables.
|
||||
// A Manager is required to create Controllers.
|
||||
type Manager interface {
|
||||
// Add will set requested dependencies on the component, and cause the component to be
|
||||
// started when Start is called. Add will inject any dependencies for which the argument
|
||||
// implements the inject interface - e.g. inject.Client.
|
||||
// Depending on if a Runnable implements LeaderElectionRunnable interface, a Runnable can be run in either
|
||||
// non-leaderelection mode (always running) or leader election mode (managed by leader election if enabled).
|
||||
Add(Runnable) error
|
||||
|
||||
// Elected is closed when this manager is elected leader of a group of
|
||||
// managers, either because it won a leader election or because no leader
|
||||
// election was configured.
|
||||
Elected() <-chan struct{}
|
||||
|
||||
// SetFields will set any dependencies on an object for which the object has implemented the inject
|
||||
// interface - e.g. inject.Client.
|
||||
SetFields(interface{}) error
|
||||
|
||||
// AddMetricsExtraHandler adds an extra handler served on path to the http server that serves metrics.
|
||||
// Might be useful to register some diagnostic endpoints e.g. pprof. Note that these endpoints meant to be
|
||||
// sensitive and shouldn't be exposed publicly.
|
||||
// If the simple path -> handler mapping offered here is not enough, a new http server/listener should be added as
|
||||
// Runnable to the manager via Add method.
|
||||
AddMetricsExtraHandler(path string, handler http.Handler) error
|
||||
|
||||
// AddHealthzCheck allows you to add Healthz checker
|
||||
AddHealthzCheck(name string, check healthz.Checker) error
|
||||
|
||||
// AddReadyzCheck allows you to add Readyz checker
|
||||
AddReadyzCheck(name string, check healthz.Checker) error
|
||||
|
||||
// Start starts all registered Controllers and blocks until the Stop channel is closed.
|
||||
// Returns an error if there is an error starting any controller.
|
||||
Start(<-chan struct{}) error
|
||||
|
||||
// GetConfig returns an initialized Config
|
||||
GetConfig() *rest.Config
|
||||
|
||||
// GetScheme returns an initialized Scheme
|
||||
GetScheme() *runtime.Scheme
|
||||
|
||||
// GetClient returns a client configured with the Config. This client may
|
||||
// not be a fully "direct" client -- it may read from a cache, for
|
||||
// instance. See Options.NewClient for more information on how the default
|
||||
// implementation works.
|
||||
GetClient() client.Client
|
||||
|
||||
// GetFieldIndexer returns a client.FieldIndexer configured with the client
|
||||
GetFieldIndexer() client.FieldIndexer
|
||||
|
||||
// GetCache returns a cache.Cache
|
||||
GetCache() cache.Cache
|
||||
|
||||
// GetEventRecorderFor returns a new EventRecorder for the provided name
|
||||
GetEventRecorderFor(name string) record.EventRecorder
|
||||
|
||||
// GetRESTMapper returns a RESTMapper
|
||||
GetRESTMapper() meta.RESTMapper
|
||||
|
||||
// GetAPIReader returns a reader that will be configured to use the API server.
|
||||
// This should be used sparingly and only when the client does not fit your
|
||||
// use case.
|
||||
GetAPIReader() client.Reader
|
||||
|
||||
// GetWebhookServer returns a webhook.Server
|
||||
GetWebhookServer() *webhook.Server
|
||||
}
|
||||
|
||||
// Options are the arguments for creating a new Manager
|
||||
type Options struct {
|
||||
// Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources
|
||||
// Defaults to the kubernetes/client-go scheme.Scheme, but it's almost always better
|
||||
// idea to pass your own scheme in. See the documentation in pkg/scheme for more information.
|
||||
Scheme *runtime.Scheme
|
||||
|
||||
// MapperProvider provides the rest mapper used to map go types to Kubernetes APIs
|
||||
MapperProvider func(c *rest.Config) (meta.RESTMapper, error)
|
||||
|
||||
// SyncPeriod determines the minimum frequency at which watched resources are
|
||||
// reconciled. A lower period will correct entropy more quickly, but reduce
|
||||
// responsiveness to change if there are many watched resources. Change this
|
||||
// value only if you know what you are doing. Defaults to 10 hours if unset.
|
||||
// there will a 10 percent jitter between the SyncPeriod of all controllers
|
||||
// so that all controllers will not send list requests simultaneously.
|
||||
SyncPeriod *time.Duration
|
||||
|
||||
// LeaderElection determines whether or not to use leader election when
|
||||
// starting the manager.
|
||||
LeaderElection bool
|
||||
|
||||
// LeaderElectionNamespace determines the namespace in which the leader
|
||||
// election configmap will be created.
|
||||
LeaderElectionNamespace string
|
||||
|
||||
// LeaderElectionID determines the name of the configmap that leader election
|
||||
// will use for holding the leader lock.
|
||||
LeaderElectionID string
|
||||
|
||||
// LeaseDuration is the duration that non-leader candidates will
|
||||
// wait to force acquire leadership. This is measured against time of
|
||||
// last observed ack. Default is 15 seconds.
|
||||
LeaseDuration *time.Duration
|
||||
// RenewDeadline is the duration that the acting master will retry
|
||||
// refreshing leadership before giving up. Default is 10 seconds.
|
||||
RenewDeadline *time.Duration
|
||||
// RetryPeriod is the duration the LeaderElector clients should wait
|
||||
// between tries of actions. Default is 2 seconds.
|
||||
RetryPeriod *time.Duration
|
||||
|
||||
// Namespace if specified restricts the manager's cache to watch objects in
|
||||
// the desired namespace Defaults to all namespaces
|
||||
//
|
||||
// Note: If a namespace is specified, controllers can still Watch for a
|
||||
// cluster-scoped resource (e.g Node). For namespaced resources the cache
|
||||
// will only hold objects from the desired namespace.
|
||||
Namespace string
|
||||
|
||||
// MetricsBindAddress is the TCP address that the controller should bind to
|
||||
// for serving prometheus metrics.
|
||||
// It can be set to "0" to disable the metrics serving.
|
||||
MetricsBindAddress string
|
||||
|
||||
// HealthProbeBindAddress is the TCP address that the controller should bind to
|
||||
// for serving health probes
|
||||
HealthProbeBindAddress string
|
||||
|
||||
// Readiness probe endpoint name, defaults to "readyz"
|
||||
ReadinessEndpointName string
|
||||
|
||||
// Liveness probe endpoint name, defaults to "healthz"
|
||||
LivenessEndpointName string
|
||||
|
||||
// Port is the port that the webhook server serves at.
|
||||
// It is used to set webhook.Server.Port.
|
||||
Port int
|
||||
// Host is the hostname that the webhook server binds to.
|
||||
// It is used to set webhook.Server.Host.
|
||||
Host string
|
||||
|
||||
// CertDir is the directory that contains the server key and certificate.
|
||||
// if not set, webhook server would look up the server key and certificate in
|
||||
// {TempDir}/k8s-webhook-server/serving-certs. The server key and certificate
|
||||
// must be named tls.key and tls.crt, respectively.
|
||||
CertDir string
|
||||
// Functions to all for a user to customize the values that will be injected.
|
||||
|
||||
// NewCache is the function that will create the cache to be used
|
||||
// by the manager. If not set this will use the default new cache function.
|
||||
NewCache cache.NewCacheFunc
|
||||
|
||||
// NewClient will create the client to be used by the manager.
|
||||
// If not set this will create the default DelegatingClient that will
|
||||
// use the cache for reads and the client for writes.
|
||||
NewClient NewClientFunc
|
||||
|
||||
// DryRunClient specifies whether the client should be configured to enforce
|
||||
// dryRun mode.
|
||||
DryRunClient bool
|
||||
|
||||
// EventBroadcaster records Events emitted by the manager and sends them to the Kubernetes API
|
||||
// Use this to customize the event correlator and spam filter
|
||||
EventBroadcaster record.EventBroadcaster
|
||||
|
||||
// Dependency injection for testing
|
||||
newRecorderProvider func(config *rest.Config, scheme *runtime.Scheme, logger logr.Logger, broadcaster record.EventBroadcaster) (recorder.Provider, error)
|
||||
newResourceLock func(config *rest.Config, recorderProvider recorder.Provider, options leaderelection.Options) (resourcelock.Interface, error)
|
||||
newMetricsListener func(addr string) (net.Listener, error)
|
||||
newHealthProbeListener func(addr string) (net.Listener, error)
|
||||
}
|
||||
|
||||
// NewClientFunc allows a user to define how to create a client
|
||||
type NewClientFunc func(cache cache.Cache, config *rest.Config, options client.Options) (client.Client, error)
|
||||
|
||||
// Runnable allows a component to be started.
|
||||
// It's very important that Start blocks until
|
||||
// it's done running.
|
||||
type Runnable interface {
|
||||
// Start starts running the component. The component will stop running
|
||||
// when the channel is closed. Start blocks until the channel is closed or
|
||||
// an error occurs.
|
||||
Start(<-chan struct{}) error
|
||||
}
|
||||
|
||||
// RunnableFunc implements Runnable using a function.
|
||||
// It's very important that the given function block
|
||||
// until it's done running.
|
||||
type RunnableFunc func(<-chan struct{}) error
|
||||
|
||||
// Start implements Runnable
|
||||
func (r RunnableFunc) Start(s <-chan struct{}) error {
|
||||
return r(s)
|
||||
}
|
||||
|
||||
// LeaderElectionRunnable knows if a Runnable needs to be run in the leader election mode.
|
||||
type LeaderElectionRunnable interface {
|
||||
// NeedLeaderElection returns true if the Runnable needs to be run in the leader election mode.
|
||||
// e.g. controllers need to be run in leader election mode, while webhook server doesn't.
|
||||
NeedLeaderElection() bool
|
||||
}
|
||||
|
||||
// New returns a new Manager for creating Controllers.
|
||||
func New(config *rest.Config, options Options) (Manager, error) {
|
||||
// Initialize a rest.config if none was specified
|
||||
if config == nil {
|
||||
return nil, fmt.Errorf("must specify Config")
|
||||
}
|
||||
|
||||
// Set default values for options fields
|
||||
options = setOptionsDefaults(options)
|
||||
|
||||
// Create the mapper provider
|
||||
mapper, err := options.MapperProvider(config)
|
||||
if err != nil {
|
||||
log.Error(err, "Failed to get API Group-Resources")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the cache for the cached read client and registering informers
|
||||
cache, err := options.NewCache(config, cache.Options{Scheme: options.Scheme, Mapper: mapper, Resync: options.SyncPeriod, Namespace: options.Namespace})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
apiReader, err := client.New(config, client.Options{Scheme: options.Scheme, Mapper: mapper})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
writeObj, err := options.NewClient(cache, config, client.Options{Scheme: options.Scheme, Mapper: mapper})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if options.DryRunClient {
|
||||
writeObj = client.NewDryRunClient(writeObj)
|
||||
}
|
||||
|
||||
// Create the recorder provider to inject event recorders for the components.
|
||||
// TODO(directxman12): the log for the event provider should have a context (name, tags, etc) specific
|
||||
// to the particular controller that it's being injected into, rather than a generic one like is here.
|
||||
recorderProvider, err := options.newRecorderProvider(config, options.Scheme, log.WithName("events"), options.EventBroadcaster)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the resource lock to enable leader election)
|
||||
resourceLock, err := options.newResourceLock(config, recorderProvider, leaderelection.Options{
|
||||
LeaderElection: options.LeaderElection,
|
||||
LeaderElectionID: options.LeaderElectionID,
|
||||
LeaderElectionNamespace: options.LeaderElectionNamespace,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the metrics listener. This will throw an error if the metrics bind
|
||||
// address is invalid or already in use.
|
||||
metricsListener, err := options.newMetricsListener(options.MetricsBindAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// By default we have no extra endpoints to expose on metrics http server.
|
||||
metricsExtraHandlers := make(map[string]http.Handler)
|
||||
|
||||
// Create health probes listener. This will throw an error if the bind
|
||||
// address is invalid or already in use.
|
||||
healthProbeListener, err := options.newHealthProbeListener(options.HealthProbeBindAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stop := make(chan struct{})
|
||||
|
||||
return &controllerManager{
|
||||
config: config,
|
||||
scheme: options.Scheme,
|
||||
cache: cache,
|
||||
fieldIndexes: cache,
|
||||
client: writeObj,
|
||||
apiReader: apiReader,
|
||||
recorderProvider: recorderProvider,
|
||||
resourceLock: resourceLock,
|
||||
mapper: mapper,
|
||||
metricsListener: metricsListener,
|
||||
metricsExtraHandlers: metricsExtraHandlers,
|
||||
internalStop: stop,
|
||||
internalStopper: stop,
|
||||
elected: make(chan struct{}),
|
||||
port: options.Port,
|
||||
host: options.Host,
|
||||
certDir: options.CertDir,
|
||||
leaseDuration: *options.LeaseDuration,
|
||||
renewDeadline: *options.RenewDeadline,
|
||||
retryPeriod: *options.RetryPeriod,
|
||||
healthProbeListener: healthProbeListener,
|
||||
readinessEndpointName: options.ReadinessEndpointName,
|
||||
livenessEndpointName: options.LivenessEndpointName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// defaultNewClient creates the default caching client
|
||||
func defaultNewClient(cache cache.Cache, config *rest.Config, options client.Options) (client.Client, error) {
|
||||
// Create the Client for Write operations.
|
||||
c, err := client.New(config, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &client.DelegatingClient{
|
||||
Reader: &client.DelegatingReader{
|
||||
CacheReader: cache,
|
||||
ClientReader: c,
|
||||
},
|
||||
Writer: c,
|
||||
StatusClient: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// defaultHealthProbeListener creates the default health probes listener bound to the given address
|
||||
func defaultHealthProbeListener(addr string) (net.Listener, error) {
|
||||
if addr == "" || addr == "0" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listening on %s: %v", addr, err)
|
||||
}
|
||||
return ln, nil
|
||||
}
|
||||
|
||||
// setOptionsDefaults set default values for Options fields
|
||||
func setOptionsDefaults(options Options) Options {
|
||||
// Use the Kubernetes client-go scheme if none is specified
|
||||
if options.Scheme == nil {
|
||||
options.Scheme = scheme.Scheme
|
||||
}
|
||||
|
||||
if options.MapperProvider == nil {
|
||||
options.MapperProvider = func(c *rest.Config) (meta.RESTMapper, error) {
|
||||
return apiutil.NewDynamicRESTMapper(c)
|
||||
}
|
||||
}
|
||||
|
||||
// Allow newClient to be mocked
|
||||
if options.NewClient == nil {
|
||||
options.NewClient = defaultNewClient
|
||||
}
|
||||
|
||||
// Allow newCache to be mocked
|
||||
if options.NewCache == nil {
|
||||
options.NewCache = cache.New
|
||||
}
|
||||
|
||||
// Allow newRecorderProvider to be mocked
|
||||
if options.newRecorderProvider == nil {
|
||||
options.newRecorderProvider = internalrecorder.NewProvider
|
||||
}
|
||||
|
||||
// Allow newResourceLock to be mocked
|
||||
if options.newResourceLock == nil {
|
||||
options.newResourceLock = leaderelection.NewResourceLock
|
||||
}
|
||||
|
||||
if options.newMetricsListener == nil {
|
||||
options.newMetricsListener = metrics.NewListener
|
||||
}
|
||||
leaseDuration, renewDeadline, retryPeriod := defaultLeaseDuration, defaultRenewDeadline, defaultRetryPeriod
|
||||
if options.LeaseDuration == nil {
|
||||
options.LeaseDuration = &leaseDuration
|
||||
}
|
||||
|
||||
if options.RenewDeadline == nil {
|
||||
options.RenewDeadline = &renewDeadline
|
||||
}
|
||||
|
||||
if options.RetryPeriod == nil {
|
||||
options.RetryPeriod = &retryPeriod
|
||||
}
|
||||
|
||||
if options.EventBroadcaster == nil {
|
||||
options.EventBroadcaster = record.NewBroadcaster()
|
||||
}
|
||||
|
||||
if options.ReadinessEndpointName == "" {
|
||||
options.ReadinessEndpointName = defaultReadinessEndpoint
|
||||
}
|
||||
|
||||
if options.LivenessEndpointName == "" {
|
||||
options.LivenessEndpointName = defaultLivenessEndpoint
|
||||
}
|
||||
|
||||
if options.newHealthProbeListener == nil {
|
||||
options.newHealthProbeListener = defaultHealthProbeListener
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
20
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go
generated
vendored
Normal file
20
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/doc.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Package signals contains libraries for handling signals to gracefully
|
||||
// shutdown the manager in combination with Kubernetes pod graceful termination
|
||||
// policy.
|
||||
package signals
|
43
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go
generated
vendored
Normal file
43
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
package signals
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
)
|
||||
|
||||
var onlyOneSignalHandler = make(chan struct{})
|
||||
|
||||
// SetupSignalHandler registers for SIGTERM and SIGINT. A stop channel is returned
|
||||
// which is closed on one of these signals. If a second signal is caught, the program
|
||||
// is terminated with exit code 1.
|
||||
func SetupSignalHandler() (stopCh <-chan struct{}) {
|
||||
close(onlyOneSignalHandler) // panics when called twice
|
||||
|
||||
stop := make(chan struct{})
|
||||
c := make(chan os.Signal, 2)
|
||||
signal.Notify(c, shutdownSignals...)
|
||||
go func() {
|
||||
<-c
|
||||
close(stop)
|
||||
<-c
|
||||
os.Exit(1) // second signal. Exit directly.
|
||||
}()
|
||||
|
||||
return stop
|
||||
}
|
26
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go
generated
vendored
Normal file
26
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_posix.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
package signals
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM}
|
23
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go
generated
vendored
Normal file
23
vendor/sigs.k8s.io/controller-runtime/pkg/manager/signals/signal_windows.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
package signals
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var shutdownSignals = []os.Signal{os.Interrupt}
|
Reference in New Issue
Block a user