Преглед изворни кода

feat(cli): create tipi group and assign it to user and folders

Nicolas Meienberger пре 1 година
родитељ
комит
7926c45d88

+ 1 - 1
packages/cli/.env.test

@@ -5,4 +5,4 @@ APPS_REPO_URL=https://test.com/test
 ROOT_FOLDER_HOST=/runtipi
 STORAGE_PATH=/runtipi
 TIPI_VERSION=1
-
+REDIS_PASSWORD=redis

+ 6 - 2
packages/cli/src/executors/app/app.executors.ts

@@ -168,10 +168,14 @@ export class AppExecutors {
       await compose(appId, 'down --remove-orphans --volumes --rmi all');
 
       this.logger.info(`Deleting folder ${appDirPath}`);
-      await fs.promises.rm(appDirPath, { recursive: true, force: true });
+      await fs.promises.rm(appDirPath, { recursive: true, force: true }).catch((err) => {
+        this.logger.error(`Error deleting folder ${appDirPath}: ${err.message}`);
+      });
 
       this.logger.info(`Deleting folder ${appDataDirPath}`);
-      await fs.promises.rm(appDataDirPath, { recursive: true, force: true });
+      await fs.promises.rm(appDataDirPath, { recursive: true, force: true }).catch((err) => {
+        this.logger.error(`Error deleting folder ${appDataDirPath}: ${err.message}`);
+      });
 
       this.logger.info(`App ${appId} uninstalled`);
       return { success: true, message: `App ${appId} uninstalled successfully` };

+ 3 - 1
packages/cli/src/executors/app/app.helpers.ts

@@ -192,5 +192,7 @@ export const copyDataDir = async (id: string) => {
   );
 
   // Remove any .gitkeep files from the app-data folder at any level
-  await execAsync(`find ${storagePath}/app-data/${id}/data -name .gitkeep -delete`);
+  if (await pathExists(`${storagePath}/app-data/${id}/data`)) {
+    await execAsync(`find ${storagePath}/app-data/${id}/data -name .gitkeep -delete`).catch(() => {});
+  }
 };

+ 34 - 6
packages/cli/src/executors/system/system.executors.ts

@@ -56,18 +56,43 @@ export class SystemExecutors {
   };
 
   private ensureFilePermissions = async (rootFolderHost: string, logSudoRequest = true) => {
+    const logger = new TerminalSpinner('');
     // if we are running as root, we don't need to change permissions
     if (process.getuid && process.getuid() === 0) {
       return;
     }
 
     if (logSudoRequest) {
-      const logger = new TerminalSpinner('');
       logger.log('Tipi needs to change permissions on some files and folders and will ask for your password.');
     }
 
+    // Create group tipi if it does not exist
+    try {
+      await execAsync('getent group tipi');
+    } catch (e) {
+      try {
+        await execAsync('sudo groupadd tipi');
+        logger.done('Created group tipi');
+      } catch (e2) {
+        logger.fail('Failed to create group tipi');
+        fileLogger.error(e2);
+      }
+    }
+
+    // Add current user to group tipi
+    if (!(await execAsync(`groups ${process.env.USER}`)).stdout.includes('tipi')) {
+      try {
+        await execAsync(`sudo usermod -aG tipi ${process.env.USER}`);
+        // Reload permissions
+        await execAsync('newgrp tipi');
+      } catch (e) {
+        logger.fail('Failed to add current user to group tipi');
+      }
+    }
+
     const filesAndFolders = [
       path.join(rootFolderHost, 'apps'),
+      // path.join(rootFolderHost, 'app-data'),
       path.join(rootFolderHost, 'logs'),
       path.join(rootFolderHost, 'media'),
       path.join(rootFolderHost, 'repos'),
@@ -82,11 +107,12 @@ export class SystemExecutors {
     await Promise.all(
       filesAndFolders.map(async (fileOrFolder) => {
         if (await pathExists(fileOrFolder)) {
-          if (process.getgid && process.getuid) {
-            await execAsync(`sudo chown -R ${process.getuid()}:${process.getgid()} ${fileOrFolder}`);
-          }
-
-          await execAsync(`sudo chmod -R 750 ${fileOrFolder}`);
+          await execAsync(`sudo chown -R :tipi ${fileOrFolder}`).catch((e) => {
+            fileLogger.error(e);
+          });
+          await execAsync(`sudo chmod -R 770 ${fileOrFolder}`).catch((e) => {
+            fileLogger.error(e);
+          });
         }
       }),
     );
@@ -390,6 +416,8 @@ export class SystemExecutors {
         process.stderr.write(data);
       });
 
+      spinner.done(`Tipi ${targetVersion} successfully updated. Please run './runtipi-cli start' to start Tipi again.`);
+
       return { success: true, message: 'Tipi updated' };
     } catch (e) {
       spinner.fail('Tipi update failed, see logs for more details (logs/error.log)');

+ 9 - 0
packages/cli/src/executors/system/system.helpers.ts

@@ -33,6 +33,8 @@ type EnvKeys =
   | 'REDIS_PASSWORD'
   | 'LOCAL_DOMAIN'
   | 'DEMO_MODE'
+  | 'TIPI_GID'
+  | 'TIPI_UID'
   // eslint-disable-next-line @typescript-eslint/ban-types
   | (string & {});
 
@@ -177,6 +179,13 @@ export const generateSystemEnvFile = async () => {
   envMap.set('LOCAL_DOMAIN', data.localDomain || 'tipi.lan');
   envMap.set('NODE_ENV', 'production');
 
+  const currentUserGroup = process.getgid ? String(process.getgid()) : '1000';
+  const currentUserId = process.getuid ? String(process.getuid()) : '1000';
+  const { stdout: tipiGroupId } = await execAsync('getent group tipi | cut -d: -f3');
+
+  envMap.set('TIPI_GID', tipiGroupId.trim() || currentUserGroup);
+  envMap.set('TIPI_UID', currentUserId);
+
   await fs.promises.writeFile(envFilePath, envMapToString(envMap));
 
   return envMap;

+ 5 - 1
packages/cli/src/services/watcher/watcher.ts

@@ -84,7 +84,11 @@ const killOtherWorkers = async () => {
     }
 
     console.log(`Killing worker with pid ${pid}`);
-    process.kill(Number(pid));
+    try {
+      process.kill(Number(pid));
+    } catch (e) {
+      console.error(`Error killing worker with pid ${pid}: ${e}`);
+    }
   });
 };
 

+ 2 - 5
scripts/install.sh

@@ -188,11 +188,8 @@ chmod +x ./runtipi-cli
 # Check if user is in docker group
 if [ "$(id -u)" -ne 0 ]; then
   if ! groups | grep -q docker; then
-    echo ""
-    echo "User is not in docker group. Please make sure your user is allowed to run docker commands and restart the script."
-    echo "See https://docs.docker.com/engine/install/linux-postinstall/ for more information."
-    echo ""
-    exit 1
+    sudo usermod -aG docker "$USER"
+    newgrp docker
   fi
 fi