Skip to content

Commit

Permalink
Merge pull request #3697 from canonical/default-mount-target-dart-ffi
Browse files Browse the repository at this point in the history
[gui] add ffi for getting mount target from source
  • Loading branch information
ricab authored Oct 22, 2024
2 parents 316af44 + d9c986f commit fdf1fa1
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 109 deletions.
14 changes: 8 additions & 6 deletions include/multipass/dart_ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ extern "C"
// clang-format on
const char* multipass_version();

const char* generate_petname();
char* generate_petname();

const char* get_server_address();
char* get_server_address();

struct KeyCertificatePair
{
Expand All @@ -27,19 +27,21 @@ enum SettingResult
UnexpectedError,
};

const char* settings_file();
char* settings_file();

enum SettingResult get_setting(const char* key, const char** output);
enum SettingResult get_setting(char* key, char** output);

enum SettingResult set_setting(const char* key, const char* value, const char** output);
enum SettingResult set_setting(char* key, char* value, char** output);

int uid();

int gid();

int default_id();

long long memory_in_bytes(const char* value);
long long memory_in_bytes(char* value);

char* default_mount_target(char* source);
}

#endif // MULTIPASS_DART_FFI_H
10 changes: 1 addition & 9 deletions src/client/cli/cmd/mount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,7 @@ mp::ParseCode cmd::Mount::parse_args(mp::ArgParser* parser)

auto entry = request.add_target_paths();
entry->set_instance_name(instance_name.toStdString());

if (target_path.isEmpty())
{
entry->set_target_path(source_path.toStdString());
}
else
{
entry->set_target_path(target_path.toStdString());
}
entry->set_target_path(target_path.toStdString());
}

QRegularExpression map_matcher("^([0-9]+[:][0-9]+)$");
Expand Down
222 changes: 128 additions & 94 deletions src/client/gui/ffi/dart_ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "multipass/memory_size.h"
#include "multipass/name_generator.h"
#include "multipass/settings/settings.h"
#include "multipass/utils.h"
#include "multipass/version.h"

namespace mp = multipass;
Expand All @@ -22,88 +23,101 @@ const char* multipass_version()
return mp::version_string;
}

const char* generate_petname()
try
char* generate_petname()
{
static mp::NameGenerator::UPtr generator = mp::make_default_name_generator();
const auto name = generator->make_name();
return strdup(name.c_str());
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("failed generating petname: {}", e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, "failed generating petname");
return nullptr;
static constexpr auto error = "failed generating petname";
try
{
static mp::NameGenerator::UPtr generator = mp::make_default_name_generator();
const auto name = generator->make_name();
return strdup(name.c_str());
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("{}: {}", error, e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, error);
return nullptr;
}
}

const char* get_server_address()
try
{
const auto address = mpc::get_server_address();
return strdup(address.c_str());
}
catch (const std::exception& e)
char* get_server_address()
{
mpl::log(mpl::Level::warning, category, fmt::format("failed retrieving server address: {}", e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, "failed retrieving server address");
return nullptr;
static constexpr auto error = "failed retrieving server address";
try
{
const auto address = mpc::get_server_address();
return strdup(address.c_str());
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("{}: {}", error, e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, error);
return nullptr;
}
}

struct KeyCertificatePair get_cert_pair()
try
{
const auto provider = mpc::get_cert_provider();
const auto cert = provider->PEM_certificate();
const auto key = provider->PEM_signing_key();
struct KeyCertificatePair pair
{
};
pair.pem_cert = strdup(cert.c_str());
pair.pem_priv_key = strdup(key.c_str());
return pair;
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("failed retrieving certificate key pair: {}", e.what()));
return KeyCertificatePair{nullptr, nullptr};
}
catch (...)
{
mpl::log(mpl::Level::warning, category, "failed retrieving certificate key pair");
return KeyCertificatePair{nullptr, nullptr};
static constexpr auto error = "failed retrieving certificate key pair";
try
{
const auto provider = mpc::get_cert_provider();
const auto cert = provider->PEM_certificate();
const auto key = provider->PEM_signing_key();
struct KeyCertificatePair pair
{
};
pair.pem_cert = strdup(cert.c_str());
pair.pem_priv_key = strdup(key.c_str());
return pair;
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("{}: {}", error, e.what()));
return KeyCertificatePair{nullptr, nullptr};
}
catch (...)
{
mpl::log(mpl::Level::warning, category, error);
return KeyCertificatePair{nullptr, nullptr};
}
}

static std::once_flag initialize_settings_once_flag;

const char* settings_file()
try
char* settings_file()
{
const auto file_name = mpc::persistent_settings_filename().toStdString();
return strdup(file_name.c_str());
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("failed getting settings file: {}", e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, "failed getting settings file");
return nullptr;
static constexpr auto error = "failed getting settings file";
try
{
const auto file_name = mpc::persistent_settings_filename().toStdString();
return strdup(file_name.c_str());
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("{}: {}", error, e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, error);
return nullptr;
}
}

