using Fleet.Core; using Fleet.Hosting; using MoShiro.Probe; TimeProvider time = TimeProvider.System; INodeLog log = new ConsoleNodeLog(time); if (PlatformCheck.VerifyCrypto() is { } problem) { log.Error("startup failed", ("err", problem)); return 1; } string configPath = "/etc/moshiro/probe.json"; for (int i = 0; i < args.Length - 1; i++) { if (args[i] == "--config") { configPath = args[i + 1]; } } ProbeFile file; LoadedNodeIdentity identity; RestartController restart; try { file = NodeConfig.Load(configPath, ProbeConfigContext.Default.ProbeFile); restart = new RestartController(RestartSchedule.Resolve(file.RestartAt)); if (!Uri.TryCreate(file.Fleet.Server, UriKind.Absolute, out _)) { throw new InvalidOperationException("probe.json needs fleet.server (the panel address)"); } identity = LoadedNodeIdentity.Load(file.Fleet.IdentityDir); if (!identity.NodeId.Value.StartsWith(MoShiro.Protocol.ProbeId.Prefix, StringComparison.Ordinal)) { identity.Dispose(); throw new InvalidOperationException($"the identity in {file.Fleet.IdentityDir} is not a probe's: enroll with a probe join token"); } if (!OwnerGuard.Check(file.Fleet.IdentityDir, file.Fleet.RequireOwner, log)) { identity.Dispose(); return 1; } } catch (Exception ex) when (ex is IOException or InvalidDataException or InvalidOperationException or System.Text.Json.JsonException or System.Security.Cryptography.CryptographicException) { log.Error("startup failed", ("err", ex.Message)); return 1; } using var restartScope = restart; string directory = Path.GetDirectoryName(Path.GetFullPath(configPath))!; using (identity) { using var app = new ProbeApp(file, identity, directory, time, log, restart); await ServiceShell.RunAsync(app.RunAsync, log, restart, time); } return 0;