github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/build/sources/packer_ext3_linux.go (about) 1 // Copyright (c) 2019, 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" 13 "os/exec" 14 "syscall" 15 16 args "github.com/sylabs/singularity/internal/pkg/runtime/engines/singularity/rpc" 17 "github.com/sylabs/singularity/internal/pkg/sylog" 18 "github.com/sylabs/singularity/pkg/build/types" 19 "github.com/sylabs/singularity/pkg/util/loop" 20 ) 21 22 // Pack puts relevant objects in a Bundle! 23 func (p *Ext3Packer) Pack() (*types.Bundle, error) { 24 rootfs := p.srcfile 25 26 err := p.unpackExt3(p.b, p.info, rootfs) 27 if err != nil { 28 sylog.Errorf("unpackExt3 Failed: %s", err) 29 return nil, err 30 } 31 32 return p.b, nil 33 } 34 35 // unpackExt3 mounts the ext3 image using a loop device and then copies its contents to the bundle 36 func (p *Ext3Packer) unpackExt3(b *types.Bundle, info *loop.Info64, rootfs string) error { 37 tmpmnt, err := ioutil.TempDir(p.b.Path, "mnt") 38 if err != nil { 39 return fmt.Errorf("While making tmp mount point: %v", err) 40 } 41 42 var number int 43 info.Flags = loop.FlagsAutoClear 44 arguments := &args.LoopArgs{ 45 Image: rootfs, 46 Mode: os.O_RDONLY, 47 Info: *info, 48 } 49 if err := getLoopDevice(arguments); err != nil { 50 return err 51 } 52 53 path := fmt.Sprintf("/dev/loop%d", number) 54 sylog.Debugf("Mounting loop device %s to %s\n", path, tmpmnt) 55 err = syscall.Mount(path, tmpmnt, "ext3", syscall.MS_NOSUID|syscall.MS_RDONLY|syscall.MS_NODEV, "errors=remount-ro") 56 if err != nil { 57 return fmt.Errorf("While mounting image: %v", err) 58 } 59 defer syscall.Unmount(tmpmnt, 0) 60 61 // copy filesystem into bundle rootfs 62 sylog.Debugf("Copying filesystem from %s to %s in Bundle\n", tmpmnt, b.Rootfs()) 63 var stderr bytes.Buffer 64 cmd := exec.Command("cp", "-r", tmpmnt+`/.`, b.Rootfs()) 65 cmd.Stderr = &stderr 66 if err := cmd.Run(); err != nil { 67 return fmt.Errorf("While copying files: %v: %v", err, stderr.String()) 68 } 69 70 return err 71 } 72 73 // getLoopDevice attaches a loop device with the specified arguments 74 func getLoopDevice(arguments *args.LoopArgs) error { 75 var reply int 76 reply = 1 77 loopdev := new(loop.Device) 78 loopdev.MaxLoopDevices = 256 79 loopdev.Info = &arguments.Info 80 loopdev.Shared = arguments.Shared 81 82 return loopdev.AttachFromPath(arguments.Image, arguments.Mode, &reply) 83 }