Add app source and tests
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2221
lib/Peach/comms/Comms.dart
Normal file
2221
lib/Peach/comms/Comms.dart
Normal file
File diff suppressed because it is too large
Load Diff
223
lib/Peach/comms/ConnectComms.dart
Normal file
223
lib/Peach/comms/ConnectComms.dart
Normal file
@@ -0,0 +1,223 @@
|
||||
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/ServerProfile.dart';
|
||||
import '../about/internal/application/ServiceConfig.dart';
|
||||
import '../about/internal/application/StepTracker.dart';
|
||||
import 'Comms.dart';
|
||||
|
||||
/// The transport contract: everything Peach can ask a remote server to do.
|
||||
/// In the Autoreceptive reference this is the HTTP surface; here the wire is
|
||||
/// SSH, but the role is identical — one abstract description of every remote
|
||||
/// call, implemented by exactly one class ([SshService]) and reached only
|
||||
/// through the [DataManager].
|
||||
abstract class ConnectComms {
|
||||
// ── session ───────────────────────────────────────────────────────────────
|
||||
bool get isConnected;
|
||||
bool get canRevert;
|
||||
Stream<LogLine> get logs;
|
||||
Stream<TransferProgress?> get transferProgress;
|
||||
Stream<List<DeployStep>> get stepStream;
|
||||
|
||||
Future<void> connect(ServerProfile s);
|
||||
void requestCancel();
|
||||
void disconnect();
|
||||
void dispose();
|
||||
|
||||
// ── deployment ────────────────────────────────────────────────────────────
|
||||
Future<DeployResult> deploy({
|
||||
required ServerProfile server,
|
||||
required ServiceConfig service,
|
||||
required Uint8List jarBytes,
|
||||
required String jarLabel,
|
||||
});
|
||||
|
||||
Future<DeployResult> deployWeb({
|
||||
required ServerProfile server,
|
||||
required ServiceConfig service,
|
||||
required Uint8List archiveBytes,
|
||||
required int fileCount,
|
||||
});
|
||||
|
||||
Future<DeployResult> restartOnly(ServerProfile server, ServiceConfig service);
|
||||
|
||||
Future<DeployResult> revert();
|
||||
|
||||
Future<void> discardBackup();
|
||||
|
||||
// ── provisioning ──────────────────────────────────────────────────────────
|
||||
Future<DeployResult> installSystemdUnit({
|
||||
required ServerProfile server,
|
||||
required String unitName,
|
||||
required String unitContent,
|
||||
bool enable = true,
|
||||
bool startNow = true,
|
||||
});
|
||||
|
||||
Future<String> detectPackageManager(ServerProfile server);
|
||||
|
||||
Future<Map<String, String>> probeEnvironment(
|
||||
ServerProfile server,
|
||||
List<String> detectByKey,
|
||||
);
|
||||
|
||||
Future<DeployResult> installEnvironment({
|
||||
required ServerProfile server,
|
||||
required String command,
|
||||
required List<String> units,
|
||||
});
|
||||
|
||||
Future<DeployResult> installPackages({
|
||||
required ServerProfile server,
|
||||
required String command,
|
||||
String? enableUnit,
|
||||
});
|
||||
|
||||
// ── service & health ──────────────────────────────────────────────────────
|
||||
Future<HealthResult> checkHealth(ServerProfile server, ServiceConfig service);
|
||||
|
||||
Future<String> serviceStatus(ServerProfile server, ServiceConfig service);
|
||||
|
||||
Future<DeployResult> serviceControl(
|
||||
ServerProfile server,
|
||||
ServiceConfig service,
|
||||
String action,
|
||||
);
|
||||
|
||||
Future<List<String>> nginxRoots(ServerProfile server);
|
||||
|
||||
// ── logs ──────────────────────────────────────────────────────────────────
|
||||
Future<void> fetchLogs(
|
||||
ServerProfile server,
|
||||
ServiceConfig service, {
|
||||
DateTime? since,
|
||||
DateTime? until,
|
||||
});
|
||||
|
||||
Future<void> followLogs(ServerProfile server, ServiceConfig service);
|
||||
|
||||
void stopLogs();
|
||||
|
||||
// ── redis ─────────────────────────────────────────────────────────────────
|
||||
Future<(bool, String)> redisPing(
|
||||
ServerProfile server, {
|
||||
String host,
|
||||
int port,
|
||||
String pass,
|
||||
int db,
|
||||
});
|
||||
|
||||
Future<String> redisConfigPassword(ServerProfile server);
|
||||
|
||||
Future<int> redisDbSize(
|
||||
ServerProfile server, {
|
||||
String host,
|
||||
int port,
|
||||
String pass,
|
||||
int db,
|
||||
});
|
||||
|
||||
Future<(int, Map<int, int>)> redisDatabases(
|
||||
ServerProfile server, {
|
||||
String host,
|
||||
int port,
|
||||
String pass,
|
||||
});
|
||||
|
||||
Future<List<(String, String)>> redisKeysTyped(
|
||||
ServerProfile server, {
|
||||
String pattern,
|
||||
String filterType,
|
||||
int limit,
|
||||
String host,
|
||||
int port,
|
||||
String pass,
|
||||
int db,
|
||||
});
|
||||
|
||||
Future<List<String>> redisKeys(
|
||||
ServerProfile server, {
|
||||
String pattern,
|
||||
int limit,
|
||||
String host,
|
||||
int port,
|
||||
String pass,
|
||||
int db,
|
||||
});
|
||||
|
||||
Future<RedisEntry> redisGet(
|
||||
ServerProfile server,
|
||||
String key, {
|
||||
String host,
|
||||
int port,
|
||||
String pass,
|
||||
int db,
|
||||
});
|
||||
|
||||
// ── docker ────────────────────────────────────────────────────────────────
|
||||
Future<DockerStatus> dockerStatus(ServerProfile server);
|
||||
|
||||
Future<List<DockerContainer>> dockerPs(ServerProfile server, {bool all});
|
||||
|
||||
Future<String> dockerAction(ServerProfile server, String id, String action);
|
||||
|
||||
Future<String> dockerLogs(ServerProfile server, String id, {int tail});
|
||||
|
||||
Future<String> dockerTest(ServerProfile server);
|
||||
|
||||
Future<(bool, String)> dockerRun(ServerProfile server, DockerRunSpec spec);
|
||||
|
||||
// ── kafka ─────────────────────────────────────────────────────────────────
|
||||
Future<KafkaStatus> kafkaDetect(ServerProfile server);
|
||||
|
||||
Future<String> kafkaTest(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
});
|
||||
|
||||
Future<List<KafkaTopic>> kafkaTopics(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
bool includeInternal,
|
||||
});
|
||||
|
||||
Future<List<KafkaConsumerGroup>> kafkaGroups(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
});
|
||||
|
||||
Future<KafkaCluster> kafkaCluster(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
});
|
||||
|
||||
// ── remote filesystem ─────────────────────────────────────────────────────
|
||||
Future<List<RemoteEntry>> listDir(ServerProfile server, String path);
|
||||
|
||||
Future<String> resolveHome(ServerProfile server);
|
||||
|
||||
Future<void> uploadFile(
|
||||
ServerProfile server,
|
||||
Uint8List bytes,
|
||||
String remotePath,
|
||||
);
|
||||
|
||||
Future<Uint8List> downloadFile(ServerProfile server, String remotePath);
|
||||
|
||||
Future<void> deleteRemote(
|
||||
ServerProfile server,
|
||||
String remotePath,
|
||||
bool isDir,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user