refactor: SSHClientX.exec

This commit is contained in:
lollipopkit🏳️‍⚧️
2024-08-15 11:27:22 +08:00
parent 267b0b0a69
commit 195ddd2bcc
16 changed files with 155 additions and 221 deletions

View File

@@ -31,8 +31,8 @@ class ServerPrivateInfo {
final List<String>? tags;
@HiveField(7)
final String? alterUrl;
@HiveField(8)
final bool? autoConnect;
@HiveField(8, defaultValue: true)
final bool autoConnect;
/// [id] of the jump server
@HiveField(9)
@@ -59,7 +59,7 @@ class ServerPrivateInfo {
this.keyId,
this.tags,
this.alterUrl,
this.autoConnect,
this.autoConnect = true,
this.jumpId,
this.custom,
this.wolCfg,
@@ -75,7 +75,7 @@ class ServerPrivateInfo {
final keyId = json['pubKeyId'] as String?;
final tags = (json['tags'] as List?)?.cast<String>();
final alterUrl = json['alterUrl'] as String?;
final autoConnect = json['autoConnect'] as bool?;
final autoConnect = json['autoConnect'] as bool? ?? true;
final jumpId = json['jumpId'] as String?;
final custom = json['customCmd'] == null
? null
@@ -128,9 +128,7 @@ class ServerPrivateInfo {
if (alterUrl != null) {
data['alterUrl'] = alterUrl;
}
if (autoConnect != null) {
data['autoConnect'] = autoConnect;
}
data['autoConnect'] = autoConnect;
if (jumpId != null) {
data['jumpId'] = jumpId;
}
@@ -160,7 +158,7 @@ class ServerPrivateInfo {
custom?.cmds != old.custom?.cmds;
}
IpPort fromStringUrl() {
(String, int) fromStringUrl() {
if (alterUrl == null) {
throw SSHErr(type: SSHErrType.connect, message: 'alterUrl is null');
}
@@ -177,7 +175,7 @@ class ServerPrivateInfo {
if (port <= 0 || port > 65535) {
throw SSHErr(type: SSHErrType.connect, message: 'alterUrl port error');
}
return IpPort(ip_, port_);
return (ip_, port_);
}
@override
@@ -206,11 +204,6 @@ class ServerPrivateInfo {
logoUrl: 'https://example.com/logo.png',
),
);
}
class IpPort {
final String ip;
final int port;
IpPort(this.ip, this.port);
bool get isRoot => user == 'root';
}

View File

@@ -25,7 +25,7 @@ class ServerPrivateInfoAdapter extends TypeAdapter<ServerPrivateInfo> {
keyId: fields[5] as String?,
tags: (fields[6] as List?)?.cast<String>(),
alterUrl: fields[7] as String?,
autoConnect: fields[8] as bool?,
autoConnect: fields[8] == null ? true : fields[8] as bool,
jumpId: fields[9] as String?,
custom: fields[10] as ServerCustom?,
wolCfg: fields[11] as WakeOnLanCfg?,

View File

@@ -34,7 +34,7 @@ class ServerProvider extends ChangeNotifier {
final _manualDisconnectedIds = <String>{};
Future<void> load() async {
// Issue #147
// #147
// Clear all servers because of restarting app will cause duplicate servers
final oldServers = Map<String, Server>.from(_servers);
_servers.clear();
@@ -46,7 +46,7 @@ class ServerProvider extends ChangeNotifier {
final originServer = oldServers[spi.id];
final newServer = genServer(spi);
/// Issues #258
/// #258
/// If not [shouldReconnect], then keep the old state.
if (originServer != null && !originServer.spi.shouldReconnect(spi)) {
newServer.conn = originServer.conn;
@@ -112,20 +112,20 @@ class ServerProvider extends ChangeNotifier {
return;
}
await Future.wait(_servers.values.map((s) => _connectFn(s, onlyFailed)));
}
await Future.wait(_servers.values.map((s) async {
if (onlyFailed) {
if (s.conn != ServerConn.failed) return;
TryLimiter.reset(s.spi.id);
}
Future<void> _connectFn(Server s, bool onlyFailed) async {
if (onlyFailed) {
if (s.conn != ServerConn.failed) return;
TryLimiter.reset(s.spi.id);
}
if (_manualDisconnectedIds.contains(s.spi.id)) return;
if (!(s.spi.autoConnect ?? true) && s.conn == ServerConn.disconnected ||
_manualDisconnectedIds.contains(s.spi.id)) {
return;
}
return await _getData(s.spi);
if (s.conn == ServerConn.disconnected && !s.spi.autoConnect) {
return;
}
return await _getData(s.spi);
}));
}
Future<void> startAutoRefresh() async {
@@ -301,16 +301,16 @@ class ServerProvider extends ChangeNotifier {
final scriptRaw = ShellFunc.allScript(spi.custom?.cmds).uint8List;
try {
final writeScriptResult = await s.client!.runForOutput(
ShellFunc.getInstallShellCmd(spi.id),
action: (session) async {
final (_, writeScriptResult) = await s.client!.exec(
(session) async {
session.stdin.add(scriptRaw);
session.stdin.close();
},
entry: ShellFunc.getInstallShellCmd(spi.id),
);
if (writeScriptResult.isNotEmpty) {
ShellFunc.switchScriptDir(spi.id);
throw String.fromCharCodes(writeScriptResult);
throw writeScriptResult;
}
} on SSHAuthAbortError catch (e) {
TryLimiter.inc(sid);

View File

@@ -8,28 +8,27 @@ import 'package:server_box/data/res/provider.dart';
final class SystemdProvider {
late final SSHClient _client;
late final bool isRoot;
SystemdProvider.init(ServerPrivateInfo spi) {
isRoot = spi.isRoot;
_client = Pros.server.pick(spi: spi)!.client!;
getUnits();
}
final isBusy = false.vn;
final isRoot = false.vn;
final units = <SystemdUnit>[].vn;
Future<void> getUnits() async {
isBusy.value = true;
try {
final result = await _client.runScriptIn(_getUnitsCmd);
final result = await _client.execForOutput(_getUnitsCmd);
final units = result.split('\n');
final isRootRaw = units.firstOrNull;
isRoot.value = isRootRaw == '0';
final userUnits = <String>[];
final systemUnits = <String>[];
for (final unit in units.skip(1)) {
for (final unit in units) {
if (unit.startsWith('/etc/systemd/system')) {
systemUnits.add(unit);
} else if (unit.startsWith('~/.config/systemd/user')) {
@@ -64,7 +63,7 @@ for unit in ${unitNames_.join(' ')}; do
echo -n "${ShellFunc.seperator}\n\$state"
done
''';
final result = await _client.runScriptIn(script);
final result = await _client.execForOutput(script);
final units = result.split(ShellFunc.seperator);
final parsedUnits = <SystemdUnit>[];
@@ -124,17 +123,8 @@ done
});
return parsedUnits;
}
}
String _getIniVal(String line) {
return line.split('=').last;
}
const _getUnitsCmd = '''
# If root, get system & user units, otherwise get user units
uid=\$(id -u)
echo \$uid
late final _getUnitsCmd = '''
get_files() {
unit_type=\$1
base_dir=\$2
@@ -149,14 +139,12 @@ get_files() {
get_type_files() {
unit_type=\$1
base_dir=""
if [ "\$uid" -eq 0 ]; then
get_files \$unit_type /etc/systemd/system
get_files \$unit_type ~/.config/systemd/user
else
get_files \$unit_type ~/.config/systemd/user
fi
${isRoot ? """
get_files \$unit_type /etc/systemd/system
get_files \$unit_type ~/.config/systemd/user""" : """
get_files \$unit_type ~/.config/systemd/user"""}
}
types="service socket mount timer"
@@ -165,3 +153,8 @@ for type in \$types; do
get_type_files \$type
done
''';
}
String _getIniVal(String line) {
return line.split('=').last;
}

View File

@@ -1,7 +1,8 @@
// This file is generated by fl_build. Do not edit.
// ignore_for_file: prefer_single_quotes
class BuildData {
static const String name = 'ServerBox';
static const int build = 1058;
static const int script = 56;
static const String name = "ServerBox";
static const int build = 1060;
static const int script = 57;
}