-
Notifications
You must be signed in to change notification settings - Fork 744
Az implementation #4061
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
Az implementation #4061
Changes from all commits
a444f51
94648e1
4cdd38d
5ec148f
aeab9a5
bc3e81c
59dc732
48d6ec7
acc2e04
f000acf
6739f0b
f00a058
71a6e04
d55b2cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1034,6 +1034,8 @@ mp::InstanceStatus::Status grpc_instance_status_for(const mp::VirtualMachine::St | |
| return mp::InstanceStatus::SUSPENDING; | ||
| case mp::VirtualMachine::State::suspended: | ||
| return mp::InstanceStatus::SUSPENDED; | ||
| case mp::VirtualMachine::State::unavailable: | ||
| return mp::InstanceStatus::UNAVAILABLE; | ||
| case mp::VirtualMachine::State::unknown: | ||
| default: | ||
| return mp::InstanceStatus::UNKNOWN; | ||
|
|
@@ -2083,6 +2085,12 @@ try | |
| continue; | ||
| } | ||
|
|
||
| if (vm->current_state() == VirtualMachine::State::unavailable) | ||
| { | ||
| add_fmt_to(errors, "instance '{}' is not available", name); | ||
| continue; | ||
| } | ||
|
|
||
| auto& vm_mounts = mounts[name]; | ||
| if (vm_mounts.find(target_path) != vm_mounts.end()) | ||
| { | ||
|
|
@@ -2259,9 +2267,13 @@ try | |
| continue; | ||
| } | ||
| case VirtualMachine::State::suspending: | ||
| case VirtualMachine::State::unavailable: | ||
| // TODO: format State directly | ||
| fmt::format_to(std::back_inserter(start_errors), | ||
| "Cannot start the instance '{}' while suspending.", | ||
| name); | ||
| "Cannot start the instance '{}' while {}.", | ||
| name, | ||
| vm.current_state() == VirtualMachine::State::suspending ? "suspending" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will be easier once the Hyper-V branch is in: https://github.com/canonical/multipass/pull/4080/files#diff-d847b18fbc46d755306da3eb6cac52de71043c1cc87ff345cdf8b034ad141ffaR158 You could add a TODO here, or convince @xmkg to split that off 😉 |
||
| : "unavailable"); | ||
| continue; | ||
| case VirtualMachine::State::delayed_shutdown: | ||
| delayed_shutdown_instances.erase(name); | ||
|
|
@@ -2364,6 +2376,14 @@ try | |
| if (status.ok()) | ||
| { | ||
| status = cmd_vms(instance_selection.operative_selection, [this](auto& vm) { | ||
| if (vm.current_state() == VirtualMachine::State::unavailable) | ||
| { | ||
| mpl::log(mpl::Level::info, | ||
| vm.vm_name, | ||
| "Ignoring suspend since instance is unavailable."); | ||
| return grpc::Status::OK; | ||
| } | ||
|
Comment on lines
+2379
to
+2385
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Idem: shouldn't this be handled by the VM? It would go in the direction of relieving the daemon from such concerns. |
||
|
|
||
| stop_mounts(vm.vm_name); | ||
|
|
||
| vm.suspend(); | ||
|
|
@@ -2485,6 +2505,14 @@ try | |
| { | ||
| const auto& instance_name = vm_it->first; | ||
|
|
||
| if (vm_it->second->current_state() == VirtualMachine::State::unavailable) | ||
| { | ||
| mpl::log(mpl::Level::info, | ||
| instance_name, | ||
| "Ignoring delete since instance is unavailable."); | ||
| continue; | ||
| } | ||
|
|
||
| auto snapshot_pick_it = instance_snapshots_map.find(instance_name); | ||
| const auto& [pick, all] = snapshot_pick_it == instance_snapshots_map.end() | ||
| ? SnapshotPick{{}, true} | ||
|
|
@@ -2533,12 +2561,19 @@ try | |
| const auto target_path = | ||
| QDir::cleanPath(QString::fromStdString(path_entry.target_path())).toStdString(); | ||
|
|
||
| if (operative_instances.find(name) == operative_instances.end()) | ||
| auto vm = operative_instances.find(name); | ||
| if (vm == operative_instances.end()) | ||
| { | ||
| add_fmt_to(errors, "instance '{}' does not exist", name); | ||
| continue; | ||
| } | ||
|
|
||
| if (vm->second->current_state() == VirtualMachine::State::unavailable) | ||
| { | ||
| mpl::log(mpl::Level::info, name, "Ignoring umount since instance unavailable."); | ||
| continue; | ||
| } | ||
|
|
||
| auto& vm_spec_mounts = vm_instance_specs[name].mounts; | ||
| auto& vm_mounts = mounts[name]; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,8 @@ | |
|
|
||
| #include <fmt/format.h> | ||
|
|
||
| #include <scope_guard.hpp> | ||
|
|
||
| #include <QJsonDocument> | ||
|
|
||
| namespace mpl = multipass::logging; | ||
|
|
@@ -115,10 +117,42 @@ void BaseAvailabilityZone::set_available(const bool new_available) | |
| return; | ||
|
|
||
| m.available = new_available; | ||
| serialize(); | ||
| auto serialize_guard = sg::make_scope_guard([this]() noexcept { | ||
| try | ||
| { | ||
| serialize(); | ||
| } | ||
| catch (const std::exception& e) | ||
| { | ||
| mpl::error(m.name, "Failed to serialize availability zone: {}", e.what()); | ||
| } | ||
| }); | ||
|
|
||
| for (auto& vm : m.vms) | ||
| vm.get().set_available(m.available); | ||
| try | ||
| { | ||
| for (auto& vm : m.vms) | ||
| vm.get().set_available(new_available); | ||
| } | ||
| catch (...) | ||
| { | ||
| // if an error occurs fallback to available. | ||
| m.available = true; | ||
|
|
||
| // make sure nothing is still unavailable. | ||
| for (auto& vm : m.vms) | ||
| { | ||
| // setting the state here breaks encapsulation, but it's already broken. | ||
| std::unique_lock vm_lock{vm.get().state_mutex}; | ||
| if (vm.get().current_state() == VirtualMachine::State::unavailable) | ||
| { | ||
| vm.get().state = VirtualMachine::State::off; | ||
| vm.get().update_state(); | ||
| } | ||
|
Comment on lines
+144
to
+150
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you considered force-stop instead? That would avoid breaking encapsulation yet again and make sure there were no leftover processes.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shutdown is ignored when an instance is unavailable. There aren't any leftover processes since an unavailable instance is always off. Using |
||
| } | ||
|
|
||
| // rethrow the error so something else can deal with it. | ||
| throw; | ||
| } | ||
| } | ||
|
|
||
| void BaseAvailabilityZone::add_vm(VirtualMachine& vm) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.