diff --git a/include/multipass/exceptions/ssh_exception.h b/include/multipass/exceptions/ssh_exception.h index d6f52536707..5c64c9d00e2 100644 --- a/include/multipass/exceptions/ssh_exception.h +++ b/include/multipass/exceptions/ssh_exception.h @@ -30,5 +30,13 @@ class SSHException : public std::runtime_error { } }; + +class SSHExecFailure : public SSHException +{ +public: + SSHExecFailure(const std::string& what_arg) : SSHException(what_arg) + { + } +}; } // namespace multipass #endif // MULTIPASS_SSH_EXCEPTION_H diff --git a/src/client/cli/cmd/start.cpp b/src/client/cli/cmd/start.cpp index c6b93f11059..d0c5ca90a8c 100644 --- a/src/client/cli/cmd/start.cpp +++ b/src/client/cli/cmd/start.cpp @@ -65,11 +65,6 @@ mp::ReturnCode cmd::Start::run(mp::ArgParser* parser) cout << update_notice(reply.update_info()); } - if (!reply.log_line().empty()) - { - cout << "Warning: " << reply.log_line(); - } - return ReturnCode::Ok; }; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index e4638e30b26..94efe5e9a74 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -3385,7 +3385,7 @@ mp::Daemon::async_wait_for_ready_all(grpc::ServerReaderWriterInterface unconfigured{{"eth7", "", true}}; + + auto mock_factory = use_a_mock_vm_factory(); + const auto [temp_dir, filename] = plant_instance_json(fake_json_contents(mac_addr, unconfigured)); + + auto instance_ptr = std::make_unique>(mock_instance_name); + EXPECT_CALL(*mock_factory, create_virtual_machine(_, _)).WillOnce([&instance_ptr](const auto&, auto&) { + return std::move(instance_ptr); + }); + + EXPECT_CALL(*instance_ptr, wait_until_ssh_up).WillRepeatedly(Return()); + EXPECT_CALL(*instance_ptr, current_state()).WillRepeatedly(Return(mp::VirtualMachine::State::off)); + EXPECT_CALL(*instance_ptr, start()).Times(1); + EXPECT_CALL(*instance_ptr, add_network_interface(_, _)).Times(1); + + config_builder.data_directory = temp_dir->path(); + config_builder.vault = std::make_unique>(); + + mp::Daemon daemon{config_builder.build()}; + + mp::StartRequest request; + request.mutable_instance_names()->add_instance_name(mock_instance_name); + + StrictMock> server; + + EXPECT_CALL(server, Write(Property(&mp::StartReply::log_line, HasSubstr("Cannot create a SSH shell")), _)).Times(1); + + auto status = call_daemon_slot(daemon, &mp::Daemon::start, request, std::move(server)); + + EXPECT_THAT(status.error_message(), StrEq("")); + EXPECT_TRUE(status.ok()); +} + struct WithSSH : public TestDaemonStart, WithParamInterface { }; @@ -126,7 +163,7 @@ TEST_P(WithSSH, startConfiguresInterfaces) return std::move(instance_ptr); }); - EXPECT_CALL(*instance_ptr, wait_until_ssh_up(_)).WillRepeatedly(Return()); + EXPECT_CALL(*instance_ptr, wait_until_ssh_up).WillRepeatedly(Return()); EXPECT_CALL(*instance_ptr, current_state()).WillRepeatedly(Return(mp::VirtualMachine::State::off)); EXPECT_CALL(*instance_ptr, start()).Times(1); EXPECT_CALL(*instance_ptr, add_network_interface(_, _)).Times(1); @@ -144,7 +181,7 @@ TEST_P(WithSSH, startConfiguresInterfaces) if (expected_status) { EXPECT_CALL(server, - Write(Property(&mp::StartReply::log_line, HasSubstr("failure configuring network interfaces")), _)) + Write(Property(&mp::StartReply::log_line, HasSubstr("Failure configuring network interfaces")), _)) .Times(1); } else