github.com/taubyte/tau-cli@v0.1.13-0.20240326000942-487f0d57edfc/singletons/session/discovery.go (about)

     1  package session
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path"
     7  	"strconv"
     8  
     9  	"github.com/mitchellh/go-ps"
    10  )
    11  
    12  func parentId() int {
    13  	var ppid int
    14  
    15  	envppid := os.Getenv("TAU_PPID")
    16  	if envppid != "" {
    17  		ppid, _ = strconv.Atoi(envppid)
    18  	} else {
    19  		ppid = os.Getppid()
    20  	}
    21  
    22  	process, err := ps.FindProcess(ppid)
    23  	if err != nil {
    24  		return ppid
    25  	}
    26  
    27  	// This is for `go run .`
    28  	if process.Executable() == "go" || process.Executable() == "node" {
    29  		return process.PPid()
    30  	}
    31  
    32  	return process.Pid()
    33  }
    34  
    35  func discoverOrCreateConfigFileLoc() (string, error) {
    36  	grandPid := parentId()
    37  
    38  	var err error
    39  	processDir, found := nearestProcessDirectory(grandPid)
    40  	if !found {
    41  		processDir, err = createProcessDirectory(grandPid)
    42  		if err != nil {
    43  			return "", err
    44  		}
    45  	}
    46  
    47  	return processDir, nil
    48  }
    49  
    50  /*
    51  Nearest process directory will climb up the process tree until it finds a
    52  directory or the pid reaches 1
    53  */
    54  func nearestProcessDirectory(pid int) (processDir string, found bool) {
    55  	processDir = directoryFromPid(pid)
    56  
    57  	_, err := os.Stat(processDir)
    58  	if err != nil {
    59  		process, err := ps.FindProcess(pid)
    60  		if err != nil {
    61  			return
    62  		}
    63  		if process == nil {
    64  			return
    65  		}
    66  
    67  		ppid := process.PPid()
    68  		if ppid == 1 {
    69  			return
    70  		}
    71  
    72  		processDir = directoryFromPid(ppid)
    73  
    74  		_, err = os.Stat(processDir)
    75  		if err != nil {
    76  			return nearestProcessDirectory(ppid)
    77  		}
    78  	}
    79  
    80  	return processDir, true
    81  }
    82  
    83  func directoryFromPid(pid int) string {
    84  	return path.Join(os.TempDir(), fmt.Sprintf("%s-%d", sessionDirPrefix, pid))
    85  }
    86  
    87  func createProcessDirectory(pid int) (string, error) {
    88  	processDir := directoryFromPid(pid)
    89  
    90  	err := os.Mkdir(processDir, os.ModePerm)
    91  	if err != nil {
    92  		return "", err
    93  	}
    94  
    95  	return processDir, nil
    96  }