Skip to content

Commit

Permalink
[Security Solution][Endpoint] Improve dev tool so that incomplete age…
Browse files Browse the repository at this point in the history
…nt 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.
  • Loading branch information
paul-tavares authored May 31, 2023
1 parent aa1d266 commit ccf0099
Showing 1 changed file with 45 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();

/**
Expand Down

0 comments on commit ccf0099

Please sign in to comment.