12
"github.com/containers/storage/pkg/archive"
13
"github.com/containers/storage/pkg/chrootarchive"
14
"github.com/sirupsen/logrus"
15
"github.com/vbauerster/mpb/v8"
16
"github.com/vbauerster/mpb/v8/decor"
19
// ExecCmd executes a command with args and returns its output as a string along
20
// with an error, if any.
21
func ExecCmd(name string, args ...string) (string, error) {
22
cmd := exec.Command(name, args...)
23
var stdout bytes.Buffer
24
var stderr bytes.Buffer
30
return "", fmt.Errorf("`%v %v` failed: %v %v (%v)", name, strings.Join(args, " "), stderr.String(), stdout.String(), err)
33
return stdout.String(), nil
36
// ExecCmdWithStdStreams execute a command with the specified standard streams.
37
func ExecCmdWithStdStreams(stdin io.Reader, stdout, stderr io.Writer, env []string, name string, args ...string) error {
38
cmd := exec.Command(name, args...)
46
return fmt.Errorf("`%v %v` failed: %v", name, strings.Join(args, " "), err)
52
// UntarToFileSystem untars an os.file of a tarball to a destination in the filesystem
53
func UntarToFileSystem(dest string, tarball *os.File, options *archive.TarOptions) error {
54
logrus.Debugf("untarring %s", tarball.Name())
55
return archive.Untar(tarball, dest, options)
58
// Creates a new tar file and writes bytes from io.ReadCloser
59
func CreateTarFromSrc(source string, dest string) error {
60
file, err := os.Create(dest)
62
return fmt.Errorf("could not create tarball file '%s': %w", dest, err)
65
return TarChrootToFilesystem(source, file)
68
// TarToFilesystem creates a tarball from source and writes to an os.file
70
func TarToFilesystem(source string, tarball *os.File) error {
71
tb, err := Tar(source)
76
_, err = io.Copy(tarball, tb)
80
logrus.Debugf("wrote tarball file %s", tarball.Name())
84
// Tar creates a tarball from source and returns a readcloser of it
85
func Tar(source string) (io.ReadCloser, error) {
86
logrus.Debugf("creating tarball of %s", source)
87
return archive.Tar(source, archive.Uncompressed)
90
// TarChrootToFilesystem creates a tarball from source and writes to an os.file
91
// provided while chrooted to the source.
92
func TarChrootToFilesystem(source string, tarball *os.File) error {
93
tb, err := TarWithChroot(source)
98
_, err = io.Copy(tarball, tb)
102
logrus.Debugf("wrote tarball file %s", tarball.Name())
106
// TarWithChroot creates a tarball from source and returns a readcloser of it
107
// while chrooted to the source.
108
func TarWithChroot(source string) (io.ReadCloser, error) {
109
logrus.Debugf("creating tarball of %s", source)
110
return chrootarchive.Tar(source, nil, source)
113
// GuardedRemoveAll functions much like os.RemoveAll but
114
// will not delete certain catastrophic paths.
115
func GuardedRemoveAll(path string) error {
116
if path == "" || path == "/" {
117
return fmt.Errorf("refusing to recursively delete `%s`", path)
119
return os.RemoveAll(path)
122
func ProgressBar(prefix string, size int64, onComplete string) (*mpb.Progress, *mpb.Bar) {
124
mpb.WithWidth(80), // Do not go below 80, see bug #17718
125
mpb.WithRefreshRate(180*time.Millisecond),
128
bar := p.AddBar(size,
129
mpb.BarFillerClearOnComplete(),
130
mpb.PrependDecorators(
131
decor.OnComplete(decor.Name(prefix), onComplete),
133
mpb.AppendDecorators(
134
decor.OnComplete(decor.CountersKibiByte("%.1f / %.1f"), ""),
138
bar.SetTotal(0, true)