Skip to content

Commit 16aa411

Browse files
committed
fix: running HTTP status endpoint
Signed-off-by: Andrei Kvapil <[email protected]>
1 parent 8fd97e2 commit 16aa411

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,17 @@ Set `etcd-await-election` as your command's entry point in the container or exec
1717

1818
The relevant environment variables are:
1919

20-
| Variable | Description |
20+
Variable | Description |
2121
|-----------------------------------|-------------|
2222
| `ETCD_AWAIT_ELECTION_LOCK_NAME` | Name of the lock within etcd used for the election process. |
2323
| `ETCD_AWAIT_ELECTION_IDENTITY` | Unique identity for the instance competing for leadership. Typically set to the pod's name. |
24-
| `ETCD_AWAIT_ELECTION_STATUS_ENDPOINT` | Optional: HTTP endpoint to report leadership status. |
25-
| `ETCD_AWAIT_ELECTION_LEASE_DURATION` | Optional: Lease duration (seconds) before a leader must renew. Default: 15. |
26-
| `ETCD_AWAIT_ELECTION_RENEW_DEADLINE` | Optional: Time limit (seconds) for the leader to renew the lease. Default: 10. |
27-
| `ETCD_AWAIT_ELECTION_RETRY_PERIOD` | Optional: Time interval (seconds) to retry a failed election. Default: 2. |
24+
| `ETCD_AWAIT_ELECTION_STATUS_ENDPOINT` | HTTP endpoint to report leadership status, formatted as `host:port` (e.g., `127.0.0.1:1234`). Optional: If not set, no status will be reported. |
25+
| `ETCD_AWAIT_ELECTION_LEASE_DURATION` | Lease duration (seconds) before a leader must renew. Optional: Default is 15 seconds. |
26+
| `ETCD_AWAIT_ELECTION_RENEW_DEADLINE` | Time limit (seconds) for the leader to renew the lease. Optional: Default is 10 seconds. |
27+
| `ETCD_AWAIT_ELECTION_RETRY_PERIOD` | Time interval (seconds) to retry a failed election. Optional: Default is 2 seconds. |
2828
| `ETCD_AWAIT_ELECTION_ENDPOINTS` | Comma-separated list of etcd endpoints. |
2929
| `ETCD_AWAIT_ELECTION_CERT`, `ETCD_AWAIT_ELECTION_KEY`, `ETCD_AWAIT_ELECTION_CACERT` | TLS certificates for secure communication with etcd. |
30-
| `ETCD_AWAIT_ELECTION_FORCE_ACQUIRE` | Optional: Set to any non-empty value to forcefully acquire leadership by deleting existing locks. Only one instance should run with this option. |
31-
30+
| `ETCD_AWAIT_ELECTION_FORCE_ACQUIRE` | Set to any non-empty value to forcefully acquire leadership by deleting existing locks. Optional: Use with caution as only one instance should run with this option. |
3231

3332
### Installation
3433

@@ -45,6 +44,7 @@ ETCD_AWAIT_ELECTION_KEY=/etc/etcd/pki/etcdctl-etcd-client.key \
4544
ETCD_AWAIT_ELECTION_ENDPOINTS='https://127.0.0.1:2379' \
4645
ETCD_AWAIT_ELECTION_LOCK_NAME=test \
4746
ETCD_AWAIT_ELECTION_IDENTITY=$HOSTNAME \
47+
ETCD_AWAIT_ELECTION_STATUS_ENDPOINT=127.0.0.1:1234 \
4848
etcd-await-election sleep 100m
4949
```
5050

main.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ func (el *AwaitElection) Run() error {
258258
return err
259259
}
260260

261+
// Start the status endpoint to serve HTTP requests
262+
el.startStatusEndpoint(ctx)
263+
261264
go el.keepLeaseAlive(ctx)
262265

263266
// Check current leader immediately
@@ -353,17 +356,20 @@ func (el *AwaitElection) monitorLeadership(ctx context.Context, cancel context.C
353356

354357
func (el *AwaitElection) startStatusEndpoint(ctx context.Context) {
355358
if el.StatusEndpoint == "" {
359+
log.Printf("Status endpoint not configured")
356360
return
357361
}
358362

359363
serveMux := http.NewServeMux()
360364
serveMux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
361365
leaderResp, err := el.Election.Leader(ctx)
362366
if err != nil || string(leaderResp.Kvs[0].Value) != el.LeaderIdentity {
363-
http.Error(writer, "Not leader", http.StatusServiceUnavailable)
367+
writer.Write([]byte("{\"status\": \"ok\", \"phase\": \"awaiting\"}\n"))
364368
return
365369
}
366-
writer.Write([]byte("{\"status\": \"ok\"}"))
370+
writer.Header().Set("Content-Type", "application/json")
371+
writer.WriteHeader(http.StatusOK)
372+
writer.Write([]byte("{\"status\": \"ok\", \"phase\": \"running\"}\n"))
367373
})
368374

369375
statusServer := http.Server{
@@ -373,8 +379,12 @@ func (el *AwaitElection) startStatusEndpoint(ctx context.Context) {
373379
return ctx
374380
},
375381
}
382+
376383
go func() {
377-
_ = statusServer.ListenAndServe()
384+
log.Printf("Starting status endpoint on %s", el.StatusEndpoint)
385+
if err := statusServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
386+
log.Printf("Failed to start status server: %v", err)
387+
}
378388
}()
379389
}
380390

0 commit comments

Comments
 (0)