Skip to content

Commit

Permalink
[vm factory] added create_vm_and_instance_disk_data function for clon…
Browse files Browse the repository at this point in the history
…ing process.
  • Loading branch information
georgeliao committed Jan 12, 2024
1 parent e188993 commit d815a5e
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/daemon/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2763,6 +2763,8 @@ void mp::Daemon::clone(const CloneRequest* request,
destination_name)};
}

Check warning on line 2764 in src/daemon/daemon.cpp

View check run for this annotation

Codecov / codecov/patch

src/daemon/daemon.cpp#L2764

Added line #L2764 was not covered by tests

const mp::VMImage dest_vm_image = fetch_image_for(destination_name, *config->factory, *config->vault);

// start to construct VirtualMachineDescription

Check warning on line 2768 in src/daemon/daemon.cpp

View check run for this annotation

Codecov / codecov/patch

src/daemon/daemon.cpp#L2768

Added line #L2768 was not covered by tests
mp::VirtualMachineDescription dest_vm_desc{dest_vm_spec.num_cores,
dest_vm_spec.mem_size,
Expand All @@ -2771,7 +2773,7 @@ void mp::Daemon::clone(const CloneRequest* request,
dest_vm_spec.default_mac_address,
dest_vm_spec.extra_interfaces,

Check warning on line 2774 in src/daemon/daemon.cpp

View check run for this annotation

Codecov / codecov/patch

src/daemon/daemon.cpp#L2774

Added line #L2774 was not covered by tests
dest_vm_spec.ssh_username,
fetch_image_for(destination_name, *config->factory, *config->vault),
dest_vm_image,
cloud_init_config_iso_file_path.string().c_str(),
{},
{},

Check warning on line 2779 in src/daemon/daemon.cpp

View check run for this annotation

Codecov / codecov/patch

src/daemon/daemon.cpp#L2779

Added line #L2779 was not covered by tests
Expand Down
98 changes: 98 additions & 0 deletions src/platform/backends/qemu/qemu_virtual_machine_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@
#include "qemu_virtual_machine_factory.h"
#include "qemu_virtual_machine.h"

#include <multipass/cloud_init_iso.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 <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 @@ -57,6 +60,101 @@ mp::VirtualMachine::UPtr mp::QemuVirtualMachineFactory::create_virtual_machine(c
get_instance_directory(desc.vm_name));
}

