Skip to content

Commit

Permalink
Add setting LXD resource cache goroutine
Browse files Browse the repository at this point in the history
  • Loading branch information
chez-shanpu committed May 26, 2023
1 parent 5f86e41 commit d637cdc
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 7 deletions.
68 changes: 67 additions & 1 deletion server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/whywaita/shoes-lxd-multi/server/pkg/api"
"github.com/whywaita/shoes-lxd-multi/server/pkg/config"
"github.com/whywaita/shoes-lxd-multi/server/pkg/lxdclient"
"github.com/whywaita/shoes-lxd-multi/server/pkg/metric"
)

Expand All @@ -26,13 +27,22 @@ func main() {
}

func run() error {
hostConfigs, mapping, listenPort, overCommitPercent, err := config.Load()
hostConfigs, mapping, periodSec, listenPort, overCommitPercent, err := config.Load()
if err != nil {
return fmt.Errorf("failed to create server: %w", err)
}

go serveMetrics(context.Background(), hostConfigs)

// lxd resource cache
t := time.NewTicker(time.Duration(periodSec) * time.Second)
var hcs []config.HostConfig
hostConfigs.Range(func(key string, value config.HostConfig) bool {
hcs = append(hcs, value)
return true
})
go setLXDResourceCacheWithTicker(hcs, t)

server, err := api.New(hostConfigs, mapping, overCommitPercent)
if err != nil {
return fmt.Errorf("failed to create server: %w", err)
Expand Down Expand Up @@ -70,3 +80,59 @@ func serveMetrics(ctx context.Context, hostConfigs *config.HostConfigMap) {
log.Fatal(err)
}
}

func setLXDResourceCacheWithTicker(hcs []config.HostConfig, ticker *time.Ticker) {
for {
_ = <-ticker.C

log.Print("LXD cache is updating")
if err := setLXDResourceCache(hcs); err != nil {
log.Fatal(err)
}
}
}

func setLXDResourceCache(hcs []config.HostConfig) error {
hosts, err := lxdclient.ConnectLXDs(hcs)
if err != nil {
return fmt.Errorf("failed to connect LXD hosts: %s", err)
}

for _, host := range hosts {
if err := setLXDHostResourceCache(&host); err != nil {
return err
}
}
return nil
}

func setLXDHostResourceCache(host *lxdclient.LXDHost) error {
allCPU, allMemory, hostname, err := lxdclient.ScrapeLXDHostResources(host.Client)
if err != nil {
return fmt.Errorf("failed to scrape lxd resources: %s", err)
}

instances, err := lxdclient.GetAnyInstances(host.Client)
if err != nil {
return fmt.Errorf("failed to retrieve list of instance (host: %s): %s", hostname, err)
}

allocatedCPU, allocatedMemory, err := lxdclient.ScrapeLXDHostAllocatedResources(instances)
if err != nil {
return fmt.Errorf("failed to scrape instance info: %s", err)
}

s := lxdclient.LXDStatus{
Resource: lxdclient.Resource{
CPUTotal: allCPU,
MemoryTotal: allMemory,
CPUUsed: allocatedCPU,
MemoryUsed: allocatedMemory,
},
HostConfig: host.HostConfig,
}
if err := lxdclient.SetStatusCache(host.HostConfig.LxdHost, s); err != nil {
return fmt.Errorf("failed to set status cache: %s", err)
}
return nil
}
25 changes: 19 additions & 6 deletions server/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const (

// EnvLXDResourceTypeMapping is mapping resource in lxd
EnvLXDResourceTypeMapping = "LXD_MULTI_RESOURCE_TYPE_MAPPING"
// EnvLXDResourceCachePeriodSec is period of setting LXD resource cache
EnvLXDResourceCachePeriodSec = "LXD_MULTI_RESOURCE_CACHE_PERIOD_SEC"
// EnvPort will listen port
EnvPort = "LXD_MULTI_PORT"
// EnvOverCommit will set percent of over commit in CPU
Expand All @@ -30,18 +32,29 @@ type Mapping struct {
}

// Load load config from Environment values
func Load() (*HostConfigMap, map[myshoespb.ResourceType]Mapping, int, uint64, error) {
func Load() (*HostConfigMap, map[myshoespb.ResourceType]Mapping, int64, int, uint64, error) {
hostConfigs, err := loadHostConfigs()
if err != nil {
return nil, nil, -1, 0, fmt.Errorf("failed to load host config: %w", err)
return nil, nil, 0, -1, 0, fmt.Errorf("failed to load host config: %w", err)
}

envMappingJSON := os.Getenv(EnvLXDResourceTypeMapping)
var m map[myshoespb.ResourceType]Mapping
if envMappingJSON != "" {
m, err = readResourceTypeMapping(envMappingJSON)
if err != nil {
return nil, nil, -1, 0, fmt.Errorf("failed to read %s: %w", EnvLXDResourceTypeMapping, err)
return nil, nil, 0, -1, 0, fmt.Errorf("failed to read %s: %w", EnvLXDResourceTypeMapping, err)
}
}

envPeriodSec := os.Getenv(EnvLXDResourceCachePeriodSec)
var periodSec int64
if envPeriodSec == "" {
periodSec = 10
} else {
periodSec, err = strconv.ParseInt(envPeriodSec, 10, 64)
if err != nil {
return nil, nil, 0, -1, 0, fmt.Errorf("failed to parse %s, need to uint: %w", EnvOverCommit, err)
}
}

Expand All @@ -52,7 +65,7 @@ func Load() (*HostConfigMap, map[myshoespb.ResourceType]Mapping, int, uint64, er
} else {
port, err = strconv.Atoi(envPort)
if err != nil {
return nil, nil, -1, 0, fmt.Errorf("failed to parse %s, need to int: %w", EnvPort, err)
return nil, nil, 0, -1, 0, fmt.Errorf("failed to parse %s, need to int: %w", EnvPort, err)
}
}

Expand All @@ -63,11 +76,11 @@ func Load() (*HostConfigMap, map[myshoespb.ResourceType]Mapping, int, uint64, er
} else {
overCommitPercent, err = strconv.ParseUint(envOCP, 10, 64)
if err != nil {
return nil, nil, -1, 0, fmt.Errorf("failed to parse %s, need to uint: %w", EnvOverCommit, err)
return nil, nil, 0, -1, 0, fmt.Errorf("failed to parse %s, need to uint: %w", EnvOverCommit, err)
}
}

return hostConfigs, m, port, overCommitPercent, nil
return hostConfigs, m, periodSec, port, overCommitPercent, nil
}

func readResourceTypeMapping(env string) (map[myshoespb.ResourceType]Mapping, error) {
Expand Down

0 comments on commit d637cdc

Please sign in to comment.