feat: support custom server deployment drafts
This commit is contained in:
@@ -11,6 +11,10 @@ const plugin: GamePluginResponse = {
|
||||
serverType: "runtime",
|
||||
manifestRef: "artifact://runtime-manifest",
|
||||
createFormSchemaRef: "schemas/create.json",
|
||||
createFields: [
|
||||
{ key: "gamePort", label: "游戏端口", type: "port", required: true, defaultValue: "7777" },
|
||||
{ key: "maxPlayers", label: "最大玩家数", type: "number", required: true, defaultValue: "64" }
|
||||
],
|
||||
requiredRunCapabilities: ["process.install"],
|
||||
declaredPermissions: ["server.create"],
|
||||
permissions: { ai: false, logs: true, files: false, jobs: true, artifacts: false },
|
||||
@@ -65,11 +69,17 @@ describe("runtime profile server creation contracts", () => {
|
||||
).toEqual({
|
||||
id: "server-1",
|
||||
pluginId: "game.runtime",
|
||||
runEndpointId: "",
|
||||
runEndpointId: undefined,
|
||||
name: "Runtime Server",
|
||||
idempotencyKey: "web:create:server-1:17",
|
||||
profileKey: "local",
|
||||
bindings: { "server-root": "runtime.server-root", "rcon.password": "secret://runtime/server-1/rcon" }
|
||||
bindings: { "server-root": "runtime.server-root", "rcon.password": "secret://runtime/server-1/rcon" },
|
||||
deployment: {
|
||||
mode: "guided-install",
|
||||
profileKey: "local",
|
||||
runtimeBindings: { "server-root": "runtime.server-root", "rcon.password": "secret://runtime/server-1/rcon" },
|
||||
createInputs: { gamePort: "7777", maxPlayers: "64" }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,4 +94,11 @@ describe("runtime profile server creation contracts", () => {
|
||||
});
|
||||
expect(serverInstanceIdFromName("测试服", 18)).toBe("server-18");
|
||||
});
|
||||
|
||||
it("keeps complete paths and commands in a write-only deployment payload", () => {
|
||||
const form = defaultServerCreateForm([plugin], []);
|
||||
const request = serverCreateRequestFromForm({ ...form, name: "Venv Server", deploymentMode: "custom-command", serverRoot: "/srv/venv-server", workingDirectory: "/srv/venv-server", startCommand: "/srv/venv-server/.venv/bin/python server.py", shell: "" }, 19);
|
||||
expect(request.runEndpointId).toBeUndefined();
|
||||
expect(request.deployment).toMatchObject({ mode: "custom-command", serverRoot: "/srv/venv-server", workingDirectory: "/srv/venv-server", startCommand: "/srv/venv-server/.venv/bin/python server.py" });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,11 +16,24 @@ export function serverCreateRequestFromForm(form: ServerCreateFormState, sequenc
|
||||
return {
|
||||
id,
|
||||
pluginId: form.pluginId.trim(),
|
||||
runEndpointId: form.runEndpointId.trim(),
|
||||
runEndpointId: form.runEndpointId.trim() || undefined,
|
||||
name: form.name.trim(),
|
||||
idempotencyKey: lifecycleIdempotencyKey("create", id, sequence),
|
||||
profileKey: form.profileKey.trim(),
|
||||
bindings: Object.fromEntries(Object.entries(form.bindings).map(([key, value]) => [key, value.trim()]).filter(([, value]) => value !== ""))
|
||||
profileKey: form.profileKey.trim() || undefined,
|
||||
bindings: Object.fromEntries(Object.entries(form.bindings).map(([key, value]) => [key, value.trim()]).filter(([, value]) => value !== "")),
|
||||
deployment: {
|
||||
mode: form.deploymentMode,
|
||||
profileKey: form.profileKey.trim() || undefined,
|
||||
runtimeBindings: Object.fromEntries(Object.entries(form.bindings).map(([key, value]) => [key, value.trim()]).filter(([, value]) => value !== "")),
|
||||
createInputs: Object.fromEntries(Object.entries(form.createInputs).map(([key, value]) => [key, value.trim()])),
|
||||
serverRoot: form.serverRoot.trim() || undefined,
|
||||
workingDirectory: form.workingDirectory.trim() || undefined,
|
||||
installCommand: form.installCommand.trim() || undefined,
|
||||
startCommand: form.startCommand.trim() || undefined,
|
||||
stopCommand: form.stopCommand.trim() || undefined,
|
||||
statusCommand: form.statusCommand.trim() || undefined,
|
||||
shell: form.shell || undefined
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user