Commit 97e6c2b3 authored by Nicholas Verne's avatar Nicholas Verne Committed by Commit Bot

Enables the upgrade of Crostini container from Settings.

We restart vm when upgrading, if it wasn't running already.

Bug: 1024693
Change-Id: I00e093f7bbf83eb04a6adb4029a4612e99950ae4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2026559Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarDavid Munro <davidmunro@google.com>
Commit-Queue: Nicholas Verne <nverne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738422}
parent 62e43a8e
...@@ -788,15 +788,13 @@ bool CrostiniManager::ShouldPromptContainerUpgrade( ...@@ -788,15 +788,13 @@ bool CrostiniManager::ShouldPromptContainerUpgrade(
return false; return false;
} }
bool upgradable = IsContainerUpgradeable(container_id); bool upgradable = IsContainerUpgradeable(container_id);
if (upgradable) {
// Currently a true return value from this function implies the
// prompt must be shown. Storing this state in CrostiniManager implies that
// the prompt will only be shown once per session.
container_upgrade_prompt_shown_.insert(container_id);
}
return upgradable; return upgradable;
} }
void CrostiniManager::UpgradePromptShown(const ContainerId& container_id) {
container_upgrade_prompt_shown_.insert(container_id);
}
base::Optional<ContainerInfo> CrostiniManager::GetContainerInfo( base::Optional<ContainerInfo> CrostiniManager::GetContainerInfo(
std::string vm_name, std::string vm_name,
std::string container_name) { std::string container_name) {
...@@ -1545,6 +1543,23 @@ vm_tools::cicerone::UpgradeContainerRequest::Version ConvertVersion( ...@@ -1545,6 +1543,23 @@ vm_tools::cicerone::UpgradeContainerRequest::Version ConvertVersion(
} }
} }
// Watches the Crostini restarter until the VM started phase, then aborts the
// sequence.
class AbortOnVmStartObserver : public CrostiniManager::RestartObserver {
public:
explicit AbortOnVmStartObserver(
base::WeakPtr<CrostiniManager> crostini_manager)
: crostini_manager_(crostini_manager) {}
void OnVmStarted(bool success) override {
if (crostini_manager_) {
crostini_manager_->AbortRestartCrostini(restart_id_, base::DoNothing());
}
}
private:
base::WeakPtr<CrostiniManager> crostini_manager_;
};
} // namespace } // namespace
void CrostiniManager::UpgradeContainer(const ContainerId& key, void CrostiniManager::UpgradeContainer(const ContainerId& key,
...@@ -1577,10 +1592,34 @@ void CrostiniManager::UpgradeContainer(const ContainerId& key, ...@@ -1577,10 +1592,34 @@ void CrostiniManager::UpgradeContainer(const ContainerId& key,
request.set_container_name(container_name); request.set_container_name(container_name);
request.set_source_version(ConvertVersion(source_version)); request.set_source_version(ConvertVersion(source_version));
request.set_target_version(ConvertVersion(target_version)); request.set_target_version(ConvertVersion(target_version));
GetCiceroneClient()->UpgradeContainer(
std::move(request), CrostiniResultCallback do_upgrade_container = base::BindOnce(
base::BindOnce(&CrostiniManager::OnUpgradeContainer, [](base::WeakPtr<CrostiniManager> crostini_manager,
weak_ptr_factory_.GetWeakPtr(), std::move(callback))); vm_tools::cicerone::UpgradeContainerRequest request,
CrostiniResultCallback final_callback, CrostiniResult result) {
// When we fail to start the VM, we can't continue the upgrade.
if (result != CrostiniResult::SUCCESS &&
result != CrostiniResult::RESTART_ABORTED) {
LOG(ERROR) << "Failed to restart the vm before attempting container "
"upgrade. Result code "
<< static_cast<int>(result);
std::move(final_callback)
.Run(CrostiniResult::UPGRADE_CONTAINER_FAILED);
return;
}
GetCiceroneClient()->UpgradeContainer(
std::move(request),
base::BindOnce(&CrostiniManager::OnUpgradeContainer,
crostini_manager, std::move(final_callback)));
},
weak_ptr_factory_.GetWeakPtr(), std::move(request), std::move(callback));
if (!IsVmRunning(vm_name)) {
RestartCrostini(vm_name, container_name, std::move(do_upgrade_container),
new AbortOnVmStartObserver(weak_ptr_factory_.GetWeakPtr()));
} else {
std::move(do_upgrade_container).Run(CrostiniResult::SUCCESS);
}
} }
void CrostiniManager::CancelUpgradeContainer(const ContainerId& key, void CrostiniManager::CancelUpgradeContainer(const ContainerId& key,
......
...@@ -138,6 +138,9 @@ class CrostiniManager : public KeyedService, ...@@ -138,6 +138,9 @@ class CrostiniManager : public KeyedService,
// Callback indicating success or failure // Callback indicating success or failure
using BoolCallback = base::OnceCallback<void(bool success)>; using BoolCallback = base::OnceCallback<void(bool success)>;
using RestartId = int;
static const RestartId kUninitializedRestartId = -1;
// Observer class for the Crostini restart flow. // Observer class for the Crostini restart flow.
class RestartObserver { class RestartObserver {
public: public:
...@@ -155,6 +158,10 @@ class CrostiniManager : public KeyedService, ...@@ -155,6 +158,10 @@ class CrostiniManager : public KeyedService,
virtual void OnContainerStarted(CrostiniResult result) {} virtual void OnContainerStarted(CrostiniResult result) {}
virtual void OnSshKeysFetched(bool success) {} virtual void OnSshKeysFetched(bool success) {}
virtual void OnContainerMounted(bool success) {} virtual void OnContainerMounted(bool success) {}
protected:
friend class CrostiniManager;
RestartId restart_id_;
}; };
struct RestartOptions { struct RestartOptions {
...@@ -405,8 +412,6 @@ class CrostiniManager : public KeyedService, ...@@ -405,8 +412,6 @@ class CrostiniManager : public KeyedService,
uint8_t guest_port, uint8_t guest_port,
BoolCallback callback); BoolCallback callback);
using RestartId = int;
static const RestartId kUninitializedRestartId = -1;
// Runs all the steps required to restart the given crostini vm and container. // Runs all the steps required to restart the given crostini vm and container.
// The optional |observer| tracks progress. If provided, it must be alive // The optional |observer| tracks progress. If provided, it must be alive
// until the restart completes (i.e. when |callback| is called) or the restart // until the restart completes (i.e. when |callback| is called) or the restart
...@@ -579,6 +584,7 @@ class CrostiniManager : public KeyedService, ...@@ -579,6 +584,7 @@ class CrostiniManager : public KeyedService,
bool IsContainerUpgradeable(const ContainerId& container_id); bool IsContainerUpgradeable(const ContainerId& container_id);
bool ShouldPromptContainerUpgrade(const ContainerId& container_id); bool ShouldPromptContainerUpgrade(const ContainerId& container_id);
void UpgradePromptShown(const ContainerId& container_id);
private: private:
class CrostiniRestarter; class CrostiniRestarter;
......
...@@ -341,9 +341,11 @@ bool ShouldConfigureDefaultContainer(Profile* profile) { ...@@ -341,9 +341,11 @@ bool ShouldConfigureDefaultContainer(Profile* profile) {
!default_container_configured && !ansible_playbook_file_path.empty(); !default_container_configured && !ansible_playbook_file_path.empty();
} }
// TODO(davidmunro): Answer based on flag and current container version. bool ShouldAllowContainerUpgrade(Profile* profile) {
bool ShouldAllowContainerUpgrade() { return CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(profile) &&
return false; crostini::CrostiniManager::GetForProfile(profile)
->IsContainerUpgradeable(ContainerId(
kCrostiniDefaultVmName, kCrostiniDefaultContainerName));
} }
void LaunchCrostiniApp(Profile* profile, void LaunchCrostiniApp(Profile* profile,
......
...@@ -65,7 +65,7 @@ bool IsUninstallable(Profile* profile, const std::string& app_id); ...@@ -65,7 +65,7 @@ bool IsUninstallable(Profile* profile, const std::string& app_id);
bool IsCrostiniRunning(Profile* profile); bool IsCrostiniRunning(Profile* profile);
// Whether the user is able to perform a container upgrade. // Whether the user is able to perform a container upgrade.
bool ShouldAllowContainerUpgrade(); bool ShouldAllowContainerUpgrade(Profile* profile);
// Returns whether default Crostini container should be configured according to // Returns whether default Crostini container should be configured according to
// the configuration specified by CrostiniAnsiblePlaybook user policy. // the configuration specified by CrostiniAnsiblePlaybook user policy.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h" #include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
#include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.h" #include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.h"
#include "chrome/common/webui_url_constants.h" #include "chrome/common/webui_url_constants.h"
...@@ -62,6 +63,10 @@ bool CrostiniUpgraderDialog::CanCloseDialog() const { ...@@ -62,6 +63,10 @@ bool CrostiniUpgraderDialog::CanCloseDialog() const {
void CrostiniUpgraderDialog::OnDialogShown(content::WebUI* webui) { void CrostiniUpgraderDialog::OnDialogShown(content::WebUI* webui) {
upgrader_ui_ = static_cast<CrostiniUpgraderUI*>(webui->GetController()); upgrader_ui_ = static_cast<CrostiniUpgraderUI*>(webui->GetController());
upgrader_ui_->set_launch_closure(std::move(launch_closure_)); upgrader_ui_->set_launch_closure(std::move(launch_closure_));
crostini::CrostiniManager::GetForProfile(Profile::FromWebUI(webui))
->UpgradePromptShown(
crostini::ContainerId(crostini::kCrostiniDefaultVmName,
crostini::kCrostiniDefaultContainerName));
return SystemWebDialogDelegate::OnDialogShown(webui); return SystemWebDialogDelegate::OnDialogShown(webui);
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "ui/display/screen.h"
namespace chromeos { namespace chromeos {
namespace settings { namespace settings {
...@@ -291,23 +292,6 @@ void CrostiniHandler::OnCrostiniInstallerViewStatusChanged(bool status) { ...@@ -291,23 +292,6 @@ void CrostiniHandler::OnCrostiniInstallerViewStatusChanged(bool status) {
} }
} }
void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
bool in_progress) {
// Other side listens with cr.addWebUIListener
FireWebUIListener("crostini-export-import-operation-status-changed",
base::Value(in_progress));
}
void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetSize());
chromeos::SessionManagerClient* client =
chromeos::SessionManagerClient::Get();
client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload,
weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnQueryAdbSideload( void CrostiniHandler::OnQueryAdbSideload(
SessionManagerClient::AdbSideloadResponseCode response_code, SessionManagerClient::AdbSideloadResponseCode response_code,
bool enabled) { bool enabled) {
...@@ -377,10 +361,34 @@ bool CrostiniHandler::CheckEligibilityToChangeArcAdbSideloading() const { ...@@ -377,10 +361,34 @@ bool CrostiniHandler::CheckEligibilityToChangeArcAdbSideloading() const {
return true; return true;
} }
void CrostiniHandler::LaunchTerminal() {
crostini::LaunchCrostiniApp(
profile_, crostini::GetTerminalId(),
display::Screen::GetScreen()->GetPrimaryDisplay().id());
}
void CrostiniHandler::HandleRequestContainerUpgradeView( void CrostiniHandler::HandleRequestContainerUpgradeView(
const base::ListValue* args) { const base::ListValue* args) {
CHECK_EQ(0U, args->GetSize()); CHECK_EQ(0U, args->GetSize());
chromeos::CrostiniUpgraderDialog::Show(base::DoNothing()); chromeos::CrostiniUpgraderDialog::Show(base::BindOnce(
&CrostiniHandler::LaunchTerminal, weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
bool in_progress) {
// Other side listens with cr.addWebUIListener
FireWebUIListener("crostini-export-import-operation-status-changed",
base::Value(in_progress));
}
void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(0U, args->GetSize());
chromeos::SessionManagerClient* client =
chromeos::SessionManagerClient::Get();
client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload,
weak_ptr_factory_.GetWeakPtr()));
} }
} // namespace settings } // namespace settings
......
...@@ -70,6 +70,8 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler, ...@@ -70,6 +70,8 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleEnableArcAdbRequest(const base::ListValue* args); void HandleEnableArcAdbRequest(const base::ListValue* args);
// Handle a request for disabling adb sideloading in ARC. // Handle a request for disabling adb sideloading in ARC.
void HandleDisableArcAdbRequest(const base::ListValue* args); void HandleDisableArcAdbRequest(const base::ListValue* args);
// Launch the Crostini terminal.
void LaunchTerminal();
// Handle a request for showing the container upgrade view. // Handle a request for showing the container upgrade view.
void HandleRequestContainerUpgradeView(const base::ListValue* args); void HandleRequestContainerUpgradeView(const base::ListValue* args);
// Callback of HandleQueryArcAdbRequest. // Callback of HandleQueryArcAdbRequest.
......
...@@ -641,7 +641,7 @@ void AddCrostiniStrings(content::WebUIDataSource* html_source, ...@@ -641,7 +641,7 @@ void AddCrostiniStrings(content::WebUIDataSource* html_source,
html_source->AddBoolean("isEnterpriseManaged", html_source->AddBoolean("isEnterpriseManaged",
IsDeviceManaged() || IsProfileManaged(profile)); IsDeviceManaged() || IsProfileManaged(profile));
html_source->AddBoolean("showCrostiniContainerUpgrade", html_source->AddBoolean("showCrostiniContainerUpgrade",
crostini::ShouldAllowContainerUpgrade()); crostini::ShouldAllowContainerUpgrade(profile));
} }
void AddPluginVmStrings(content::WebUIDataSource* html_source, void AddPluginVmStrings(content::WebUIDataSource* html_source,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment