Skip to content

Commit 6c0f6c1

Browse files
committed
Implement leaderelection type getter via restmapper
1 parent 801e12a commit 6c0f6c1

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

pkg/client/apiutil/apimachinery.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ import (
3636
func NewDiscoveryRESTMapper(c *rest.Config) (meta.RESTMapper, error) {
3737
// Get a mapper
3838
dc := discovery.NewDiscoveryClientForConfigOrDie(c)
39+
40+
// TODO(mszostok): here we have useful info about all supported groups and resource
41+
// in api-server
3942
gr, err := restmapper.GetAPIGroupResources(dc)
4043
if err != nil {
4144
return nil, err

pkg/leaderelection/leader_election.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ type Options struct {
4343
// LeaderElectionID determines the name of the configmap that leader election
4444
// will use for holding the leader lock.
4545
LeaderElectionID string
46+
47+
// LeaderElectionLockType determines leader election lock type for holding
48+
// the leader lock information.
49+
LeaderElectionLockType LockType
4650
}
4751

4852
// NewResourceLock creates a new config map resource lock for use in a leader
@@ -80,7 +84,7 @@ func NewResourceLock(config *rest.Config, recorderProvider recorder.Provider, op
8084
}
8185

8286
// TODO(JoelSpeed): switch to leaderelection object in 1.12
83-
return resourcelock.New(resourcelock.ConfigMapsResourceLock,
87+
return resourcelock.New(options.LeaderElectionLockType.Name(),
8488
options.LeaderElectionNamespace,
8589
options.LeaderElectionID,
8690
client.CoreV1(),
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package leaderelection
2+
3+
import (
4+
"fmt"
5+
6+
coordinationv1 "k8s.io/api/coordination/v1"
7+
"k8s.io/apimachinery/pkg/api/meta"
8+
"k8s.io/apimachinery/pkg/runtime/schema"
9+
"k8s.io/client-go/tools/leaderelection/resourcelock"
10+
)
11+
12+
type LockType int
13+
14+
const (
15+
UndefinedResourceLock LockType = iota
16+
ConfigMapsResourceLock
17+
LeasesResourceLock
18+
EndpointsResourceLock
19+
)
20+
21+
func (l LockType) Name() string {
22+
switch l {
23+
case EndpointsResourceLock:
24+
return resourcelock.EndpointsResourceLock
25+
case ConfigMapsResourceLock:
26+
return resourcelock.ConfigMapsResourceLock
27+
case LeasesResourceLock:
28+
return resourcelock.LeasesResourceLock
29+
default:
30+
return ""
31+
}
32+
}
33+
34+
// GetPreferredLockType chooses the Lease lock if `lease.coordination.k8s.io` is available.
35+
// Otherwise, the ConfigMap resource lock is used.
36+
func GetPreferredLockType(mapper meta.RESTMapper) (LockType, error) {
37+
// check if new leader election api is available
38+
_, err := mapper.RESTMapping(schema.GroupKind{
39+
Kind: "Lease",
40+
Group: coordinationv1.GroupName,
41+
})
42+
switch {
43+
case err == nil:
44+
return LeasesResourceLock, nil
45+
case meta.IsNoMatchError(err):
46+
return ConfigMapsResourceLock, nil
47+
default:
48+
return UndefinedResourceLock, fmt.Errorf("unable to retrieve supported server groups: %v", err)
49+
}
50+
}

pkg/manager/manager.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ type Options struct {
118118
// will use for holding the leader lock.
119119
LeaderElectionID string
120120

121+
// LeaderElectionLockType determines leader election lock type for holding
122+
// the leader lock information.
123+
LeaderElectionLockType leaderelection.LockType
124+
121125
// LeaseDuration is the duration that non-leader candidates will
122126
// wait to force acquire leadership. This is measured against time of
123127
// last observed ack. Default is 15 seconds.
@@ -245,10 +249,19 @@ func New(config *rest.Config, options Options) (Manager, error) {
245249
}
246250

247251
// Create the resource lock to enable leader election)
252+
if options.LeaderElectionLockType == leaderelection.UndefinedResourceLock { // this should be moved somehow into `setOptionsDefaults` func
253+
lockType, err := leaderelection.GetPreferredLockType(mapper)
254+
if err != nil {
255+
return nil, err
256+
}
257+
options.LeaderElectionLockType = lockType
258+
}
259+
248260
resourceLock, err := options.newResourceLock(config, recorderProvider, leaderelection.Options{
249261
LeaderElection: options.LeaderElection,
250262
LeaderElectionID: options.LeaderElectionID,
251263
LeaderElectionNamespace: options.LeaderElectionNamespace,
264+
LeaderElectionLockType: options.LeaderElectionLockType,
252265
})
253266
if err != nil {
254267
return nil, err

0 commit comments

Comments
 (0)