2019-12-27 19:12:08 +00:00
|
|
|
// Copyright © 2019 Ettore Di Giacinto <mudler@gentoo.org>
|
|
|
|
// Daniele Rondina <geaaru@sabayonlinux.org>
|
|
|
|
//
|
|
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-02-12 09:20:07 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
2020-02-12 10:21:08 +00:00
|
|
|
"os/user"
|
2020-02-12 09:20:07 +00:00
|
|
|
"path/filepath"
|
2020-02-12 10:21:08 +00:00
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
"time"
|
2019-12-27 19:12:08 +00:00
|
|
|
|
2021-10-19 11:05:25 +00:00
|
|
|
types "github.com/mudler/luet/pkg/api/core/types"
|
2021-08-04 14:16:54 +00:00
|
|
|
fileHelper "github.com/mudler/luet/pkg/helpers/file"
|
2020-12-19 16:23:59 +00:00
|
|
|
pkg "github.com/mudler/luet/pkg/package"
|
2020-02-12 09:20:07 +00:00
|
|
|
solver "github.com/mudler/luet/pkg/solver"
|
2020-05-01 06:18:18 +00:00
|
|
|
|
2021-08-11 14:26:34 +00:00
|
|
|
"github.com/pkg/errors"
|
2019-12-27 19:12:08 +00:00
|
|
|
v "github.com/spf13/viper"
|
2021-08-11 14:26:34 +00:00
|
|
|
"gopkg.in/yaml.v2"
|
2019-12-27 19:12:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var LuetCfg = NewLuetConfig(v.GetViper())
|
2020-02-12 10:21:08 +00:00
|
|
|
var AvailableResolvers = strings.Join([]string{solver.QLearningResolverType}, " ")
|
2019-12-27 19:12:08 +00:00
|
|
|
|
|
|
|
type LuetLoggingConfig struct {
|
2020-05-09 08:08:21 +00:00
|
|
|
// Path of the logfile
|
|
|
|
Path string `mapstructure:"path"`
|
|
|
|
// Enable/Disable logging to file
|
|
|
|
EnableLogFile bool `mapstructure:"enable_logfile"`
|
|
|
|
// Enable JSON format logging in file
|
|
|
|
JsonFormat bool `mapstructure:"json_format"`
|
|
|
|
|
|
|
|
// Log level
|
|
|
|
Level string `mapstructure:"level"`
|
|
|
|
|
|
|
|
// Enable emoji
|
|
|
|
EnableEmoji bool `mapstructure:"enable_emoji"`
|
|
|
|
// Enable/Disable color in logging
|
|
|
|
Color bool `mapstructure:"color"`
|
2019-12-27 19:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type LuetGeneralConfig struct {
|
2021-08-11 14:26:34 +00:00
|
|
|
SameOwner bool `yaml:"same_owner,omitempty" mapstructure:"same_owner"`
|
|
|
|
Concurrency int `yaml:"concurrency,omitempty" mapstructure:"concurrency"`
|
|
|
|
Debug bool `yaml:"debug,omitempty" mapstructure:"debug"`
|
|
|
|
ShowBuildOutput bool `yaml:"show_build_output,omitempty" mapstructure:"show_build_output"`
|
|
|
|
SpinnerMs int `yaml:"spinner_ms,omitempty" mapstructure:"spinner_ms"`
|
|
|
|
SpinnerCharset int `yaml:"spinner_charset,omitempty" mapstructure:"spinner_charset"`
|
|
|
|
FatalWarns bool `yaml:"fatal_warnings,omitempty" mapstructure:"fatal_warnings"`
|
2019-12-27 19:12:08 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 10:21:08 +00:00
|
|
|
type LuetSolverOptions struct {
|
2021-08-11 14:26:34 +00:00
|
|
|
solver.Options `yaml:"options,omitempty"`
|
|
|
|
Type string `yaml:"type,omitempty" mapstructure:"type"`
|
|
|
|
LearnRate float32 `yaml:"rate,omitempty" mapstructure:"rate"`
|
|
|
|
Discount float32 `yaml:"discount,omitempty" mapstructure:"discount"`
|
|
|
|
MaxAttempts int `yaml:"max_attempts,omitempty" mapstructure:"max_attempts"`
|
|
|
|
Implementation solver.SolverType `yaml:"implementation,omitempty" mapstructure:"implementation"`
|
2020-02-12 10:21:08 +00:00
|
|
|
}
|
|
|
|
|
2020-12-03 17:53:57 +00:00
|
|
|
func (opts LuetSolverOptions) ResolverIsSet() bool {
|
|
|
|
switch opts.Type {
|
|
|
|
case solver.QLearningResolverType:
|
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-12 10:21:08 +00:00
|
|
|
func (opts LuetSolverOptions) Resolver() solver.PackageResolver {
|
|
|
|
switch opts.Type {
|
|
|
|
case solver.QLearningResolverType:
|
|
|
|
if opts.LearnRate != 0.0 {
|
|
|
|
return solver.NewQLearningResolver(opts.LearnRate, opts.Discount, opts.MaxAttempts, 999999)
|
|
|
|
|
|
|
|
}
|
|
|
|
return solver.SimpleQLearningSolver()
|
|
|
|
}
|
|
|
|
|
2021-08-07 09:11:42 +00:00
|
|
|
return &solver.Explainer{}
|
2020-02-12 10:21:08 +00:00
|
|
|
}
|
|
|
|
|
2020-02-12 11:23:37 +00:00
|
|
|
func (opts *LuetSolverOptions) CompactString() string {
|
|
|
|
return fmt.Sprintf("type: %s rate: %f, discount: %f, attempts: %d, initialobserved: %d",
|
|
|
|
opts.Type, opts.LearnRate, opts.Discount, opts.MaxAttempts, 999999)
|
|
|
|
}
|
|
|
|
|
2019-12-30 20:56:13 +00:00
|
|
|
type LuetSystemConfig struct {
|
|
|
|
DatabaseEngine string `yaml:"database_engine" mapstructure:"database_engine"`
|
|
|
|
DatabasePath string `yaml:"database_path" mapstructure:"database_path"`
|
|
|
|
Rootfs string `yaml:"rootfs" mapstructure:"rootfs"`
|
2020-02-01 18:35:30 +00:00
|
|
|
PkgsCachePath string `yaml:"pkgs_cache_path" mapstructure:"pkgs_cache_path"`
|
2020-04-30 18:29:28 +00:00
|
|
|
TmpDirBase string `yaml:"tmpdir_base" mapstructure:"tmpdir_base"`
|
2019-12-30 20:56:13 +00:00
|
|
|
}
|
|
|
|
|
2021-08-03 14:17:55 +00:00
|
|
|
func (s *LuetSystemConfig) SetRootFS(path string) error {
|
2021-08-04 14:16:54 +00:00
|
|
|
p, err := fileHelper.Rel2Abs(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2021-08-03 14:17:55 +00:00
|
|
|
}
|
2021-08-04 14:16:54 +00:00
|
|
|
|
|
|
|
s.Rootfs = p
|
2021-08-03 14:17:55 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-11-07 17:28:23 +00:00
|
|
|
func (sc *LuetSystemConfig) GetRepoDatabaseDirPath(name string) string {
|
2020-02-12 09:20:07 +00:00
|
|
|
dbpath := filepath.Join(sc.Rootfs, sc.DatabasePath)
|
|
|
|
dbpath = filepath.Join(dbpath, "repos/"+name)
|
|
|
|
err := os.MkdirAll(dbpath, os.ModePerm)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return dbpath
|
|
|
|
}
|
|
|
|
|
2020-11-07 17:28:23 +00:00
|
|
|
func (sc *LuetSystemConfig) GetSystemRepoDatabaseDirPath() string {
|
2020-02-12 09:20:07 +00:00
|
|
|
dbpath := filepath.Join(sc.Rootfs,
|
|
|
|
sc.DatabasePath)
|
|
|
|
err := os.MkdirAll(dbpath, os.ModePerm)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return dbpath
|
|
|
|
}
|
|
|
|
|
2020-11-07 17:28:23 +00:00
|
|
|
func (sc *LuetSystemConfig) GetSystemPkgsCacheDirPath() (ans string) {
|
2020-02-12 09:20:07 +00:00
|
|
|
var cachepath string
|
|
|
|
if sc.PkgsCachePath != "" {
|
|
|
|
cachepath = sc.PkgsCachePath
|
|
|
|
} else {
|
|
|
|
// Create dynamic cache for test suites
|
|
|
|
cachepath, _ = ioutil.TempDir(os.TempDir(), "cachepkgs")
|
|
|
|
}
|
|
|
|
|
|
|
|
if filepath.IsAbs(cachepath) {
|
|
|
|
ans = cachepath
|
|
|
|
} else {
|
|
|
|
ans = filepath.Join(sc.GetSystemRepoDatabaseDirPath(), cachepath)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-11-07 17:28:23 +00:00
|
|
|
func (sc *LuetSystemConfig) GetRootFsAbs() (string, error) {
|
|
|
|
return filepath.Abs(sc.Rootfs)
|
|
|
|
}
|
|
|
|
|
2019-12-27 19:12:08 +00:00
|
|
|
|
2021-08-11 09:18:16 +00:00
|
|
|
type LuetKV struct {
|
|
|
|
Key string `json:"key" yaml:"key" mapstructure:"key"`
|
|
|
|
Value string `json:"value" yaml:"value" mapstructure:"value"`
|
|
|
|
}
|
|
|
|
|
2019-12-27 19:12:08 +00:00
|
|
|
type LuetConfig struct {
|
2021-08-11 14:26:34 +00:00
|
|
|
Viper *v.Viper `yaml:"-"`
|
2019-12-27 19:12:08 +00:00
|
|
|
|
2021-08-11 14:26:34 +00:00
|
|
|
Logging LuetLoggingConfig `yaml:"logging,omitempty" mapstructure:"logging"`
|
|
|
|
General LuetGeneralConfig `yaml:"general,omitempty" mapstructure:"general"`
|
|
|
|
System LuetSystemConfig `yaml:"system" mapstructure:"system"`
|
|
|
|
Solver LuetSolverOptions `yaml:"solver,omitempty" mapstructure:"solver"`
|
2019-12-27 19:12:08 +00:00
|
|
|
|
2021-10-19 11:05:25 +00:00
|
|
|
RepositoriesConfDir []string `yaml:"repos_confdir,omitempty" mapstructure:"repos_confdir"`
|
|
|
|
ConfigProtectConfDir []string `yaml:"config_protect_confdir,omitempty" mapstructure:"config_protect_confdir"`
|
|
|
|
ConfigProtectSkip bool `yaml:"config_protect_skip,omitempty" mapstructure:"config_protect_skip"`
|
|
|
|
ConfigFromHost bool `yaml:"config_from_host,omitempty" mapstructure:"config_from_host"`
|
|
|
|
SystemRepositories types.LuetRepositories `yaml:"repositories,omitempty" mapstructure:"repositories"`
|
2020-06-02 09:08:37 +00:00
|
|
|
|
2021-08-11 09:18:16 +00:00
|
|
|
FinalizerEnvs []LuetKV `json:"finalizer_envs,omitempty" yaml:"finalizer_envs,omitempty" mapstructure:"finalizer_envs,omitempty"`
|
|
|
|
|
2021-08-11 14:26:34 +00:00
|
|
|
ConfigProtectConfFiles []ConfigProtectConfFile `yaml:"-" mapstructure:"-"`
|
2019-12-27 19:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewLuetConfig(viper *v.Viper) *LuetConfig {
|
|
|
|
if viper == nil {
|
|
|
|
viper = v.New()
|
|
|
|
}
|
|
|
|
|
|
|
|
GenDefault(viper)
|
2020-06-02 09:08:37 +00:00
|
|
|
return &LuetConfig{Viper: viper, ConfigProtectConfFiles: nil}
|
2019-12-27 19:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func GenDefault(viper *v.Viper) {
|
|
|
|
viper.SetDefault("logging.level", "info")
|
2020-05-07 06:14:37 +00:00
|
|
|
viper.SetDefault("logging.enable_logfile", false)
|
|
|
|
viper.SetDefault("logging.path", "/var/log/luet.log")
|
2020-01-03 14:20:42 +00:00
|
|
|
viper.SetDefault("logging.json_format", false)
|
2020-05-09 08:08:21 +00:00
|
|
|
viper.SetDefault("logging.enable_emoji", true)
|
|
|
|
viper.SetDefault("logging.color", true)
|
2019-12-27 19:12:08 +00:00
|
|
|
|
|
|
|
viper.SetDefault("general.concurrency", runtime.NumCPU())
|
|
|
|
viper.SetDefault("general.debug", false)
|
|
|
|
viper.SetDefault("general.show_build_output", false)
|
|
|
|
viper.SetDefault("general.spinner_ms", 100)
|
|
|
|
viper.SetDefault("general.spinner_charset", 22)
|
2020-01-03 14:41:45 +00:00
|
|
|
viper.SetDefault("general.fatal_warnings", false)
|
2019-12-27 19:12:08 +00:00
|
|
|
|
2020-04-11 18:05:56 +00:00
|
|
|
u, err := user.Current()
|
|
|
|
// os/user doesn't work in from scratch environments
|
2020-05-30 14:51:10 +00:00
|
|
|
if err != nil || (u != nil && u.Uid == "0") {
|
2020-02-01 16:58:23 +00:00
|
|
|
viper.SetDefault("general.same_owner", true)
|
|
|
|
} else {
|
|
|
|
viper.SetDefault("general.same_owner", false)
|
|
|
|
}
|
|
|
|
|
2019-12-30 20:56:13 +00:00
|
|
|
viper.SetDefault("system.database_engine", "boltdb")
|
|
|
|
viper.SetDefault("system.database_path", "/var/cache/luet")
|
|
|
|
viper.SetDefault("system.rootfs", "/")
|
2020-04-30 18:29:28 +00:00
|
|
|
viper.SetDefault("system.tmpdir_base", filepath.Join(os.TempDir(), "tmpluet"))
|
2020-02-01 18:35:30 +00:00
|
|
|
viper.SetDefault("system.pkgs_cache_path", "packages")
|
2019-12-30 20:56:13 +00:00
|
|
|
|
2019-12-27 19:12:08 +00:00
|
|
|
viper.SetDefault("repos_confdir", []string{"/etc/luet/repos.conf.d"})
|
2020-06-02 07:04:40 +00:00
|
|
|
viper.SetDefault("config_protect_confdir", []string{"/etc/luet/config.protect.d"})
|
2020-10-02 20:25:21 +00:00
|
|
|
viper.SetDefault("config_protect_skip", false)
|
2020-11-07 17:56:25 +00:00
|
|
|
// TODO: Set default to false when we are ready for migration.
|
|
|
|
viper.SetDefault("config_from_host", true)
|
2019-12-27 19:12:08 +00:00
|
|
|
viper.SetDefault("cache_repositories", []string{})
|
|
|
|
viper.SetDefault("system_repositories", []string{})
|
2021-08-11 09:18:16 +00:00
|
|
|
viper.SetDefault("finalizer_envs", make(map[string]string, 0))
|
2020-02-12 10:21:08 +00:00
|
|
|
|
|
|
|
viper.SetDefault("solver.type", "")
|
|
|
|
viper.SetDefault("solver.rate", 0.7)
|
|
|
|
viper.SetDefault("solver.discount", 1.0)
|
|
|
|
viper.SetDefault("solver.max_attempts", 9000)
|
2019-12-27 19:12:08 +00:00
|
|
|
}
|
2020-12-19 16:23:59 +00:00
|
|
|
|
|
|
|
func (c *LuetConfig) GetSystemDB() pkg.PackageDatabase {
|
|
|
|
switch LuetCfg.GetSystem().DatabaseEngine {
|
|
|
|
case "boltdb":
|
|
|
|
return pkg.NewBoltDatabase(
|
|
|
|
filepath.Join(LuetCfg.GetSystem().GetSystemRepoDatabaseDirPath(), "luet.db"))
|
|
|
|
default:
|
|
|
|
return pkg.NewInMemoryDatabase(true)
|
|
|
|
}
|
|
|
|
}
|
2019-12-27 19:12:08 +00:00
|
|
|
|
2021-10-19 11:05:25 +00:00
|
|
|
func (c *LuetConfig) AddSystemRepository(r types.LuetRepository) {
|
2019-12-27 19:12:08 +00:00
|
|
|
c.SystemRepositories = append(c.SystemRepositories, r)
|
|
|
|
}
|
|
|
|
|
2021-08-11 09:18:16 +00:00
|
|
|
func (c *LuetConfig) GetFinalizerEnvsMap() map[string]string {
|
|
|
|
ans := make(map[string]string, 0)
|
|
|
|
|
|
|
|
for _, kv := range c.FinalizerEnvs {
|
|
|
|
ans[kv.Key] = kv.Value
|
|
|
|
}
|
|
|
|
return ans
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetConfig) SetFinalizerEnv(k, v string) {
|
|
|
|
keyPresent := false
|
|
|
|
envs := []LuetKV{}
|
|
|
|
|
|
|
|
for _, kv := range c.FinalizerEnvs {
|
|
|
|
if kv.Key == k {
|
|
|
|
keyPresent = true
|
|
|
|
envs = append(envs, LuetKV{Key: kv.Key, Value: v})
|
|
|
|
} else {
|
|
|
|
envs = append(envs, kv)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !keyPresent {
|
|
|
|
envs = append(envs, LuetKV{Key: k, Value: v})
|
|
|
|
}
|
|
|
|
|
|
|
|
c.FinalizerEnvs = envs
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetConfig) GetFinalizerEnvs() []string {
|
|
|
|
ans := []string{}
|
|
|
|
for _, kv := range c.FinalizerEnvs {
|
|
|
|
ans = append(ans, fmt.Sprintf("%s=%s", kv.Key, kv.Value))
|
|
|
|
}
|
|
|
|
return ans
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetConfig) GetFinalizerEnv(k string) (string, error) {
|
|
|
|
keyNotPresent := true
|
|
|
|
ans := ""
|
|
|
|
for _, kv := range c.FinalizerEnvs {
|
|
|
|
if kv.Key == k {
|
|
|
|
keyNotPresent = false
|
|
|
|
ans = kv.Value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if keyNotPresent {
|
|
|
|
return "", errors.New("Finalizer key " + k + " not found")
|
|
|
|
}
|
|
|
|
return ans, nil
|
|
|
|
}
|
|
|
|
|
2019-12-27 19:12:08 +00:00
|
|
|
func (c *LuetConfig) GetLogging() *LuetLoggingConfig {
|
|
|
|
return &c.Logging
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetConfig) GetGeneral() *LuetGeneralConfig {
|
|
|
|
return &c.General
|
|
|
|
}
|
|
|
|
|
2019-12-30 20:56:13 +00:00
|
|
|
func (c *LuetConfig) GetSystem() *LuetSystemConfig {
|
|
|
|
return &c.System
|
|
|
|
}
|
|
|
|
|
2020-02-12 10:21:08 +00:00
|
|
|
func (c *LuetConfig) GetSolverOptions() *LuetSolverOptions {
|
|
|
|
return &c.Solver
|
|
|
|
}
|
|
|
|
|
2021-08-11 14:26:34 +00:00
|
|
|
func (c *LuetConfig) YAML() ([]byte, error) {
|
|
|
|
return yaml.Marshal(c)
|
|
|
|
}
|
|
|
|
|
2020-06-02 09:08:37 +00:00
|
|
|
func (c *LuetConfig) GetConfigProtectConfFiles() []ConfigProtectConfFile {
|
|
|
|
return c.ConfigProtectConfFiles
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetConfig) AddConfigProtectConfFile(file *ConfigProtectConfFile) {
|
|
|
|
if c.ConfigProtectConfFiles == nil {
|
|
|
|
c.ConfigProtectConfFiles = []ConfigProtectConfFile{*file}
|
|
|
|
} else {
|
|
|
|
c.ConfigProtectConfFiles = append(c.ConfigProtectConfFiles, *file)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-19 11:05:25 +00:00
|
|
|
func (c *LuetConfig) GetSystemRepository(name string) (*types.LuetRepository, error) {
|
|
|
|
var ans *types.LuetRepository = nil
|
2020-01-12 22:30:10 +00:00
|
|
|
|
|
|
|
for idx, repo := range c.SystemRepositories {
|
|
|
|
if repo.Name == name {
|
|
|
|
ans = &c.SystemRepositories[idx]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ans == nil {
|
|
|
|
return nil, errors.New("Repository " + name + " not found")
|
|
|
|
}
|
|
|
|
|
|
|
|
return ans, nil
|
|
|
|
}
|
|
|
|
|
2019-12-27 19:12:08 +00:00
|
|
|
func (c *LuetGeneralConfig) GetSpinnerMs() time.Duration {
|
|
|
|
duration, err := time.ParseDuration(fmt.Sprintf("%dms", c.SpinnerMs))
|
|
|
|
if err != nil {
|
|
|
|
return 100 * time.Millisecond
|
|
|
|
}
|
|
|
|
return duration
|
|
|
|
}
|
|
|
|
|
2020-04-18 21:22:00 +00:00
|
|
|
func (c *LuetLoggingConfig) SetLogLevel(s string) {
|
|
|
|
c.Level = s
|
|
|
|
}
|
|
|
|
|
2020-04-30 18:29:28 +00:00
|
|
|
func (c *LuetSystemConfig) InitTmpDir() error {
|
2021-08-09 11:17:14 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-06-01 14:43:31 +00:00
|
|
|
if _, err := os.Stat(c.TmpDirBase); err != nil {
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
err = os.MkdirAll(c.TmpDirBase, os.ModePerm)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2020-05-01 06:18:18 +00:00
|
|
|
}
|
|
|
|
return nil
|
2020-04-30 18:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetSystemConfig) CleanupTmpDir() error {
|
|
|
|
return os.RemoveAll(c.TmpDirBase)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetSystemConfig) TempDir(pattern string) (string, error) {
|
2020-05-01 06:18:18 +00:00
|
|
|
err := c.InitTmpDir()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2020-04-30 18:29:28 +00:00
|
|
|
return ioutil.TempDir(c.TmpDirBase, pattern)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *LuetSystemConfig) TempFile(pattern string) (*os.File, error) {
|
2020-05-01 06:18:18 +00:00
|
|
|
err := c.InitTmpDir()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-04-30 18:29:28 +00:00
|
|
|
return ioutil.TempFile(c.TmpDirBase, pattern)
|
|
|
|
}
|