Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multipass clone #3264

Open
wants to merge 121 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
bb854f4
[grpc] Added multipass clone protobuf message place holder.
georgeliao Sep 28, 2023
540bf4d
[grpc] Added missing fields of clone message
georgeliao Oct 2, 2023
22d2fe5
[cli] Added clone command line class and functions interfaces.
georgeliao Oct 2, 2023
9684262
[cli] Added parse_args implementation and invocation.
georgeliao Oct 2, 2023
932ba41
[cli] Added grpc code on the frond end.
georgeliao Oct 2, 2023
50c4be6
[grpc] Create the rpc framework for daemon::clone function.
georgeliao Oct 3, 2023
aa8e2a1
Added rpc_request fill-in code on the front end.
georgeliao Oct 3, 2023
70a2c8c
Added source_name validity check.
georgeliao Oct 4, 2023
ab4566c
Added specified destination name check.
georgeliao Oct 4, 2023
dd8a725
Added generating destination name.
georgeliao Oct 4, 2023
e3aae14
Added the source instance state check.
georgeliao Oct 4, 2023
91aa4c7
Small renaming for the vm instance pointer variable
georgeliao Oct 12, 2023
870030c
Formatted legacy code diff on this branch based on the new .clang-for…
georgeliao Oct 12, 2023
8125fe4
[daemon] Added clone_spec_item_and_write_to_instance_db lambda functi…
georgeliao Oct 12, 2023
afdaf89
[daemon] Wrap the destination name related code into generate_destina…
georgeliao Oct 12, 2023
4c24fc5
[imageVault] Added clone method for DefaultVMImageVault class
georgeliao Oct 13, 2023
4a83765
[daemon] Added vault clone method interface and the caller of that.
georgeliao Oct 13, 2023
0f5e799
[daemon] Added the code of virtual machine instance folder copy.
georgeliao Oct 16, 2023
463220a
[file_ops] Added copy file wrapper function.
georgeliao Oct 18, 2023
9216330
[daemon] replace the std file copy function with the wrapper one.
georgeliao Oct 18, 2023
1df9c0f
[daemon] added qemu_iso and the meta_data and network-config parts.
georgeliao Oct 19, 2023
660a2d7
[daemon] Added mount directory creation.
georgeliao Oct 19, 2023
3c107b5
[daemon] Added mount command for the iso file.
georgeliao Oct 19, 2023
d36ed1e
[daemon] add the loading the same parts of iso file and write to the …
georgeliao Oct 19, 2023
88ec4d5
[daemon] Added unmount command.
georgeliao Oct 19, 2023
dcbcc79
[daemon] Added removing directory.
georgeliao Oct 19, 2023
4598f9b
[daemon] added create_virtual_machine and init_mount code for destina…
georgeliao Oct 20, 2023
217a14b
[daemon] fix the compiler warning which caused the build failure.
georgeliao Oct 20, 2023
a69e720
[daemon] small fix for rebase conflict.
georgeliao Nov 2, 2023
d43eaeb
[daemon, cli] Added the reply message of clone and improved the clone…
georgeliao Nov 14, 2023
2a3cfcc
[snapshot] modified the find_parent function and added call to snapsh…
georgeliao Nov 16, 2023
72c1ec7
[snapshot] added qemu_snapshot constructor that is based on another s…
georgeliao Nov 16, 2023
f28d6f5
[snapshot] added clone function interface.
georgeliao Nov 20, 2023
e72f78e
[virtual_machine] added clone method of qemu virtual machine
georgeliao Nov 20, 2023
c32e571
[virtual machine] added clone_snapshots method place holder.
georgeliao Nov 20, 2023
b9fdcba
[virtual machine] small name improvement for the snapshot clone funct…
georgeliao Nov 20, 2023
4d96b5d
[snapshot] fix the constness of snapshot classes
georgeliao Nov 20, 2023
79348b1
[virtual machine] fix the constness of snapshot in clone_one_snapshot…
georgeliao Nov 21, 2023
1b9526c
[virtual machine] added the implementation of clone_snapshots functio…
georgeliao Nov 21, 2023
eed8a10
[snapshot] reverted the in RAM clone snapshot related code.
georgeliao Nov 21, 2023
50f8cb1
[snapshot] added new constructor for for constructing from file and r…
georgeliao Nov 21, 2023
12c71c9
[snapshot] added qemu_snapshot constructor.
georgeliao Nov 21, 2023
8daa47f
[virtual machine] added make_specific_snapshot function place holder
georgeliao Nov 21, 2023
cebfd75
[virtual machine] added make_specific_snapshot qemu implementation.
georgeliao Nov 21, 2023
9ab0761
[virtual machine] added public method load_snapshots_and_update_uniqu…
georgeliao Nov 22, 2023
fc2276f
[virtual machine] added load one file to snapshot function. PS: refac…
georgeliao Nov 22, 2023
fd85513
[daemon] added the loading and updating snapshots calls, now the whol…
georgeliao Nov 22, 2023
8e88728
[json] added update_unique_identifiers_of_metadata function and refac…
georgeliao Nov 27, 2023
b6248b6
[virtual machine] added load_snapshots_common to reduce the repeated …
georgeliao Nov 27, 2023
e357c69
[virtual machine] added variadic templated function load_snapshot_and…
georgeliao Nov 27, 2023
ec0a58f
[virtual machine] changed load_snapshots_common function to variadic …
georgeliao Nov 27, 2023
8ddfd13
[virtual machine] added explanatory comment for load_snapshots_common…
georgeliao Nov 27, 2023
3d6c2b9
[cli] replaced the destination name positional argument with option.
georgeliao Dec 11, 2023
f0cd182
[cli] fix the warning (compilation error) after upgrading to ubuntu 2…
georgeliao Jan 3, 2024
ebe3d15
[cli] fixed and refined the destination name description.
georgeliao Jan 3, 2024
e6b3853
[daemon] added destination name validity check.
georgeliao Jan 3, 2024
94a209d
[virtual machine] improved the name generator based on the team discu…
georgeliao Jan 10, 2024
5d43210
[utils] move some yaml helpers functions into utils.cpp to set up the…
georgeliao Jan 11, 2024
9c39ef9
[daemon] small refactoring, localize the lambda function further.
georgeliao Jan 11, 2024
3312963
[virtual machine] small fix for the start index of the name generator.
georgeliao Jan 11, 2024
c34cc7e
[vm factory] added create_vm_and_instance_disk_data function for clon…
georgeliao Jan 12, 2024
9b0ed71
[vm factory] added create_vm_and_instance_disk_data interface and cal…
georgeliao Jan 12, 2024
489f729
[vm factory] using the new read_from function to read the cloud-init-…
georgeliao Feb 1, 2024
04b1885
[cloud init] added at operator, it is similar with std::unordered_map…
georgeliao Feb 7, 2024
1aeb2cc
[vm factory] added load string and replace name functionality of mak…
georgeliao Feb 8, 2024
3e8c487
[cloud init] added contains function.
georgeliao Feb 8, 2024
451b8be
[vm factory] refine the client code of make_cloud_init_network_config…
georgeliao Feb 8, 2024
2be5c64
[cloud init] clean up some CloudInitIso utility functions/
georgeliao Feb 8, 2024
816332e
[vm factory] added early back-end check for the clone operation.
georgeliao Feb 9, 2024
6e64f88
[json util] refined on the source name to destination name string re…
georgeliao Feb 13, 2024
c3adf14
[daemon] added run_at_boot commands unique identifiers update for clo…
georgeliao Feb 13, 2024
6ad68c1
[daemon] moved cloned_instance_count from virtual machine class to vm…
georgeliao Feb 14, 2024
72494e8
[daemon] fix a small error from the previous commit.
georgeliao Feb 14, 2024
9a7f03e
[daemon] refined the clone_spec_item function.
georgeliao Feb 15, 2024
80fbb16
[daemon] use find_instance_and_react to make the error report of clon…
georgeliao Feb 20, 2024
ce421a6
[daemon] correct the extra interfaces update in clone.
georgeliao Feb 21, 2024
a86ee4c
[daemon] removed update_extra_interfaces_mac_address_of_run_at_boot s…
georgeliao Feb 22, 2024
0cf0e1b
[vm factory] added scope_guard clean up function for the create_vm_an…
georgeliao Feb 23, 2024
81989ca
[cloud init] rebase fix.
georgeliao Mar 4, 2024
b967e05
[json utils] fix formatting.
georgeliao Mar 5, 2024
0155bed
fixed the post-merge compilation.
georgeliao Apr 9, 2024
9a9e6ce
[bash completion] added clone bash completion
georgeliao Apr 10, 2024
b417a14
[unit test] added clone cli tests.
georgeliao Apr 12, 2024
e4d42b3
[unit test][daemon] added the daemon clone unit test frame work.
georgeliao Apr 15, 2024
001c271
[unit test][daemon] added unusual unit test case.
georgeliao Apr 15, 2024
38264f5
[unit test][daemon] added failsOnCloneOnNonStoppedInstance test.
georgeliao Apr 15, 2024
07bbee2
rebase fix.
georgeliao Apr 29, 2024
cc852cb
[yaml utils] made the make_cloud_init_meta_config to update instance_…
georgeliao Apr 30, 2024
3709a51
[json utils] added updating cloud init instance id in snapshot file c…
georgeliao Apr 30, 2024
c01957c
[unit test][json utils] added unit tests for update_cloud_init_instan…
georgeliao Apr 30, 2024
1198623
[json utils] changed update_unique_identifiers_of_metadata parameter …
georgeliao Apr 30, 2024
3d96042
[clone] small comment correction.
georgeliao Apr 30, 2024
2b9388a
[clone] small cleanup for some comments.
georgeliao May 1, 2024
068edfd
[daemon] refined the the roll back mechanism in clone.
georgeliao May 3, 2024
626caad
[unit test] added more unit tests for client failed command line args…
georgeliao May 3, 2024
27baf8e
[unit test] added clone invalid option unit test.
georgeliao May 3, 2024
828e191
[cmd] added AnimatedSpinner to clone command.
georgeliao May 3, 2024
86afbe8
[client][unit test] added command fail error to cover action_on_failu…
georgeliao May 4, 2024
95ed901
[vm factory] use in class data member instances_dir to derive the sou…
georgeliao May 6, 2024
9026f42
[vm image] improve one function parameter name.
georgeliao May 6, 2024
7350433
[clone] function name improvement.
georgeliao May 8, 2024
9a81142
[clone] added update_cloned_cloud_init utility function.
georgeliao May 8, 2024
6c344cd
[cloud init] [unit test] added unit test for update_cloned_cloud_init…
georgeliao May 8, 2024
f978e60
[vm factory] use update_cloned_cloud_init function to prepare for uni…
georgeliao May 8, 2024
ded0973
[unit test] added FileOps::copy unit test.
georgeliao May 8, 2024
1006fd6
[image vault] added unit test for DefaultVMImageVault::clone.
georgeliao May 8, 2024
5c7efea
[image vault] [unit test] added imageCloneFailOnNonExistSrcImage case.
georgeliao May 9, 2024
2dd7ed5
[image vault] [unit test] added imageCloneFailOnAlreadyExistDestImage…
georgeliao May 9, 2024
32acd01
[lxd image vault][unit test] added lxdImageVaultCloneThrow unit test.
georgeliao May 9, 2024
9e7f913
[unit test] added coverage for DaemonRpc::clone.
georgeliao May 24, 2024
9c978d0
[daemon] small refactor on generate_next_clone_name function.
georgeliao May 27, 2024
889584a
[cloud init] small function name improvement and typo correction.
georgeliao May 27, 2024
7db5392
[vm image] improves the image_path sub-string replacement, get it con…
georgeliao May 27, 2024
1289824
[qemu][vm factory] fixed rollback instance directory removal did not …
georgeliao May 30, 2024
c6da907
[clone] added metadata non-empty check for the non-qemu backend cases.
georgeliao May 30, 2024
6cdacec
[unit test] removed assertion line coverage unit test because windows…
georgeliao Jun 11, 2024
1497b0a
[qemu][vm factory] using the QemuVirtualMachine constructor directly …
georgeliao Jun 11, 2024
96b8d55
[qemu][vm factory] added copy_instance_dir_without_snapshot_files fun…
georgeliao Jun 13, 2024
fb3bc56
[qemu] remove all load_snapshots_and_update_unique_identifiers relate…
georgeliao Jun 13, 2024
8bd9626
[virtual machine] added the placeholder of the remove_all_snapshots_f…
georgeliao Jun 14, 2024
c1cd11e
[qemu][virtual machine] added qemu remove_all_snapshots_from_the_imag…
georgeliao Jun 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion completions/bash/multipass
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ _multipass_complete()
prev_opts=false
multipass_cmds="authenticate transfer delete exec find help info launch list mount networks \
purge recover restart restore shell snapshot start stop suspend umount version get set \
alias aliases unalias"
clone alias aliases unalias"

