Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e0b9e03

Browse filesBrowse files
committed
fix: cleanup stale temporary directories
please note that this might take a while because we clean by batches, use `find ~/.symfony5/tmp -type d -mindepth 1 -maxdepth 1 -delete` if you are eager
1 parent f7b227d commit e0b9e03
Copy full SHA for e0b9e03

File tree

4 files changed

+84
-2
lines changed
Filter options

4 files changed

+84
-2
lines changed

‎local/php/composer.go

Copy file name to clipboardExpand all lines: local/php/composer.go
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func Composer(dir string, args, env []string, stdout, stderr, logger io.Writer,
7878
fmt.Fprintln(logger, " WARNING: Unable to find Composer, downloading one. It is recommended to install Composer yourself at https://getcomposer.org/download/")
7979
// we don't store it under bin/ to avoid it being found by findComposer as we want to only use it as a fallback
8080
binDir := filepath.Join(util.GetHomeDir(), "composer")
81-
if path, err = downloadComposer(binDir); err != nil {
81+
if path, err = downloadComposer(binDir, debugLogger); err != nil {
8282
return ComposerResult{
8383
code: 1,
8484
error: errors.Wrap(err, "unable to find composer, get it at https://getcomposer.org/download/"),
@@ -157,7 +157,7 @@ func findComposer(extraBin string, logger zerolog.Logger) (string, error) {
157157
return "", os.ErrNotExist
158158
}
159159

160-
func downloadComposer(dir string) (string, error) {
160+
func downloadComposer(dir string, debugLogger zerolog.Logger) (string, error) {
161161
if err := os.MkdirAll(dir, 0755); err != nil {
162162
return "", err
163163
}
@@ -193,6 +193,7 @@ func downloadComposer(dir string) (string, error) {
193193
SkipNbArgs: 1,
194194
Stdout: &stdout,
195195
Stderr: &stdout,
196+
Logger: debugLogger,
196197
}
197198
ret := e.Execute(false)
198199
if ret == 1 {

‎local/php/executor.go

Copy file name to clipboardExpand all lines: local/php/executor.go
+78Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"runtime"
3030
"strings"
3131
"syscall"
32+
"time"
3233

3334
"github.com/pkg/errors"
3435
"github.com/rs/xid"
@@ -291,6 +292,7 @@ func (e *Executor) Config(loadDotEnv bool) error {
291292
}
292293

293294
func (e *Executor) CleanupTemporaryDirectories() {
295+
go cleanupStaleTemporaryDirectories(e.Logger)
294296
if e.iniDir != "" {
295297
os.RemoveAll(e.iniDir)
296298
}
@@ -299,6 +301,82 @@ func (e *Executor) CleanupTemporaryDirectories() {
299301
}
300302
}
301303

304+
// The Symfony CLI used to leak temporary directories until v5.10.8. The bug is
305+
// fixed but because directories names are random they are not going to be
306+
// reused and thus are not going to be cleaned up. And because they might be
307+
// in-use by running servers we can't simply delete the parent directory. This
308+
// is why we make our best to find the oldest directories and remove then,
309+
// cleaning the directory little by little.
310+
func cleanupStaleTemporaryDirectories(mainLogger zerolog.Logger) {
311+
parentDirectory := filepath.Join(util.GetHomeDir(), "tmp")
312+
mainLogger = mainLogger.With().Str("dir", parentDirectory).Logger()
313+
314+
if len(parentDirectory) < 6 {
315+
mainLogger.Warn().Msg("temporary dir path looks too short")
316+
return
317+
}
318+
319+
mainLogger.Debug().Msg("Starting temporary directory cleanup...")
320+
dir, err := os.Open(parentDirectory)
321+
if err != nil {
322+
mainLogger.Warn().Err(err).Msg("Failed to open temporary directory")
323+
return
324+
}
325+
defer dir.Close()
326+
327+
// the duration after which we consider temporary directories as
328+
// stale and can be removed
329+
cutoff := time.Now().Add(-7 * 24 * time.Hour)
330+
331+
for {
332+
// we might have a lof of entries so we need to work in batches
333+
entries, err := dir.Readdirnames(30)
334+
if err == io.EOF {
335+
mainLogger.Debug().Msg("Cleaning is done...")
336+
return
337+
}
338+
if err != nil {
339+
mainLogger.Warn().Err(err).Msg("Failed to read entries")
340+
return
341+
}
342+
343+
for _, entry := range entries {
344+
logger := mainLogger.With().Str("entry", entry).Logger()
345+
346+
// we generate temporary directory names with
347+
// `xid.New().String()` which is always 20 char long
348+
if len(entry) != 20 {
349+
logger.Debug().Msg("found an entry that is not from us")
350+
continue
351+
} else if _, err := xid.FromString(entry); err != nil {
352+
logger.Debug().Err(err).Msg("found an entry that is not from us")
353+
continue
354+
}
355+
356+
entryPath := filepath.Join(parentDirectory, entry)
357+
file, err := os.Open(entryPath)
358+
if err != nil {
359+
logger.Warn().Err(err).Msg("failed to read entry")
360+
continue
361+
} else if fi, err := file.Stat(); err != nil {
362+
logger.Warn().Err(err).Msg("failed to read entry")
363+
continue
364+
} else if !fi.IsDir() {
365+
logger.Warn().Err(err).Msg("entry is not a directory")
366+
continue
367+
} else if fi.ModTime().After(cutoff) {
368+
logger.Debug().Any("cutoff", cutoff).Msg("entry is more recent than cutoff, keeping it for now")
369+
continue
370+
}
371+
372+
logger.Debug().Str("entry", entry).Msg("entry matches the criterias, removing it")
373+
if err := os.RemoveAll(entryPath); err != nil {
374+
logger.Warn().Err(err).Msg("failed to remove entry")
375+
}
376+
}
377+
}
378+
}
379+
302380
// Find composer depending on the configuration
303381
func (e *Executor) findComposer(extraBin string) (string, error) {
304382
if scriptDir, err := e.DetectScriptDir(); err == nil {

‎local/php/php_server.go

Copy file name to clipboardExpand all lines: local/php/php_server.go
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ func (p *Server) Start(ctx context.Context, pidFile *pid.PidFile) (*pid.PidFile,
166166
BinName: binName,
167167
Args: args,
168168
scriptDir: p.projectDir,
169+
Logger: p.logger,
169170
}
170171
p.logger.Info().Int("port", port).Msg("listening")
171172

‎main.go

Copy file name to clipboardExpand all lines: main.go
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,14 @@ func main() {
6868
BinName: args[1],
6969
Args: args[1:],
7070
ExtraEnv: getCliExtraEnv(),
71+
Logger: terminal.Logger,
7172
}
7273
os.Exit(e.Execute(true))
7374
}
7475
// called via "symfony console"?
7576
if len(args) >= 2 && args[1] == "console" {
7677
if executor, err := php.SymonyConsoleExecutor(args[2:]); err == nil {
78+
executor.Logger = terminal.Logger
7779
executor.ExtraEnv = getCliExtraEnv()
7880
os.Exit(executor.Execute(false))
7981
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.