Compare commits

...

12 Commits

Author SHA1 Message Date
amery 0158dc3a3c cluster: add recursive RegionIterator to Zone
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-19 16:46:13 +00:00
amery 9226cf2dfd cluster: introduce RegionIterator
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-19 16:46:13 +00:00
amery 173dba0c3b cluster: decouple getRegion() from finishRegion()
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-19 16:46:13 +00:00
karasz 3a2a20a611 Merge pull request 'cluster: introduce Region.Cluser and m/{region}/k8s_token to store a cluster's token' (#42) from pr-amery-k8s_token into main
Reviewed-on: #42
2024-03-19 17:44:47 +01:00
amery 019143820f cluster: remove k8s_token files from zones on write if found
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-19 16:42:56 +00:00
amery d3bbe6d270 cluster: introduce Region.Cluster and m/{region}/k8s_token
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-19 16:42:56 +00:00
amery 7125e28b74 cluster: extend usage of the ZoneRegionsFileName constant
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-19 16:42:56 +00:00
karasz 7f5ac151c8 Merge pull request 'wireguard: switch from gcfg to asciigoat.org/ini/basic' (#8) from pr-amery-wireguard-ini into main
Reviewed-on: #8
2024-03-09 11:10:02 +01:00
karasz 28bcaa2838 Merge pull request 'jpictl: add --version and version command' (#44) from pr-amery-version into main
Reviewed-on: #44
2024-03-09 11:09:33 +01:00
karasz 3cafb1a4e2 Merge pull request 'ceph: prevent osd label update on startup' (#41) from pr-amery-ceph into main
Reviewed-on: #41
2024-03-09 11:08:30 +01:00
amery 09bec11506 jpictl: add --version and version command
from `git describe` using go:generate and embed

Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-02 23:15:56 +00:00
amery 14686ff5a8 ceph: prevent osd label update on startup
Signed-off-by: Alejandro Mery <amery@jpi.io>
2024-03-02 19:16:37 +00:00
6 changed files with 193 additions and 19 deletions
+1
View File
@@ -1 +1,2 @@
.tmp
.version
+5 -2
View File
@@ -2,6 +2,8 @@
package main
import (
_ "embed"
"github.com/spf13/cobra"
)
@@ -12,8 +14,9 @@ const (
var (
rootCmd = &cobra.Command{
Use: CmdName,
Short: "control tool for jpi.cloud",
Use: CmdName,
Short: "control tool for jpi.cloud",
Version: version,
}
)
+31
View File
@@ -0,0 +1,31 @@
package main
import (
_ "embed"
"fmt"
"os"
"github.com/spf13/cobra"
)
//go:generate sh -c "git describe | tr -d '\r\n' > .version"
//go:embed .version
var version string
var versionCmd = &cobra.Command{
Use: "version",
Short: "Returns jpictl's version",
Args: cobra.NoArgs,
Run: func(_ *cobra.Command, _ []string) {
_, _ = fmt.Fprintf(os.Stdout, "%s\n", version)
},
}
func init() {
if version == "" {
version = "undetermined"
}
rootCmd.AddCommand(versionCmd)
}
+3
View File
@@ -39,6 +39,9 @@ func writeGlobalToBuffer(w *bytes.Buffer, c *GlobalConfig) {
_, _ = fmt.Fprintf(w, "%s = %s\n", "mon_initial_members", strings.Join(c.Monitors, ", "))
_, _ = fmt.Fprintf(w, "%s = %s\n", "mon_host", joinAddrs(c.MonitorsAddr, ", "))
_, _ = fmt.Fprintf(w, "%s = %s\n", "cluster_network", c.ClusterNetwork.String())
_, _ = fmt.Fprintf(w, "\n; %s\n", "don't rewrite labels on startup")
_, _ = fmt.Fprintf(w, "%s = %s\n", "osd_class_update_on_start", "false")
}
func joinAddrs(addrs []netip.Addr, sep string) string {
+33
View File
@@ -4,6 +4,7 @@ import (
"io/fs"
"path"
"sort"
"strings"
"darvaza.org/core"
)
@@ -12,6 +13,10 @@ const (
// ZoneRegionsFileName indicates the file containing
// region names as references
ZoneRegionsFileName = "regions"
// RegionClusterTokenFileName contains the kubernetes
// token of the cluster this region represents
RegionClusterTokenFileName = "k8s_token"
)
func (m *Cluster) scan(opts *ScanOptions) error {
@@ -186,6 +191,8 @@ func (z *Zone) scan() error {
switch {
case name == ZoneRegionsFileName:
err = z.loadRegions()
case name == RegionClusterTokenFileName:
err = z.loadClusterToken()
case e.IsDir():
err = z.scanSubdirectory(name)
default:
@@ -218,6 +225,32 @@ func (z *Zone) loadRegions() error {
return err
}
func (z *Zone) loadClusterToken() error {
var token string
filename := path.Join(z.Name, RegionClusterTokenFileName)
lines, err := z.zones.ReadLines(filename)
if err != nil {
return err
}
// first non-empty line
for _, s := range lines {
s = strings.TrimSpace(s)
if s != "" {
token = s
break
}
}
err = z.zones.setRegionClusterToken(z.Name, token)
if err != nil {
err = core.Wrap(err, filename)
}
return err
}
func (z *Zone) scanSubdirectory(name string) error {
m := &Machine{
zone: z,
+120 -17
View File
@@ -8,14 +8,23 @@ import (
var (
_ MachineIterator = (*Region)(nil)
_ ZoneIterator = (*Region)(nil)
_ RegionIterator = (*Zone)(nil)
_ RegionIterator = (*Cluster)(nil)
)
// A RegionIterator is a set of Regions we can iterate on
type RegionIterator interface {
ForEachRegion(func(*Region) bool)
}
// Region represents a group of zones geographically related
type Region struct {
m *Cluster
zones []*Zone
Name string
Cluster *string `json:",omitempty" yaml:",omitempty"`
Regions []string `json:",omitempty" yaml:",omitempty"`
}
@@ -106,6 +115,26 @@ func (m *Cluster) setRegionZones(name string, zones ...*Zone) {
})
}
func (m *Cluster) setRegionClusterToken(name string, token string) error {
for i := range m.Regions {
r := &m.Regions[i]
if r.Name == name {
// found
r.Cluster = &token
return nil
}
}
// new
m.Regions = append(m.Regions, Region{
m: m,
Name: name,
Cluster: &token,
})
return nil
}
func (m *Cluster) appendRegionRegions(name string, subs ...string) {
for i := range m.Regions {
r := &m.Regions[i]
@@ -124,6 +153,28 @@ func (m *Cluster) appendRegionRegions(name string, subs ...string) {
})
}
// ForEachRegion calls a function on all regions this zone belongs to.
func (z *Zone) ForEachRegion(fn func(*Region) bool) {
if fn == nil {
return
}
z.zones.ForEachRegion(func(r *Region) bool {
var match bool
r.ForEachZone(func(z2 *Zone) bool {
match = (z == z2)
return match
})
if match && fn(r) {
return true
}
return false
})
}
func (z *Zone) appendRegions(regions ...string) error {
for _, s := range regions {
// TODO: validate
@@ -147,7 +198,7 @@ func (m *Cluster) finishRegion(r *Region) {
r.m = m
sub := []string{}
for _, name := range r.Regions {
r2, ok := m.getRegion(name)
r2, ok := m.getFinishRegion(name)
if !ok {
m.warn(nil).WithField("region", name).Print("unknown region")
continue
@@ -162,9 +213,7 @@ func (m *Cluster) finishRegion(r *Region) {
func (m *Cluster) getRegion(name string) (*Region, bool) {
for i := range m.Regions {
r := &m.Regions[i]
if name == r.Name {
m.finishRegion(r)
return r, true
}
}
@@ -172,17 +221,22 @@ func (m *Cluster) getRegion(name string) (*Region, bool) {
return nil, false
}
func (m *Cluster) getFinishRegion(name string) (*Region, bool) {
if r, ok := m.getRegion(name); ok {
m.finishRegion(r)
return r, true
}
return nil, false
}
// SyncRegions writes to the file system the regions this [Zone]
// belongs to.
func (z *Zone) SyncRegions() error {
err := z.syncZoneRegions()
if err == nil {
z.ForEachMachine(func(p *Machine) bool {
if p.IsActive() {
err = p.RemoveFile("region")
} else {
err = p.WriteStringFile("none\n", "region")
}
err = z.syncMachineRegions(p)
return err != nil
})
}
@@ -190,8 +244,24 @@ func (z *Zone) SyncRegions() error {
return err
}
func (*Zone) syncMachineRegions(p *Machine) error {
var err error
if p.IsActive() {
err = p.RemoveFile("region")
} else {
err = p.WriteStringFile("none\n", "region")
}
if err == nil {
err = p.RemoveFile(RegionClusterTokenFileName)
}
return err
}
func (z *Zone) syncZoneRegions() error {
name := filepath.Join(z.Name, "regions")
name := filepath.Join(z.Name, ZoneRegionsFileName)
if len(z.Regions) > 0 {
var buf bytes.Buffer
@@ -210,9 +280,25 @@ func (z *Zone) syncZoneRegions() error {
// SyncRegions writes to the file system the regions covered
// by this meta-region
func (r *Region) SyncRegions() error {
name := filepath.Join(r.Name, "regions")
if err := r.syncRegionsFile(); err != nil {
return err
}
if len(r.Regions) > 0 {
return r.syncClusterFile()
}
func (r *Region) mkdir() error {
return r.m.MkdirAll(r.Name)
}
func (r *Region) syncRegionsFile() error {
var err error
name := filepath.Join(r.Name, ZoneRegionsFileName)
if len(r.Regions) == 0 {
err = r.m.RemoveFile(name)
} else if err = r.mkdir(); err == nil {
var buf bytes.Buffer
for _, s := range r.Regions {
@@ -220,12 +306,29 @@ func (r *Region) SyncRegions() error {
_, _ = buf.WriteRune('\n')
}
if err := r.m.MkdirAll(r.Name); err != nil {
return err
}
return r.m.WriteStringFile(buf.String(), name)
err = r.m.WriteStringFile(buf.String(), name)
}
return r.m.RemoveFile(name)
return err
}
func (r *Region) syncClusterFile() error {
var err error
name := filepath.Join(r.Name, RegionClusterTokenFileName)
if r.Cluster == nil {
err = r.m.RemoveFile(name)
} else if err = r.mkdir(); err == nil {
var buf bytes.Buffer
_, _ = buf.WriteString(*r.Cluster)
if buf.Len() > 0 {
_, _ = buf.WriteRune('\n')
}
err = r.m.WriteStringFile(buf.String(), name)
}
return err
}