github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/build/sources/packer_squashfs.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package sources
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os/exec"
    13  	"strconv"
    14  
    15  	"github.com/sylabs/singularity/internal/pkg/sylog"
    16  	"github.com/sylabs/singularity/pkg/build/types"
    17  	"github.com/sylabs/singularity/pkg/util/loop"
    18  )
    19  
    20  // SquashfsPacker holds the locations of where to pack from and to, aswell as image offset info
    21  type SquashfsPacker struct {
    22  	srcfile string
    23  	b       *types.Bundle
    24  	info    *loop.Info64
    25  }
    26  
    27  // Pack puts relevant objects in a Bundle!
    28  func (p *SquashfsPacker) Pack() (*types.Bundle, error) {
    29  	rootfs := p.srcfile
    30  
    31  	err := p.unpackSquashfs(p.b, p.info, rootfs)
    32  	if err != nil {
    33  		sylog.Errorf("unpackSquashfs Failed: %s", err)
    34  		return nil, err
    35  	}
    36  
    37  	return p.b, nil
    38  }
    39  
    40  // unpackSquashfs removes the image header with dd and then unpackes image into bundle directories with unsquashfs
    41  func (p *SquashfsPacker) unpackSquashfs(b *types.Bundle, info *loop.Info64, rootfs string) (err error) {
    42  	var stderr bytes.Buffer
    43  
    44  	trimfile, err := ioutil.TempFile(p.b.Path, "trim.squashfs")
    45  	if err != nil {
    46  		return fmt.Errorf("While making tmp file: %v", err)
    47  	}
    48  
    49  	// trim header
    50  	sylog.Debugf("Creating copy of %s without header at %s\n", rootfs, trimfile.Name())
    51  	cmd := exec.Command("dd", "bs="+strconv.Itoa(int(info.Offset)), "skip=1", "if="+rootfs, "of="+trimfile.Name())
    52  	cmd.Stderr = &stderr
    53  	if err := cmd.Run(); err != nil {
    54  		return fmt.Errorf("Trimming header Failed: %v: %v", err, stderr.String())
    55  	}
    56  
    57  	// copy filesystem into bundle rootfs
    58  	sylog.Debugf("Unsquashing %s to %s in Bundle\n", trimfile.Name(), b.Rootfs())
    59  	stderr.Reset()
    60  	cmd = exec.Command("unsquashfs", "-f", "-d", b.Rootfs(), trimfile.Name())
    61  	cmd.Stderr = &stderr
    62  	if err := cmd.Run(); err != nil {
    63  		return fmt.Errorf("unsquashfs Failed: %v: %v", err, stderr.String())
    64  	}
    65  
    66  	return err
    67  }