enum SettingResult get_setting(const char* key, const char** output)
enum SettingResult get_setting(char* key, char** output)
{
static constexpr auto error = "failed retrieving setting with key";
const QString key_string{key};
free((void*)key);
free(key);
try
{
std::call_once(initialize_settings_once_flag, mpc::register_global_settings_handlers);
Expand All @@ -113,34 +127,31 @@ enum SettingResult get_setting(const char* key, const char** output)
}
catch (const mp::UnrecognizedSettingException& e)
{
mpl::log(mpl::Level::warning,
category,
fmt::format("failed retrieving setting with key '{}': {}", key_string, e.what()));
mpl::log(mpl::Level::warning, category, fmt::format("{} '{}': {}", error, key_string, e.what()));
*output = nullptr;
return SettingResult::KeyNotFound;
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning,
category,
fmt::format("failed retrieving setting with key '{}': {}", key_string, e.what()));
mpl::log(mpl::Level::warning, category, fmt::format("{} '{}': {}", error, key_string, e.what()));
*output = strdup(e.what());
return SettingResult::UnexpectedError;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, fmt::format("failed retrieving setting with key '{}'", key_string));
mpl::log(mpl::Level::warning, category, fmt::format("{} '{}'", error, key_string));
*output = strdup("unknown error");
return SettingResult::UnexpectedError;
}
}

enum SettingResult set_setting(const char* key, const char* value, const char** output)
enum SettingResult set_setting(char* key, char* value, char** output)
{
static constexpr auto error = "failed storing setting with key";
const QString key_string{key};
free((void*)key);
free(key);
const QString value_string{value};
free((void*)value);
free(value);
try
{
std::call_once(initialize_settings_once_flag, mpc::register_global_settings_handlers);
Expand All @@ -152,31 +163,29 @@ enum SettingResult set_setting(const char* key, const char* value, const char**
{
mpl::log(mpl::Level::warning,
category,
fmt::format("failed storing setting with key '{}'='{}': {}", key_string, value_string, e.what()));
fmt::format("{} '{}'='{}': {}", error, key_string, value_string, e.what()));
*output = nullptr;
return SettingResult::KeyNotFound;
}
catch (const mp::InvalidSettingException& e)
{
mpl::log(mpl::Level::warning,
category,
fmt::format("failed storing setting with key '{}'='{}': {}", key_string, value_string, e.what()));
fmt::format("{} '{}'='{}': {}", error, key_string, value_string, e.what()));
*output = strdup(e.what());
return SettingResult::InvalidValue;
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning,
category,
fmt::format("failed storing setting with key '{}'='{}': {}", key_string, value_string, e.what()));
fmt::format("{} '{}'='{}': {}", error, key_string, value_string, e.what()));
*output = strdup(e.what());
return SettingResult::UnexpectedError;
}
catch (...)
{
mpl::log(mpl::Level::warning,
category,
fmt::format("failed storing setting with key '{}'='{}'", key_string, value_string));
mpl::log(mpl::Level::warning, category, fmt::format("{} '{}'='{}'", error, key_string, value_string));
*output = strdup("unknown error");
return SettingResult::UnexpectedError;
}
Expand All @@ -197,21 +206,46 @@ int default_id()
return mp::default_id;
}

long long memory_in_bytes(const char* value)
try
{
std::string string_value{value};
free((void*)value);
return mp::in_bytes(string_value);
}
catch (const std::exception& e)
long long memory_in_bytes(char* value)
{
mpl::log(mpl::Level::warning, category, fmt::format("failed converting memory to bytes: {}", e.what()));
return -1;
static constexpr auto error = "failed converting memory to bytes";
try
{
std::string string_value{value};
free(value);
return mp::in_bytes(string_value);
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("{}: {}", error, e.what()));
return -1;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, error);
return -1;
}
}
catch (...)

char* default_mount_target(char* source)
{
mpl::log(mpl::Level::warning, category, "failed converting memory to bytes");
return -1;
static constexpr auto error = "failed retrieving default mount target";
try
{
const QString q_source{source};
free(source);
const auto target = MP_UTILS.default_mount_target(q_source).toStdString();
return strdup(target.c_str());
}
catch (const std::exception& e)
{
mpl::log(mpl::Level::warning, category, fmt::format("{}: {}", error, e.what()));
return nullptr;
}
catch (...)
{
mpl::log(mpl::Level::warning, category, error);
return nullptr;
}
}
}
8 changes: 8 additions & 0 deletions src/client/gui/lib/ffi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ final _memoryInBytes = _lib.lookupFunction<
ffi.LongLong Function(ffi.Pointer<Utf8>),
int Function(ffi.Pointer<Utf8>)>('memory_in_bytes');

final _defaultMountTarget = _lib.lookupFunction<
ffi.Pointer<Utf8> Function(ffi.Pointer<Utf8>),
ffi.Pointer<Utf8> Function(ffi.Pointer<Utf8>)>('default_mount_target');

final class _NativeKeyCertificatePair extends ffi.Struct {
// ignore: non_constant_identifier_names
external ffi.Pointer<Utf8> pem_cert;
Expand Down Expand Up @@ -171,3 +175,7 @@ int memoryInBytes(String value) {
? throw Exception('Could not convert $value to bytes')
: result;
}

String defaultMountTarget({required String source}) {
return _defaultMountTarget(source.toNativeUtf8()).string;
}

0 comments on commit fdf1fa1

Please sign in to comment.