mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 17:05:18 +00:00
119 lines
3.7 KiB
JavaScript
Executable File
119 lines
3.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const child = require("child_process");
|
|
const fs = require("fs");
|
|
const os = require("os");
|
|
const path = require("path");
|
|
|
|
const axios = require("axios");
|
|
const rimraf = require("rimraf");
|
|
const tar = require("tar");
|
|
|
|
const { version } = require("./package.json");
|
|
|
|
// Strip any v4.0.0-1 style suffix (but not -rc1) so that the correct package is
|
|
// downloaded if there is a mistake in the NPM publish and we need to release a
|
|
// -1, etc. (because NPM packages are immutable and can't be fixed after a mistake).
|
|
let strippedVersion = version.replace(/-[0-9]+/i, "");
|
|
if (!strippedVersion.startsWith("v")) {
|
|
strippedVersion = `v${strippedVersion}`;
|
|
}
|
|
|
|
const binDir = path.join(__dirname, "install");
|
|
// Determine the install directory by version so that we can detect when we need
|
|
// to upgrade to a new version.
|
|
const installDir = path.join(binDir, strippedVersion);
|
|
|
|
const platform = (() => {
|
|
switch (os.type()) {
|
|
case "Windows_NT":
|
|
return "windows";
|
|
case "Linux":
|
|
return "linux";
|
|
case "Darwin":
|
|
return "macos";
|
|
default:
|
|
throw new Error(`platform ${os.type} unrecognized`);
|
|
}
|
|
})();
|
|
|
|
const binName = platform === "windows" ? "fleetctl.exe" : "fleetctl";
|
|
const binPath = path.join(installDir, binName);
|
|
|
|
const install = async () => {
|
|
const url = `https://github.com/fleetdm/fleet/releases/download/fleet-${strippedVersion}/fleetctl_${strippedVersion}_${platform}.tar.gz`;
|
|
|
|
fs.mkdirSync(installDir, { recursive: true });
|
|
|
|
try {
|
|
const response = await axios({ url, responseType: "stream" });
|
|
|
|
// Strip the outer directory when extracting. Just get the binary.
|
|
const tarWriter = tar.extract({ strip: 1, cwd: installDir });
|
|
response.data.pipe(tarWriter);
|
|
|
|
// Need to return a promise with the writer to ensure we can await for it to complete.
|
|
return new Promise((resolve, reject) => {
|
|
tarWriter.on("finish", resolve);
|
|
tarWriter.on("error", reject);
|
|
});
|
|
} catch (err) {
|
|
throw new Error(`download archive ${url}: ${err.message}`);
|
|
}
|
|
};
|
|
|
|
const run = async () => {
|
|
if (!fs.existsSync(binPath)) {
|
|
// Remove any existing binaries before installing the new one.
|
|
rimraf.sync(binDir);
|
|
console.log(`Installing fleetctl ${strippedVersion}...`);
|
|
try {
|
|
await install();
|
|
} catch (err) {
|
|
// Users commonly see permission errors when trying to install the binaries if they have run
|
|
// `sudo npm install -g fleetctl` (or the Windows equivalent of running as admin), then later
|
|
// try to run fleetctl without those elevated privileges.
|
|
if (err.code === "EACCES") {
|
|
switch (process.platform) {
|
|
case "darwin":
|
|
case "linux":
|
|
console.error(
|
|
"Error: It looks like your fleetctl has been installed as root."
|
|
);
|
|
console.error("Please re-run this command with sudo.");
|
|
process.exit(1);
|
|
break;
|
|
case "win32":
|
|
case "win64":
|
|
console.error(
|
|
"Error: It looks like your fleetctl has been installed as administrator."
|
|
);
|
|
console.error(
|
|
"Please re-run this command using 'Run as administrator'."
|
|
);
|
|
process.exit(1);
|
|
break;
|
|
default:
|
|
// Fall through to generic error print below
|
|
}
|
|
}
|
|
console.error(`Error: Failed to install: ${err.message}`);
|
|
process.exit(1);
|
|
}
|
|
console.log("Install completed.");
|
|
}
|
|
|
|
const [, , ...args] = process.argv;
|
|
const options = { cwd: process.cwd(), stdio: "inherit" };
|
|
const { status, error } = child.spawnSync(binPath, args, options);
|
|
|
|
if (error) {
|
|
console.error(error);
|
|
process.exit(1);
|
|
}
|
|
|
|
process.exit(status);
|
|
};
|
|
|
|
run();
|