diff --git a/README.md b/README.md index 5ae2e2b..35d54aa 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,7 @@ dotnet run --project src/Sms.TaskTwo.Avalonia/Sms.TaskTwo.Avalonia.csproj ### Linux - Запись в `~/.config/environment.d/` (systemd `KEY=value`). -- **Применить к сессии** (`ReloadEnvironment`): текущий процесс, `systemctl --user set-environment`, при наличии — `dbus-update-environment`. -- Новые login-сессии могут потребовать перелогин — ограничение systemd. +- **Применить к сессии** не поддерживается: переменные подхватываются после перезапуска login-сессии. ## Предположения (ТЗ) diff --git a/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs b/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs index cbd4fd2..cbfd938 100644 --- a/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs +++ b/src/Sms.Environment.Linux/LinuxEnvironmentVariableStore.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using Sms.Environment; namespace Sms.Environment.Linux; @@ -6,7 +5,6 @@ namespace Sms.Environment.Linux; public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore { private const string ManagedFileName = "99-sms-task-two.conf"; - private const int SystemctlBatchSize = 32; private readonly string _managedFilePath; private readonly string _environmentDirectory; @@ -121,7 +119,6 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore } System.Environment.SetEnvironmentVariable(name, null); - TryRunSystemctl(["--user", "unset-environment", name], out _); } catch (Exception ex) when (ex is UnauthorizedAccessException or IOException) { @@ -131,141 +128,14 @@ public sealed class LinuxEnvironmentVariableStore : IEnvironmentVariableStore } } - public EnvironmentReloadResult ReloadEnvironment() - { - var variables = GetUserPersistedEnvironment(); - ApplyToCurrentProcess(variables); - - if (variables.Count == 0) + public EnvironmentReloadResult ReloadEnvironment() => + new() { - return new EnvironmentReloadResult - { - Success = true, - Message = "Пользовательских переменных для применения нет.", - }; - } - - var messages = new List(); - if (TryApplyViaSystemctl(variables, out var systemctlError)) - { - messages.Add("systemd user manager обновлён (systemctl --user set-environment)."); - } - else if (systemctlError is not null) - { - messages.Add($"systemctl: {systemctlError}"); - } - - if (TryApplyViaDbusUpdateEnvironment(variables, out var dbusError)) - { - messages.Add("D-Bus session обновлён (dbus-update-environment)."); - } - else if (dbusError is not null) - { - messages.Add($"dbus-update-environment: {dbusError}"); - } - - var processApplied = messages.Count > 0 || variables.Count > 0; - return new EnvironmentReloadResult - { - Success = processApplied, - Message = processApplied - ? $"Применено {variables.Count} переменных к текущему процессу. {string.Join(' ', messages)}" - : "Не удалось применить переменные к сессии.", + Success = false, + Message = + "Применение переменных к сессии в Linux не поддерживается. " + + "Значения сохраняются в ~/.config/environment.d/ и подхватываются после перезапуска login-сессии.", }; - } - - private static void ApplyToCurrentProcess(IReadOnlyDictionary variables) - { - foreach (var pair in variables) - { - System.Environment.SetEnvironmentVariable(pair.Key, pair.Value); - } - } - - private static bool TryApplyViaSystemctl( - IReadOnlyDictionary variables, - out string? errorMessage) - { - errorMessage = null; - var pairs = variables.ToList(); - for (var offset = 0; offset < pairs.Count; offset += SystemctlBatchSize) - { - var arguments = new List { "--user", "set-environment" }; - foreach (var pair in pairs.Skip(offset).Take(SystemctlBatchSize)) - { - arguments.Add($"{pair.Key}={pair.Value}"); - } - - if (!TryRunSystemctl(arguments, out errorMessage)) - { - return false; - } - } - - return true; - } - - private static bool TryApplyViaDbusUpdateEnvironment( - IReadOnlyDictionary variables, - out string? errorMessage) - { - var arguments = new List(); - foreach (var pair in variables) - { - arguments.Add($"{pair.Key}={pair.Value}"); - } - - return TryRunCommand("dbus-update-environment", arguments, out errorMessage); - } - - private static bool TryRunSystemctl(IReadOnlyList arguments, out string? errorMessage) => - TryRunCommand("systemctl", arguments, out errorMessage); - - private static bool TryRunCommand( - string fileName, - IReadOnlyList arguments, - out string? errorMessage) - { - errorMessage = null; - try - { - var startInfo = new ProcessStartInfo - { - FileName = fileName, - RedirectStandardError = true, - RedirectStandardOutput = true, - UseShellExecute = false, - }; - foreach (var argument in arguments) - { - startInfo.ArgumentList.Add(argument); - } - - using var process = Process.Start(startInfo); - if (process is null) - { - errorMessage = "не удалось запустить процесс"; - return false; - } - - var stderr = process.StandardError.ReadToEnd(); - process.WaitForExit(5000); - if (process.ExitCode == 0) - { - return true; - } - - errorMessage = string.IsNullOrWhiteSpace(stderr) - ? $"код выхода {process.ExitCode}" - : stderr.Trim(); - return false; - } - catch (Exception ex) - { - errorMessage = ex.Message; - return false; - } - } private Dictionary LoadManagedFile() {