Skip to content

Commit

Permalink
Address code review
Browse files Browse the repository at this point in the history
* cpus is now a uint32 in multipass.proto
* removed LinuxSystemInfo struct and replaced with two functions
* get_cpus() and get_total_ram() are now platform functions with a linux implementation
* configuring a VM's resources now uses daemonInfoProvider properly
* cpu, ram, and disk sliders get from daemonInfoProvder in providers.dart instead of their own defined providers
  • Loading branch information
levkropp committed Jan 9, 2025
1 parent d29c1fe commit 94d3af8
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 127 deletions.
2 changes: 2 additions & 0 deletions include/multipass/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class Platform : public Singleton<Platform>
virtual QString default_privileged_mounts() const;
virtual bool is_image_url_supported() const;
[[nodiscard]] virtual std::string bridge_nomenclature() const;
virtual int get_cpus() const;
virtual long long get_total_ram() const;
};

QString interpret_setting(const QString& key, const QString& val);
Expand Down
40 changes: 9 additions & 31 deletions src/client/gui/lib/catalogue/launch_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ import '../vm_details/mount_points.dart';
import '../vm_details/ram_slider.dart';
import '../vm_details/spec_input.dart';

// Define the daemonInfoProvider here
final daemonInfoProvider = FutureProvider.autoDispose<DaemonInfoReply>((ref) {
return ref.watch(grpcClientProvider).daemonInfo();
});

final launchingImageProvider = StateProvider<ImageInfo>((_) => ImageInfo());

final randomNameProvider = Provider.autoDispose(
Expand Down Expand Up @@ -89,36 +84,19 @@ class _LaunchFormState extends ConsumerState<LaunchForm> {
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w300),
);

final daemonInfo = ref.watch(daemonInfoProvider);

