From 013434f60078bff0048484b18d2fa28e0e823d5b Mon Sep 17 00:00:00 2001 From: Chris Townsend Date: Wed, 22 May 2019 10:03:18 -0400 Subject: [PATCH] backends/daemon: Allow for backend to determine its data/cache dirs Fixes #774 --- include/multipass/utils.h | 1 + include/multipass/virtual_machine_factory.h | 5 ++--- src/daemon/daemon.cpp | 7 +++++-- src/daemon/daemon_config.cpp | 6 ++++-- .../libvirt/libvirt_virtual_machine_factory.h | 6 +++++- .../backends/qemu/qemu_virtual_machine_factory.h | 6 +++++- src/utils/utils.cpp | 8 ++++++++ tests/mock_virtual_machine_factory.h | 5 ++--- tests/stub_virtual_machine_factory.h | 9 ++++++--- tests/test_utils.cpp | 16 ++++++++++++++++ 10 files changed, 54 insertions(+), 15 deletions(-) diff --git a/include/multipass/utils.h b/include/multipass/utils.h index 8befcbbd00..d4495d25f1 100644 --- a/include/multipass/utils.h +++ b/include/multipass/utils.h @@ -54,6 +54,7 @@ enum class TimeoutAction QDir base_dir(const QString& path); multipass::Path make_dir(const QDir& a_dir, const QString& name); bool is_dir(const std::string& path); +QString backend_directory_path(const Path& path, const QString& subdirectory); std::string filename_for(const std::string& path); QString make_uuid(); std::string contents_of(const multipass::Path& file_path); diff --git a/include/multipass/virtual_machine_factory.h b/include/multipass/virtual_machine_factory.h index 983699eaac..0d2500e4e9 100644 --- a/include/multipass/virtual_machine_factory.h +++ b/include/multipass/virtual_machine_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Canonical, Ltd. + * Copyright (C) 2017-2019 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,8 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * Authored by: Alberto Aguirre - * */ #ifndef MULTIPASS_VIRTUAL_MACHINE_FACTORY_H @@ -53,6 +51,7 @@ class VirtualMachineFactory virtual void prepare_instance_image(const VMImage& instance_image, const VirtualMachineDescription& desc) = 0; virtual void configure(const std::string& name, YAML::Node& meta_config, YAML::Node& user_config) = 0; virtual void check_hypervisor_support() = 0; + virtual QString get_backend_directory_name() = 0; protected: VirtualMachineFactory() = default; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 93648972cc..cdc3301f98 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -546,7 +546,9 @@ grpc::Status ssh_reboot(const std::string& hostname, int port, const std::string mp::Daemon::Daemon(std::unique_ptr the_config) : config{std::move(the_config)}, - vm_instance_specs{load_db(config->data_directory, config->cache_directory)}, + vm_instance_specs{load_db( + mp::utils::backend_directory_path(config->data_directory, config->factory->get_backend_directory_name()), + mp::utils::backend_directory_path(config->cache_directory, config->factory->get_backend_directory_name()))}, daemon_rpc{config->server_address, config->connection_type, *config->cert_provider, *config->client_cert_store}, metrics_provider{"https://api.staging.jujucharms.com/omnibus/v4/multipass/metrics", get_unique_id(config->data_directory), config->data_directory}, @@ -1756,7 +1758,8 @@ void mp::Daemon::persist_instances() auto key = QString::fromStdString(record.first); instance_records_json.insert(key, vm_spec_to_json(record.second)); } - QDir data_dir{config->data_directory}; + QDir data_dir{ + mp::utils::backend_directory_path(config->data_directory, config->factory->get_backend_directory_name())}; mp::write_json(instance_records_json, data_dir.filePath(instance_db_name)); } diff --git a/src/daemon/daemon_config.cpp b/src/daemon/daemon_config.cpp index c4163b0e4b..b0745571a9 100644 --- a/src/daemon/daemon_config.cpp +++ b/src/daemon/daemon_config.cpp @@ -96,8 +96,10 @@ std::unique_ptr mp::DaemonConfigBuilder::build() { hosts.push_back(image.get()); } - vault = std::make_unique(hosts, url_downloader.get(), cache_directory, data_directory, - days_to_expire); + vault = std::make_unique( + hosts, url_downloader.get(), + mp::utils::backend_directory_path(cache_directory, factory->get_backend_directory_name()), + mp::utils::backend_directory_path(data_directory, factory->get_backend_directory_name()), days_to_expire); } if (name_generator == nullptr) name_generator = mp::make_default_name_generator(); diff --git a/src/platform/backends/libvirt/libvirt_virtual_machine_factory.h b/src/platform/backends/libvirt/libvirt_virtual_machine_factory.h index 2f2d9d9b52..52d68c0afe 100644 --- a/src/platform/backends/libvirt/libvirt_virtual_machine_factory.h +++ b/src/platform/backends/libvirt/libvirt_virtual_machine_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Canonical, Ltd. + * Copyright (C) 2018-2019 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,6 +43,10 @@ class LibVirtVirtualMachineFactory final : public VirtualMachineFactory void prepare_instance_image(const VMImage& instance_image, const VirtualMachineDescription& desc) override; void configure(const std::string& name, YAML::Node& meta_config, YAML::Node& user_config) override; void check_hypervisor_support() override; + QString get_backend_directory_name() override + { + return {}; + }; private: const ProcessFactory* process_factory; diff --git a/src/platform/backends/qemu/qemu_virtual_machine_factory.h b/src/platform/backends/qemu/qemu_virtual_machine_factory.h index b82db71428..1309a15a23 100644 --- a/src/platform/backends/qemu/qemu_virtual_machine_factory.h +++ b/src/platform/backends/qemu/qemu_virtual_machine_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2018 Canonical, Ltd. + * Copyright (C) 2017-2019 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +41,10 @@ class QemuVirtualMachineFactory final : public VirtualMachineFactory void prepare_instance_image(const VMImage& instance_image, const VirtualMachineDescription& desc) override; void configure(const std::string& name, YAML::Node& meta_config, YAML::Node& user_config) override; void check_hypervisor_support() override; + QString get_backend_directory_name() override + { + return {}; + }; private: const ProcessFactory* process_factory; diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index 5c40d21cf5..7a231788cd 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -175,6 +175,14 @@ mp::Path mp::utils::make_dir(const QDir& a_dir, const QString& name) return a_dir.filePath(name); } +QString mp::utils::backend_directory_path(const mp::Path& path, const QString& subdirectory) +{ + if (subdirectory.isEmpty()) + return path; + + return mp::Path("%1/%2").arg(path).arg(subdirectory); +} + QString mp::utils::make_uuid() { auto uuid = QUuid::createUuid().toString(); diff --git a/tests/mock_virtual_machine_factory.h b/tests/mock_virtual_machine_factory.h index 90de389e62..daf3b1de82 100644 --- a/tests/mock_virtual_machine_factory.h +++ b/tests/mock_virtual_machine_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Canonical, Ltd. + * Copyright (C) 2017-2019 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,8 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * Authored by: Alberto Aguirre - * */ #ifndef MULTIPASS_MOCK_VIRTUAL_MACHINE_FACTORY_H @@ -40,6 +38,7 @@ struct MockVirtualMachineFactory : public VirtualMachineFactory MOCK_METHOD2(prepare_instance_image, void(const VMImage&, const VirtualMachineDescription&)); MOCK_METHOD3(configure, void(const std::string&, YAML::Node&, YAML::Node&)); MOCK_METHOD0(check_hypervisor_support, void()); + MOCK_METHOD0(get_backend_directory_name, QString()); }; } } diff --git a/tests/stub_virtual_machine_factory.h b/tests/stub_virtual_machine_factory.h index 2a77c3011a..72cda180f2 100644 --- a/tests/stub_virtual_machine_factory.h +++ b/tests/stub_virtual_machine_factory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Canonical, Ltd. + * Copyright (C) 2017-2019 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,8 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * Authored by: Alberto Aguirre - * */ #ifndef MULTIPASS_STUB_VIRTUAL_MACHINE_FACTORY_H @@ -62,6 +60,11 @@ struct StubVirtualMachineFactory : public multipass::VirtualMachineFactory void check_hypervisor_support() override { } + + QString get_backend_directory_name() override + { + return {}; + } }; } } diff --git a/tests/test_utils.cpp b/tests/test_utils.cpp index 3830a8abbf..748ab44521 100644 --- a/tests/test_utils.cpp +++ b/tests/test_utils.cpp @@ -334,6 +334,22 @@ TEST(Utils, filename_only_is_returned) EXPECT_THAT(mp::utils::filename_for(full_path), Eq(file_name)); } +TEST(Utils, no_subdirectory_returns_same_path) +{ + mp::Path original_path{"/tmp/foo"}; + QString empty_subdir{}; + + EXPECT_THAT(mp::utils::backend_directory_path(original_path, empty_subdir), Eq(original_path)); +} + +TEST(Utils, subdirectory_returns_new_path) +{ + mp::Path original_path{"/tmp/foo"}; + QString subdir{"bar"}; + + EXPECT_THAT(mp::utils::backend_directory_path(original_path, subdir), Eq(mp::Path{"/tmp/foo/bar"})); +} + TEST(Utils, vm_running_returns_true) { mp::VirtualMachine::State state = mp::VirtualMachine::State::running;