Skip to content

Commit

Permalink
Merge pull request #604 from monstermunchkin/misc/unpack
Browse files Browse the repository at this point in the history
Use Unpack function in archive package
  • Loading branch information
stgraber authored Mar 22, 2022
2 parents c46b14b + c6add03 commit 2636489
Show file tree
Hide file tree
Showing 16 changed files with 412 additions and 87 deletions.
25 changes: 13 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,29 @@ replace google.golang.org/grpc/naming => google.golang.org/grpc v1.29.1
require (
github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3
github.com/gobuffalo/packr/v2 v2.8.3
github.com/lxc/lxd v0.0.0-20211216085512-a2849ac27902
github.com/lxc/lxd v0.0.0-20220321221753-1e535dcd5db5
github.com/mudler/docker-companion v0.4.6-0.20211015133729-bd4704fad372
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.3.0
github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
github.com/spf13/cobra v1.4.0
github.com/stretchr/testify v1.7.1
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
gopkg.in/antchfx/htmlquery.v1 v1.2.2
gopkg.in/flosch/pongo2.v3 v3.0.0-20141028000813-5e81b817a0c4
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20211123104302-8fea106b46e2 // indirect
github.com/Microsoft/hcsshim v0.9.1 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20220301192128-fe11a1f79e80 // indirect
github.com/antchfx/xpath v1.2.0 // indirect
github.com/containerd/cgroups v1.0.2 // indirect
github.com/containerd/continuity v0.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.10.1 // indirect
github.com/fsouza/go-dockerclient v1.7.6 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.11.3 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v20.10.13+incompatible // indirect
github.com/fsouza/go-dockerclient v1.7.10 // indirect
github.com/google/go-containerregistry v0.8.0 // indirect
github.com/heroku/docker-registry-client v0.0.0-20211012143308-9463674c8930 // indirect
github.com/moby/sys/mount v0.3.0 // indirect
github.com/moby/sys/mount v0.3.1 // indirect
github.com/opencontainers/umoci v0.4.8-0.20211009121349-9c76304c034d // indirect
github.com/urfave/cli v1.22.5 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
google.golang.org/protobuf v1.28.0 // indirect
)
316 changes: 274 additions & 42 deletions go.sum

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions shared/archive_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package shared

import (
"fmt"
"io"
"os"
"strings"

lxd "github.com/lxc/lxd/shared"
"golang.org/x/sys/unix"
)

// Unpack unpacks a tarball.
func Unpack(file string, path string) error {
extractArgs, extension, _, err := lxd.DetectCompression(file)
if err != nil {
return err
}

command := ""
args := []string{}
var reader io.Reader
if strings.HasPrefix(extension, ".tar") {
command = "tar"
args = append(args, "--restrict", "--force-local")
args = append(args, "-C", path, "--numeric-owner", "--xattrs-include=*")
args = append(args, extractArgs...)
args = append(args, "-")

f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()

reader = f
} else if strings.HasPrefix(extension, ".squashfs") {
// unsquashfs does not support reading from stdin,
// so ProgressTracker is not possible.
command = "unsquashfs"
args = append(args, "-f", "-d", path, "-n")

// Limit unsquashfs chunk size to 10% of memory and up to 256MB (default)
// When running on a low memory system, also disable multi-processing
mem, err := lxd.DeviceTotalMemory()
mem = mem / 1024 / 1024 / 10
if err == nil && mem < 256 {
args = append(args, "-da", fmt.Sprintf("%d", mem), "-fr", fmt.Sprintf("%d", mem), "-p", "1")
}

args = append(args, file)
} else {
return fmt.Errorf("Unsupported image format: %s", extension)
}

err = lxd.RunCommandWithFds(reader, nil, command, args...)
if err != nil {
// We can't create char/block devices in unpriv containers so ignore related errors.
if command == "unsquashfs" {
runError, ok := err.(lxd.RunError)
if !ok || runError.Stderr == "" {
return err
}

// Confirm that all errors are related to character or block devices.
found := false
for _, line := range strings.Split(runError.Stderr, "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}

if !strings.Contains(line, "failed to create block device") {
continue
}

if !strings.Contains(line, "failed to create character device") {
continue
}

// We found an actual error.
found = true
}

if !found {
// All good, assume everything unpacked.
return nil
}
}

// Check if we ran out of space
fs := unix.Statfs_t{}

err1 := unix.Statfs(path, &fs)
if err1 != nil {
return err1
}

// Check if we're running out of space
if int64(fs.Bfree) < 10 {
return fmt.Errorf("Unable to unpack image, run out of disk space")
}

return fmt.Errorf("Unpack failed: %w", err)
}

return nil
}
4 changes: 1 addition & 3 deletions sources/alpine-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"path/filepath"
"strings"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -83,7 +81,7 @@ func (s *alpineLinux) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
}
Expand Down
4 changes: 2 additions & 2 deletions sources/alt-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"path/filepath"
"strings"