final cpusSlider = daemonInfo.when(
data: (info) => CpusSlider(
initialValue: defaultCpus,
maxCpus: info.cpus.toInt(), // Pass the max CPUs to the slider
onSaved: (value) => launchRequest.numCores = value!,
),
loading: () => CircularProgressIndicator(),
error: (error, stack) => Text('Error: $error'),
final cpusSlider = CpusSlider(
initialValue: defaultCpus,
onSaved: (value) => launchRequest.numCores = value!,
);

final memorySlider = daemonInfo.when(
data: (info) => RamSlider(
initialValue: defaultRam,
maxRam: info.memory.toInt(), // Pass the max RAM to the slider
onSaved: (value) => launchRequest.memSize = '${value!}B',
),
loading: () => CircularProgressIndicator(),
error: (error, stack) => Text('Error: $error'),
final memorySlider = RamSlider(
initialValue: defaultRam,
onSaved: (value) => launchRequest.memSize = '${value!}B',
);

final diskSlider = daemonInfo.when(
data: (info) => DiskSlider(
initialValue: defaultRam,
maxDisk: info.availableSpace.toInt(), // Pass the available space to the slider
onSaved: (value) => launchRequest.memSize = '${value!}B',
),
loading: () => CircularProgressIndicator(),
error: (error, stack) => Text('Error: $error'),
final diskSlider = DiskSlider(
initialValue: defaultDisk,
onSaved: (value) => launchRequest.diskSpace = '${value!}B',
);

final bridgedSwitch = FormField<bool>(
Expand Down
4 changes: 4 additions & 0 deletions src/client/gui/lib/providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ final daemonAvailableProvider = Provider((ref) {
return false;
});

final daemonInfoProvider = FutureProvider((ref) {
return ref.watch(grpcClientProvider).daemonInfo();
});

class AllVmInfosNotifier extends Notifier<List<DetailedInfoItem>> {
@override
List<DetailedInfoItem> build() {
Expand Down
10 changes: 4 additions & 6 deletions src/client/gui/lib/vm_details/cpus_slider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,23 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../providers.dart';

class CpusSlider extends ConsumerStatefulWidget {
final int? initialValue;
final FormFieldSetter<int> onSaved;

final int maxCpus;

const CpusSlider({
super.key,
this.initialValue,
required this.onSaved,
this.maxCpus=1,
});

@override
ConsumerState<CpusSlider> createState() => _CpusSliderState();
}

class _CpusSliderState extends ConsumerState<CpusSlider> {


final min = 1;

late final controller = TextEditingController(
Expand Down Expand Up @@ -60,7 +57,8 @@ class _CpusSliderState extends ConsumerState<CpusSlider> {

@override
Widget build(BuildContext context) {
final cores = widget.maxCpus;
final daemonInfo = ref.watch(daemonInfoProvider);
final cores = daemonInfo.valueOrNull?.cpus.toInt() ?? min;
final max = math.max(widget.initialValue ?? 0, cores);

final textField = TextField(
Expand Down
15 changes: 3 additions & 12 deletions src/client/gui/lib/vm_details/disk_slider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,22 @@ import '../tooltip.dart';
import 'mapping_slider.dart';
import 'memory_slider.dart';

final diskSizeProvider = FutureProvider((ref) {
return ref
.watch(grpcClientProvider)
.daemonInfo()
.then((r) => r.availableSpace.toInt());
});

class DiskSlider extends ConsumerWidget {
final int? initialValue;
final int min;
final FormFieldSetter<int> onSaved;

final int maxDisk;

DiskSlider({
const DiskSlider({
super.key,
int? min,
this.initialValue,
required this.onSaved,
this.maxDisk=1,
}) : min = min ?? 1.gibi;

@override
Widget build(BuildContext context, WidgetRef ref) {
final disk = maxDisk ?? min;
final daemonInfo = ref.watch(daemonInfoProvider);
final disk = daemonInfo.valueOrNull?.availableSpace.toInt() ?? min;
final max = math.max(initialValue ?? 0, disk);
final enabled = min != max;

Expand Down
19 changes: 9 additions & 10 deletions src/client/gui/lib/vm_details/ram_slider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../providers.dart';
import 'mapping_slider.dart';
import 'memory_slider.dart';

class RamSlider extends ConsumerWidget {


final int? initialValue;
final int min;
final FormFieldSetter<int> onSaved;

final int maxRam;

const RamSlider({
super.key,
int? min,
this.initialValue,
required this.onSaved,
this.maxRam=1,
});
}) : min = min ?? 512.mebi;

@override
Widget build(BuildContext context, WidgetRef ref) {

final ram = maxRam ?? 512.mebi;
final daemonInfo = ref.watch(daemonInfoProvider);
final ram = daemonInfo.valueOrNull?.memory.toInt() ?? min;
final max = math.max(initialValue ?? 0, ram);

return MemorySlider(
label: 'Memory',
initialValue: initialValue,
min: 512.mebi,
max: math.max(initialValue ?? 0, ram),
min: min,
max: max,
sysMax: ram,
onSaved: onSaved,
);
Expand Down
17 changes: 0 additions & 17 deletions src/client/gui/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
globbing:
dependency: transitive
description:
name: globbing
sha256: "4f89cfaf6fa74c9c1740a96259da06bd45411ede56744e28017cc534a12b6e2d"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
google_identity_services_web:
dependency: transitive
description:
Expand Down Expand Up @@ -698,15 +690,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.3.0+3"
system_info2:
dependency: "direct main"
description:
path: "."
ref: "4.0.0+mp"
resolved-ref: ea5fac0e3a03db72276d946f6ca9abc9939e737a
url: "https://github.com/andrei-toterman/system_info.git"
source: git
version: "4.0.0"
term_glyph:
dependency: transitive
description:
Expand Down
4 changes: 0 additions & 4 deletions src/client/gui/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ dependencies:
rxdart: ^0.28.0
shared_preferences: ^2.3.2
synchronized: ^3.3.0+3
system_info2:
git:
url: https://github.com/andrei-toterman/system_info.git
ref: 4.0.0+mp
tray_menu:
git:
url: https://github.com/andrei-toterman/tray_menu.git
Expand Down
39 changes: 2 additions & 37 deletions src/daemon/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2789,11 +2789,8 @@ try // clang-format on
QStorageInfo storage_info{config->data_directory};
response.set_available_space(storage_info.bytesTotal());

#if defined(__linux__)
auto sys_info = read_linux_system_info();
response.set_cpus(sys_info.cpus);
response.set_memory(sys_info.memory);
#endif
response.set_cpus(MP_PLATFORM.get_cpus());
response.set_memory(MP_PLATFORM.get_total_ram());

server->Write(response);
status_promise->set_value(grpc::Status{});
Expand Down Expand Up @@ -3801,35 +3798,3 @@ void mp::Daemon::add_bridged_interface(const std::string& instance_name)
throw mp::BridgeFailureException("Cannot update instance settings", instance_name, preferred_net);
}
}

mp::LinuxSystemInfo mp::read_linux_system_info()
{
LinuxSystemInfo info{};
#if defined(__linux__)
// Simple parsing from /proc files:
{
std::ifstream cpuinfo{"/proc/cpuinfo"};
std::string line;
while (std::getline(cpuinfo, line))
{
if (line.rfind("processor", 0) == 0)
info.cpus++;
}
}
{
std::ifstream meminfo{"/proc/meminfo"};
std::string line;
while (std::getline(meminfo, line))
{
if (line.rfind("MemTotal:", 0) == 0)
{
long kb = 0;
std::sscanf(line.c_str(), "MemTotal: %ld kB", &kb);
info.memory = kb * 1024LL;
break;
}
}
}
#endif
return info;
}
9 changes: 0 additions & 9 deletions src/daemon/daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@ namespace multipass
struct DaemonConfig;
class SettingsHandler;

struct LinuxSystemInfo
{
int cpus;
long long memory;
long long disk;
};

LinuxSystemInfo read_linux_system_info();

class Daemon : public QObject, public multipass::VMStatusMonitor
{
Q_OBJECT
Expand Down
34 changes: 34 additions & 0 deletions src/platform/platform_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <QTextStream>

#include <errno.h>
#include <fstream>
#include <linux/if_arp.h>
#include <string.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -471,3 +472,36 @@ std::string multipass::platform::host_version()
return mpu::in_multipass_snap() ? multipass::platform::detail::read_os_release()
: fmt::format("{}-{}", QSysInfo::productType(), QSysInfo::productVersion());
}

int mp::platform::Platform::get_cpus() const
{
int cpus = 0;
std::ifstream cpuinfo{"/proc/cpuinfo"};
std::string line;

while (std::getline(cpuinfo, line))
{
if (line.rfind("processor", 0) == 0)
cpus++;
}

return cpus;
}

long long mp::platform::Platform::get_total_ram() const
{
std::ifstream meminfo{"/proc/meminfo"};
std::string line;

while (std::getline(meminfo, line))
{
if (line.rfind("MemTotal:", 0) == 0)
{
long long kb = 0;
std::sscanf(line.c_str(), "MemTotal: %lld kB", &kb);
return kb * 1024LL;
}
}

return 0; // Return 0 if "MemTotal" is not found
}
2 changes: 1 addition & 1 deletion src/rpc/multipass.proto
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,6 @@ message DaemonInfoRequest {
message DaemonInfoReply {
string log_line = 1;
uint64 available_space = 2;
int32 cpus = 3;
uint32 cpus = 3;
uint64 memory = 4;
}

0 comments on commit 94d3af8

Please sign in to comment.