if [[ "${multipass_cmds}" =~ " ${cmd} " || "${multipass_cmds}" =~ ^${cmd} || "${multipass_cmds}" =~ \ ${cmd}$ ]];
then
Expand Down Expand Up @@ -269,6 +269,9 @@ _multipass_complete()
"restore")
_add_nonrepeating_args "--destructive"
;;
"clone")
_add_nonrepeating_args "--name"
;;
esac

if [[ ${prev} == -* ]]; then
Expand Down Expand Up @@ -352,6 +355,9 @@ _multipass_complete()
"snapshot")
_multipass_instances "Stopped"
;;
"clone")
_multipass_instances "Stopped"
;;
"restore")
_multipass_restorable_snapshots
;;
Expand Down
5 changes: 5 additions & 0 deletions include/multipass/cloud_init_iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class CloudInitFileOps : public Singleton<CloudInitFileOps>
const std::vector<NetworkInterface>& extra_interfaces,
const std::string& new_instance_id,
const std::filesystem::path& cloud_init_path) const;

virtual void update_cloned_cloud_init_unique_identifiers(const std::string& default_mac_addr,
const std::vector<NetworkInterface>& extra_interfaces,
const std::string& new_hostname,
const std::filesystem::path& cloud_init_path) const;
virtual void add_extra_interface_to_cloud_init(const std::string& default_mac_addr,
const NetworkInterface& extra_interfaces,
const std::filesystem::path& cloud_init_path) const;
Expand Down
1 change: 1 addition & 0 deletions include/multipass/file_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class FileOps : public Singleton<FileOps>
std::ios_base::openmode mode = std::ios_base::out) const;
virtual std::unique_ptr<std::istream> open_read(const fs::path& path,
std::ios_base::openmode mode = std::ios_base::in) const;
virtual void copy(const fs::path& src, const fs::path& dist, fs::copy_options copy_options) const;
virtual bool exists(const fs::path& path, std::error_code& err) const;
virtual bool is_directory(const fs::path& path, std::error_code& err) const;
virtual bool create_directory(const fs::path& path, std::error_code& err) const;
Expand Down
9 changes: 9 additions & 0 deletions include/multipass/json_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,22 @@

