From c477633c9b17981ccbfa0b86d28b9cd6b7202888 Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Wed, 4 Oct 2023 11:01:35 -0600 Subject: [PATCH] Add primary hostname to /info endpoint (#411) --- cmd/litefs/run.go | 4 ++-- http/server.go | 9 +++++++-- lease.go | 5 +++++ litefs.go | 41 ++++------------------------------------- mock/lease.go | 5 +++++ 5 files changed, 23 insertions(+), 41 deletions(-) diff --git a/cmd/litefs/run.go b/cmd/litefs/run.go index 5530c34..2c8c70d 100644 --- a/cmd/litefs/run.go +++ b/cmd/litefs/run.go @@ -121,7 +121,7 @@ func (c *RunCommand) Run(ctx context.Context) (err error) { // Attempt to promote local node to be the primary node via lease handoff. if c.Promote { - if info.Primary { + if info.IsPrimary { log.Printf("node is already primary, skipping promotion") } else { log.Printf("promoting node to primary") @@ -143,7 +143,7 @@ func (c *RunCommand) Run(ctx context.Context) (err error) { } // Attempt to lock the database. - if f, err = os.OpenFile(c.WithHaltLockOn+"-lock", os.O_RDWR, 0666); os.IsNotExist(err) { + if f, err = os.OpenFile(c.WithHaltLockOn+"-lock", os.O_RDWR, 0o666); os.IsNotExist(err) { return fmt.Errorf("lock file not available, are you sure %q is a LiteFS mount?", filepath.Dir(c.WithHaltLockOn)) } else if err != nil { return err diff --git a/http/server.go b/http/server.go index f8d28a7..cefddf3 100644 --- a/http/server.go +++ b/http/server.go @@ -270,12 +270,17 @@ func (s *Server) handleDebugRand(w http.ResponseWriter, r *http.Request) { func (s *Server) handleGetInfo(w http.ResponseWriter, r *http.Request) { var info litefs.NodeInfo - info.ID = s.store.ID() info.ClusterID = s.store.ClusterID() - info.Primary = s.store.IsPrimary() + info.IsPrimary = s.store.IsPrimary() info.Candidate = s.store.Candidate() info.Path = s.store.Path() + if isPrimary, primaryInfo := s.store.PrimaryInfo(); isPrimary { + info.Primary.Hostname = s.store.Leaser.Hostname() + } else if primaryInfo != nil { + info.Primary.Hostname = primaryInfo.Hostname + } + if buf, err := json.MarshalIndent(info, "", " "); err != nil { Error(w, r, err, http.StatusInternalServerError) return diff --git a/lease.go b/lease.go index e5092ab..9115f5c 100644 --- a/lease.go +++ b/lease.go @@ -14,6 +14,7 @@ type Leaser interface { // Type returns the name of the leaser. Type() string + Hostname() string AdvertiseURL() string // Acquire attempts to acquire the lease to become the primary. @@ -91,6 +92,10 @@ func (l *StaticLeaser) Close() (err error) { return nil } // Type returns "static". func (l *StaticLeaser) Type() string { return "static" } +func (l *StaticLeaser) Hostname() string { + return l.hostname +} + // AdvertiseURL returns the primary URL if this is the primary. // Otherwise returns blank. func (l *StaticLeaser) AdvertiseURL() string { diff --git a/litefs.go b/litefs.go index 653fd0f..028c8e9 100644 --- a/litefs.go +++ b/litefs.go @@ -5,7 +5,6 @@ import ( "context" "crypto/rand" "encoding/binary" - "encoding/json" "errors" "fmt" "io" @@ -60,46 +59,14 @@ func ValidateClusterID(id string) error { // NodeInfo represents basic info about a node. type NodeInfo struct { - ID uint64 `json:"id"` // node ID ClusterID string `json:"clusterID,omitempty"` // cluster ID - Primary bool `json:"primary"` // if true, node is currently primary + IsPrimary bool `json:"isPrimary"` // if true, node is currently primary Candidate bool `json:"candidate"` // if true, node is eligible to be primary Path string `json:"path"` // data directory -} - -type nodeInfoJSON struct { - ID string `json:"id"` - ClusterID string `json:"clusterID,omitempty"` - Primary bool `json:"primary"` - Candidate bool `json:"candidate"` - Path string `json:"path"` -} - -// MarshalJSON marshals info to JSON. Converts the ID to and from its string representation. -func (i NodeInfo) MarshalJSON() ([]byte, error) { - return json.Marshal(nodeInfoJSON{ - ID: FormatNodeID(i.ID), - ClusterID: i.ClusterID, - Primary: i.Primary, - Candidate: i.Candidate, - Path: i.Path, - }) -} -// UnmarshalJSON unmarshals info from JSON. -func (i *NodeInfo) UnmarshalJSON(data []byte) (err error) { - var v nodeInfoJSON - if err := json.Unmarshal(data, &v); err != nil { - return err - } - if i.ID, err = ParseNodeID(v.ID); err != nil { - return err - } - i.ClusterID = v.ClusterID - i.Primary = v.Primary - i.Candidate = v.Candidate - i.Path = v.Path - return nil + Primary struct { + Hostname string `json:"hostname"` + } `json:"primary"` } // Environment represents an interface for interacting with the host environment. diff --git a/mock/lease.go b/mock/lease.go index eadab47..ad5b402 100644 --- a/mock/lease.go +++ b/mock/lease.go @@ -11,6 +11,7 @@ var _ litefs.Leaser = (*Leaser)(nil) type Leaser struct { CloseFunc func() error + HostnameFunc func() string AdvertiseURLFunc func() string AcquireFunc func(ctx context.Context) (litefs.Lease, error) AcquireExistingFunc func(ctx context.Context, leaseID string) (litefs.Lease, error) @@ -25,6 +26,10 @@ func (l *Leaser) Close() error { func (l *Leaser) Type() string { return "mock" } +func (l *Leaser) Hostname() string { + return l.HostnameFunc() +} + func (l *Leaser) AdvertiseURL() string { return l.AdvertiseURLFunc() }