Add support for same-owner config option

This commit is contained in:
Daniele Rondina
2020-02-01 17:58:23 +01:00
parent 96f4a6c0e3
commit 524bbf990e
6 changed files with 107 additions and 27 deletions

View File

@@ -16,13 +16,14 @@
package helpers
import (
"archive/tar"
"io"
"os"
//"os/user"
//"strconv"
"path/filepath"
. "github.com/mudler/luet/pkg/config"
"github.com/docker/docker/pkg/archive"
//"github.com/docker/docker/pkg/idtools"
)
func Tar(src, dest string) error {
@@ -52,31 +53,82 @@ func Tar(src, dest string) error {
// Untar just a wrapper around the docker functions
func Untar(src, dest string, sameOwner bool) error {
var ans error
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
opts := &archive.TarOptions{
// 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'
if LuetCfg.GetGeneral().SameOwner {
// PRE: i have root privileged.
opts := &archive.TarOptions{
// 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:
}
/*
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)
return ans
}