You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
2.0 KiB
137 lines
2.0 KiB
package zones |
|
|
|
import ( |
|
"io/fs" |
|
"sort" |
|
) |
|
|
|
func (m *Zones) scan() error { |
|
for _, fn := range []func() error{ |
|
m.scanDirectory, |
|
m.scanMachines, |
|
m.scanZoneIDs, |
|
m.scanSort, |
|
} { |
|
if err := fn(); err != nil { |
|
return err |
|
} |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (m *Zones) scanDirectory() error { |
|
// each directory is a zone |
|
entries, err := fs.ReadDir(m.dir, ".") |
|
if err != nil { |
|
return err |
|
} |
|
|
|
for _, e := range entries { |
|
if e.IsDir() { |
|
z := &Zone{ |
|
zones: m, |
|
Name: e.Name(), |
|
} |
|
|
|
if err := z.scan(); err != nil { |
|
return err |
|
} |
|
|
|
m.Zones = append(m.Zones, z) |
|
} |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (m *Zones) scanMachines() error { |
|
var err error |
|
m.ForEachMachine(func(p *Machine) bool { |
|
err = p.scan() |
|
return err != nil |
|
}) |
|
return err |
|
} |
|
|
|
func (m *Zones) scanZoneIDs() error { |
|
var hasMissing bool |
|
var lastZoneID int |
|
|
|
m.ForEachZone(func(z *Zone) bool { |
|
switch { |
|
case z.ID == 0: |
|
hasMissing = true |
|
case z.ID > lastZoneID: |
|
lastZoneID = z.ID |
|
} |
|
|
|
return false |
|
}) |
|
|
|
if hasMissing { |
|
next := lastZoneID + 1 |
|
|
|
m.ForEachZone(func(z *Zone) bool { |
|
if z.ID == 0 { |
|
z.ID, next = next, next+1 |
|
} |
|
|
|
return false |
|
}) |
|
} |
|
|
|
return nil |
|
} |
|
|
|
func (m *Zones) scanSort() error { |
|
sort.SliceStable(m.Zones, func(i, j int) bool { |
|
id1 := m.Zones[i].ID |
|
id2 := m.Zones[j].ID |
|
return id1 < id2 |
|
}) |
|
|
|
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 |
|
}) |
|
|
|
return false |
|
}) |
|
|
|
m.ForEachMachine(func(p *Machine) bool { |
|
sort.SliceStable(p.RingAddresses, func(i, j int) bool { |
|
ri1 := p.RingAddresses[i] |
|
ri2 := p.RingAddresses[j] |
|
|
|
return ri1.Ring < ri2.Ring |
|
}) |
|
|
|
return false |
|
}) |
|
|
|
return nil |
|
} |
|
|
|
func (z *Zone) scan() error { |
|
// each directory is a machine |
|
entries, err := fs.ReadDir(z.zones.dir, z.Name) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
for _, e := range entries { |
|
if e.IsDir() { |
|
m := &Machine{ |
|
zone: z, |
|
Name: e.Name(), |
|
} |
|
|
|
z.Machines = append(z.Machines, m) |
|
} |
|
} |
|
|
|
return nil |
|
}
|
|
|