mp::VirtualMachine::UPtr mp::QemuVirtualMachineFactory::create_vm_and_instance_disk_data(

Check warning on line 63 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L63

Added line #L63 was not covered by tests
const QString& data_directory,
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,
VMStatusMonitor& monitor)
{
const QString backend_data_direcotry =
mp::utils::backend_directory_path(data_directory, get_backend_directory_name());

Check warning on line 73 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L73

Added line #L73 was not covered by tests
const auto instances_data_directory =
std::filesystem::path(backend_data_direcotry.toStdString()) / "vault" / "instances";
const std::filesystem::path source_instance_data_directory = instances_data_directory / source_name;
const std::filesystem::path dest_instance_data_directory = instances_data_directory / destination_name;

Check warning on line 77 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L75-L77

Added lines #L75 - L77 were not covered by tests

MP_FILEOPS.copy(source_instance_data_directory,

Check warning on line 79 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L79

Added line #L79 was not covered by tests
dest_instance_data_directory,
std::filesystem::copy_options::recursive);

const YAML::Node network_data =
mpu::make_cloud_init_network_config(dest_vm_spec.default_mac_address, dest_vm_spec.extra_interfaces);
CloudInitIso qemu_iso;
if (!network_data.IsNull())

Check warning on line 86 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L84-L86

Added lines #L84 - L86 were not covered by tests
{
qemu_iso.add_file("network-config", mpu::emit_cloud_config(network_data));

Check warning on line 88 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L88

Added line #L88 was not covered by tests
}
const YAML::Node meta_data = mpu::make_cloud_init_meta_config(destination_name);
qemu_iso.add_file("meta-data", mpu::emit_cloud_config(meta_data));

Check warning on line 91 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L90-L91

Added lines #L90 - L91 were not covered by tests

// create the mount folder
const fs::path cloud_init_mount_point = dest_instance_data_directory / "cidata";
if (std::error_code err; !MP_FILEOPS.create_directory(cloud_init_mount_point, err))

Check warning on line 95 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L94-L95

Added lines #L94 - L95 were not covered by tests
{
throw std::runtime_error{
fmt::format("Could not create mount point for cloud-init-config.iso file of the instance: {} ",
destination_name)};

Check warning on line 99 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L97-L99

Added lines #L97 - L99 were not covered by tests
}

// sudo mount -o loop cloud-init-config.iso
// /root/.local/share/multipassd/vault/instances/adaptive-cat-clone/cidata
const fs::path cloud_init_config_iso_file_path = dest_instance_data_directory / "cloud-init-config.iso";

Check warning on line 104 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L104

Added line #L104 was not covered by tests
const std::string mount_command =
fmt::format("mount -o loop {} {}", cloud_init_config_iso_file_path.string(), cloud_init_mount_point.string());
if (int return_code = std::system(mount_command.c_str()); return_code != 0)

Check warning on line 107 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L106-L107

Added lines #L106 - L107 were not covered by tests
{
throw std::runtime_error{fmt::format("Error executing command : {} ", mount_command)};

Check warning on line 109 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L109

Added line #L109 was not covered by tests
}

// load files and add to qemu_iso and write to the .iso file
for (const auto filename_str : {"user-data", "vendor-data"})

Check warning on line 113 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L113

Added line #L113 was not covered by tests
{
const auto stream = MP_FILEOPS.open_read(cloud_init_mount_point / fs::path(filename_str));
std::stringstream buffer;
buffer << stream->rdbuf();
const std::string file_contents = buffer.str();
qemu_iso.add_file(filename_str, file_contents);

Check warning on line 119 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L115-L119

Added lines #L115 - L119 were not covered by tests
}
qemu_iso.write_to(QString::fromStdString(cloud_init_config_iso_file_path.string()));

Check warning on line 121 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L121

Added line #L121 was not covered by tests

// sudo umount /root/.local/share/multipassd/vault/instances/adaptive-cat-clone/cidata
const std::string unmount_command = fmt::format("umount {}", cloud_init_mount_point.string());
if (int return_code = std::system(unmount_command.c_str()); return_code != 0)

Check warning on line 125 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L124-L125

Added lines #L124 - L125 were not covered by tests
{
throw std::runtime_error{fmt::format("Error executing command : {} ", unmount_command)};

Check warning on line 127 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L127

Added line #L127 was not covered by tests
}

// delete the created mount folder
if (std::error_code err; !MP_FILEOPS.remove(cloud_init_mount_point, err))

Check warning on line 131 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L131

Added line #L131 was not covered by tests
{
throw std::runtime_error{
fmt::format("Could not remove mount point for cloud-init-config.iso file of the instance: {} ",
destination_name)};

Check warning on line 135 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L133-L135

Added lines #L133 - L135 were not covered by tests
}

// start to construct VirtualMachineDescription
mp::VirtualMachineDescription dest_vm_desc{dest_vm_spec.num_cores,

Check warning on line 139 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L139

Added line #L139 was not covered by tests
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,

Check warning on line 145 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L143-L145

Added lines #L143 - L145 were not covered by tests
dest_vm_image,
cloud_init_config_iso_file_path.string().c_str(),

Check warning on line 147 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L147

Added line #L147 was not covered by tests
{},
{},
{},
{}};

Check warning on line 151 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L151

Added line #L151 was not covered by tests

mp::VirtualMachine::UPtr cloned_instance = create_virtual_machine(dest_vm_desc, monitor);
cloned_instance->load_snapshots_and_update_unique_identifiers(src_vm_spec, dest_vm_spec, source_name);
return cloned_instance;

Check warning on line 155 in src/platform/backends/qemu/qemu_virtual_machine_factory.cpp

View check run for this annotation

Codecov / codecov/patch

src/platform/backends/qemu/qemu_virtual_machine_factory.cpp#L153-L155

Added lines #L153 - L155 were not covered by tests
}

void mp::QemuVirtualMachineFactory::remove_resources_for_impl(const std::string& name)
{
qemu_platform->remove_resources_for(name);
Expand Down
8 changes: 8 additions & 0 deletions src/platform/backends/qemu/qemu_virtual_machine_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ class QemuVirtualMachineFactory final : public BaseVirtualMachineFactory

VirtualMachine::UPtr create_virtual_machine(const VirtualMachineDescription& desc,
VMStatusMonitor& monitor) override;
VirtualMachine::UPtr create_vm_and_instance_disk_data(const QString& data_directory,
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,
VMStatusMonitor& monitor);

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 Down

0 comments on commit d815a5e

Please sign in to comment.