Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2f0a0744b | |||
| 71a1d1a7c2 | |||
| de45fa6c30 | |||
| af2d836000 | |||
| 1655ce85bc | |||
| f63ce6c4e7 | |||
| 1885c76198 | |||
| 2224e70638 |
+39
-44
@@ -22,11 +22,23 @@ func (m *Zones) Env(export bool) *Env {
|
||||
}
|
||||
}
|
||||
|
||||
// Zones returns the list of Zone IDs
|
||||
func (m *Env) Zones() []int {
|
||||
var zones []int
|
||||
|
||||
m.ForEachZone(func(z *Zone) bool {
|
||||
zones = append(zones, z.ID)
|
||||
return false
|
||||
})
|
||||
|
||||
return zones
|
||||
}
|
||||
|
||||
// WriteTo generates environment variables for shell scripts
|
||||
func (m *Env) WriteTo(w io.Writer) (int64, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
m.writeEnvVarFn(&buf, genEnvZones, "ZONES")
|
||||
m.writeEnvVarInts(&buf, m.Zones(), "ZONES")
|
||||
m.ForEachZone(func(z *Zone) bool {
|
||||
m.writeEnvZone(&buf, z)
|
||||
return false
|
||||
@@ -45,25 +57,27 @@ func (m *Env) writeEnvZone(w io.Writer, z *Zone) {
|
||||
m.writeEnvVar(w, z.Name, "ZONE%v_%s", zoneID, "NAME")
|
||||
|
||||
// ZONE{zoneID}_GW
|
||||
gatewayID := getRingZeroGatewayID(z)
|
||||
if gatewayID > 0 {
|
||||
m.writeEnvVar(w, fmt.Sprintf("%v", gatewayID), "ZONE%v_%s", zoneID, "GW")
|
||||
|
||||
// ZONE{zoneID}_IP
|
||||
if ip, ok := RingZeroAddress(zoneID, gatewayID); ok {
|
||||
m.writeEnvVar(w, ip.String(), "ZONE%v_%s", zoneID, "IP")
|
||||
}
|
||||
}
|
||||
gateways, _ := z.GatewayIDs()
|
||||
m.writeEnvVarInts(w, gateways, "ZONE%v_%s", zoneID, "GW")
|
||||
}
|
||||
|
||||
func (m *Env) writeEnvVarFn(w io.Writer, fn func(*Env) string, name string, args ...any) {
|
||||
var value string
|
||||
func (m *Env) writeEnvVarInts(w io.Writer, value []int, name string, args ...any) {
|
||||
var s string
|
||||
|
||||
if fn != nil {
|
||||
value = fn(m)
|
||||
if n := len(value); n > 0 {
|
||||
var buf bytes.Buffer
|
||||
|
||||
for i, v := range value {
|
||||
if i != 0 {
|
||||
_, _ = fmt.Fprint(&buf, " ")
|
||||
}
|
||||
_, _ = fmt.Fprintf(&buf, "%v", v)
|
||||
}
|
||||
|
||||
s = buf.String()
|
||||
}
|
||||
|
||||
m.writeEnvVar(w, value, name, args...)
|
||||
m.writeEnvVar(w, s, name, args...)
|
||||
}
|
||||
|
||||
func (m *Env) writeEnvVar(w io.Writer, value string, name string, args ...any) {
|
||||
@@ -84,35 +98,16 @@ func (m *Env) writeEnvVar(w io.Writer, value string, name string, args ...any) {
|
||||
}
|
||||
}
|
||||
|
||||
func genEnvZones(m *Env) string {
|
||||
var s []string
|
||||
|
||||
m.ForEachZone(func(z *Zone) bool {
|
||||
s = append(s, fmt.Sprintf("%v", z.ID))
|
||||
return false
|
||||
})
|
||||
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
func genEnvZoneNodes(z *Zone) string {
|
||||
s := make([]string, 0, len(z.Machines))
|
||||
for _, p := range z.Machines {
|
||||
s = append(s, p.Name)
|
||||
if n := z.Len(); n > 0 {
|
||||
s := make([]string, 0, n)
|
||||
|
||||
z.ForEachMachine(func(p *Machine) bool {
|
||||
s = append(s, p.Name)
|
||||
return false
|
||||
})
|
||||
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
func getRingZeroGatewayID(z *Zone) int {
|
||||
var gatewayID int
|
||||
|
||||
z.ForEachMachine(func(p *Machine) bool {
|
||||
if p.IsGateway() {
|
||||
gatewayID = p.ID
|
||||
}
|
||||
|
||||
return gatewayID != 0
|
||||
})
|
||||
|
||||
return gatewayID
|
||||
return ""
|
||||
}
|
||||
|
||||
+1
-6
@@ -93,12 +93,7 @@ func (m *Zones) scanSort() error {
|
||||
})
|
||||
|
||||
m.ForEachZone(func(z *Zone) bool {
|
||||
sort.SliceStable(z.Machines, func(i, j int) bool {
|
||||
id1 := z.Machines[i].ID
|
||||
id2 := z.Machines[j].ID
|
||||
return id1 < id2
|
||||
})
|
||||
|
||||
sort.Sort(z)
|
||||
return false
|
||||
})
|
||||
|
||||
|
||||
+74
-11
@@ -4,6 +4,7 @@ package zones
|
||||
import (
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/hack-pad/hackpadfs/os"
|
||||
|
||||
@@ -11,6 +12,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
_ MachineIterator = Machines(nil)
|
||||
_ sort.Interface = Machines(nil)
|
||||
|
||||
_ MachineIterator = (*Zone)(nil)
|
||||
_ MachineIterator = (*Zones)(nil)
|
||||
_ ZoneIterator = (*Zones)(nil)
|
||||
@@ -26,6 +30,62 @@ type ZoneIterator interface {
|
||||
ForEachZone(func(*Zone) bool)
|
||||
}
|
||||
|
||||
// Machines is a list of Machine objects
|
||||
type Machines []*Machine
|
||||
|
||||
// ForEachMachine calls a function for each Machine in the list
|
||||
// until instructed to terminate the loop
|
||||
func (m Machines) ForEachMachine(fn func(*Machine) bool) {
|
||||
for _, p := range m {
|
||||
if fn(p) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns the number of machines in the list
|
||||
func (m Machines) Len() int {
|
||||
return len(m)
|
||||
}
|
||||
|
||||
// Less implements sort.Interface to sort the list
|
||||
func (m Machines) Less(i, j int) bool {
|
||||
a, b := m[i], m[j]
|
||||
za, zb := a.Zone(), b.Zone()
|
||||
|
||||
switch {
|
||||
case za == zb:
|
||||
return a.ID < b.ID
|
||||
default:
|
||||
return za < zb
|
||||
}
|
||||
}
|
||||
|
||||
// Swap implements sort.Interface to sort the list
|
||||
func (m Machines) Swap(i, j int) {
|
||||
m[i], m[j] = m[j], m[i]
|
||||
}
|
||||
|
||||
// FilterMachines produces a subset of the machines offered by the given
|
||||
// iterator fulfilling a condition
|
||||
func FilterMachines(m MachineIterator, cond func(*Machine) bool) (Machines, int) {
|
||||
var out []*Machine
|
||||
|
||||
if cond == nil {
|
||||
// unconditional
|
||||
cond = func(*Machine) bool { return true }
|
||||
}
|
||||
|
||||
m.ForEachMachine(func(p *Machine) bool {
|
||||
if cond(p) {
|
||||
out = append(out, p)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return out, len(out)
|
||||
}
|
||||
|
||||
// Zone represents one zone in a cluster
|
||||
type Zone struct {
|
||||
zones *Zones
|
||||
@@ -33,23 +93,13 @@ type Zone struct {
|
||||
ID int `toml:"id"`
|
||||
Name string `toml:"name"`
|
||||
|
||||
Machines []*Machine `toml:"machines"`
|
||||
Machines `toml:"machines"`
|
||||
}
|
||||
|
||||
func (z *Zone) String() string {
|
||||
return z.Name
|
||||
}
|
||||
|
||||
// ForEachMachine calls a function for each Machine in the zone
|
||||
// until instructed to terminate the loop
|
||||
func (z *Zone) ForEachMachine(fn func(*Machine) bool) {
|
||||
for _, p := range z.Machines {
|
||||
if fn(p) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetGateway configures a machine to be the zone's ring0 gateway
|
||||
func (z *Zone) SetGateway(gatewayID int, enabled bool) error {
|
||||
var err error
|
||||
@@ -75,6 +125,19 @@ func (z *Zone) SetGateway(gatewayID int, enabled bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
// GatewayIDs returns the list of IDs of machines that act as ring0 gateways
|
||||
func (z *Zone) GatewayIDs() ([]int, int) {
|
||||
var out []int
|
||||
z.ForEachMachine(func(p *Machine) bool {
|
||||
if p.IsGateway() {
|
||||
out = append(out, p.ID)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
return out, len(out)
|
||||
}
|
||||
|
||||
// Zones represents all zones in a cluster
|
||||
type Zones struct {
|
||||
dir fs.FS
|
||||
|
||||
Reference in New Issue
Block a user