Compare commits

...

5 Commits

Author SHA1 Message Date
Ettore Di Giacinto
0589bead99 Tag 0.20.7 2021-11-04 13:02:23 +01:00
Ettore Di Giacinto
fba420865a 🔧 Preserve suid,sgid and sticky bits when extracting images 2021-11-04 11:34:36 +01:00
Ettore Di Giacinto
9857bea5ff 🎨 Lazy progressbar start 2021-10-31 21:21:08 +01:00
Ettore Di Giacinto
100c313804 Tag 0.20.6 2021-10-31 12:21:15 +01:00
Ettore Di Giacinto
d43b8c4af0 Attach platform data when creating images from tars 2021-10-31 10:48:35 +01:00
11 changed files with 142 additions and 25 deletions

View File

@@ -30,7 +30,7 @@ var cfgFile string
var Verbose bool
const (
LuetCLIVersion = "0.20.5"
LuetCLIVersion = "0.20.7"
LuetEnvPrefix = "LUET"
)

View File

@@ -27,7 +27,7 @@ import (
"github.com/pkg/errors"
)
func imageFromTar(imagename string, r io.Reader) (name.Reference, v1.Image, error) {
func imageFromTar(imagename, architecture, OS string, r io.Reader) (name.Reference, v1.Image, error) {
newRef, err := name.ParseReference(imagename)
if err != nil {
return nil, nil, err
@@ -38,7 +38,20 @@ func imageFromTar(imagename string, r io.Reader) (name.Reference, v1.Image, erro
return nil, nil, err
}
img, err := mutate.Append(empty.Image, mutate.Addendum{
baseImage := empty.Image
cfg, err := baseImage.ConfigFile()
if err != nil {
return nil, nil, err
}
cfg.Architecture = architecture
cfg.OS = OS
baseImage, err = mutate.ConfigFile(baseImage, cfg)
if err != nil {
return nil, nil, err
}
img, err := mutate.Append(baseImage, mutate.Addendum{
Layer: layer,
History: v1.History{
CreatedBy: "luet",
@@ -53,25 +66,25 @@ func imageFromTar(imagename string, r io.Reader) (name.Reference, v1.Image, erro
}
// CreateTar a imagetarball from a standard tarball
func CreateTar(srctar, dstimageTar, imagename string) error {
func CreateTar(srctar, dstimageTar, imagename, architecture, OS string) error {
f, err := os.Open(srctar)
if err != nil {
return errors.Wrap(err, "Cannot open "+srctar)
}
defer f.Close()
return CreateTarReader(f, dstimageTar, imagename)
return CreateTarReader(f, dstimageTar, imagename, architecture, OS)
}
// CreateTarReader a imagetarball from a standard tarball
func CreateTarReader(r io.Reader, dstimageTar, imagename string) error {
func CreateTarReader(r io.Reader, dstimageTar, imagename, architecture, OS string) error {
dstFile, err := os.Create(dstimageTar)
if err != nil {
return errors.Wrap(err, "Cannot create "+dstimageTar)
}
defer dstFile.Close()
newRef, img, err := imageFromTar(imagename, r)
newRef, img, err := imageFromTar(imagename, architecture, OS, r)
if err != nil {
return err
}

View File

@@ -18,6 +18,7 @@ package image_test
import (
"os"
"path/filepath"
"runtime"
. "github.com/mudler/luet/pkg/api/core/image"
"github.com/mudler/luet/pkg/api/core/types"
@@ -58,7 +59,7 @@ var _ = Describe("Create", func() {
a.Compress(dir, 1)
// Unfortunately there is no other easy way to test this
err = CreateTar(srcTar.Name(), dst.Name(), "testimage")
err = CreateTar(srcTar.Name(), dst.Name(), "testimage", runtime.GOARCH, runtime.GOOS)
Expect(err).ToNot(HaveOccurred())
b.LoadImage(dst.Name())

View File

@@ -19,6 +19,7 @@ import (
"archive/tar"
"context"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
@@ -208,6 +209,7 @@ func ExtractReader(ctx *types.Context, reader io.ReadCloser, output string, keep
PAX, Xattrs map[string]string
Uid, Gid int
Name string
FileMode fs.FileMode
}
permstore, err := ctx.Config.System.TempDir("permstore")
@@ -222,8 +224,9 @@ func ExtractReader(ctx *types.Context, reader io.ReadCloser, output string, keep
perms.SetValue(h.Name, permData{
PAX: h.PAXRecords,
Uid: h.Uid, Gid: h.Gid,
Xattrs: h.Xattrs,
Name: h.Name,
Xattrs: h.Xattrs,
Name: h.Name,
FileMode: h.FileInfo().Mode(),
})
//perms = append(perms, })
}
@@ -249,6 +252,10 @@ func ExtractReader(ctx *types.Context, reader io.ReadCloser, output string, keep
if err := os.Lchown(ff, p.Uid, p.Gid); err != nil {
ctx.Warning(err, "failed chowning file")
}
ctx.Debug("Set", p.Name, p.FileMode)
if err := os.Chmod(ff, p.FileMode); err != nil {
ctx.Warning(err, "failed chmod file")
}
}
for _, attrs := range []map[string]string{p.Xattrs, p.PAX} {
for k, attr := range attrs {

View File

@@ -27,6 +27,7 @@ import (
"os"
"path"
"path/filepath"
"runtime"
"github.com/docker/docker/pkg/pools"
v1 "github.com/google/go-containerregistry/pkg/v1"
@@ -227,7 +228,7 @@ func (a *PackageArtifact) GenerateFinalImage(ctx *types.Context, imageName strin
}
defer os.RemoveAll(tempimage.Name()) // clean up
if err := image.CreateTarReader(decompressed, tempimage.Name(), imageName); err != nil {
if err := image.CreateTarReader(decompressed, tempimage.Name(), imageName, runtime.GOARCH, runtime.GOOS); err != nil {
return errors.Wrap(err, "could not create image from tar")
}

View File

@@ -52,7 +52,6 @@ type Context struct {
s *pterm.SpinnerPrinter
spinnerLock *sync.Mutex
z *zap.Logger
AreaPrinter *pterm.AreaPrinter
ProgressBar *pterm.ProgressbarPrinter
}

View File

@@ -118,11 +118,7 @@ func (c *HttpClient) DownloadFile(p string) (string, error) {
// Initialize a progressbar only if we have one in the current context
var pb *pterm.ProgressbarPrinter
if c.context.ProgressBar != nil {
pb = pterm.DefaultProgressbar.WithTotal(int(resp.Size()))
if c.context.AreaPrinter != nil {
pb = pb.WithPrintTogether(c.context.AreaPrinter)
}
pb, _ = pb.WithTitle(filepath.Base(resp.Request.HTTPRequest.URL.RequestURI())).Start()
pb, _ = c.context.ProgressBar.WithTotal(int(resp.Size())).WithTitle(filepath.Base(resp.Request.HTTPRequest.URL.RequestURI())).Start()
}
// start download loop
t := time.NewTicker(500 * time.Millisecond)

View File

@@ -576,19 +576,19 @@ func (l *LuetInstaller) download(syncedRepos Repositories, toDownload map[string
// Check if the terminal is big enough to display a progress bar
// https://github.com/pterm/pterm/blob/4c725e56bfd9eb38e1c7b9dec187b50b93baa8bd/progressbar_printer.go#L190
w, _, err := ctx.GetTerminalSize()
var pb *pterm.ProgressbarPrinter
if ctx.IsTerminal && err == nil && w > 100 {
area, _ := pterm.DefaultArea.Start()
p, _ := pterm.DefaultProgressbar.WithPrintTogether(area).WithTotal(len(toDownload)).WithTitle("Downloading packages").Start()
ctx.AreaPrinter = area
ctx.ProgressBar = p
ctx.ProgressBar = pterm.DefaultProgressbar.WithPrintTogether(area).WithTotal(len(toDownload)).WithTitle("Downloading packages")
pb, _ = ctx.ProgressBar.Start()
defer area.Stop()
}
// Download
for i := 0; i < l.Options.Concurrency; i++ {
wg.Add(1)
go l.downloadWorker(i, wg, all, ctx)
go l.downloadWorker(i, wg, pb, all, ctx)
}
for _, c := range toDownload {
all <- c
@@ -920,7 +920,7 @@ func (l *LuetInstaller) installPackage(m ArtifactMatch, s *System) error {
return s.Database.SetPackageFiles(&pkg.PackageFile{PackageFingerprint: m.Package.GetFingerPrint(), Files: files})
}
func (l *LuetInstaller) downloadWorker(i int, wg *sync.WaitGroup, c <-chan ArtifactMatch, ctx *types.Context) error {
func (l *LuetInstaller) downloadWorker(i int, wg *sync.WaitGroup, pb *pterm.ProgressbarPrinter, c <-chan ArtifactMatch, ctx *types.Context) error {
defer wg.Done()
for p := range c {
@@ -932,8 +932,8 @@ func (l *LuetInstaller) downloadWorker(i int, wg *sync.WaitGroup, c <-chan Artif
} else {
l.Options.Context.Success(":package: Package ", p.Package.HumanReadableString(), "downloaded")
}
if ctx.ProgressBar != nil {
ctx.ProgressBar.Increment()
if pb != nil {
pb.Increment()
}
}

View File

@@ -0,0 +1,18 @@
image: "alpine"
unpack: true
includes:
- /foo
- /foo/bar
- /foo/bar/suid
- /foo/bar/sticky
- /foo/bar/sgid
steps:
- mkdir -p /foo/bar
- touch /foo/bar/suid
- touch /foo/bar/sgid
- touch /foo/bar/sticky
- chown 100:100 /foo/bar
- chown 101:101 /foo/bar/suid
- chmod u+s /foo/bar/suid
- chmod u-s,g+s /foo/bar/sgid
- chmod +t /foo/bar/sticky

View File

@@ -0,0 +1,3 @@
category: "test"
name: "extra-perms"
version: "0.1"

View File

@@ -0,0 +1,79 @@
#!/bin/bash
export LUET_NOLOCK=true
oneTimeSetUp() {
export tmpdir="$(mktemp -d)"
}
oneTimeTearDown() {
rm -rf "$tmpdir"
}
testBuild() {
[ "$LUET_BACKEND" == "img" ] && startSkipping
mkdir $tmpdir/testbuild
luet build -d --tree "$ROOT_DIR/tests/fixtures/extra_perms" --same-owner=true --destination $tmpdir/testbuild --compression gzip --full
buildst=$?
assertTrue 'create package perms 0.1' "[ -e '$tmpdir/testbuild/extra-perms-test-0.1.package.tar.gz' ]"
assertEquals 'builds successfully' "$buildst" "0"
}
testRepo() {
[ "$LUET_BACKEND" == "img" ] && startSkipping
assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]"
luet create-repo --tree "$ROOT_DIR/tests/fixtures/extra_perms" \
--output $tmpdir/testbuild \
--packages $tmpdir/testbuild \
--name "test" \
--descr "Test Repo" \
--urls $tmpdir/testrootfs \
--type http
createst=$?
assertEquals 'create repo successfully' "$createst" "0"
assertTrue 'create repository' "[ -e '$tmpdir/testbuild/repository.yaml' ]"
}
testConfig() {
[ "$LUET_BACKEND" == "img" ] && startSkipping
mkdir $tmpdir/testrootfs
cat <<EOF > $tmpdir/luet.yaml
general:
debug: true
system:
rootfs: $tmpdir/testrootfs
database_path: "/"
database_engine: "boltdb"
config_from_host: true
repositories:
- name: "main"
type: "disk"
enable: true
urls:
- "$tmpdir/testbuild"
EOF
luet config --config $tmpdir/luet.yaml
res=$?
assertEquals 'config test successfully' "$res" "0"
}
testInstall() {
[ "$LUET_BACKEND" == "img" ] && startSkipping
$ROOT_DIR/tests/integration/bin/luet install -y --config $tmpdir/luet.yaml test/extra-perms
installst=$?
assertEquals 'install test successfully' "$installst" "0"
tree $tmpdir/testrootfs/foo/bar
assertTrue 'package installed bar' "[ -d '$tmpdir/testrootfs/foo/bar' ]"
assertContains 'perms2' "$(stat -c %u:%g $tmpdir/testrootfs/foo/bar)" "100:100"
assertContains 'suid' "$(stat -c %a $tmpdir/testrootfs/foo/bar/suid)" "4644"
assertContains 'sgid' "$(stat -c %a $tmpdir/testrootfs/foo/bar/sgid)" "2644"
assertContains 'sticky' "$(stat -c %a $tmpdir/testrootfs/foo/bar/sticky)" "1644"
}
# Load shUnit2.
. "$ROOT_DIR/tests/integration/shunit2"/shunit2