diff --git a/README.md b/README.md index 2017c1be..c326d14c 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Otherwise see below for OS specific instructions. wget -qO - https://deb.nodesource.com/setup_14.x | sudo -E bash - sudo apt install nodejs -2. Create a new directory and run the Clusterio installer: +2. Log in as the user you wish to install Clusterio as (do not use root), and then create a new directory and run the Clusterio installer: mkdir clusterio cd clusterio @@ -113,14 +113,7 @@ Otherwise see below for OS specific instructions. Make sure to note down the admin authentication token it provides at the end as you will need it later. -3. If you chose to use local factorio directory for the Factorio installation then download the headless build of Factorio and unpack it: - - wget -O factorio.tar.xz https://www.factorio.com/get-download/latest/headless/linux64 - tar -xf factorio.tar.xz - - To specify a version of Factorio to download replace "latest" in the URL with a version number like "1.0.0". - -4. Optionally copy the generated systemd service files in `systemd` folder to `/etc/systemd/system/`. +3. Optionally copy the generated systemd service files in `systemd` folder to `/etc/systemd/system/`. **Ubuntu with Docker** diff --git a/packages/create/create.js b/packages/create/create.js index 1d7972a2..446b435e 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -168,6 +168,19 @@ async function validateInstallDir() { } } +async function validateNotRoot(args) { + if (args.allowInstallAsRoot) { + return; + } + + if (os.userInfo().uid === 0) { + throw new InstallError( + "Refusing to install as root. Create a separate user account for clusterio " + + "and then use su/sudo to switch to it before invoking the installer." + ); + } +} + async function installClusterio(mode, plugins) { try { await safeOutputFile("package.json", JSON.stringify({ @@ -225,6 +238,17 @@ async function installClusterio(mode, plugins) { } } +async function groupIdToName(gid) { + try { + let exec = util.promisify(child_process.exec); + let { stdout } = await exec(`getent group ${gid}`); + return stdout.split(":")[0]; + } catch (err) { + logger.warn(`getent group ${gid} failed: ${err.message}`); + return gid; + } +} + async function writeScripts(mode) { if (["standalone", "master"].includes(mode)) { if (process.platform === "win32") { @@ -245,7 +269,7 @@ Description=Clusterio Master [Service] User=${os.userInfo().username} -Group=nogroup +Group=${await groupIdToName(os.userInfo().gid)} WorkingDirectory=${process.cwd()} KillMode=mixed KillSignal=SIGINT @@ -276,7 +300,7 @@ Description=Clusterio Slave [Service] User=${os.userInfo().username} -Group=nogroup +Group=${await groupIdToName(os.userInfo().gid)} WorkingDirectory=${process.cwd()} KillMode=mixed KillSignal=SIGINT @@ -536,6 +560,9 @@ async function main() { if (process.platform === "linux") { args = args + .option("allow-install-as-root", { + nargs: 0, describe: "(Linux only) Allow installing as root (not recommended)", type: "boolean", + }) .option("download-headless", { nargs: 0, describe: "(Linux only) Automatically download and unpack the latest factorio release. " + @@ -552,6 +579,7 @@ async function main() { if (!dev) { await validateInstallDir(); + await validateNotRoot(args); } let answers = await inquirerMissingArgs(args);