diff --git a/cmd/plugin.go b/cmd/plugin.go index 8a5001bc..329f5920 100644 --- a/cmd/plugin.go +++ b/cmd/plugin.go @@ -17,6 +17,7 @@ import ( pconstants "github.com/turbot/pipe-fittings/v2/constants" "github.com/turbot/pipe-fittings/v2/contexthelpers" "github.com/turbot/pipe-fittings/v2/error_helpers" + "github.com/turbot/pipe-fittings/v2/filepaths" "github.com/turbot/pipe-fittings/v2/installationstate" pociinstaller "github.com/turbot/pipe-fittings/v2/ociinstaller" pplugin "github.com/turbot/pipe-fittings/v2/plugin" @@ -247,6 +248,9 @@ func runPluginInstallCmd(cmd *cobra.Command, args []string) { } }() + // Clean up plugin temporary directories from previous crashes/interrupted installations + filepaths.CleanupPluginTempDirs() + // if diagnostic mode is set, print out config and return if _, ok := os.LookupEnv(constants.EnvConfigDump); ok { localcmdconfig.DisplayConfig() @@ -380,6 +384,9 @@ func runPluginUpdateCmd(cmd *cobra.Command, args []string) { } }() + // Clean up plugin temporary directories from previous crashes/interrupted installations + filepaths.CleanupPluginTempDirs() + // if diagnostic mode is set, print out config and return if _, ok := os.LookupEnv(constants.EnvConfigDump); ok { localcmdconfig.DisplayConfig() @@ -636,6 +643,9 @@ func runPluginUninstallCmd(cmd *cobra.Command, args []string) { } }() + // Clean up plugin temporary directories from previous crashes/interrupted installations + filepaths.CleanupPluginTempDirs() + // if diagnostic mode is set, print out config and return if _, ok := os.LookupEnv(constants.EnvConfigDump); ok { localcmdconfig.DisplayConfig() @@ -696,6 +706,10 @@ func runPluginListCmd(cmd *cobra.Command, _ []string) { contexthelpers.StartCancelHandler(cancel) utils.LogTime("runPluginListCmd list") + + // Clean up plugin temporary directories from previous crashes/interrupted installations + filepaths.CleanupPluginTempDirs() + defer func() { utils.LogTime("runPluginListCmd end") if r := recover(); r != nil { @@ -744,6 +758,10 @@ func runPluginShowCmd(cmd *cobra.Command, args []string) { contexthelpers.StartCancelHandler(cancel) utils.LogTime("runPluginShowCmd start") + + // Clean up plugin temporary directories from previous crashes/interrupted installations + filepaths.CleanupPluginTempDirs() + defer func() { utils.LogTime("runPluginShowCmd end") if r := recover(); r != nil { diff --git a/cmd/root.go b/cmd/root.go index a293be64..69ef0a8a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -59,10 +59,9 @@ func rootCommand() *cobra.Command { } func Execute() int { - rootCmd := rootCommand() utils.LogTime("cmd.root.Execute start") defer utils.LogTime("cmd.root.Execute end") - + rootCmd := rootCommand() if err := rootCmd.Execute(); err != nil { exitCode = -1 } diff --git a/go.mod b/go.mod index fcabd309..0236b25a 100644 --- a/go.mod +++ b/go.mod @@ -6,22 +6,22 @@ toolchain go1.24.0 replace ( github.com/c-bata/go-prompt => github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50 - github.com/turbot/pipe-fittings/v2 => ../pipe-fittings + // github.com/turbot/pipe-fittings/v2 => ../pipe-fittings //github.com/turbot/tailpipe-plugin-core => ../tailpipe-plugin-core github.com/turbot/tailpipe-plugin-sdk => ../tailpipe-plugin-sdk ) require ( - github.com/Masterminds/semver/v3 v3.2.1 - github.com/hashicorp/hcl/v2 v2.20.1 + github.com/Masterminds/semver/v3 v3.4.0 + github.com/hashicorp/hcl/v2 v2.24.0 github.com/mattn/go-isatty v0.0.20 github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 github.com/turbot/go-kit v1.3.0 - github.com/turbot/pipe-fittings/v2 v2.6.0 + github.com/turbot/pipe-fittings/v2 v2.7.0-rc.0 github.com/turbot/tailpipe-plugin-sdk v0.9.2 - github.com/zclconf/go-cty v1.14.4 + github.com/zclconf/go-cty v1.16.3 golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 ) @@ -177,7 +177,7 @@ require ( github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/locker v1.0.1 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect @@ -205,7 +205,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/pflag v1.0.6 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect github.com/stevenle/topsort v0.2.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect diff --git a/go.sum b/go.sum index 856b516a..19ecc374 100644 --- a/go.sum +++ b/go.sum @@ -630,8 +630,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0 github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ= @@ -1037,8 +1037,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= -github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= +github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= +github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM= github.com/hashicorp/terraform-registry-address v0.2.1 h1:QuTf6oJ1+WSflJw6WYOHhLgwUiQ0FrROpHPYFtwTYWM= github.com/hashicorp/terraform-registry-address v0.2.1/go.mod h1:BSE9fIFzp0qWsJUUyGquo4ldV9k2n+psif6NYkBRS3Y= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -1165,8 +1165,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -1264,8 +1264,9 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= @@ -1307,6 +1308,8 @@ github.com/turbot/go-kit v1.3.0 h1:6cIYPAO5hO9fG7Zd5UBC4Ch3+C6AiiyYS0UQnrUlTV0= github.com/turbot/go-kit v1.3.0/go.mod h1:piKJMYCF8EYmKf+D2B78Csy7kOHGmnQVOWingtLKWWQ= github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50 h1:zs87uA6QZsYLk4RRxDOIxt8ro/B2V6HzoMWm05Lo7ao= github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= +github.com/turbot/pipe-fittings/v2 v2.7.0-rc.0 h1:p9/Hf0BNNjZVs5C4AqZlQgmihKt/nboh5OrfGcH8Mhk= +github.com/turbot/pipe-fittings/v2 v2.7.0-rc.0/go.mod h1:V619+tgfLaqoEXFDNzA2p24TBZVf4IkDL9FDLQecMnE= github.com/turbot/pipes-sdk-go v0.12.0 h1:esbbR7bALa5L8n/hqroMPaQSSo3gNM/4X0iTmHa3D6U= github.com/turbot/pipes-sdk-go v0.12.0/go.mod h1:Mb+KhvqqEdRbz/6TSZc2QWDrMa5BN3E4Xw+gPt2TRkc= github.com/turbot/tailpipe-plugin-core v0.2.10 h1:2+B7W4hzyS/pBr1y5ns9w84piWGq/x+WdCUjyPaPreQ= @@ -1327,10 +1330,10 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= -github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +github.com/zclconf/go-cty v1.16.3 h1:osr++gw2T61A8KVYHoQiFbFd1Lh3JOCXc/jFLJXKTxk= +github.com/zclconf/go-cty v1.16.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= github.com/zclconf/go-cty-yaml v1.0.3 h1:og/eOQ7lvA/WWhHGFETVWNduJM7Rjsv2RRpx1sdFMLc= github.com/zclconf/go-cty-yaml v1.0.3/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= diff --git a/internal/collector/collector.go b/internal/collector/collector.go index f73474ec..0d04b0a5 100644 --- a/internal/collector/collector.go +++ b/internal/collector/collector.go @@ -19,7 +19,8 @@ import ( "github.com/turbot/tailpipe-plugin-sdk/row_source" "github.com/turbot/tailpipe/internal/config" "github.com/turbot/tailpipe/internal/database" - "github.com/turbot/tailpipe/internal/filepaths" + localfilepaths "github.com/turbot/tailpipe/internal/filepaths" + "github.com/turbot/pipe-fittings/v2/filepaths" "github.com/turbot/tailpipe/internal/plugin" ) @@ -64,9 +65,12 @@ func New(pluginManager *plugin.PluginManager, partition *config.Partition, cance // get the temp data dir for this collection // - this is located in ~/.turbot/internal/collection// // first clear out any old collection temp dirs - filepaths.CleanupCollectionTempDirs() + // get the collection directory for this workspace + collectionDir := config.GlobalWorkspaceProfile.GetCollectionDir() + + filepaths.CleanupPidTempDirs(collectionDir) // then create a new collection temp dir - collectionTempDir := filepaths.EnsureCollectionTempDir() + collectionTempDir := localfilepaths.EnsureCollectionTempDir() // create the collector c := &Collector{ diff --git a/internal/filepaths/collection_temp_dir.go b/internal/filepaths/collection_temp_dir.go index 1e33b0ee..b635f0ff 100644 --- a/internal/filepaths/collection_temp_dir.go +++ b/internal/filepaths/collection_temp_dir.go @@ -1,56 +1,13 @@ package filepaths import ( - "fmt" - "github.com/turbot/pipe-fittings/v2/utils" + + "github.com/turbot/pipe-fittings/v2/filepaths" "github.com/turbot/tailpipe/internal/config" - "log/slog" - "os" - "path/filepath" - "strconv" ) func EnsureCollectionTempDir() string { collectionDir := config.GlobalWorkspaceProfile.GetCollectionDir() - - // add a PID directory to the collection directory - collectionTempDir := filepath.Join(collectionDir, fmt.Sprintf("%d", os.Getpid())) - - // create the directory if it doesn't exist - if _, err := os.Stat(collectionTempDir); os.IsNotExist(err) { - err := os.MkdirAll(collectionTempDir, 0755) - if err != nil { - slog.Error("failed to create collection temp dir", "error", err) - } - } - return collectionTempDir -} - -func CleanupCollectionTempDirs() { - // get the collection directory for this workspace - collectionDir := config.GlobalWorkspaceProfile.GetCollectionDir() - - files, err := os.ReadDir(collectionDir) - if err != nil { - slog.Warn("failed to list files in collection dir", "error", err) - return - } - for _, file := range files { - // if the file is a directory and is not our collection temp dir, remove it - if file.IsDir() { - // the folder name is the PID - check whether that pid exists - // if it doesn't, remove the folder - // Attempt to find the process - // try to parse the directory name as a pid - pid, err := strconv.ParseInt(file.Name(), 10, 32) - if err == nil { - if utils.PidExists(int(pid)) { - slog.Info(fmt.Sprintf("Cleaning existing collection temp dirs - skipping directory '%s' as process with PID %d exists", file.Name(), pid)) - continue - } - } - slog.Debug("Removing directory", "dir", file.Name()) - _ = os.RemoveAll(filepath.Join(collectionDir, file.Name())) - } - } + pidTempDir := filepaths.EnsurePidTempDir(collectionDir) + return pidTempDir } diff --git a/internal/filepaths/prune.go b/internal/filepaths/prune.go index e4c73f13..247df1a3 100644 --- a/internal/filepaths/prune.go +++ b/internal/filepaths/prune.go @@ -1,9 +1,9 @@ package filepaths import ( - "io" "os" "path/filepath" + pfilepaths "github.com/turbot/pipe-fittings/v2/filepaths" ) // PruneTree recursively deletes empty directories in the given folder. @@ -12,7 +12,7 @@ func PruneTree(folder string) error { if _, err := os.Stat(folder); os.IsNotExist(err) { return nil } - isEmpty, err := isDirEmpty(folder) + isEmpty, err := pfilepaths.IsDirEmpty(folder) if err != nil { return err } @@ -36,7 +36,7 @@ func PruneTree(folder string) error { } // Check again if the folder is empty after pruning subdirectories - isEmpty, err = isDirEmpty(folder) + isEmpty, err = pfilepaths.IsDirEmpty(folder) if err != nil { return err } @@ -47,18 +47,3 @@ func PruneTree(folder string) error { return nil } - -// isDirEmpty checks if a directory is empty. -func isDirEmpty(dir string) (bool, error) { - f, err := os.Open(dir) - if err != nil { - return false, err - } - defer f.Close() - - _, err = f.Readdir(1) - if err == io.EOF { - return true, nil - } - return false, err -}