()
| 54 | } |
| 55 | |
| 56 | func main() { |
| 57 | klog.InitFlags(nil) |
| 58 | |
| 59 | var kubeconfig string |
| 60 | var leaseLockName string |
| 61 | var leaseLockNamespace string |
| 62 | var id string |
| 63 | |
| 64 | flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file") |
| 65 | flag.StringVar(&id, "id", "", "the holder identity name") |
| 66 | flag.StringVar(&leaseLockName, "lease-lock-name", "example", "the lease lock resource name") |
| 67 | flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "default", "the lease lock resource namespace") |
| 68 | flag.Parse() |
| 69 | |
| 70 | if id == "" { |
| 71 | klog.Fatal("unable to get id (missing id flag).") |
| 72 | } |
| 73 | |
| 74 | // leader election uses the Kubernetes API by writing to a |
| 75 | // lock object, which can be a LeaseLock object (preferred), |
| 76 | // a ConfigMap, or an Endpoints (deprecated) object. |
| 77 | // Conflicting writes are detected and each client handles those actions |
| 78 | // independently. |
| 79 | config, err := buildConfig(kubeconfig) |
| 80 | if err != nil { |
| 81 | klog.Fatal(err) |
| 82 | } |
| 83 | client := clientset.NewForConfigOrDie(config) |
| 84 | |
| 85 | // we use the Lease lock type since edits to Leases are less common |
| 86 | // and fewer objects in the cluster watch "all Leases". |
| 87 | lock := &resourcelock.LeaseLock{ |
| 88 | LeaseMeta: metav1.ObjectMeta{ |
| 89 | Name: leaseLockName, |
| 90 | Namespace: leaseLockNamespace, |
| 91 | }, |
| 92 | Client: client.CoordinationV1(), |
| 93 | LockConfig: resourcelock.ResourceLockConfig{ |
| 94 | Identity: id, |
| 95 | }, |
| 96 | } |
| 97 | |
| 98 | // use a Go context so we can tell the leaderelection code when we |
| 99 | // want to step down |
| 100 | ctx, cancel := context.WithCancel(context.Background()) |
| 101 | defer cancel() |
| 102 | |
| 103 | // use a client that will stop allowing new requests once the context ends |
| 104 | config.Wrap(transport.ContextCanceller(ctx, fmt.Errorf("the leader is shutting down"))) |
| 105 | |
| 106 | // listen for interrupts or the Linux SIGTERM signal and cancel |
| 107 | // our context, which the leader election code will observe and |
| 108 | // step down |
| 109 | ch := make(chan os.Signal, 1) |
| 110 | signal.Notify(ch, os.Interrupt, syscall.SIGTERM) |
| 111 | go func() { |
| 112 | <-ch |
| 113 | log.Printf("Received termination, signaling shutdown") |
nothing calls this directly
no test coverage detected