From a6ffa6ea557e84072ef9d3de743cb3ad9b6da1f5 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sat, 4 Dec 2021 22:07:39 +0100 Subject: [PATCH] wip/gc --- pkg/api/core/types/config.go | 40 ------------ pkg/api/core/types/context.go | 15 ++++- pkg/api/core/types/garbagecollector.go | 85 ++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 41 deletions(-) create mode 100644 pkg/api/core/types/garbagecollector.go diff --git a/pkg/api/core/types/config.go b/pkg/api/core/types/config.go index ca53dffc..96732abd 100644 --- a/pkg/api/core/types/config.go +++ b/pkg/api/core/types/config.go @@ -431,43 +431,3 @@ func loadConfigProtectConFile(filename string, data []byte) (*config.ConfigProte func (c *LuetLoggingConfig) SetLogLevel(s LogLevel) { c.Level = s } - -func (c *LuetSystemConfig) InitTmpDir() error { - if !filepath.IsAbs(c.TmpDirBase) { - abs, err := fileHelper.Rel2Abs(c.TmpDirBase) - if err != nil { - return errors.Wrap(err, "while converting relative path to absolute path") - } - c.TmpDirBase = abs - } - - if _, err := os.Stat(c.TmpDirBase); err != nil { - if os.IsNotExist(err) { - err = os.MkdirAll(c.TmpDirBase, os.ModePerm) - if err != nil { - return err - } - } - } - return nil -} - -func (c *LuetSystemConfig) CleanupTmpDir() error { - return os.RemoveAll(c.TmpDirBase) -} - -func (c *LuetSystemConfig) TempDir(pattern string) (string, error) { - err := c.InitTmpDir() - if err != nil { - return "", err - } - return ioutil.TempDir(c.TmpDirBase, pattern) -} - -func (c *LuetSystemConfig) TempFile(pattern string) (*os.File, error) { - err := c.InitTmpDir() - if err != nil { - return nil, err - } - return ioutil.TempFile(c.TmpDirBase, pattern) -} diff --git a/pkg/api/core/types/context.go b/pkg/api/core/types/context.go index 0ab99f5a..5107708b 100644 --- a/pkg/api/core/types/context.go +++ b/pkg/api/core/types/context.go @@ -45,6 +45,7 @@ const ( type Context struct { context.Context + gc *GarbageCollector Config *LuetConfig IsTerminal bool NoSpinner bool @@ -57,22 +58,34 @@ type Context struct { } func NewContext() *Context { + tmp := filepath.Join(os.TempDir(), "tmpluet") + gc, _ := NewGC(tmp) return &Context{ spinnerLock: &sync.Mutex{}, IsTerminal: terminal.IsTerminal(os.Stdout), + gc: gc, Config: &LuetConfig{ ConfigFromHost: true, Logging: LuetLoggingConfig{}, General: LuetGeneralConfig{}, System: LuetSystemConfig{ DatabasePath: filepath.Join("var", "db", "packages"), - TmpDirBase: filepath.Join(os.TempDir(), "tmpluet")}, + TmpDirBase: tmp}, Solver: LuetSolverOptions{}, }, s: pterm.DefaultSpinner.WithShowTimer(false).WithRemoveWhenDone(true), } } +func (c *Context) WithGC(dir string) error { + gc, err := NewGC(dir) + if err != nil { + return err + } + c.gc = gc + return nil +} + func (c *Context) WithName(name string) *Context { newc := c.Copy() newc.name = name diff --git a/pkg/api/core/types/garbagecollector.go b/pkg/api/core/types/garbagecollector.go new file mode 100644 index 00000000..5c9610ea --- /dev/null +++ b/pkg/api/core/types/garbagecollector.go @@ -0,0 +1,85 @@ +// Copyright © 2021 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package types + +import ( + "io/ioutil" + "os" + "path/filepath" + + "github.com/hashicorp/go-multierror" + fileHelper "github.com/mudler/luet/pkg/helpers/file" + "github.com/pkg/errors" +) + +// GarbageCollector keeps track of directory assigned and cleans them up +type GarbageCollector struct { + dir string + createdDirs []string + createdFiles []string +} + +// NewGC returns a new GC instance on dir +func NewGC(s string) (*GarbageCollector, error) { + if !filepath.IsAbs(s) { + abs, err := fileHelper.Rel2Abs(s) + if err != nil { + return nil, errors.Wrap(err, "while converting relative path to absolute path") + } + s = abs + } + if _, err := os.Stat(s); err != nil { + if os.IsNotExist(err) { + err = os.MkdirAll(s, os.ModePerm) + if err != nil { + return nil, err + } + } + } + return &GarbageCollector{dir: s}, nil +} + +func (gc *GarbageCollector) Directory(pattern string) (string, error) { + dir, err := ioutil.TempDir(gc.dir, pattern) + if err != nil { + return "", err + } + gc.createdDirs = append(gc.createdDirs, dir) + return dir, err +} + +func (gc *GarbageCollector) Remove() error { + return os.RemoveAll(gc.dir) +} + +func (gc *GarbageCollector) Clean() (err error) { + for _, d := range append(gc.createdDirs, gc.createdFiles...) { + if fileHelper.Exists(d) { + multierror.Append(err, os.RemoveAll(d)) + } + } + + return +} + +func (gc *GarbageCollector) File(pattern string) (*os.File, error) { + f, err := ioutil.TempFile(gc.dir, pattern) + if err != nil { + return nil, err + } + gc.createdFiles = append(gc.createdFiles, f.Name()) + return f, err +}