441 lines
13 KiB
Dart
441 lines
13 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import '../about/external/data/Docker.dart';
|
|
import '../about/external/data/Health.dart';
|
|
import '../about/external/data/Kafka.dart';
|
|
import '../about/external/data/Redis.dart';
|
|
import '../about/internal/application/DeploymentRecord.dart';
|
|
import '../about/internal/application/ServerProfile.dart';
|
|
import '../about/internal/application/ServiceConfig.dart';
|
|
import '../about/internal/application/StepTracker.dart';
|
|
import '../about/internal/file/BuildService.dart';
|
|
import '../about/internal/file/ConnectFileStorage.dart';
|
|
import '../comms/Comms.dart';
|
|
import '../comms/ConnectComms.dart';
|
|
import '../memory/ConnectInternalMemory.dart';
|
|
import 'DataManager.dart';
|
|
|
|
/// The single concrete [DataManager], constructed once in `ParentViewModel` and
|
|
/// shared by every screen. It holds no logic — it only forwards each call to
|
|
/// whichever of the three collaborators owns it.
|
|
class AppDataManager implements DataManager {
|
|
final ConnectInternalMemory memory;
|
|
final ConnectComms comms;
|
|
final ConnectFileStorage files;
|
|
|
|
AppDataManager(this.memory, this.comms, this.files);
|
|
|
|
// ── memory ────────────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<List<ServerProfile>> getServers() => memory.getServers();
|
|
|
|
@override
|
|
Future setServers(List<ServerProfile> servers) => memory.setServers(servers);
|
|
|
|
@override
|
|
Future deleteServerSecret(String serverId) =>
|
|
memory.deleteServerSecret(serverId);
|
|
|
|
@override
|
|
Future<List<DeploymentRecord>> getDeployments() => memory.getDeployments();
|
|
|
|
@override
|
|
Future<List<DeploymentRecord>> addDeployment(DeploymentRecord record) =>
|
|
memory.addDeployment(record);
|
|
|
|
@override
|
|
Future clearDeployments() => memory.clearDeployments();
|
|
|
|
@override
|
|
Future<String> getThemeMode() => memory.getThemeMode();
|
|
|
|
@override
|
|
Future setThemeMode(String mode) => memory.setThemeMode(mode);
|
|
|
|
// ── comms: session ────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
bool get isConnected => comms.isConnected;
|
|
|
|
@override
|
|
bool get canRevert => comms.canRevert;
|
|
|
|
@override
|
|
Stream<LogLine> get logs => comms.logs;
|
|
|
|
@override
|
|
Stream<TransferProgress?> get transferProgress => comms.transferProgress;
|
|
|
|
@override
|
|
Stream<List<DeployStep>> get stepStream => comms.stepStream;
|
|
|
|
@override
|
|
Future<void> connect(ServerProfile s) => comms.connect(s);
|
|
|
|
@override
|
|
void requestCancel() => comms.requestCancel();
|
|
|
|
@override
|
|
void disconnect() => comms.disconnect();
|
|
|
|
@override
|
|
void dispose() => comms.dispose();
|
|
|
|
// ── comms: deployment ─────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<DeployResult> deploy({
|
|
required ServerProfile server,
|
|
required ServiceConfig service,
|
|
required Uint8List jarBytes,
|
|
required String jarLabel,
|
|
}) => comms.deploy(
|
|
server: server,
|
|
service: service,
|
|
jarBytes: jarBytes,
|
|
jarLabel: jarLabel,
|
|
);
|
|
|
|
@override
|
|
Future<DeployResult> deployWeb({
|
|
required ServerProfile server,
|
|
required ServiceConfig service,
|
|
required Uint8List archiveBytes,
|
|
required int fileCount,
|
|
}) => comms.deployWeb(
|
|
server: server,
|
|
service: service,
|
|
archiveBytes: archiveBytes,
|
|
fileCount: fileCount,
|
|
);
|
|
|
|
@override
|
|
Future<DeployResult> restartOnly(
|
|
ServerProfile server,
|
|
ServiceConfig service,
|
|
) => comms.restartOnly(server, service);
|
|
|
|
@override
|
|
Future<DeployResult> revert() => comms.revert();
|
|
|
|
@override
|
|
Future<void> discardBackup() => comms.discardBackup();
|
|
|
|
// ── comms: provisioning ───────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<DeployResult> installSystemdUnit({
|
|
required ServerProfile server,
|
|
required String unitName,
|
|
required String unitContent,
|
|
bool enable = true,
|
|
bool startNow = true,
|
|
}) => comms.installSystemdUnit(
|
|
server: server,
|
|
unitName: unitName,
|
|
unitContent: unitContent,
|
|
enable: enable,
|
|
startNow: startNow,
|
|
);
|
|
|
|
@override
|
|
Future<String> detectPackageManager(ServerProfile server) =>
|
|
comms.detectPackageManager(server);
|
|
|
|
@override
|
|
Future<Map<String, String>> probeEnvironment(
|
|
ServerProfile server,
|
|
List<String> detectByKey,
|
|
) => comms.probeEnvironment(server, detectByKey);
|
|
|
|
@override
|
|
Future<DeployResult> installEnvironment({
|
|
required ServerProfile server,
|
|
required String command,
|
|
required List<String> units,
|
|
}) =>
|
|
comms.installEnvironment(server: server, command: command, units: units);
|
|
|
|
@override
|
|
Future<DeployResult> installPackages({
|
|
required ServerProfile server,
|
|
required String command,
|
|
String? enableUnit,
|
|
}) => comms.installPackages(
|
|
server: server,
|
|
command: command,
|
|
enableUnit: enableUnit,
|
|
);
|
|
|
|
// ── comms: service & health ───────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<HealthResult> checkHealth(
|
|
ServerProfile server,
|
|
ServiceConfig service,
|
|
) => comms.checkHealth(server, service);
|
|
|
|
@override
|
|
Future<String> serviceStatus(ServerProfile server, ServiceConfig service) =>
|
|
comms.serviceStatus(server, service);
|
|
|
|
@override
|
|
Future<DeployResult> serviceControl(
|
|
ServerProfile server,
|
|
ServiceConfig service,
|
|
String action,
|
|
) => comms.serviceControl(server, service, action);
|
|
|
|
@override
|
|
Future<List<String>> nginxRoots(ServerProfile server) =>
|
|
comms.nginxRoots(server);
|
|
|
|
// ── comms: logs ───────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<void> fetchLogs(
|
|
ServerProfile server,
|
|
ServiceConfig service, {
|
|
DateTime? since,
|
|
DateTime? until,
|
|
}) => comms.fetchLogs(server, service, since: since, until: until);
|
|
|
|
@override
|
|
Future<void> followLogs(ServerProfile server, ServiceConfig service) =>
|
|
comms.followLogs(server, service);
|
|
|
|
@override
|
|
void stopLogs() => comms.stopLogs();
|
|
|
|
// ── comms: redis ──────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<(bool, String)> redisPing(
|
|
ServerProfile server, {
|
|
String host = '127.0.0.1',
|
|
int port = 6379,
|
|
String pass = '',
|
|
int db = 0,
|
|
}) => comms.redisPing(server, host: host, port: port, pass: pass, db: db);
|
|
|
|
@override
|
|
Future<String> redisConfigPassword(ServerProfile server) =>
|
|
comms.redisConfigPassword(server);
|
|
|
|
@override
|
|
Future<int> redisDbSize(
|
|
ServerProfile server, {
|
|
String host = '127.0.0.1',
|
|
int port = 6379,
|
|
String pass = '',
|
|
int db = 0,
|
|
}) => comms.redisDbSize(server, host: host, port: port, pass: pass, db: db);
|
|
|
|
@override
|
|
Future<(int, Map<int, int>)> redisDatabases(
|
|
ServerProfile server, {
|
|
String host = '127.0.0.1',
|
|
int port = 6379,
|
|
String pass = '',
|
|
}) => comms.redisDatabases(server, host: host, port: port, pass: pass);
|
|
|
|
@override
|
|
Future<List<(String, String)>> redisKeysTyped(
|
|
ServerProfile server, {
|
|
String pattern = '*',
|
|
String filterType = '',
|
|
int limit = 50000,
|
|
String host = '127.0.0.1',
|
|
int port = 6379,
|
|
String pass = '',
|
|
int db = 0,
|
|
}) => comms.redisKeysTyped(
|
|
server,
|
|
pattern: pattern,
|
|
filterType: filterType,
|
|
limit: limit,
|
|
host: host,
|
|
port: port,
|
|
pass: pass,
|
|
db: db,
|
|
);
|
|
|
|
@override
|
|
Future<List<String>> redisKeys(
|
|
ServerProfile server, {
|
|
String pattern = '*',
|
|
int limit = 100000,
|
|
String host = '127.0.0.1',
|
|
int port = 6379,
|
|
String pass = '',
|
|
int db = 0,
|
|
}) => comms.redisKeys(
|
|
server,
|
|
pattern: pattern,
|
|
limit: limit,
|
|
host: host,
|
|
port: port,
|
|
pass: pass,
|
|
db: db,
|
|
);
|
|
|
|
@override
|
|
Future<RedisEntry> redisGet(
|
|
ServerProfile server,
|
|
String key, {
|
|
String host = '127.0.0.1',
|
|
int port = 6379,
|
|
String pass = '',
|
|
int db = 0,
|
|
}) => comms.redisGet(server, key, host: host, port: port, pass: pass, db: db);
|
|
|
|
// ── comms: docker ─────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<DockerStatus> dockerStatus(ServerProfile server) =>
|
|
comms.dockerStatus(server);
|
|
|
|
@override
|
|
Future<List<DockerContainer>> dockerPs(
|
|
ServerProfile server, {
|
|
bool all = true,
|
|
}) => comms.dockerPs(server, all: all);
|
|
|
|
@override
|
|
Future<String> dockerAction(ServerProfile server, String id, String action) =>
|
|
comms.dockerAction(server, id, action);
|
|
|
|
@override
|
|
Future<String> dockerLogs(
|
|
ServerProfile server,
|
|
String id, {
|
|
int tail = 300,
|
|
}) => comms.dockerLogs(server, id, tail: tail);
|
|
|
|
@override
|
|
Future<String> dockerTest(ServerProfile server) => comms.dockerTest(server);
|
|
|
|
@override
|
|
Future<(bool, String)> dockerRun(ServerProfile server, DockerRunSpec spec) =>
|
|
comms.dockerRun(server, spec);
|
|
|
|
// ── comms: kafka ──────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<KafkaStatus> kafkaDetect(ServerProfile server) =>
|
|
comms.kafkaDetect(server);
|
|
|
|
@override
|
|
Future<String> kafkaTest(
|
|
ServerProfile server, {
|
|
required String binDir,
|
|
required String suffix,
|
|
required String bootstrap,
|
|
}) => comms.kafkaTest(
|
|
server,
|
|
binDir: binDir,
|
|
suffix: suffix,
|
|
bootstrap: bootstrap,
|
|
);
|
|
|
|
@override
|
|
Future<List<KafkaTopic>> kafkaTopics(
|
|
ServerProfile server, {
|
|
required String binDir,
|
|
required String suffix,
|
|
required String bootstrap,
|
|
bool includeInternal = false,
|
|
}) => comms.kafkaTopics(
|
|
server,
|
|
binDir: binDir,
|
|
suffix: suffix,
|
|
bootstrap: bootstrap,
|
|
includeInternal: includeInternal,
|
|
);
|
|
|
|
@override
|
|
Future<List<KafkaConsumerGroup>> kafkaGroups(
|
|
ServerProfile server, {
|
|
required String binDir,
|
|
required String suffix,
|
|
required String bootstrap,
|
|
}) => comms.kafkaGroups(
|
|
server,
|
|
binDir: binDir,
|
|
suffix: suffix,
|
|
bootstrap: bootstrap,
|
|
);
|
|
|
|
@override
|
|
Future<KafkaCluster> kafkaCluster(
|
|
ServerProfile server, {
|
|
required String binDir,
|
|
required String suffix,
|
|
required String bootstrap,
|
|
}) => comms.kafkaCluster(
|
|
server,
|
|
binDir: binDir,
|
|
suffix: suffix,
|
|
bootstrap: bootstrap,
|
|
);
|
|
|
|
// ── comms: remote filesystem ──────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<List<RemoteEntry>> listDir(ServerProfile server, String path) =>
|
|
comms.listDir(server, path);
|
|
|
|
@override
|
|
Future<String> resolveHome(ServerProfile server) => comms.resolveHome(server);
|
|
|
|
@override
|
|
Future<void> uploadFile(
|
|
ServerProfile server,
|
|
Uint8List bytes,
|
|
String remotePath,
|
|
) => comms.uploadFile(server, bytes, remotePath);
|
|
|
|
@override
|
|
Future<Uint8List> downloadFile(ServerProfile server, String remotePath) =>
|
|
comms.downloadFile(server, remotePath);
|
|
|
|
@override
|
|
Future<void> deleteRemote(
|
|
ServerProfile server,
|
|
String remotePath,
|
|
bool isDir,
|
|
) => comms.deleteRemote(server, remotePath, isDir);
|
|
|
|
// ── files ─────────────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
bool get buildSupported => files.buildSupported;
|
|
|
|
@override
|
|
Stream<LogLine> get buildLogs => files.buildLogs;
|
|
|
|
@override
|
|
Stream<List<DeployStep>> get buildStepStream => files.buildStepStream;
|
|
|
|
@override
|
|
Future<BuildResult> build(ServiceConfig service) => files.build(service);
|
|
|
|
@override
|
|
Future<BuildResult> buildWeb(ServiceConfig service) =>
|
|
files.buildWeb(service);
|
|
|
|
@override
|
|
void cancelBuild() => files.cancelBuild();
|
|
|
|
@override
|
|
Future<Uint8List> readArtifact(String path) => files.readArtifact(path);
|
|
|
|
@override
|
|
Future<bool> artifactExists(String path) => files.artifactExists(path);
|
|
|
|
@override
|
|
Future<(Uint8List, int)> packageWeb(String directoryPath) =>
|
|
files.packageWeb(directoryPath);
|
|
}
|