namespace multipass
{
struct VMSpecs;
class JsonUtils : public Singleton<JsonUtils>
{
public:
explicit JsonUtils(const Singleton<JsonUtils>::PrivatePass&) noexcept;

virtual void write_json(const QJsonObject& root, QString file_name) const; // transactional; creates parent dirs
virtual std::string json_to_string(const QJsonObject& root) const;
virtual QJsonValue update_cloud_init_instance_id(const QJsonValue& cloud_init_instance_id_value,
const std::string& src_vm_name,
const std::string& dest_vm_name) const;
virtual QJsonValue update_unique_identifiers_of_metadata(const QJsonValue& metadata_value,
const multipass::VMSpecs& src_specs,
const multipass::VMSpecs& dest_specs,
const std::string& src_vm_name,
const std::string& dest_vm_name) const;
virtual QJsonArray extra_interfaces_to_json_array(const std::vector<NetworkInterface>& extra_interfaces) const;
virtual std::optional<std::vector<NetworkInterface>> read_extra_interfaces(const QJsonObject& record) const;
};
Expand Down
7 changes: 7 additions & 0 deletions include/multipass/virtual_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ class VirtualMachine : private DisabledCopyMove
virtual void load_snapshots() = 0;
virtual std::vector<std::string> get_childrens_names(const Snapshot* parent) const = 0;
virtual int get_snapshot_count() const = 0;
virtual void remove_all_snapshots_from_the_image() const = 0;

QDir instance_directory() const;
std::string get_vm_name() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vm_name is a public member so you shouldn't need this accessor method, right?


VirtualMachine::State state;
const std::string vm_name;
Expand All @@ -134,4 +136,9 @@ inline QDir multipass::VirtualMachine::instance_directory() const
return instance_dir; // TODO this should probably only be known at the level of the base VM
}

