Skip to content

Commit

Permalink
Add primary hostname to /info endpoint (#411)
Browse files Browse the repository at this point in the history
  • Loading branch information
benbjohnson authored Oct 4, 2023
1 parent 0f7715a commit c477633
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 41 deletions.
4 changes: 2 additions & 2 deletions cmd/litefs/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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
Expand Down
9 changes: 7 additions & 2 deletions http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions lease.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down
41 changes: 4 additions & 37 deletions litefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"crypto/rand"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions mock/lease.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
}
Expand Down

0 comments on commit c477633

Please sign in to comment.