Skip to content

Commit

Permalink
[vm factory] apply template method pattern on the create_vm_and_clone…
Browse files Browse the repository at this point in the history
…_instance_dir_data method, only qemu is done.
  • Loading branch information
georgeliao committed Oct 26, 2024
1 parent 7ecef40 commit 5f5956b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 84 deletions.
60 changes: 9 additions & 51 deletions src/platform/backends/qemu/qemu_virtual_machine_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,17 @@
#include "qemu_virtual_machine.h"

#include <multipass/cloud_init_iso.h>
#include <multipass/constants.h>
#include <multipass/format.h>
#include <multipass/logging/log.h>
#include <multipass/platform.h>
#include <multipass/process/simple_process_spec.h>
#include <multipass/virtual_machine_description.h>
#include <multipass/vm_specs.h>
#include <multipass/yaml_node_utils.h>
#include <shared/qemu_img_utils/qemu_img_utils.h>

#include <QRegularExpression>

namespace mp = multipass;
namespace mpl = multipass::logging;
namespace mpu = multipass::utils;

namespace
{
Expand Down Expand Up @@ -63,53 +59,6 @@ mp::VirtualMachine::UPtr mp::QemuVirtualMachineFactory::create_virtual_machine(c
get_instance_directory(desc.vm_name));
}

mp::VirtualMachine::UPtr mp::QemuVirtualMachineFactory::create_vm_and_clone_instance_dir_data(
const VMSpecs& /*src_vm_spec*/,
const VMSpecs& dest_vm_spec,
const std::string& source_name,
const std::string& destination_name,
const VMImage& dest_vm_image,
const SSHKeyProvider& key_provider,
VMStatusMonitor& monitor)
{
const std::filesystem::path source_instance_data_directory{get_instance_directory(source_name).toStdString()};
const std::filesystem::path dest_instance_data_directory{get_instance_directory(destination_name).toStdString()};

copy_instance_dir_with_essential_files(source_instance_data_directory, dest_instance_data_directory);

const fs::path cloud_init_path = dest_instance_data_directory / cloud_init_file_name;

MP_CLOUD_INIT_FILE_OPS.update_identifiers(dest_vm_spec.default_mac_address,
dest_vm_spec.extra_interfaces,
destination_name,
cloud_init_path);

// start to construct VirtualMachineDescription
mp::VirtualMachineDescription dest_vm_desc{dest_vm_spec.num_cores,
dest_vm_spec.mem_size,
dest_vm_spec.disk_space,
destination_name,
dest_vm_spec.default_mac_address,
dest_vm_spec.extra_interfaces,
dest_vm_spec.ssh_username,
dest_vm_image,
cloud_init_path.string().c_str(),
{},
{},
{},
{}};

mp::VirtualMachine::UPtr cloned_instance =
std::make_unique<mp::QemuVirtualMachine>(dest_vm_desc,
qemu_platform.get(),
monitor,
key_provider,
get_instance_directory(dest_vm_desc.vm_name));
cloned_instance->remove_snapshots_from_image();

return cloned_instance;
}

void mp::QemuVirtualMachineFactory::remove_resources_for_impl(const std::string& name)
{
qemu_platform->remove_resources_for(name);
Expand Down Expand Up @@ -207,3 +156,12 @@ std::string mp::QemuVirtualMachineFactory::create_bridge_with(const NetworkInter
{
return qemu_platform->create_bridge_with(interface);
}

mp::VirtualMachine::UPtr mp::QemuVirtualMachineFactory::clone_vm_impl(const std::string& /*source_vm_name*/,
const multipass::VMSpecs& /*src_vm_specs*/,
const VirtualMachineDescription& desc,
VMStatusMonitor& monitor,
const SSHKeyProvider& key_provider)
{
return create_virtual_machine(desc, key_provider, monitor);
}
13 changes: 5 additions & 8 deletions src/platform/backends/qemu/qemu_virtual_machine_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@ class QemuVirtualMachineFactory final : public BaseVirtualMachineFactory
VirtualMachine::UPtr create_virtual_machine(const VirtualMachineDescription& desc,
const SSHKeyProvider& key_provider,
VMStatusMonitor& monitor) override;
VirtualMachine::UPtr create_vm_and_clone_instance_dir_data(const VMSpecs& src_vm_spec,
const VMSpecs& dest_vm_spec,
const std::string& source_name,
const std::string& destination_name,
const VMImage& dest_vm_image,
const SSHKeyProvider& key_provider,
VMStatusMonitor& monitor) override;

VMImage prepare_source_image(const VMImage& source_image) override;
void prepare_instance_image(const VMImage& instance_image, const VirtualMachineDescription& desc) override;
void hypervisor_health_check() override;
Expand All @@ -60,6 +52,11 @@ class QemuVirtualMachineFactory final : public BaseVirtualMachineFactory

private:
QemuVirtualMachineFactory(QemuPlatform::UPtr qemu_platform, const Path& data_dir);
VirtualMachine::UPtr clone_vm_impl(const std::string& source_vm_name,
const multipass::VMSpecs& src_vm_specs,
const VirtualMachineDescription& desc,
VMStatusMonitor& monitor,
const SSHKeyProvider& key_provider) override;

QemuPlatform::UPtr qemu_platform;
};
Expand Down
44 changes: 44 additions & 0 deletions src/platform/backends/shared/base_virtual_machine_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <multipass/network_interface.h>
#include <multipass/network_interface_info.h>
#include <multipass/virtual_machine_description.h>
#include <multipass/vm_specs.h>
#include <multipass/yaml_node_utils.h>

namespace mp = multipass;
Expand Down Expand Up @@ -83,6 +84,49 @@ void mp::BaseVirtualMachineFactory::prepare_interface(NetworkInterface& net,
}
}

