Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/core/extension/ssh_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ extension SSHClientX on SSHClient {
return (session, result.takeBytes().string);
}

Future<int?> execWithPwd(
Future<(int?, String)> execWithPwd(
String script, {
String? entry,
BuildContext? context,
Expand All @@ -121,7 +121,7 @@ extension SSHClientX on SSHClient {
required String id,
}) async {
var isRequestingPwd = false;
final (session, _) = await exec(
final (session, output) = await exec(
(sess) {
sess.stdin.add('$script\n'.uint8List);
sess.stdin.close();
Expand All @@ -147,7 +147,7 @@ extension SSHClientX on SSHClient {
onStdout: onStdout,
entry: entry,
);
return session.exitCode;
return (session.exitCode, output);
}

Future<String> execForOutput(
Expand Down
1 change: 1 addition & 0 deletions lib/data/model/app/error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum ContainerErrType {
parsePs,
parseImages,
parseStats,
podmanDetected,
}

class ContainerErr extends Err<ContainerErrType> {
Expand Down
88 changes: 66 additions & 22 deletions lib/data/provider/container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/core/extension/ssh_client.dart';
import 'package:server_box/data/model/app/error.dart';
import 'package:server_box/data/model/app/scripts/script_consts.dart';
Expand All @@ -18,6 +19,7 @@ part 'container.freezed.dart';
part 'container.g.dart';

final _dockerNotFound = RegExp(r"command not found|Unknown command|Command '\w+' not found");
final _podmanEmulationMsg = 'Emulate Docker CLI using podman';

@freezed
abstract class ContainerState with _$ContainerState {
Expand Down Expand Up @@ -84,21 +86,51 @@ class ContainerNotifier extends _$ContainerNotifier {
}
final includeStats = Stores.setting.containerParseStat.fetch();

var raw = '';
final cmd = _wrap(ContainerCmdType.execAll(state.type, sudo: sudo, includeStats: includeStats));
final code = await client?.execWithPwd(
cmd,
context: context,
onStdout: (data, _) => raw = '$raw$data',
id: hostId,
);
int? code;
String raw = '';
final errs = <String>[];
if (client != null) {
(code, raw) = await client!.execWithPwd(cmd, context: context, id: hostId);
} else {
state = state.copyWith(
isBusy: false,
error: ContainerErr(type: ContainerErrType.noClient),
);
return;
}

if (!ref.mounted) return;
state = state.copyWith(isBusy: false);

if (!context.mounted) return;

/// Code 127 means command not found
if (code == 127 || raw.contains(_dockerNotFound)) {
if (code == 127 || raw.contains(_dockerNotFound) || errs.join().contains(_dockerNotFound)) {
state = state.copyWith(error: ContainerErr(type: ContainerErrType.notInstalled));
return;
}

/// Pre-parse Podman detection
if (raw.contains(_podmanEmulationMsg)) {
state = state.copyWith(
error: ContainerErr(
type: ContainerErrType.podmanDetected,
message: l10n.podmanDockerEmulationDetected,
),
);
return;
}

/// Filter out sudo password prompt from output
if (errs.any((e) => e.contains('[sudo] password'))) {
raw = raw.split('\n').where((line) => !line.contains('[sudo] password')).join('\n');
}

/// Detect Podman not installed when using Podman mode
if (state.type == ContainerType.podman &&
(errs.any((e) => e.contains('podman: not found')) ||
raw.contains('podman: not found'))) {
state = state.copyWith(error: ContainerErr(type: ContainerErrType.notInstalled));
return;
}
Expand All @@ -122,9 +154,11 @@ class ContainerNotifier extends _$ContainerNotifier {
final version = json.decode(verRaw)['Client']['Version'];
state = state.copyWith(version: version, error: null);
} catch (e, trace) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.invalidVersion, message: '$e'),
);
if (state.error == null) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.invalidVersion, message: '$e'),
);
}
Loggers.app.warning('Container version failed', e, trace);
}

Expand All @@ -140,9 +174,11 @@ class ContainerNotifier extends _$ContainerNotifier {
final items = lines.map((e) => ContainerPs.fromRaw(e, state.type)).toList();
state = state.copyWith(items: items);
} catch (e, trace) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.parsePs, message: '$e'),
);
if (state.error == null) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.parsePs, message: '$e'),
);
}
Loggers.app.warning('Container ps failed', e, trace);
}

Expand All @@ -162,9 +198,11 @@ class ContainerNotifier extends _$ContainerNotifier {
}
state = state.copyWith(images: images);
} catch (e, trace) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.parseImages, message: '$e'),
);
if (state.error == null) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.parseImages, message: '$e'),
);
}
Loggers.app.warning('Container images failed', e, trace);
}

Expand All @@ -189,9 +227,11 @@ class ContainerNotifier extends _$ContainerNotifier {
item.parseStats(statsLine, state.version);
}
} catch (e, trace) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.parseStats, message: '$e'),
);
if (state.error == null) {
state = state.copyWith(
error: ContainerErr(type: ContainerErrType.parseStats, message: '$e'),
);
}
Loggers.app.warning('Parse docker stats: $statsRaw', e, trace);
}
}
Expand Down Expand Up @@ -227,22 +267,26 @@ class ContainerNotifier extends _$ContainerNotifier {
}