lxd "github.com/lxc/lxd/shared"
"github.com/lxc/distrobuilder/shared"
)

type altLinux struct {
Expand Down Expand Up @@ -76,7 +76,7 @@ func (s *altLinux) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
}
Expand Down
4 changes: 1 addition & 3 deletions sources/apertis-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import (
"regexp"
"strings"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -81,7 +79,7 @@ func (s *apertis) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
}
Expand Down
4 changes: 2 additions & 2 deletions sources/archlinux-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"sort"
"strings"

lxd "github.com/lxc/lxd/shared"
"github.com/lxc/distrobuilder/shared"
"gopkg.in/antchfx/htmlquery.v1"
)

Expand Down Expand Up @@ -82,7 +82,7 @@ func (s *archlinux) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack file %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down
4 changes: 1 addition & 3 deletions sources/busybox.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"os"
"path/filepath"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -47,7 +45,7 @@ func (s *busybox) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), sourceDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), sourceDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", fname, err)
}
Expand Down
6 changes: 2 additions & 4 deletions sources/fedora-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"regexp"
"sort"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -45,7 +43,7 @@ func (s *fedora) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack the base image
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down Expand Up @@ -96,7 +94,7 @@ func (s *fedora) unpackLayers(rootfsDir string) error {
for _, layer := range manifest.Layers {
s.logger.WithField("file", filepath.Join(rootfsDir, layer)).Info("Unpacking layer")

err := lxd.Unpack(filepath.Join(rootfsDir, layer), rootfsDir, false, false, nil)
err := shared.Unpack(filepath.Join(rootfsDir, layer), rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(rootfsDir, layer), err)
}
Expand Down
3 changes: 1 addition & 2 deletions sources/funtoo-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"sort"
"strings"

lxd "github.com/lxc/lxd/shared"
"gopkg.in/antchfx/htmlquery.v1"

"github.com/lxc/distrobuilder/shared"
Expand Down Expand Up @@ -112,7 +111,7 @@ func (s *funtoo) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down
4 changes: 1 addition & 3 deletions sources/gentoo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"regexp"
"strings"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -94,7 +92,7 @@ func (s *gentoo) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down
3 changes: 1 addition & 2 deletions sources/opensuse-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"sort"
"strings"

lxd "github.com/lxc/lxd/shared"
"gopkg.in/antchfx/htmlquery.v1"

"github.com/lxc/distrobuilder/shared"
Expand Down Expand Up @@ -81,7 +80,7 @@ func (s *opensuse) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down
4 changes: 1 addition & 3 deletions sources/openwrt-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"regexp"
"strings"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -151,7 +149,7 @@ func (s *openwrt) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down
4 changes: 2 additions & 2 deletions sources/rootfs-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"path"
"path/filepath"

lxd "github.com/lxc/lxd/shared"
"github.com/lxc/distrobuilder/shared"
)

type rootfs struct {
Expand Down Expand Up @@ -39,7 +39,7 @@ func (s *rootfs) Run() error {
s.logger.WithField("file", filepath.Join(fpath, filename)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, filename), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, filename), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, filename), err)
}
Expand Down
2 changes: 1 addition & 1 deletion sources/ubuntu-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ func (s ubuntu) unpack(filePath, rootDir string) error {

s.logger.WithField("file", filePath).Info("Unpacking image")

err = lxd.Unpack(filePath, rootDir, false, false, nil)
err = shared.Unpack(filePath, rootDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filePath, err)
}
Expand Down
4 changes: 1 addition & 3 deletions sources/voidlinux-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"regexp"
"strings"

lxd "github.com/lxc/lxd/shared"

"github.com/lxc/distrobuilder/shared"
)

Expand Down Expand Up @@ -83,7 +81,7 @@ func (s *voidlinux) Run() error {
s.logger.WithField("file", filepath.Join(fpath, fname)).Info("Unpacking image")

// Unpack
err = lxd.Unpack(filepath.Join(fpath, fname), s.rootfsDir, false, false, nil)
err = shared.Unpack(filepath.Join(fpath, fname), s.rootfsDir)
if err != nil {
return fmt.Errorf("Failed to unpack %q: %w", filepath.Join(fpath, fname), err)
}
Expand Down

0 comments on commit 2636489

Please sign in to comment.