From 0659e7f9d09a2b3b4ca253464e7a3c0cd4847d78 Mon Sep 17 00:00:00 2001 From: GT610 Date: Sun, 11 Jan 2026 22:03:02 +0800 Subject: [PATCH] fix(ssh): Modify the return type of execWithPwd to include the output content Adjust the return type of the `execWithPwd` method to `(int?, String)` so that it can simultaneously return the exit code and output content Fix the issue in ContainerNotifier where the return result of execWithPwd is not handled correctly Ensure that server operations (shutdown/restart/suspend) are correctly pending until the command execution is completed --- lib/core/extension/ssh_client.dart | 6 +++--- lib/data/provider/container.dart | 17 ++++++++--------- lib/view/page/server/tab/utils.dart | 26 +++++++++++++++----------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/lib/core/extension/ssh_client.dart b/lib/core/extension/ssh_client.dart index 7b721020..43e16ef8 100644 --- a/lib/core/extension/ssh_client.dart +++ b/lib/core/extension/ssh_client.dart @@ -112,7 +112,7 @@ extension SSHClientX on SSHClient { return (session, result.takeBytes().string); } - Future execWithPwd( + Future<(int?, String)> execWithPwd( String script, { String? entry, BuildContext? context, @@ -121,7 +121,7 @@ extension SSHClientX on SSHClient { required String id, }) async { var isRequestingPwd = false; - final (session, _) = await exec( + final (session, output) = await exec( (sess) { sess.stdin.add('$script\n'.uint8List); sess.stdin.close(); @@ -147,7 +147,7 @@ extension SSHClientX on SSHClient { onStdout: onStdout, entry: entry, ); - return session.exitCode; + return (session.exitCode, output); } Future execForOutput( diff --git a/lib/data/provider/container.dart b/lib/data/provider/container.dart index 69a7bc67..99473b5a 100644 --- a/lib/data/provider/container.dart +++ b/lib/data/provider/container.dart @@ -84,15 +84,14 @@ class ContainerNotifier extends _$ContainerNotifier { } final includeStats = Stores.setting.containerParseStat.fetch(); - var raw = ''; final cmd = _wrap(ContainerCmdType.execAll(state.type, sudo: sudo, includeStats: includeStats)); - final code = await client?.execWithPwd( - cmd, - context: context, - onStdout: (data, _) => raw = '$raw$data', - id: hostId, - ); + int? code; + String raw = ''; + if (client != null) { + (code, raw) = await client!.execWithPwd(cmd, context: context, id: hostId); + } + if (!ref.mounted) return; state = state.copyWith(isBusy: false); if (!context.mounted) return; @@ -234,7 +233,7 @@ class ContainerNotifier extends _$ContainerNotifier { state = state.copyWith(runLog: ''); final errs = []; - final code = await client?.execWithPwd( + final (code, _) = await client?.execWithPwd( _wrap((await sudoCompleter.future) ? 'sudo -S $cmd' : cmd), context: context, onStdout: (data, _) { @@ -242,7 +241,7 @@ class ContainerNotifier extends _$ContainerNotifier { }, onStderr: (data, _) => errs.add(data), id: hostId, - ); + ) ?? (null, null); state = state.copyWith(runLog: null); if (code != 0) { diff --git a/lib/view/page/server/tab/utils.dart b/lib/view/page/server/tab/utils.dart index cd4d94ee..5f2a6a79 100644 --- a/lib/view/page/server/tab/utils.dart +++ b/lib/view/page/server/tab/utils.dart @@ -49,7 +49,7 @@ extension _Operation on _ServerPageState { await context.showRoundDialog(title: libL10n.attention, child: Text(l10n.suspendTip)); Stores.setting.showSuspendTip.put(false); } - srv.client?.execWithPwd( + await srv.client?.execWithPwd( ShellFunc.suspend.exec(srv.spi.id, systemType: srv.status.system, customDir: null), context: context, id: srv.id, @@ -62,11 +62,13 @@ extension _Operation on _ServerPageState { void _onTapShutdown(ServerState srv) { _askFor( - func: () => srv.client?.execWithPwd( - ShellFunc.shutdown.exec(srv.spi.id, systemType: srv.status.system, customDir: null), - context: context, - id: srv.id, - ), + func: () async { + await srv.client?.execWithPwd( + ShellFunc.shutdown.exec(srv.spi.id, systemType: srv.status.system, customDir: null), + context: context, + id: srv.id, + ); + }, typ: l10n.shutdown, name: srv.spi.name, ); @@ -74,11 +76,13 @@ extension _Operation on _ServerPageState { void _onTapReboot(ServerState srv) { _askFor( - func: () => srv.client?.execWithPwd( - ShellFunc.reboot.exec(srv.spi.id, systemType: srv.status.system, customDir: null), - context: context, - id: srv.id, - ), + func: () async { + await srv.client?.execWithPwd( + ShellFunc.reboot.exec(srv.spi.id, systemType: srv.status.system, customDir: null), + context: context, + id: srv.id, + ); + }, typ: l10n.reboot, name: srv.spi.name, );