Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add primary hostname to /info endpoint #411

Merged
merged 1 commit into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading