Support APT/Docker

This commit is contained in:
Junyuan Feng
2022-03-10 15:25:14 +08:00
parent e6e08dc407
commit f0081e0587
10 changed files with 143 additions and 93 deletions

View File

@@ -1,6 +1,5 @@
import 'dart:convert';
import 'package:dartssh2/dartssh2.dart';
import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/core/provider_base.dart';
import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
import 'package:toolbox/data/model/distribution.dart';
@@ -8,41 +7,68 @@ import 'package:toolbox/data/model/distribution.dart';
class AptProvider extends BusyProvider {
SSHClient? client;
Distribution? dist;
String? whoami;
List<AptUpgradePkgInfo>? upgradeable;
String? error;
String? updateLog;
AptProvider();
void init(SSHClient client, Distribution dist) {
Future<void> init(SSHClient client, Distribution dist) async {
this.client = client;
this.dist = dist;
whoami = (await client.run('whoami').string).trim();
}
bool get isSU => whoami == 'root';
void clear() {
client = null;
dist = null;
upgradeable = null;
}
bool get isReady {
return upgradeable != null && !isBusy;
error = null;
updateLog = null;
whoami = null;
}
Future<void> refreshInstalled() async {
if (client == null) {
error = 'No client';
return;
}
await update();
final result = utf8.decode(await client!.run('apt list --upgradeable'));
final list = result.split('\n').sublist(4);
list.removeWhere((element) => element.isEmpty);
upgradeable = list.map((e) => AptUpgradePkgInfo(e, dist!)).toList();
notifyListeners();
final result = await client!.run('apt list --upgradeable').string;
try {
final list = result.split('\n').sublist(4);
list.removeWhere((element) => element.isEmpty);
upgradeable = list.map((e) => AptUpgradePkgInfo(e, dist!)).toList();
} catch (e) {
error = e.toString();
} finally {
notifyListeners();
}
}
Future<void> update() async {
if (client == null) {
error = 'No client';
return;
}
await client!.run('apt update');
}
// Future<void> upgrade() async {
// setBusyState();
// await client!.run('apt upgrade -y');
// refreshInstalled();
// }
Future<void> upgrade() async {
if (client == null) {
error = 'No client';
return;
}
updateLog = null;
final session = await client!.execute('apt upgrade -y');
session.stdout.listen((data) {
updateLog = (updateLog ?? '') + data.string;
notifyListeners();
});
refreshInstalled();
}
}

View File

@@ -33,8 +33,12 @@ class DockerProvider extends BusyProvider {
error = 'invalid version';
notifyListeners();
} else {
version = verSplit[1].split(' ').last;
edition = verSplit[0].split(': ')[1];
try {
version = verSplit[1].split(' ').last;
edition = verSplit[0].split(': ')[1];
} catch (e) {
error = e.toString();
}
}
final raw = await client!.run('docker ps -a').string;
@@ -43,11 +47,17 @@ class DockerProvider extends BusyProvider {
notifyListeners();
return;
}
final lines = raw.split('\n');
lines.removeAt(0);
lines.removeWhere((element) => element.isEmpty);
running = lines.map((e) => DockerPsItem.fromRawString(e)).toList();
notifyListeners();
try {
final lines = raw.split('\n');
lines.removeAt(0);
lines.removeWhere((element) => element.isEmpty);
running = lines.map((e) => DockerPsItem.fromRawString(e)).toList();
} catch (e) {
error = e.toString();
} finally {
notifyListeners();
}
}
Future<bool> stop(String id) async {

View File

@@ -1,10 +1,10 @@
import 'dart:async';
import 'dart:convert';
import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/core/provider_base.dart';
import 'package:toolbox/data/model/server/cpu_2_status.dart';
import 'package:toolbox/data/model/server/cpu_status.dart';
@@ -178,8 +178,10 @@ class ServerProvider extends BusyProvider {
final si = _servers[idx];
try {
if (si.client == null) return;
final raw = utf8.decode(await si.client!.run(
r"cat /proc/net/dev && date +%s && echo 'A====A' && cat /etc/os-release | grep PRETTY_NAME && echo 'A====A' && cat /proc/stat | grep cpu && echo 'A====A' && paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp) | column -s $'\t' -t | sed 's/\(.\)..$/.\1°C/' && echo 'A====A' && uptime && echo 'A====A' && cat /proc/net/snmp && echo 'A====A' && df -h && echo 'A====A' && free -m"));
final raw = await si.client!
.run(
r"cat /proc/net/dev && date +%s && echo 'A====A' && cat /etc/os-release | grep PRETTY_NAME && echo 'A====A' && cat /proc/stat | grep cpu && echo 'A====A' && paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp) | column -s $'\t' -t | sed 's/\(.\)..$/.\1°C/' && echo 'A====A' && uptime && echo 'A====A' && cat /proc/net/snmp && echo 'A====A' && df -h && echo 'A====A' && free -m")
.string;
final lines = raw.split('A====A').map((e) => e.trim()).toList();
_getCPU(spi, lines[2], lines[3]);
_getMem(spi, lines[7]);
@@ -321,10 +323,10 @@ class ServerProvider extends BusyProvider {
}
Future<String?> runSnippet(ServerPrivateInfo spi, Snippet snippet) async {
final result = await _servers
return await _servers
.firstWhere((element) => element.info == spi)
.client!
.run(snippet.script);
return utf8.decode(result);
.run(snippet.script)
.string;
}
}

View File

@@ -2,9 +2,9 @@
class BuildData {
static const String name = "ServerBox";
static const int build = 106;
static const int build = 107;
static const String engine =
"Flutter 2.10.3 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 7e9793dee1 (6 days ago) • 2022-03-02 11:23:12 -0600\nEngine • revision bd539267b4\nTools • Dart 2.16.1 • DevTools 2.9.2\n";
static const String buildAt = "2022-03-08 18:06:40.014600";
static const int modifications = 8;
"Flutter 2.10.3 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 7e9793dee1 (8 days ago) • 2022-03-02 11:23:12 -0600\nEngine • revision bd539267b4\nTools • Dart 2.16.1 • DevTools 2.9.2\n";
static const String buildAt = "2022-03-10 13:25:24.362670";
static const int modifications = 11;
}