feat: one-line install for agents and probes from one shared script (curl | bash, zsh, PowerShell) [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful
ci/woodpecker/push/main-amd64-build Pipeline was successful
This commit is contained in:
1 parent
5528753d45
commit
af2962fc58
29 files changed
+558
-124
No files matched your search
@@ -6,7 +6,7 @@ using MoShiro.Protocol;
|
||||
|
||||
namespace MoShiro.Backend.Api;
|
||||
|
||||
/// <summary>运维端点:<c>/healthz</c>、<c>/metrics</c>(admin 令牌)、安装脚本。</summary>
|
||||
/// <summary>运维端点:<c>/healthz</c>、<c>/metrics</c>(admin 令牌)、一行安装脚本(<c>/install</c>、<c>/install.ps1</c>)。</summary>
|
||||
public static class OpsEndpoints
|
||||
{
|
||||
private const string Tag = "ops";
|
||||
@@ -19,10 +19,30 @@ public static class OpsEndpoints
|
||||
app.MapGet("/metrics", MetricsAsync)
|
||||
.Api("metrics_get", "Prometheus metrics (admin token)", Tag)
|
||||
.Produces(StatusCodes.Status200OK, contentType: "text/plain").ProducesProblems(401, 403);
|
||||
app.MapGet("/install.sh", (HttpContext http) => NotShipped(http))
|
||||
.Api("install_sh", "Installer for Linux nodes", Tag).ProducesProblems(501);
|
||||
app.MapGet("/install.ps1", (HttpContext http) => NotShipped(http))
|
||||
.Api("install_ps1", "Installer for Windows nodes", Tag).ProducesProblems(501);
|
||||
// 一行安装:curl -fsSL 'https://panel/install?code=…' | bash(macOS 用 zsh),irm 'https://panel/install.ps1?code=…' | iex(Windows)。
|
||||
// Agent 和 Probe 是同一份脚本,角色、网关和镜像由一次性代码决定;代码不能用就是 404。
|
||||
app.MapGet("/install", (HttpContext http, JoinTokenService tokens, BackendOptions options, string? code) => InstallAsync(http, tokens, options, code, "install.sh", "text/x-shellscript"))
|
||||
.Api("install_sh", "One-line installer for Linux and macOS nodes (agent or probe, decided by the code)", Tag)
|
||||
.Produces(StatusCodes.Status200OK, contentType: "text/x-shellscript").ProducesProblems(404);
|
||||
app.MapGet("/install.sh", (HttpContext http, JoinTokenService tokens, BackendOptions options, string? code) => InstallAsync(http, tokens, options, code, "install.sh", "text/x-shellscript"))
|
||||
.ExcludeFromDescription();
|
||||
app.MapGet("/install.ps1", (HttpContext http, JoinTokenService tokens, BackendOptions options, string? code) => InstallAsync(http, tokens, options, code, "install.ps1", "text/plain"))
|
||||
.Api("install_ps1", "One-line installer for Windows nodes (agent or probe, decided by the code)", Tag)
|
||||
.Produces(StatusCodes.Status200OK, contentType: "text/plain").ProducesProblems(404);
|
||||
}
|
||||
|
||||
private static async Task<IResult> InstallAsync(HttpContext http, JoinTokenService tokens, BackendOptions options, string? code, string resource, string contentType)
|
||||
{
|
||||
string baseUrl = options.PublicUrl ?? $"{http.Request.Scheme}://{http.Request.Host}";
|
||||
InstallTarget? target = string.IsNullOrEmpty(code) ? null : await tokens.ResolveInstallAsync(code, baseUrl, http.RequestAborted);
|
||||
if (target is null)
|
||||
{
|
||||
return Problems.Create(http, MoShiroErrors.NotFound, "the install code is invalid, expired or already used");
|
||||
}
|
||||
|
||||
string script = InstallScripts.Render(resource, target);
|
||||
http.Response.Headers.CacheControl = "no-store";
|
||||
return TypedResults.Text(script, contentType + "; charset=utf-8");
|
||||
}
|
||||
|
||||
private static async Task<IResult> HealthAsync(HttpContext http, OpsService ops)
|
||||
@@ -46,8 +66,4 @@ public static class OpsEndpoints
|
||||
|
||||
return TypedResults.Text(await ops.RenderPrometheusAsync(http.RequestAborted), "text/plain; version=0.0.4");
|
||||
}
|
||||
|
||||
/// <summary>安装脚本需要下载节点程序的发布物,那属于打包与部署(M6),目前还没有。</summary>
|
||||
private static IResult NotShipped(HttpContext http) =>
|
||||
Problems.Create(http, StatusCodes.Status501NotImplemented, ErrorCodeHttpMap.NotImplemented.Value, "the node installer ships with packaging (M6)");
|
||||
}
|
||||
Reference in new issue
Block a user