mp::VirtualMachine::UPtr mp::BaseVirtualMachineFactory::create_vm_and_clone_instance_dir_data(
const VMSpecs& src_vm_spec,
const VMSpecs& dest_vm_spec,
const std::string& source_name,
const std::string& destination_name,
const VMImage& dest_vm_image,
const multipass::SSHKeyProvider& key_provider,
VMStatusMonitor& monitor)
{
const std::filesystem::path source_instance_data_directory{get_instance_directory(source_name).toStdString()};
const std::filesystem::path dest_instance_data_directory{get_instance_directory(destination_name).toStdString()};

copy_instance_dir_with_essential_files(source_instance_data_directory, dest_instance_data_directory);

const fs::path cloud_init_path = dest_instance_data_directory / cloud_init_file_name;

MP_CLOUD_INIT_FILE_OPS.update_identifiers(dest_vm_spec.default_mac_address,
dest_vm_spec.extra_interfaces,
destination_name,
cloud_init_path);

// start to construct VirtualMachineDescription
mp::VirtualMachineDescription dest_vm_desc{dest_vm_spec.num_cores,
dest_vm_spec.mem_size,
dest_vm_spec.disk_space,
destination_name,
dest_vm_spec.default_mac_address,
dest_vm_spec.extra_interfaces,
dest_vm_spec.ssh_username,
dest_vm_image,
cloud_init_path.string().c_str(),
{},
{},
{},
{}};

mp::VirtualMachine::UPtr cloned_instance =
clone_vm_impl(source_name, src_vm_spec, dest_vm_desc, monitor, key_provider);
cloned_instance->remove_snapshots_from_image();

return cloned_instance;
}

void mp::copy_instance_dir_with_essential_files(const fs::path& source_instance_dir_path,
const fs::path& dest_instance_dir_path)
{
Expand Down
21 changes: 17 additions & 4 deletions src/platform/backends/shared/base_virtual_machine_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@ class BaseVirtualMachineFactory : public VirtualMachineFactory
const std::string& destination_name,
const VMImage& dest_vm_image,
const SSHKeyProvider& key_provider,
VMStatusMonitor& monitor) override
{
throw NotImplementedOnThisBackendException("clone");
}
VMStatusMonitor& monitor) override final;

void remove_resources_for(const std::string& name) final;

Expand Down Expand Up @@ -99,6 +96,12 @@ class BaseVirtualMachineFactory : public VirtualMachineFactory
virtual void remove_resources_for_impl(const std::string& name) = 0;

private:
virtual VirtualMachine::UPtr clone_vm_impl(const std::string& source_vm_name,
const multipass::VMSpecs& src_vm_specs,
const VirtualMachineDescription& desc,
VMStatusMonitor& monitor,
const SSHKeyProvider& key_provider);

Path instances_dir;
};

Expand Down Expand Up @@ -127,4 +130,14 @@ inline void multipass::BaseVirtualMachineFactory::require_clone_support() const
throw NotImplementedOnThisBackendException{"clone"};

Check warning on line 130 in src/platform/backends/shared/base_virtual_machine_factory.h

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/shared/base_virtual_machine_factory.h#L130

Added line #L130 was not covered by tests
}

inline multipass::VirtualMachine::UPtr multipass::BaseVirtualMachineFactory::clone_vm_impl(

Check warning on line 133 in src/platform/backends/shared/base_virtual_machine_factory.h

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/shared/base_virtual_machine_factory.h#L133

Added line #L133 was not covered by tests
const std::string& source_vm_name,
const VMSpecs& src_vm_specs,
const VirtualMachineDescription& desc,
VMStatusMonitor& monitor,
const SSHKeyProvider& key_provider)
{
throw NotImplementedOnThisBackendException{"clone"};

Check warning on line 140 in src/platform/backends/shared/base_virtual_machine_factory.h

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/shared/base_virtual_machine_factory.h#L140

Added line #L140 was not covered by tests
}

#endif // MULTIPASS_BASE_VIRTUAL_MACHINE_FACTORY_H
11 changes: 0 additions & 11 deletions tests/stub_virtual_machine_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,6 @@ struct StubVirtualMachineFactory : public multipass::BaseVirtualMachineFactory
return std::make_unique<StubVirtualMachine>();
}

multipass::VirtualMachine::UPtr create_vm_and_clone_instance_dir_data(const VMSpecs& src_vm_spec,
const VMSpecs& dest_vm_spec,
const std::string& source_name,
const std::string& destination_name,
const VMImage& dest_vm_image,
const SSHKeyProvider& key_provider,
VMStatusMonitor& monitor) override
{
return std::make_unique<StubVirtualMachine>();
}

void remove_resources_for_impl(const std::string& name) override
{
}
Expand Down
10 changes: 0 additions & 10 deletions tests/test_base_virtual_machine_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,6 @@ struct MockBaseFactory : mp::BaseVirtualMachineFactory
create_virtual_machine,
(const mp::VirtualMachineDescription&, const mp::SSHKeyProvider&, mp::VMStatusMonitor&),
(override));
MOCK_METHOD(mp::VirtualMachine::UPtr,
create_vm_and_clone_instance_dir_data,
(const mp::VMSpecs&,
const mp::VMSpecs&,
const std::string&,
const std::string&,
const mp::VMImage&,
const mp::SSHKeyProvider&,
mp::VMStatusMonitor&),
(override));
MOCK_METHOD(mp::VMImage, prepare_source_image, (const mp::VMImage&), (override));
MOCK_METHOD(void, prepare_instance_image, (const mp::VMImage&, const mp::VirtualMachineDescription&), (override));
MOCK_METHOD(void, hypervisor_health_check, (), (override));
Expand Down

0 comments on commit 5f5956b

Please sign in to comment.