github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/build/sources/conveyorPacker_busybox.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 "io" 11 "io/ioutil" 12 "net/http" 13 "os" 14 "os/exec" 15 "path/filepath" 16 17 "github.com/sylabs/singularity/internal/pkg/sylog" 18 "github.com/sylabs/singularity/pkg/build/types" 19 ) 20 21 // BusyBoxConveyor only needs to hold the conveyor to have the needed data to pack 22 type BusyBoxConveyor struct { 23 b *types.Bundle 24 } 25 26 // BusyBoxConveyorPacker only needs to hold the conveyor to have the needed data to pack 27 type BusyBoxConveyorPacker struct { 28 BusyBoxConveyor 29 } 30 31 // Get just stores the source 32 func (c *BusyBoxConveyor) Get(b *types.Bundle) (err error) { 33 c.b = b 34 35 // get mirrorURL, OSVerison, and Includes components to definition 36 mirrorurl, ok := b.Recipe.Header["mirrorurl"] 37 if !ok { 38 return fmt.Errorf("Invalid busybox header, no MirrurURL specified") 39 } 40 41 err = c.insertBaseEnv() 42 if err != nil { 43 return fmt.Errorf("While inserting base environment: %v", err) 44 } 45 46 err = c.insertBaseFiles() 47 if err != nil { 48 return fmt.Errorf("While inserting files: %v", err) 49 } 50 51 busyBoxPath, err := c.insertBusyBox(mirrorurl) 52 if err != nil { 53 return fmt.Errorf("While inserting busybox: %v", err) 54 } 55 56 cmd := exec.Command(busyBoxPath, `--install`, filepath.Join(c.b.Rootfs(), "/bin")) 57 58 sylog.Debugf("\n\tBusyBox Path: %s\n\tMirrorURL: %s\n", busyBoxPath, mirrorurl) 59 60 err = cmd.Run() 61 if err != nil { 62 return fmt.Errorf("While performing busybox install: %v", err) 63 } 64 65 return nil 66 } 67 68 // Pack puts relevant objects in a Bundle! 69 func (cp *BusyBoxConveyorPacker) Pack() (b *types.Bundle, err error) { 70 err = cp.insertRunScript() 71 if err != nil { 72 return nil, fmt.Errorf("While inserting base environment: %v", err) 73 } 74 75 return cp.b, nil 76 } 77 78 func (c *BusyBoxConveyor) insertBaseFiles() error { 79 if err := ioutil.WriteFile(filepath.Join(c.b.Rootfs(), "/etc/passwd"), []byte("root:!:0:0:root:/root:/bin/sh"), 0664); err != nil { 80 return err 81 } 82 83 if err := ioutil.WriteFile(filepath.Join(c.b.Rootfs(), "/etc/group"), []byte(" root:x:0:"), 0664); err != nil { 84 return err 85 } 86 87 if err := ioutil.WriteFile(filepath.Join(c.b.Rootfs(), "/etc/hosts"), []byte("127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4"), 0664); err != nil { 88 return err 89 } 90 91 return nil 92 } 93 94 func (c *BusyBoxConveyor) insertBusyBox(mirrorurl string) (busyBoxPath string, err error) { 95 os.Mkdir(filepath.Join(c.b.Rootfs(), "/bin"), 0755) 96 97 resp, err := http.Get(mirrorurl) 98 if err != nil { 99 return "", fmt.Errorf("While performing http request: %v", err) 100 } 101 defer resp.Body.Close() 102 103 f, err := os.Create(filepath.Join(c.b.Rootfs(), "/bin/busybox")) 104 if err != nil { 105 return 106 } 107 defer f.Close() 108 109 bytesWritten, err := io.Copy(f, resp.Body) 110 if err != nil { 111 return 112 } 113 114 //Simple check to make sure file received is the correct size 115 if bytesWritten != resp.ContentLength { 116 return "", fmt.Errorf("File received is not the right size. Supposed to be: %v Actually: %v", resp.ContentLength, bytesWritten) 117 } 118 119 err = os.Chmod(f.Name(), 0755) 120 if err != nil { 121 return 122 } 123 124 return filepath.Join(c.b.Rootfs(), "/bin/busybox"), nil 125 } 126 127 func (c *BusyBoxConveyor) insertBaseEnv() (err error) { 128 if err = makeBaseEnv(c.b.Rootfs()); err != nil { 129 return 130 } 131 return nil 132 } 133 134 func (cp *BusyBoxConveyorPacker) insertRunScript() error { 135 if err := ioutil.WriteFile(filepath.Join(cp.b.Rootfs(), "/.singularity.d/runscript"), []byte("#!/bin/sh\n"), 0755); err != nil { 136 return err 137 } 138 139 return nil 140 } 141 142 // CleanUp removes any tmpfs owned by the conveyorPacker on the filesystem 143 func (c *BusyBoxConveyor) CleanUp() { 144 os.RemoveAll(c.b.Path) 145 }