diff --git a/cmd/server/main-server.go b/cmd/server/main-server.go index 6a6d441ba..8b3e2dc83 100644 --- a/cmd/server/main-server.go +++ b/cmd/server/main-server.go @@ -202,7 +202,7 @@ func main() { return } defer func() { - err = waveLock.Unlock() + err = waveLock.Close() if err != nil { log.Printf("error releasing wave lock: %v\n", err) } diff --git a/go.mod b/go.mod index 26ed5e328..9f4774c85 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/wavetermdev/htmltoken v0.1.0 golang.org/x/crypto v0.28.0 + golang.org/x/sys v0.26.0 golang.org/x/term v0.25.0 ) @@ -41,7 +42,6 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect go.uber.org/atomic v1.7.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect ) replace github.com/kevinburke/ssh_config => github.com/wavetermdev/ssh_config v0.0.0-20240306041034-17e2087ebde2 diff --git a/pkg/wavebase/wavebase-posix.go b/pkg/wavebase/wavebase-posix.go new file mode 100644 index 000000000..352302221 --- /dev/null +++ b/pkg/wavebase/wavebase-posix.go @@ -0,0 +1,30 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +//go:build !windows + +package wavebase + +import ( + "log" + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +func AcquireWaveLock() (FDLock, error) { + homeDir := GetWaveHomeDir() + lockFileName := filepath.Join(homeDir, WaveLockFile) + log.Printf("[base] acquiring lock on %s\n", lockFileName) + fd, err := os.OpenFile(lockFileName, os.O_RDWR|os.O_CREATE, 0600) + if err != nil { + return nil, err + } + err = unix.Flock(int(fd.Fd()), unix.LOCK_EX|unix.LOCK_NB) + if err != nil { + fd.Close() + return nil, err + } + return fd, nil +} diff --git a/pkg/wavebase/wavebase-win.go b/pkg/wavebase/wavebase-win.go new file mode 100644 index 000000000..a22ac2f85 --- /dev/null +++ b/pkg/wavebase/wavebase-win.go @@ -0,0 +1,29 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +//go:build windows + +package wavebase + +import ( + "fmt" + "log" + "path/filepath" + + "github.com/alexflint/go-filemutex" +) + +func AcquireWaveLock() (FDLock, error) { + homeDir := GetWaveHomeDir() + lockFileName := filepath.Join(homeDir, WaveLockFile) + log.Printf("[base] acquiring lock on %s\n", lockFileName) + m, err := filemutex.New(lockFileName) + if err != nil { + return nil, fmt.Errorf("filemutex new error: %w", err) + } + err = m.TryLock() + if err != nil { + return nil, fmt.Errorf("filemutex trylock error: %w", err) + } + return m, nil +} diff --git a/pkg/wavebase/wavebase.go b/pkg/wavebase/wavebase.go index a4c366919..fd0cb5738 100644 --- a/pkg/wavebase/wavebase.go +++ b/pkg/wavebase/wavebase.go @@ -17,8 +17,6 @@ import ( "strings" "sync" "time" - - "github.com/alexflint/go-filemutex" ) // set by main-server.go @@ -41,6 +39,10 @@ const AppPathBinDir = "bin" var baseLock = &sync.Mutex{} var ensureDirCache = map[string]bool{} +type FDLock interface { + Close() error +} + func IsDevMode() bool { pdev := os.Getenv(WaveDevVarName) return pdev != "" @@ -200,19 +202,6 @@ func DetermineLocale() string { return strings.Replace(truncated, "_", "-", -1) } -func AcquireWaveLock() (*filemutex.FileMutex, error) { - homeDir := GetWaveHomeDir() - lockFileName := filepath.Join(homeDir, WaveLockFile) - log.Printf("[base] acquiring lock on %s\n", lockFileName) - m, err := filemutex.New(lockFileName) - if err != nil { - return nil, err - } - - err = m.TryLock() - return m, err -} - func ClientArch() string { return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) }