[Security Solution][Endpoint] Improve dev tool so that incomplete agent downloads are deleted from disk cache (#158682)

## Summary

- Adds logic to the Agent Download services (part of dev scripts) so
that if the process is interrupted (ex. `SIGNINT` signal from CLI), any
download currently in flight will be deleted from disk, thus avoiding
storing agent download files that are incomplete and invalid.
This commit is contained in:
Paul Tavares 2023-05-31 15:37:01 -04:00 committed by GitHub
parent aa1d266939
commit ccf0099470
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -85,9 +85,16 @@ class AgentDownloadStorage extends SettingsStorage<AgentDownloadStorageSettings>
try {
const outputStream = fs.createWriteStream(newDownloadInfo.fullFilePath);
const { body } = await nodeFetch(agentDownloadUrl);
await finished(body.pipe(outputStream));
await handleProcessInterruptions(
async () => {
const { body } = await nodeFetch(agentDownloadUrl);
await finished(body.pipe(outputStream));
},
() => {
fs.unlinkSync(newDownloadInfo.fullFilePath);
}
);
} catch (e) {
// Try to clean up download case it failed halfway through
await unlink(newDownloadInfo.fullFilePath);
@ -134,6 +141,42 @@ class AgentDownloadStorage extends SettingsStorage<AgentDownloadStorageSettings>
}
}
const handleProcessInterruptions = async <T>(
runFn: (() => T) | (() => Promise<T>),
/** The synchronous cleanup callback */
cleanup: () => void
): Promise<T> => {
const eventNames = ['SIGINT', 'exit', 'uncaughtException', 'unhandledRejection'];
const stopListeners = () => {
for (const eventName of eventNames) {
process.off(eventName, cleanup);
}
};
for (const eventName of eventNames) {
process.on(eventName, cleanup);
}
let runnerResponse: T | Promise<T>;
try {
runnerResponse = runFn();
} catch (e) {
stopListeners();
throw e;
}
if ('finally' in runnerResponse) {
(runnerResponse as Promise<T>).finally(() => {
stopListeners();
});
} else {
stopListeners();
}
return runnerResponse;
};
const agentDownloadsClient = new AgentDownloadStorage();
/**