inline std::string multipass::VirtualMachine::get_vm_name() const
{
return vm_name;
}

#endif // MULTIPASS_VIRTUAL_MACHINE_H
8 changes: 8 additions & 0 deletions include/multipass/virtual_machine_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ class VirtualMachineFactory : private DisabledCopyMove
virtual VirtualMachine::UPtr create_virtual_machine(const VirtualMachineDescription& desc,
const SSHKeyProvider& key_provider,
VMStatusMonitor& monitor) = 0;
virtual 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) = 0;

/** Removes any resources associated with a VM of the given name.
*
Expand All @@ -73,6 +80,7 @@ class VirtualMachineFactory : private DisabledCopyMove
virtual std::vector<NetworkInterfaceInfo> networks() const = 0;
virtual void require_snapshots_support() const = 0;
virtual void require_suspend_support() const = 0;
virtual void require_clone_support() const = 0;

protected:
VirtualMachineFactory() = default;
Expand Down
1 change: 1 addition & 0 deletions include/multipass/vm_image_vault.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class VMImageVault : private DisabledCopyMove
virtual void update_images(const FetchType& fetch_type, const PrepareAction& prepare,
const ProgressMonitor& monitor) = 0;
virtual MemorySize minimum_image_size_for(const std::string& id) = 0;
virtual void clone(const std::string& source_instance_name, const std::string& destination_instance_name) = 0;
virtual VMImageHost* image_host_for(const std::string& remote_name) const = 0;
virtual std::vector<std::pair<std::string, VMImageInfo>> all_info_for(const Query& query) const = 0;

Expand Down
23 changes: 13 additions & 10 deletions include/multipass/vm_specs.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct VMSpecs
std::unordered_map<std::string, VMMount> mounts;
bool deleted;
QJsonObject metadata;
int clone_count = 0; // tracks the number of cloned vm from this source vm (regardless of deletes)
};

inline bool operator==(const VMSpecs& a, const VMSpecs& b)
Expand All @@ -57,16 +58,18 @@ inline bool operator==(const VMSpecs& a, const VMSpecs& b)
a.state,
a.mounts,
a.deleted,
a.metadata) == std::tie(b.num_cores,
b.mem_size,
b.disk_space,
b.default_mac_address,
b.extra_interfaces,
b.ssh_username,
b.state,
b.mounts,
b.deleted,
b.metadata);
a.metadata,
a.clone_count) == std::tie(b.num_cores,
b.mem_size,
b.disk_space,
b.default_mac_address,
b.extra_interfaces,
b.ssh_username,
b.state,
b.mounts,
b.deleted,
b.metadata,
a.clone_count);
}

inline bool operator!=(const VMSpecs& a, const VMSpecs& b) // TODO drop in C++20
Expand Down
2 changes: 2 additions & 0 deletions src/client/cli/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "cmd/alias.h"
#include "cmd/aliases.h"
#include "cmd/authenticate.h"
#include "cmd/clone.h"
#include "cmd/delete.h"
#include "cmd/exec.h"
#include "cmd/find.h"
Expand Down Expand Up @@ -108,6 +109,7 @@ mp::Client::Client(ClientConfig& config)
add_command<cmd::Delete>(aliases);
add_command<cmd::Umount>();
add_command<cmd::Version>();
add_command<cmd::Clone>();

sort_commands();

Expand Down
1 change: 1 addition & 0 deletions src/client/cli/cmd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ add_library(commands STATIC
aliases.cpp
animated_spinner.cpp
authenticate.cpp
clone.cpp
common_cli.cpp
create_alias.cpp
delete.cpp
Expand Down
109 changes: 109 additions & 0 deletions src/client/cli/cmd/clone.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (C) 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
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#include "clone.h"

#include "animated_spinner.h"
#include "common_cli.h"

#include <multipass/cli/argparser.h>

namespace mp = multipass;
namespace cmd = multipass::cmd;

mp::ReturnCode cmd::Clone::run(ArgParser* parser)
{
const auto parscode = parse_args(parser);
if (parscode != ParseCode::Ok)
{
return parser->returnCodeFrom(parscode);
}

AnimatedSpinner spinner{cout};
auto action_on_success = [this, &spinner](CloneReply& reply) -> ReturnCode {
spinner.stop();
cout << reply.reply_message();

return ReturnCode::Ok;
};

auto action_on_failure = [this, &spinner](grpc::Status& status, CloneReply& reply) -> ReturnCode {
spinner.stop();
return standard_failure_handler_for(name(), cerr, status, reply.reply_message());
};

spinner.start("Cloning " + rpc_request.source_name());
return dispatch(&RpcMethod::clone, rpc_request, action_on_success, action_on_failure);
}

std::string cmd::Clone::name() const
{
return "clone";
}

QString cmd::Clone::short_help() const
{
return QStringLiteral("Clone an Ubuntu instance");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we typical refer to them simply as an instance. See snapshot.cpp

}

QString cmd::Clone::description() const
{
return QStringLiteral("A clone is a complete independent copy of a whole virtual machine instance");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should describe an action since it is a description of multipass clone; an action. Right now, it describes an object. How about something like:

Create a complete independent copy of an existing instance

WDYT

}

mp::ParseCode cmd::Clone::parse_args(ArgParser* parser)
{
parser->addPositionalArgument("source_name", "The name of the source virtual machine instance", "<source_name>");

const QCommandLineOption destination_name_option{
{"n", "name"},
"An optional name for the destination instance, it obeys the same validity rules as instance names (see "
"\"help launch\"). Default: \"<source_name>-cloneN\", where N is the Nth cloned instance of the original "
"instance.",
"destination-name"};

parser->addOption(destination_name_option);

const auto status = parser->commandParse(this);
if (status != ParseCode::Ok)
{
return status;
}

const auto number_of_positional_arguments = parser->positionalArguments().count();
if (number_of_positional_arguments < 1)
{
cerr << "Please provide the name of the source instance.\n";
return ParseCode::CommandLineError;
}

if (number_of_positional_arguments > 1)
{
cerr << "Too many arguments.\n";
return ParseCode::CommandLineError;
}

const auto source_name = parser->positionalArguments()[0];
rpc_request.set_source_name(source_name.toStdString());
rpc_request.set_verbosity_level(parser->verbosityLevel());
if (parser->isSet(destination_name_option))
{
rpc_request.set_destination_name(parser->value(destination_name_option).toStdString());
}

return ParseCode::Ok;
}
44 changes: 44 additions & 0 deletions src/client/cli/cmd/clone.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 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
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#ifndef MULTIPASS_CLONE_H
#define MULTIPASS_CLONE_H

#include <multipass/cli/command.h>

namespace multipass
{
namespace cmd
{
class Clone final : public Command
{
public:
using Command::Command;
ReturnCode run(ArgParser* parser) override;

std::string name() const override;
QString short_help() const override;
QString description() const override;

private:
ParseCode parse_args(ArgParser* parser);

CloneRequest rpc_request;
};
} // namespace cmd
} // namespace multipass
#endif // MULTIPASS_CLONE_H
Loading
Loading