github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/build/sources/conveyorPacker_debootstrap.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 "fmt" 10 "os" 11 "os/exec" 12 "runtime" 13 "strings" 14 15 "github.com/sylabs/singularity/internal/pkg/sylog" 16 "github.com/sylabs/singularity/pkg/build/types" 17 ) 18 19 // DebootstrapConveyorPacker holds stuff that needs to be packed into the bundle 20 type DebootstrapConveyorPacker struct { 21 b *types.Bundle 22 mirrorurl string 23 osversion string 24 include string 25 } 26 27 // Get downloads container information from the specified source 28 func (cp *DebootstrapConveyorPacker) Get(b *types.Bundle) (err error) { 29 cp.b = b 30 31 // check for debootstrap on system(script using "singularity_which" not sure about its importance) 32 debootstrapPath, err := exec.LookPath("debootstrap") 33 if err != nil { 34 return fmt.Errorf("debootstrap is not in PATH... Perhaps 'apt-get install' it: %v", err) 35 } 36 37 if err = cp.getRecipeHeaderInfo(); err != nil { 38 return err 39 } 40 41 if os.Getuid() != 0 { 42 return fmt.Errorf("You must be root to build with debootstrap") 43 } 44 45 // run debootstrap command 46 cmd := exec.Command(debootstrapPath, `--variant=minbase`, `--exclude=openssl,udev,debconf-i18n,e2fsprogs`, `--include=apt,`+cp.include, `--arch=`+runtime.GOARCH, cp.osversion, cp.b.Rootfs(), cp.mirrorurl) 47 cmd.Stdout = os.Stdout 48 cmd.Stderr = os.Stderr 49 50 sylog.Debugf("\n\tDebootstrap Path: %s\n\tIncludes: apt(default),%s\n\tDetected Arch: %s\n\tOSVersion: %s\n\tMirrorURL: %s\n", debootstrapPath, cp.include, runtime.GOARCH, cp.osversion, cp.mirrorurl) 51 52 // run debootstrap 53 if err = cmd.Run(); err != nil { 54 return fmt.Errorf("While debootstrapping: %v", err) 55 } 56 57 return nil 58 } 59 60 // Pack puts relevant objects in a Bundle! 61 func (cp *DebootstrapConveyorPacker) Pack() (*types.Bundle, error) { 62 63 //change root directory permissions to 0755 64 if err := os.Chmod(cp.b.Rootfs(), 0755); err != nil { 65 return nil, fmt.Errorf("While changing bundle rootfs perms: %v", err) 66 } 67 68 err := cp.insertBaseEnv(cp.b) 69 if err != nil { 70 return nil, fmt.Errorf("While inserting base environtment: %v", err) 71 } 72 73 err = cp.insertRunScript(cp.b) 74 if err != nil { 75 return nil, fmt.Errorf("While inserting runscript: %v", err) 76 } 77 78 return cp.b, nil 79 } 80 81 func (cp *DebootstrapConveyorPacker) getRecipeHeaderInfo() (err error) { 82 var ok bool 83 84 //get mirrorURL, OSVerison, and Includes components to definition 85 cp.mirrorurl, ok = cp.b.Recipe.Header["mirrorurl"] 86 if !ok { 87 return fmt.Errorf("Invalid debootstrap header, no MirrorURL specified") 88 } 89 90 cp.osversion, ok = cp.b.Recipe.Header["osversion"] 91 if !ok { 92 return fmt.Errorf("Invalid debootstrap header, no OSVersion specified") 93 } 94 95 include, _ := cp.b.Recipe.Header["include"] 96 97 //check for include environment variable and add it to requires string 98 include += ` ` + os.Getenv("INCLUDE") 99 100 //trim leading and trailing whitespace 101 include = strings.TrimSpace(include) 102 103 //convert Requires string to comma separated list 104 cp.include = strings.Replace(include, ` `, `,`, -1) 105 106 return nil 107 } 108 109 func (cp *DebootstrapConveyorPacker) insertBaseEnv(b *types.Bundle) (err error) { 110 if err = makeBaseEnv(b.Rootfs()); err != nil { 111 return 112 } 113 return nil 114 } 115 116 func (cp *DebootstrapConveyorPacker) insertRunScript(b *types.Bundle) (err error) { 117 f, err := os.Create(b.Rootfs() + "/.singularity.d/runscript") 118 if err != nil { 119 return 120 } 121 122 defer f.Close() 123 124 _, err = f.WriteString("#!/bin/sh\n") 125 if err != nil { 126 return 127 } 128 129 if err != nil { 130 return 131 } 132 133 f.Sync() 134 135 err = os.Chmod(b.Rootfs()+"/.singularity.d/runscript", 0755) 136 if err != nil { 137 return 138 } 139 140 return nil 141 } 142 143 // CleanUp removes any tmpfs owned by the conveyorPacker on the filesystem 144 func (cp *DebootstrapConveyorPacker) CleanUp() { 145 os.RemoveAll(cp.b.Path) 146 }