enable CGO by default now.
This commit is contained in:
@@ -235,9 +235,15 @@ async function startBuild(config) {
|
||||
"info",
|
||||
);
|
||||
|
||||
await streamBuildOutput(buildId);
|
||||
await streamBuildOutput(buildId, config);
|
||||
} catch (err) {
|
||||
addBuildOutput(`\nERROR: ${err.message}\n`, "error");
|
||||
if (!config.disableCgo) {
|
||||
addBuildOutput(
|
||||
"Hint: This build used CGO. If it keeps failing, try enabling the 'Disable CGO' option and build again.\n",
|
||||
"warn",
|
||||
);
|
||||
}
|
||||
buildStatusText.textContent = "Build failed";
|
||||
buildStatus.querySelector("div").className =
|
||||
"flex items-center gap-2 p-3 rounded-lg bg-red-900/40 border border-red-700/60";
|
||||
@@ -250,7 +256,7 @@ async function startBuild(config) {
|
||||
}
|
||||
}
|
||||
|
||||
async function streamBuildOutput(buildId) {
|
||||
async function streamBuildOutput(buildId, config = {}) {
|
||||
const res = await fetch(`/api/build/${buildId}/stream`, {
|
||||
credentials: "include",
|
||||
});
|
||||
@@ -295,6 +301,13 @@ async function streamBuildOutput(buildId) {
|
||||
? "fa-solid fa-circle-check"
|
||||
: "fa-solid fa-circle-xmark";
|
||||
|
||||
if (!data.success && !config.disableCgo) {
|
||||
addBuildOutput(
|
||||
"Hint: This build used CGO. If it keeps failing, try enabling the 'Disable CGO' option and build again.\n",
|
||||
"warn",
|
||||
);
|
||||
}
|
||||
|
||||
if (data.success && data.files) {
|
||||
const buildData = {
|
||||
id: data.buildId,
|
||||
|
||||
@@ -443,6 +443,27 @@ bulkUninstallBtn?.addEventListener("click", async () => {
|
||||
window.toggleClientSelection = toggleClientSelection;
|
||||
window.isClientSelected = (clientId) => selectedClients.has(clientId);
|
||||
window.syncClientSelection = syncSelectionState;
|
||||
window.removeClientFromDashboard = async (clientId) => {
|
||||
if (!clientId) return false;
|
||||
try {
|
||||
const res = await fetch(`/api/clients/${clientId}`, {
|
||||
method: "DELETE",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
if (!res.ok) {
|
||||
const data = await res.json().catch(() => ({}));
|
||||
alert(data.error || "Failed to remove client from dashboard");
|
||||
return false;
|
||||
}
|
||||
selectedClients.delete(clientId);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert("Failed to remove client from dashboard");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
window.banClient = async (clientId) => {
|
||||
if (!clientId) return;
|
||||
if (!confirm(`Ban IP for ${clientId} and block future connections?`)) return;
|
||||
@@ -578,6 +599,23 @@ menu.addEventListener("click", async (e) => {
|
||||
closeMenu(clearContext);
|
||||
return;
|
||||
}
|
||||
} else if (action === "remove-dashboard") {
|
||||
if (
|
||||
!confirm(
|
||||
`Remove ${contextCard} from the dashboard list?\n\nUse this for stale clients that are already gone. If that client reconnects later, it will appear again.`,
|
||||
)
|
||||
) {
|
||||
closeMenu(clearContext);
|
||||
return;
|
||||
}
|
||||
|
||||
const removed = await window.removeClientFromDashboard(contextCard);
|
||||
if (removed) {
|
||||
updateBulkToolbar();
|
||||
setTimeout(() => loadWithOptions({ force: true }), 200);
|
||||
}
|
||||
closeMenu(clearContext);
|
||||
return;
|
||||
}
|
||||
|
||||
const ok = await sendCommand(contextCard, action);
|
||||
|
||||
@@ -17,6 +17,7 @@ menu.innerHTML = `
|
||||
<button class="w-full text-left px-3 py-2.5 mb-1 rounded-lg border border-slate-800 bg-slate-800/60 hover:bg-slate-700 flex items-center gap-2" data-action="reconnect"><i class="fa-solid fa-rotate"></i> Reconnect</button>
|
||||
<button class="w-full text-left px-3 py-2.5 mb-1 rounded-lg border border-red-800 bg-red-900/40 hover:bg-red-800/60 text-red-100 flex items-center gap-2" data-action="disconnect"><i class="fa-solid fa-plug-circle-xmark"></i> Disconnect</button>
|
||||
<button class="w-full text-left px-3 py-2.5 rounded-lg border border-red-900 bg-red-950/60 hover:bg-red-900/80 text-red-200 flex items-center gap-2" data-action="uninstall"><i class="fa-solid fa-trash"></i> Uninstall</button>
|
||||
<button class="w-full mt-1 text-left px-3 py-2.5 rounded-lg border border-rose-900 bg-rose-950/70 hover:bg-rose-900/90 text-rose-200 flex items-center gap-2" data-action="remove-dashboard"><i class="fa-solid fa-user-xmark"></i> Remove From Dashboard</button>
|
||||
<div id="plugin-section" class="hidden">
|
||||
<div class="border-t border-slate-700 my-2"></div>
|
||||
<div class="text-[11px] uppercase tracking-wider text-slate-400 px-1 mb-1">Plugins</div>
|
||||
|
||||
@@ -229,7 +229,6 @@
|
||||
type="checkbox"
|
||||
name="disable-cgo"
|
||||
class="w-4 h-4"
|
||||
checked
|
||||
/>
|
||||
<span>Disable CGO</span>
|
||||
</label>
|
||||
|
||||
@@ -128,11 +128,41 @@ export async function startBuildProcess(
|
||||
...process.env,
|
||||
GOOS: os,
|
||||
GOARCH: actualArch,
|
||||
CGO_ENABLED: config.disableCgo !== false ? "0" : "1",
|
||||
CGO_ENABLED: config.disableCgo === true ? "0" : "1",
|
||||
GOWORK: "off",
|
||||
...(goarm ? { GOARM: goarm } : {}),
|
||||
};
|
||||
|
||||
if (env.CGO_ENABLED === "1") {
|
||||
const targetKey = `${os}/${actualArch}${goarm ? `/v${goarm}` : ""}`;
|
||||
const cCompilerByTarget: Record<string, string> = {
|
||||
"linux/amd64": "gcc",
|
||||
"windows/amd64": "x86_64-w64-mingw32-gcc",
|
||||
"windows/386": "i686-w64-mingw32-gcc",
|
||||
};
|
||||
const cxxCompilerByTarget: Record<string, string> = {
|
||||
"linux/amd64": "g++",
|
||||
"windows/amd64": "x86_64-w64-mingw32-g++",
|
||||
"windows/386": "i686-w64-mingw32-g++",
|
||||
};
|
||||
|
||||
const cc = cCompilerByTarget[targetKey];
|
||||
const cxx = cxxCompilerByTarget[targetKey];
|
||||
if (cc) {
|
||||
env.CC = cc;
|
||||
sendToStream({ type: "output", text: `CGO compiler: ${cc}\n`, level: "info" });
|
||||
} else {
|
||||
sendToStream({
|
||||
type: "output",
|
||||
text: `CGO compiler not mapped for ${targetKey}; falling back to default compiler lookup\n`,
|
||||
level: "warn",
|
||||
});
|
||||
}
|
||||
if (cxx) {
|
||||
env.CXX = cxx;
|
||||
}
|
||||
}
|
||||
|
||||
let ldflags = config.stripDebug !== false ? "-s -w" : "";
|
||||
|
||||
if (config.serverUrl) {
|
||||
@@ -181,7 +211,7 @@ export async function startBuildProcess(
|
||||
const buildTool = config.obfuscate ? "garble" : "go";
|
||||
const tagArg = config.noPrinting ? "-tags noprint " : "";
|
||||
logger.info(`[build:${buildId.substring(0, 8)}] Building: ${buildTool} build ${tagArg}${ldflags ? `-ldflags="${ldflags}" ` : ""}-o ${outDir}/${outputName} ./cmd/agent`);
|
||||
logger.info(`[build:${buildId.substring(0, 8)}] Environment: GOOS=${os} GOARCH=${actualArch} CGO_ENABLED=${env.CGO_ENABLED}`);
|
||||
logger.info(`[build:${buildId.substring(0, 8)}] Environment: GOOS=${os} GOARCH=${actualArch} CGO_ENABLED=${env.CGO_ENABLED} CC=${env.CC || "<default>"}`);
|
||||
|
||||
const buildCmd = config.obfuscate
|
||||
? (config.noPrinting
|
||||
|
||||
@@ -4,6 +4,7 @@ import { AuditAction, logAudit } from "../../auditLog";
|
||||
import * as clientManager from "../../clientManager";
|
||||
import {
|
||||
banIp,
|
||||
clientExists,
|
||||
deleteClientRow,
|
||||
getClientIp,
|
||||
listClients,
|
||||
@@ -121,6 +122,51 @@ export async function handleClientRoutes(
|
||||
return Response.json({ ok: true, updated: success }, { headers: deps.CORS_HEADERS });
|
||||
}
|
||||
|
||||
const clientDeleteMatch = url.pathname.match(/^\/api\/clients\/([^/]+)$/);
|
||||
if (req.method === "DELETE" && clientDeleteMatch) {
|
||||
const user = await authenticateRequest(req);
|
||||
if (!user) return new Response("Unauthorized", { status: 401 });
|
||||
|
||||
try {
|
||||
requirePermission(user, "clients:control");
|
||||
} catch (error) {
|
||||
if (error instanceof Response) return error;
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
}
|
||||
|
||||
const targetId = clientDeleteMatch[1];
|
||||
const target = clientManager.getClient(targetId);
|
||||
const existsInDb = clientExists(targetId);
|
||||
if (!target && !existsInDb) {
|
||||
return Response.json({ error: "Client not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
if (target) {
|
||||
try {
|
||||
target.ws.close(4000, "removed");
|
||||
} catch {
|
||||
// Connection may already be closed.
|
||||
}
|
||||
clientManager.deleteClient(targetId);
|
||||
setOnlineState(targetId, false);
|
||||
}
|
||||
|
||||
deleteClientRow(targetId);
|
||||
|
||||
const ip = server.requestIP(req)?.address || "unknown";
|
||||
logAudit({
|
||||
timestamp: Date.now(),
|
||||
username: user.username,
|
||||
ip,
|
||||
action: AuditAction.COMMAND,
|
||||
targetClientId: targetId,
|
||||
details: "remove_dashboard",
|
||||
success: true,
|
||||
});
|
||||
|
||||
return Response.json({ ok: true }, { headers: deps.CORS_HEADERS });
|
||||
}
|
||||
|
||||
if (req.method === "POST") {
|
||||
const cmdMatch = url.pathname.match(/^\/api\/clients\/(.+)\/command$/);
|
||||
if (cmdMatch) {
|
||||
|
||||
Reference in New Issue
Block a user