github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/db/db_local/service.go (about) 1 package db_local 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "strconv" 8 "strings" 9 10 filehelpers "github.com/turbot/go-kit/files" 11 "github.com/turbot/steampipe/pkg/constants" 12 "github.com/turbot/steampipe/pkg/filepaths" 13 "github.com/turbot/steampipe/pkg/utils" 14 ) 15 16 // GetState checks that the database instance is running and returns its details 17 func GetState() (*RunningDBInstanceInfo, error) { 18 utils.LogTime("db.GetStatus start") 19 defer utils.LogTime("db.GetStatus end") 20 21 info, err := loadRunningInstanceInfo() 22 if err != nil { 23 return nil, err 24 } 25 26 if info == nil { 27 log.Println("[TRACE] GetRunStatus - loadRunningInstanceInfo returned nil ") 28 // we do not have a info file 29 return nil, errorIfUnknownService() 30 } 31 32 pidExists, err := utils.PidExists(info.Pid) 33 if err != nil { 34 return nil, err 35 } 36 if !pidExists { 37 log.Printf("[TRACE] GetState - pid %v does not exist\n", info.Pid) 38 // nothing to do here 39 os.Remove(filepaths.RunningInfoFilePath()) 40 return nil, nil 41 } 42 43 return info, nil 44 } 45 46 // errorIfUnknownService returns an error if it can find a `postmaster.pid` in the `INSTALL_DIR` 47 // and the PID recorded in the found `postmaster.pid` is running - nil otherwise. 48 // 49 // This is because, this function is called when we cannot find the steampipe service state file. 50 // 51 // No steampipe state file indicates that the service is not running, so, if the service 52 // is running without us knowing about it, then it's an irrecoverable state 53 func errorIfUnknownService() error { 54 // no postmaster.pid, we are good 55 if !filehelpers.FileExists(filepaths.GetPostmasterPidLocation()) { 56 return nil 57 } 58 59 // read the content of the postmaster.pid file 60 fileContent, err := os.ReadFile(filepaths.GetPostmasterPidLocation()) 61 if err != nil { 62 return err 63 } 64 65 // the first line contains the PID 66 lines := strings.FieldsFunc(string(fileContent), func(r rune) bool { 67 return r == '\n' 68 }) 69 70 // make sure that there's split up content 71 if len(lines) == 0 { 72 return nil 73 } 74 75 // extract it 76 pid, err := strconv.ParseInt(lines[0], 10, 64) 77 if err != nil { 78 return err 79 } 80 81 // check if a process with that PID exists 82 exists, err := utils.PidExists(int(pid)) 83 if err != nil { 84 return err 85 } 86 if exists { 87 // if it does, then somehow we don't know about it. Error out 88 return fmt.Errorf("service is running in an unknown state [PID: %d] - try killing it with %s", pid, constants.Bold("steampipe service stop --force")) 89 } 90 91 // the pid does not exist 92 // this can confuse postgres as per https://postgresapp.com/documentation/troubleshooting.html 93 // delete it 94 os.Remove(filepaths.GetPostmasterPidLocation()) 95 96 // this must be a stale file left over by PG. Ignore 97 return nil 98 }