Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mikhail-sakhnov committed Mar 7, 2025
1 parent dd4b113 commit 9db41e5
Showing 1 changed file with 60 additions and 3 deletions.
63 changes: 60 additions & 3 deletions neonvm-runner/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"os/exec"
"os/signal"
"runtime"
"strconv"
"strings"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -487,17 +488,34 @@ func runQEMU(

callbacks = cpuServerCallbacks{
get: func(logger *zap.Logger) (*vmv1.MilliCPU, error) {
return lo.ToPtr(vmv1.MilliCPU(lastValue.Load())), nil
switch cfg.cpuScalingMode {
case vmv1.CpuScalingModeSysfs:
cpu, err := getNeonvmDaemonCPU()
if err != nil {
logger.Error("failed to get CPU from NeonVM Daemon", zap.Error(err))
return nil, err
}
return &cpu, nil
case vmv1.CpuScalingModeQMP:
return lo.ToPtr(vmv1.MilliCPU(lastValue.Load())), nil
default:
panic(fmt.Errorf("unknown CPU scaling mode %s", cfg.cpuScalingMode))
}
},
set: func(logger *zap.Logger, cpu vmv1.MilliCPU) error {
if cfg.cpuScalingMode == vmv1.CpuScalingModeSysfs {
switch cfg.cpuScalingMode {
case vmv1.CpuScalingModeSysfs:
err := setNeonvmDaemonCPU(cpu)
if err != nil {
logger.Error("setting CPU through NeonVM Daemon failed", zap.Any("cpu", cpu), zap.Error(err))
return err
}
case vmv1.CpuScalingModeQMP:
lastValue.Store(uint32(cpu))
return nil
default:
panic(fmt.Errorf("unknown CPU scaling mode %s", cfg.cpuScalingMode))
}
lastValue.Store(uint32(cpu))
return nil
},
ready: func(logger *zap.Logger) bool {
Expand Down Expand Up @@ -865,6 +883,45 @@ func setNeonvmDaemonCPU(cpu vmv1.MilliCPU) error {
return nil
}

func getNeonvmDaemonCPU() (vmv1.MilliCPU, error) {
_, vmIP, _, err := calcIPs(defaultNetworkCIDR)
if err != nil {
return 0, fmt.Errorf("could not calculate VM IP address: %w", err)
}

ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
defer cancel()

url := fmt.Sprintf("http://%s:25183/cpu", vmIP)

req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return 0, fmt.Errorf("could not build request: %w", err)
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return 0, fmt.Errorf("could not send request: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return 0, fmt.Errorf("neonvm-daemon responded with status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return 0, fmt.Errorf("could not read response: %w", err)
}

value, err := strconv.ParseUint(string(body), 10, 32)
if err != nil {
return 0, fmt.Errorf("could not parse response: %w", err)
}

return vmv1.MilliCPU(value), nil
}

// checkNeonvmDaemonCPU sends a GET request to the NeonVM Daemon to get the current CPU limit for the sake of readiness probe.
func checkNeonvmDaemonCPU() error {
_, vmIP, _, err := calcIPs(defaultNetworkCIDR)
Expand Down

0 comments on commit 9db41e5

Please sign in to comment.