diff --git a/.github/workflows/bins.yaml b/.github/workflows/bins.yaml index 7923e2d74..1fc2bedc6 100644 --- a/.github/workflows/bins.yaml +++ b/.github/workflows/bins.yaml @@ -132,3 +132,9 @@ jobs: package: iperf secrets: token: ${{ secrets.HUB_JWT }} + cpubench: + uses: ./.github/workflows/bin-package.yaml + with: + package: cpubench + secrets: + token: ${{ secrets.HUB_JWT }} diff --git a/bins/packages/cpubench/cpubench.sh b/bins/packages/cpubench/cpubench.sh new file mode 100644 index 000000000..c77c8a6f4 --- /dev/null +++ b/bins/packages/cpubench/cpubench.sh @@ -0,0 +1,32 @@ +CPU_BENCHMARK_VERSION="v0.1" +CPU_BENCHMARK_CHECKSUM="25891eb15ec0b1bb8d745a8af3907895" +CPU_BENCHMARK_LINK="https://github.com/threefoldtech/cpu-benchmark-simple/releases/download/${CPU_BENCHMARK_VERSION}/grid-cpubench-simple-0.1-linux-amd64-static" + +download_cpubench() { + echo "downloading cpubench" + download_file ${CPU_BENCHMARK_LINK} ${CPU_BENCHMARK_CHECKSUM} cpubench +} + + +prepare_cpubench() { + echo "[+] prepare cpubench" + github_name "cpubench-${CPU_BENCHMARK_VERSION}" +} + +install_cpubench() { + echo "[+] install cpubench" + mkdir -p "${ROOTDIR}/usr/bin" + + cp ${DISTDIR}/cpubench ${ROOTDIR}/usr/bin/cpubench + chmod +x ${ROOTDIR}/usr/bin/cpubench +} + +build_cpubench() { + pushd "${DISTDIR}" + + download_cpubench + prepare_cpubench + install_cpubench + + popd +} diff --git a/cmds/modules/zui/header.go b/cmds/modules/zui/header.go index 12709b6eb..c165109e5 100644 --- a/cmds/modules/zui/header.go +++ b/cmds/modules/zui/header.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "strings" + "syscall" + "unsafe" "github.com/gizak/termui/v3/widgets" "github.com/pkg/errors" @@ -43,6 +45,7 @@ func headerRenderer(ctx context.Context, c zbus.Client, h *widgets.Paragraph, r "\n" + " This is node %s (farmer %s)\n" + " running Zero-OS version [%s](fg:blue) (mode [%s](fg:cyan))\n" + + " kernel: %s\n" + " cache disk: %s" host := stubs.NewVersionMonitorStub(c) @@ -77,7 +80,15 @@ func headerRenderer(ctx context.Context, c zbus.Client, h *widgets.Paragraph, r cache = red("no ssd disks detected") } - h.Text = fmt.Sprintf(s, nodeID, farm, version.String(), env.RunningMode.String(), cache) + var utsname syscall.Utsname + var uname string + if err := syscall.Uname(&utsname); err != nil { + uname = red(err.Error()) + } else { + uname = green(string(unsafe.Slice((*byte)(unsafe.Pointer(&utsname.Release)), len(utsname.Release)))) + } + + h.Text = fmt.Sprintf(s, nodeID, farm, version.String(), env.RunningMode.String(), uname, cache) r.Signal() } }() diff --git a/cmds/modules/zui/main.go b/cmds/modules/zui/main.go index ba08b706d..6906bc074 100644 --- a/cmds/modules/zui/main.go +++ b/cmds/modules/zui/main.go @@ -67,11 +67,11 @@ func action(ctx *cli.Context) error { header := widgets.NewParagraph() header.Border = true - header.SetRect(0, 0, width, 7) + header.SetRect(0, 0, width, 8) netgrid := ui.NewGrid() netgrid.Title = "Network" - netgrid.SetRect(0, 7, width, 14) + netgrid.SetRect(0, 8, width, 14) resources := ui.NewGrid() resources.Title = "Provision" diff --git a/pkg/gridtypes/zos/zmachine.go b/pkg/gridtypes/zos/zmachine.go index 793a289cf..2f755c622 100644 --- a/pkg/gridtypes/zos/zmachine.go +++ b/pkg/gridtypes/zos/zmachine.go @@ -184,7 +184,7 @@ func (v ZMachine) Valid(getter gridtypes.WorkloadGetter) error { } } if v.ComputeCapacity.CPU == 0 { - return fmt.Errorf("cpu capcity can't be 0") + return fmt.Errorf("cpu capacity can't be 0") } if v.ComputeCapacity.Memory < 250*gridtypes.Megabyte { return fmt.Errorf("mem capacity can't be less that 250M") diff --git a/pkg/perf/monitor.go b/pkg/perf/monitor.go index 9afe28f28..4d7c40318 100644 --- a/pkg/perf/monitor.go +++ b/pkg/perf/monitor.go @@ -6,6 +6,7 @@ import ( "github.com/go-co-op/gocron" "github.com/gomodule/redigo/redis" + "github.com/rs/zerolog/log" "github.com/pkg/errors" "github.com/threefoldtech/zos/pkg/utils" @@ -14,7 +15,7 @@ import ( // PerformanceMonitor holds the module data type PerformanceMonitor struct { scheduler *gocron.Scheduler - pool redis.Pool + pool *redis.Pool tasks []Task } @@ -29,7 +30,7 @@ func NewPerformanceMonitor(redisAddr string) (*PerformanceMonitor, error) { return &PerformanceMonitor{ scheduler: scheduler, - pool: *redisPool, + pool: redisPool, tasks: []Task{}, }, nil } @@ -61,23 +62,24 @@ func (pm *PerformanceMonitor) runTask(ctx context.Context, task Task) error { // Run adds the tasks to the corn queue and start the scheduler func (pm *PerformanceMonitor) Run(ctx context.Context) error { for _, task := range pm.tasks { - _, err := pm.scheduler.CronWithSeconds(task.Cron()).Do(func() error { + if _, err := pm.scheduler.CronWithSeconds(task.Cron()).Do(func() error { return pm.runTask(ctx, task) - }) - if err != nil { + }); err != nil { return errors.Wrapf(err, "failed to schedule the task: %s", task.ID()) } - ok, err := pm.exists(task.ID()) - if err != nil { - return errors.Wrapf(err, "failed to find key %s", task.ID()) - } + go func(task Task) { + ok, err := pm.exists(task.ID()) + if err != nil { + log.Error().Err(err).Msgf("failed to find key %s", task.ID()) + } - if !ok { - if err := pm.runTask(ctx, task); err != nil { - return errors.Wrapf(err, "failed to run task: %s", task.ID()) + if !ok { + if err := pm.runTask(ctx, task); err != nil { + log.Error().Err(err).Msgf("failed to run task: %s", task.ID()) + } } - } + }(task) } diff --git a/pkg/vm.go b/pkg/vm.go index 655085021..b9ef42aa6 100644 --- a/pkg/vm.go +++ b/pkg/vm.go @@ -6,6 +6,7 @@ import ( "net" "path/filepath" + "github.com/shirou/gopsutil/cpu" "github.com/threefoldtech/zos/pkg/gridtypes" "github.com/threefoldtech/zos/pkg/gridtypes/zos" ) @@ -126,7 +127,7 @@ type VM struct { Network VMNetworkInfo // KernelImage path to uncompressed linux kernel ELF KernelImage string - // InitrdImage (optiona) path to initrd disk + // InitrdImage (optional) path to initrd disk InitrdImage string // KernelArgs to override the default kernel arguments. (default: "ro console=ttyS0 noapic reboot=k panic=1 pci=off nomodules") KernelArgs KernelArgs @@ -175,8 +176,16 @@ func (vm *VM) Validate() error { return fmt.Errorf("invalid memory must not be less than 250M") } - if vm.CPU == 0 || vm.CPU > 32 { - return fmt.Errorf("invalid cpu must be between 1 and 32") + cpus, err := cpu.Counts(true) + if err != nil { + return fmt.Errorf("failed to get count of cpus") + } + + if vm.CPU == 0 || vm.CPU > uint8(cpus) { + if cpus == 1 { + return fmt.Errorf("invalid cpu must be 1") + } + return fmt.Errorf("invalid cpu must be between 1 and %d", cpus) } for _, shared := range vm.Shared { @@ -234,7 +243,7 @@ func (n *NetMetric) Nu() float64 { } // MachineMetric is a container for metrics from multiple networks -// currently only groped as private (wiregaurd + yggdrasil), and public (public Ips) +// currently only grouped as private (wireguard + yggdrasil), and public (public Ips) type MachineMetric struct { Private NetMetric Public NetMetric