fix & opt

- apt/yum if not root, auto try saved pwd
- ServerPrivateInfo.authorization: Object => String pwd
- fix apt parse: caused by irrelevant output
- serverprovider replace _servers[idx] with s
This commit is contained in:
Junyuan Feng
2022-05-24 12:44:12 +08:00
parent f60b09abe4
commit cb5aed8e79
12 changed files with 79 additions and 70 deletions

View File

@@ -11,7 +11,7 @@ import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
import 'package:toolbox/data/model/distribution.dart';
typedef PwdRequestFunc = Future<String> Function(
bool lastTimes, String? userName);
int triedTimes, String? userName);
final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
class AptProvider extends BusyProvider {
@@ -87,7 +87,12 @@ class AptProvider extends BusyProvider {
list = list.sublist(0, endLine);
break;
default:
list = list.sublist(4);
// avoid other outputs
// such as: [Could not chdir to home directory /home/test: No such file or directory, , WARNING: apt does not have a stable CLI interface. Use with caution in scripts., , Listing...]
final idx = list.indexWhere((element) => element.contains('[upgradable from:'));
if (idx != -1) {
list = list.sublist(idx);
}
list.removeWhere((element) => element.isEmpty);
}
upgradeable = list.map((e) => UpgradePkgInfo(e, dist!)).toList();
@@ -153,8 +158,8 @@ class AptProvider extends BusyProvider {
final user = pwdRequestWithUserReg.firstMatch(event)?.group(1);
logger.info('sudo password request for $user');
triedTimes++;
final pwd = await (onPasswordRequest ?? (_, __) async => '')(
triedTimes == 3, user);
final pwd =
await (onPasswordRequest ?? (_, __) async => '')(triedTimes, user);
if (pwd.isEmpty) {
logger.info('sudo password request cancelled');
return;

View File

@@ -43,6 +43,7 @@ const shellCmd = "export LANG=en_US.utf-8 \necho '$seperator' \n"
const shellPath = '.serverbox.sh';
const memPrefix = 'Mem:';
final cpuTempReg = RegExp('(x86_pkg_temp|cpu_thermal)');
final numReg = RegExp(r'\s{1,}');
class ServerProvider extends BusyProvider {
List<ServerInfo> _servers = [];
@@ -91,8 +92,7 @@ class ServerProvider extends BusyProvider {
final socket = await SSHSocket.connect(spi.ip, spi.port);
if (spi.pubKeyId == null) {
return SSHClient(socket,
username: spi.user,
onPasswordRequest: () => spi.authorization as String);
username: spi.user, onPasswordRequest: () => spi.pwd);
}
final key = locator<PrivateKeyStore>().get(spi.pubKeyId!);
return SSHClient(socket,
@@ -163,25 +163,23 @@ class ServerProvider extends BusyProvider {
}
Future<void> _getData(ServerPrivateInfo spi) async {
final idx = _servers.indexWhere((element) => element.info == spi);
final state = _servers[idx].connectionState;
final s = _servers.firstWhere((element) => element.info == spi);
final state = s.connectionState;
if (state == ServerConnectionState.failed ||
state == ServerConnectionState.disconnected) {
_servers[idx].connectionState = ServerConnectionState.connecting;
s.connectionState = ServerConnectionState.connecting;
notifyListeners();
final time1 = DateTime.now();
try {
_servers[idx].client = await genClient(spi);
s.client = await genClient(spi);
final time2 = DateTime.now();
logger.info(
'Connected to [${spi.name}] in [${time2.difference(time1).toString()}].');
_servers[idx].connectionState = ServerConnectionState.connected;
_servers[idx]
.client!
.run("echo '$shellCmd' > $shellPath && chmod +x $shellPath");
s.connectionState = ServerConnectionState.connected;
s.client!.run("echo '$shellCmd' > $shellPath && chmod +x $shellPath");
} catch (e) {
_servers[idx].connectionState = ServerConnectionState.failed;
_servers[idx].status.failedInfo = '$e ## ';
s.connectionState = ServerConnectionState.failed;
s.status.failedInfo = '$e ## ';
logger.warning(e);
} finally {
notifyListeners();
@@ -189,12 +187,11 @@ class ServerProvider extends BusyProvider {
}
// if client is null, return
final si = _servers[idx];
if (si.client == null) return;
final raw = await si.client!.run("sh $shellPath").string;
if (s.client == null) return;
final raw = await s.client!.run("sh $shellPath").string;
if (raw.isEmpty) {
_servers[idx].connectionState = ServerConnectionState.failed;
_servers[idx].status.failedInfo = 'Empty output';
s.connectionState = ServerConnectionState.failed;
s.status.failedInfo = 'Empty output';
notifyListeners();
return;
}
@@ -210,8 +207,8 @@ class ServerProvider extends BusyProvider {
_getTcp(spi, lines[4]);
_getNetSpeed(spi, lines[0]);
} catch (e) {
_servers[idx].connectionState = ServerConnectionState.failed;
servers[idx].status.failedInfo = e.toString();
s.connectionState = ServerConnectionState.failed;
s.status.failedInfo = e.toString();
logger.warning(e);
rethrow;
} finally {
@@ -307,7 +304,7 @@ class ServerProvider extends BusyProvider {
final idx = lines.lastWhere((element) => element.startsWith('Tcp:'),
orElse: () => '');
if (idx != '') {
final vals = idx.split(RegExp(r'\s{1,}'));
final vals = idx.split(numReg);
info.status.tcp = TcpStatus(vals[5].i, vals[6].i, vals[7].i, vals[8].i);
}
}
@@ -320,7 +317,7 @@ class ServerProvider extends BusyProvider {
if (items.indexOf(item) == 0 || item.isEmpty) {
continue;
}
final vals = item.split(RegExp(r'\s{1,}'));
final vals = item.split(numReg);
list.add(DiskInfo(vals[0], vals[5],
int.parse(vals[4].replaceFirst('%', '')), vals[2], vals[1], vals[3]));
}