Future<ContainerErr?> run(String cmd, {bool autoRefresh = true}) async {
if (client == null) {
return ContainerErr(type: ContainerErrType.noClient);
}

cmd = switch (state.type) {
ContainerType.docker => 'docker $cmd',
ContainerType.podman => 'podman $cmd',
};

state = state.copyWith(runLog: '');
final errs = <String>[];
final code = await client?.execWithPwd(
final (code, _) = await client?.execWithPwd(
_wrap((await sudoCompleter.future) ? 'sudo -S $cmd' : cmd),
context: context,
onStdout: (data, _) {
state = state.copyWith(runLog: '${state.runLog}$data');
},
onStderr: (data, _) => errs.add(data),
id: hostId,
);
) ?? (null, null);
state = state.copyWith(runLog: null);

if (code != 0) {
Expand Down
6 changes: 6 additions & 0 deletions lib/generated/l10n/l10n.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1933,6 +1933,12 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Logs'**
String get logs;

/// No description provided for @podmanDockerEmulationDetected.
///
/// In en, this message translates to:
/// **'Podman Docker emulation detected. Please switch to Podman in settings.'**
String get podmanDockerEmulationDetected;
}

class _AppLocalizationsDelegate
Expand Down
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1031,4 +1031,8 @@ class AppLocalizationsDe extends AppLocalizations {

@override
String get logs => 'Protokolle';

@override
String get podmanDockerEmulationDetected =>
'Podman Docker-Emulation erkannt. Bitte wechseln Sie in den Einstellungen zu Podman.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1022,4 +1022,8 @@ class AppLocalizationsEn extends AppLocalizations {

@override
String get logs => 'Logs';

@override
String get podmanDockerEmulationDetected =>
'Podman Docker emulation detected. Please switch to Podman in settings.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_es.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1033,4 +1033,8 @@ class AppLocalizationsEs extends AppLocalizations {

@override
String get logs => 'Registros';

@override
String get podmanDockerEmulationDetected =>
'Detectada emulación de Podman Docker. Por favor, cambie a Podman en la configuración.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_fr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1036,4 +1036,8 @@ class AppLocalizationsFr extends AppLocalizations {

@override
String get logs => 'Journaux';

@override
String get podmanDockerEmulationDetected =>
'Émulation Podman Docker détectée. Veuillez passer à Podman dans les paramètres.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_id.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1022,4 +1022,8 @@ class AppLocalizationsId extends AppLocalizations {

@override
String get logs => 'Log';

@override
String get podmanDockerEmulationDetected =>
'Emulasi Podman Docker terdeteksi. Silakan beralih ke Podman di pengaturan.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_ja.dart
Original file line number Diff line number Diff line change
Expand Up @@ -992,4 +992,8 @@ class AppLocalizationsJa extends AppLocalizations {

@override
String get logs => 'ログ';

@override
String get podmanDockerEmulationDetected =>
'Podman Docker エミュレーションが検出されました。設定で Podman に切り替えてください。';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_nl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1029,4 +1029,8 @@ class AppLocalizationsNl extends AppLocalizations {

@override
String get logs => 'Logboeken';

@override
String get podmanDockerEmulationDetected =>
'Podman Docker-emulatie gedetecteerd. Schakel over naar Podman in de instellingen.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_pt.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1024,4 +1024,8 @@ class AppLocalizationsPt extends AppLocalizations {

@override
String get logs => 'Logs';

@override
String get podmanDockerEmulationDetected =>
'Emulação Podman Docker detectada. Por favor, alterne para Podman nas configurações.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_ru.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1028,4 +1028,8 @@ class AppLocalizationsRu extends AppLocalizations {

@override
String get logs => 'Журналы';

@override
String get podmanDockerEmulationDetected =>
'Обнаружена эмуляция Podman Docker. Пожалуйста, переключитесь на Podman в настройках.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_tr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1023,4 +1023,8 @@ class AppLocalizationsTr extends AppLocalizations {

@override
String get logs => 'Günlükler';

@override
String get podmanDockerEmulationDetected =>
'Podman Docker emülasyonu tespit edildi. Lütfen ayarlarda Podman\'a geçin.';
}
4 changes: 4 additions & 0 deletions lib/generated/l10n/l10n_uk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1028,4 +1028,8 @@ class AppLocalizationsUk extends AppLocalizations {

@override
String get logs => 'Журнали';

@override
String get podmanDockerEmulationDetected =>
'Виявлено емуляцію Podman Docker. Будь ласка, переключіться на Podman у налаштуваннях.';
}
8 changes: 8 additions & 0 deletions lib/generated/l10n/l10n_zh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,10 @@ class AppLocalizationsZh extends AppLocalizations {

@override
String get logs => '日志';

@override
String get podmanDockerEmulationDetected =>
'检测到 Podman Docker 仿真。请在设置中切换到 Podman。';
}

/// The translations for Chinese, as used in Taiwan (`zh_TW`).
Expand Down Expand Up @@ -1931,4 +1935,8 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {

@override
String get logs => '日誌';

@override
String get podmanDockerEmulationDetected =>
'檢測到 Podman Docker 仿真。請在設定中切換到 Podman。';
}
3 changes: 2 additions & 1 deletion lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "Schreiben",
"writeScriptFailTip": "Das Schreiben des Skripts ist fehlgeschlagen, möglicherweise aufgrund fehlender Berechtigungen oder das Verzeichnis existiert nicht.",
"writeScriptTip": "Nach der Verbindung mit dem Server wird ein Skript in `~/.config/server_box` \n | `/tmp/server_box` geschrieben, um den Systemstatus zu überwachen. Sie können den Skriptinhalt überprüfen.",
"logs": "Protokolle"
"logs": "Protokolle",
"podmanDockerEmulationDetected": "Podman Docker-Emulation erkannt. Bitte wechseln Sie in den Einstellungen zu Podman."
}
3 changes: 2 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -304,5 +304,6 @@
"menuGitHubRepository": "GitHub Repository",
"menuWiki": "Wiki",
"menuHelp": "Help",
"logs": "Logs"
"logs": "Logs",
"podmanDockerEmulationDetected": "Podman Docker emulation detected. Please switch to Podman in settings."
}
3 changes: 2 additions & 1 deletion lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "Escribir",
"writeScriptFailTip": "La escritura en el script falló, posiblemente por falta de permisos o porque el directorio no existe.",
"writeScriptTip": "Después de conectarse al servidor, se escribirá un script en `~/.config/server_box` \n | `/tmp/server_box` para monitorear el estado del sistema. Puedes revisar el contenido del script.",
"logs": "Registros"
"logs": "Registros",
"podmanDockerEmulationDetected": "Detectada emulación de Podman Docker. Por favor, cambie a Podman en la configuración."
}
3 changes: 2 additions & 1 deletion lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "Écrire",
"writeScriptFailTip": "Échec de l'écriture dans le script, probablement en raison d'un manque de permissions ou que le répertoire n'existe pas.",
"writeScriptTip": "Après la connexion au serveur, un script sera écrit dans `~/.config/server_box` \n | `/tmp/server_box` pour surveiller l'état du système. Vous pouvez examiner le contenu du script.",
"logs": "Journaux"
"logs": "Journaux",
"podmanDockerEmulationDetected": "Émulation Podman Docker détectée. Veuillez passer à Podman dans les paramètres."
}
3 changes: 2 additions & 1 deletion lib/l10n/app_id.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "Tulis",
"writeScriptFailTip": "Penulisan ke skrip gagal, mungkin karena tidak ada izin atau direktori tidak ada.",
"writeScriptTip": "Setelah terhubung ke server, sebuah skrip akan ditulis ke `~/.config/server_box` \n | `/tmp/server_box` untuk memantau status sistem. Anda dapat meninjau konten skrip tersebut.",
"logs": "Log"
"logs": "Log",
"podmanDockerEmulationDetected": "Emulasi Podman Docker terdeteksi. Silakan beralih ke Podman di pengaturan."
}
3 changes: 2 additions & 1 deletion lib/l10n/app_ja.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "書き込み",
"writeScriptFailTip": "スクリプトの書き込みに失敗しました。権限がないかディレクトリが存在しない可能性があります。",
"writeScriptTip": "サーバーへの接続後、システムステータスを監視するスクリプトが `~/.config/server_box` \n | `/tmp/server_box` に書き込まれます。スクリプトの内容を確認できます。",
"logs": "ログ"
"logs": "ログ",
"podmanDockerEmulationDetected": "Podman Docker エミュレーションが検出されました。設定で Podman に切り替えてください。"
}
3 changes: 2 additions & 1 deletion lib/l10n/app_nl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "Schrijven",
"writeScriptFailTip": "Het schrijven naar het script is mislukt, mogelijk door gebrek aan rechten of omdat de map niet bestaat.",
"writeScriptTip": "Na het verbinden met de server wordt een script geschreven naar `~/.config/server_box` \n | `/tmp/server_box` om de systeemstatus te monitoren. U kunt de inhoud van het script controleren.",
"logs": "Logboeken"
"logs": "Logboeken",
"podmanDockerEmulationDetected": "Podman Docker-emulatie gedetecteerd. Schakel over naar Podman in de instellingen."
}
3 changes: 2 additions & 1 deletion lib/l10n/app_pt.arb
Original file line number Diff line number Diff line change
Expand Up @@ -294,5 +294,6 @@
"write": "Escrita",
"writeScriptFailTip": "Falha ao escrever no script, possivelmente devido à falta de permissões ou o diretório não existe.",
"writeScriptTip": "Após conectar ao servidor, um script será escrito em `~/.config/server_box` \n | `/tmp/server_box` para monitorar o status do sistema. Você pode revisar o conteúdo do script.",
"logs": "Logs"
"logs": "Logs",
"podmanDockerEmulationDetected": "Emulação Podman Docker detectada. Por favor, alterne para Podman nas configurações."
}
Loading