using System.Reflection; using System.Security.Cryptography; using System.Text; namespace MoShiro.Backend.Api; /// /// 一行安装脚本:packaging/install/ 下的 install.sh 和 install.ps1 作为嵌入资源打进 Backend,原样返回,不替换任何值。 /// 静态,所以它的 SHA-256 在一个版本内固定:CI 构建时算出来写进签名的发布清单,面板给的命令先核对哈希再执行(docs/security/access.md 第 10 节)。 /// 角色、面板地址、代码都走命令里的环境变量。 /// public static class InstallScripts { public const string Sh = "install.sh"; public const string Ps1 = "install.ps1"; /// CI 的发布公钥(packaging/update/release-key.pub.pem):脚本里内置的就是这一把,测试核对两边一致。 public static string ReleaseKey() => Read("release-key.pub.pem").Trim(); public static string Script(string resource) => Read(resource); /// compose 文件的资源名(agent.yaml、probe.yaml、backend.yaml 对应的);不是这三个就是 null。 public static string? ComposeResource(string file) => file is "agent.yaml" or "probe.yaml" or "backend.yaml" ? "compose-" + file : null; /// 某个角色(agent、probe)的 compose 文件的 SHA-256;其他角色返回空。 public static string ComposeSha256(string? role) => role is "agent" or "probe" ? Sha256("compose-" + role + ".yaml") : string.Empty; /// 脚本内容的 SHA-256(小写十六进制,按 UTF-8 字节)。 public static string Sha256(string resource) => Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(Read(resource)))); private static string Read(string resource) { using Stream stream = typeof(InstallScripts).Assembly.GetManifestResourceStream(resource) ?? throw new InvalidOperationException($"the embedded resource {resource} is missing"); using var reader = new StreamReader(stream); return reader.ReadToEnd(); } }