mirror of
https://github.com/mudler/luet.git
synced 2025-07-04 02:56:18 +00:00
Add support for same-owner config option
This commit is contained in:
parent
96f4a6c0e3
commit
524bbf990e
12
cmd/root.go
12
cmd/root.go
@ -17,6 +17,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@ -110,8 +111,19 @@ func init() {
|
|||||||
pflags.StringVar(&cfgFile, "config", "", "config file (default is $HOME/.luet.yaml)")
|
pflags.StringVar(&cfgFile, "config", "", "config file (default is $HOME/.luet.yaml)")
|
||||||
pflags.BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
|
pflags.BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
|
||||||
pflags.Bool("fatal", false, "Enables Warnings to exit")
|
pflags.Bool("fatal", false, "Enables Warnings to exit")
|
||||||
|
|
||||||
|
u, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
Fatal("failed to retrieve user identity:", err.Error())
|
||||||
|
}
|
||||||
|
sameOwner := false
|
||||||
|
if u.Uid == "0" {
|
||||||
|
sameOwner = true
|
||||||
|
}
|
||||||
|
pflags.Bool("same-owner", sameOwner, "Maintain same owner on uncompress.")
|
||||||
pflags.Int("concurrency", runtime.NumCPU(), "Concurrency")
|
pflags.Int("concurrency", runtime.NumCPU(), "Concurrency")
|
||||||
|
|
||||||
|
config.LuetCfg.Viper.BindPFlag("general.same_owner", pflags.Lookup("same-owner"))
|
||||||
config.LuetCfg.Viper.BindPFlag("general.debug", pflags.Lookup("verbose"))
|
config.LuetCfg.Viper.BindPFlag("general.debug", pflags.Lookup("verbose"))
|
||||||
config.LuetCfg.Viper.BindPFlag("general.concurrency", pflags.Lookup("concurrency"))
|
config.LuetCfg.Viper.BindPFlag("general.concurrency", pflags.Lookup("concurrency"))
|
||||||
config.LuetCfg.Viper.BindPFlag("general.fatal_warnings", pflags.Lookup("fatal"))
|
config.LuetCfg.Viper.BindPFlag("general.fatal_warnings", pflags.Lookup("fatal"))
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
# Enable warnings to exit
|
# Enable warnings to exit
|
||||||
# fatal_warnings: false
|
# fatal_warnings: false
|
||||||
#
|
#
|
||||||
|
# Try extracting tree/packages with the same ownership as exists in the archive (default for superuser).
|
||||||
|
# same_owner: false
|
||||||
|
#
|
||||||
# ---------------------------------------------
|
# ---------------------------------------------
|
||||||
# System configuration section:
|
# System configuration section:
|
||||||
# ---------------------------------------------
|
# ---------------------------------------------
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
. "github.com/mudler/luet/pkg/config"
|
||||||
"github.com/mudler/luet/pkg/helpers"
|
"github.com/mudler/luet/pkg/helpers"
|
||||||
. "github.com/mudler/luet/pkg/logger"
|
. "github.com/mudler/luet/pkg/logger"
|
||||||
"github.com/mudler/luet/pkg/solver"
|
"github.com/mudler/luet/pkg/solver"
|
||||||
@ -294,14 +295,15 @@ func (a *PackageArtifact) Unpack(dst string, keepPerms bool) error {
|
|||||||
return errors.Wrap(err, "Cannot copy to "+a.GetPath()+".uncompressed")
|
return errors.Wrap(err, "Cannot copy to "+a.GetPath()+".uncompressed")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = helpers.Untar(a.GetPath()+".uncompressed", dst, keepPerms)
|
err = helpers.Untar(a.GetPath()+".uncompressed", dst,
|
||||||
|
LuetCfg.GetGeneral().SameOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
// Defaults to tar only (covers when "none" is supplied)
|
// Defaults to tar only (covers when "none" is supplied)
|
||||||
default:
|
default:
|
||||||
return helpers.Untar(a.GetPath(), dst, keepPerms)
|
return helpers.Untar(a.GetPath(), dst, LuetCfg.GetGeneral().SameOwner)
|
||||||
}
|
}
|
||||||
return errors.New("Compression type must be supplied")
|
return errors.New("Compression type must be supplied")
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os/user"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ type LuetLoggingConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LuetGeneralConfig struct {
|
type LuetGeneralConfig struct {
|
||||||
|
SameOwner bool `mapstructure:"same_owner"`
|
||||||
Concurrency int `mapstructure:"concurrency"`
|
Concurrency int `mapstructure:"concurrency"`
|
||||||
Debug bool `mapstructure:"debug"`
|
Debug bool `mapstructure:"debug"`
|
||||||
ShowBuildOutput bool `mapstructure:"show_build_output"`
|
ShowBuildOutput bool `mapstructure:"show_build_output"`
|
||||||
@ -125,7 +127,6 @@ func NewLuetConfig(viper *v.Viper) *LuetConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GenDefault(viper *v.Viper) {
|
func GenDefault(viper *v.Viper) {
|
||||||
|
|
||||||
viper.SetDefault("logging.level", "info")
|
viper.SetDefault("logging.level", "info")
|
||||||
viper.SetDefault("logging.path", "")
|
viper.SetDefault("logging.path", "")
|
||||||
viper.SetDefault("logging.json_format", false)
|
viper.SetDefault("logging.json_format", false)
|
||||||
@ -137,6 +138,13 @@ func GenDefault(viper *v.Viper) {
|
|||||||
viper.SetDefault("general.spinner_charset", 22)
|
viper.SetDefault("general.spinner_charset", 22)
|
||||||
viper.SetDefault("general.fatal_warnings", false)
|
viper.SetDefault("general.fatal_warnings", false)
|
||||||
|
|
||||||
|
u, _ := user.Current()
|
||||||
|
if u.Uid == "0" {
|
||||||
|
viper.SetDefault("general.same_owner", true)
|
||||||
|
} else {
|
||||||
|
viper.SetDefault("general.same_owner", false)
|
||||||
|
}
|
||||||
|
|
||||||
viper.SetDefault("system.database_engine", "boltdb")
|
viper.SetDefault("system.database_engine", "boltdb")
|
||||||
viper.SetDefault("system.database_path", "/var/cache/luet")
|
viper.SetDefault("system.database_path", "/var/cache/luet")
|
||||||
viper.SetDefault("system.rootfs", "/")
|
viper.SetDefault("system.rootfs", "/")
|
||||||
@ -182,11 +190,13 @@ func (c *LuetGeneralConfig) String() string {
|
|||||||
ans := fmt.Sprintf(`
|
ans := fmt.Sprintf(`
|
||||||
general:
|
general:
|
||||||
concurrency: %d
|
concurrency: %d
|
||||||
|
same_owner: %t
|
||||||
debug: %t
|
debug: %t
|
||||||
fatal_warnings: %t
|
fatal_warnings: %t
|
||||||
show_build_output: %t
|
show_build_output: %t
|
||||||
spinner_ms: %d
|
spinner_ms: %d
|
||||||
spinner_charset: %d`, c.Concurrency, c.Debug, c.FatalWarns, c.ShowBuildOutput,
|
spinner_charset: %d`, c.Concurrency, c.SameOwner, c.Debug,
|
||||||
|
c.FatalWarns, c.ShowBuildOutput,
|
||||||
c.SpinnerMs, c.SpinnerCharset)
|
c.SpinnerMs, c.SpinnerCharset)
|
||||||
|
|
||||||
return ans
|
return ans
|
||||||
|
@ -16,13 +16,14 @@
|
|||||||
package helpers
|
package helpers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"archive/tar"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
//"os/user"
|
"path/filepath"
|
||||||
//"strconv"
|
|
||||||
|
. "github.com/mudler/luet/pkg/config"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
//"github.com/docker/docker/pkg/idtools"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Tar(src, dest string) error {
|
func Tar(src, dest string) error {
|
||||||
@ -52,31 +53,82 @@ func Tar(src, dest string) error {
|
|||||||
|
|
||||||
// Untar just a wrapper around the docker functions
|
// Untar just a wrapper around the docker functions
|
||||||
func Untar(src, dest string, sameOwner bool) error {
|
func Untar(src, dest string, sameOwner bool) error {
|
||||||
|
var ans error
|
||||||
|
|
||||||
in, err := os.Open(src)
|
in, err := os.Open(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer in.Close()
|
defer in.Close()
|
||||||
|
|
||||||
opts := &archive.TarOptions{
|
if LuetCfg.GetGeneral().SameOwner {
|
||||||
// NOTE: NoLchown boolean is used for chmod of the symlink
|
// PRE: i have root privileged.
|
||||||
// Probably it's needed set this always to true.
|
|
||||||
NoLchown: true,
|
opts := &archive.TarOptions{
|
||||||
ExcludePatterns: []string{"dev/"}, // prevent 'operation not permitted'
|
// NOTE: NoLchown boolean is used for chmod of the symlink
|
||||||
|
// Probably it's needed set this always to true.
|
||||||
|
NoLchown: true,
|
||||||
|
ExcludePatterns: []string{"dev/"}, // prevent 'operation not permitted'
|
||||||
|
}
|
||||||
|
|
||||||
|
ans = archive.Untar(in, dest, opts)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var fileReader io.ReadCloser = in
|
||||||
|
|
||||||
|
tr := tar.NewReader(fileReader)
|
||||||
|
for {
|
||||||
|
header, err := tr.Next()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case err == io.EOF:
|
||||||
|
goto tarEof
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
case header == nil:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// the target location where the dir/file should be created
|
||||||
|
target := filepath.Join(dest, header.Name)
|
||||||
|
|
||||||
|
// Check the file type
|
||||||
|
switch header.Typeflag {
|
||||||
|
|
||||||
|
// if its a dir and it doesn't exist create it
|
||||||
|
case tar.TypeDir:
|
||||||
|
if _, err := os.Stat(target); err != nil {
|
||||||
|
if err := os.MkdirAll(target, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle creation of file
|
||||||
|
case tar.TypeReg:
|
||||||
|
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy over contents
|
||||||
|
if _, err := io.Copy(f, tr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// manually close here after each file operation; defering would cause each
|
||||||
|
// file close to wait until all operations have completed.
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
case tar.TypeSymlink:
|
||||||
|
source := header.Linkname
|
||||||
|
err := os.Symlink(source, target)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tarEof:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return ans
|
||||||
u, err := user.Current()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// TODO: This seems not sufficient for untar with normal user.
|
|
||||||
if u.Uid != "0" {
|
|
||||||
uid, _ := strconv.Atoi(u.Uid)
|
|
||||||
gid, _ := strconv.Atoi(u.Gid)
|
|
||||||
opts.ChownOpts = &idtools.Identity{UID: uid, GID: gid}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return archive.Untar(in, dest, opts)
|
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,8 @@ func GetRepoDatabaseDirPath(name string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetSystemRepoDatabaseDirPath() string {
|
func GetSystemRepoDatabaseDirPath() string {
|
||||||
dbpath := filepath.Join(config.LuetCfg.GetSystem().Rootfs, config.LuetCfg.GetSystem().DatabasePath)
|
dbpath := filepath.Join(config.LuetCfg.GetSystem().Rootfs,
|
||||||
|
config.LuetCfg.GetSystem().DatabasePath)
|
||||||
err := os.MkdirAll(dbpath, os.ModePerm)
|
err := os.MkdirAll(dbpath, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user