github.com/hpcng/singularity@v3.1.1+incompatible/pkg/image/sif.go (about) 1 // Copyright (c) 2018-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 image 7 8 import ( 9 "bytes" 10 "fmt" 11 "os" 12 "syscall" 13 14 "github.com/sylabs/sif/pkg/sif" 15 ) 16 17 const ( 18 sifMagic = "\x53\x49\x46\x5f\x4d\x41\x47\x49\x43" 19 ) 20 21 type sifFormat struct{} 22 23 func (f *sifFormat) initializer(img *Image, fileinfo os.FileInfo) error { 24 if fileinfo.IsDir() { 25 return fmt.Errorf("not a SIF file image") 26 } 27 b := make([]byte, bufferSize) 28 if n, err := img.File.Read(b); err != nil || n != bufferSize { 29 return fmt.Errorf("can't read first %d bytes: %s", bufferSize, err) 30 } 31 if bytes.Index(b, []byte(sifMagic)) == -1 { 32 return fmt.Errorf("SIF magic not found") 33 } 34 35 // Load the SIF file 36 fimg, err := sif.LoadContainerFp(img.File, !img.Writable) 37 if err != nil { 38 return err 39 } 40 41 // Get the default system partition image 42 part, _, err := fimg.GetPartPrimSys() 43 if err != nil { 44 return err 45 } 46 47 // record the fs type 48 fstype, err := part.GetFsType() 49 if err != nil { 50 return err 51 } 52 if fstype == sif.FsSquash { 53 img.Partitions[0].Type = SQUASHFS 54 } else if fstype == sif.FsExt3 { 55 img.Partitions[0].Type = EXT3 56 } else { 57 return fmt.Errorf("unknown file system type: %v", fstype) 58 } 59 60 img.Partitions[0].Offset = uint64(part.Fileoff) 61 img.Partitions[0].Size = uint64(part.Filelen) 62 img.Partitions[0].Name = RootFs 63 64 // store all remaining sections 65 img.Sections = make([]Section, 0) 66 67 for _, desc := range fimg.DescrArr { 68 if ptype, err := desc.GetPartType(); err == nil { 69 // overlay partitions 70 if ptype == sif.PartOverlay && part.Groupid == desc.Groupid && desc.Used { 71 fstype, err := desc.GetFsType() 72 if err != nil { 73 continue 74 } 75 partition := Section{ 76 Offset: uint64(desc.Fileoff), 77 Size: uint64(desc.Filelen), 78 Name: desc.GetName(), 79 } 80 switch fstype { 81 case sif.FsSquash: 82 partition.Type = SQUASHFS 83 case sif.FsExt3: 84 partition.Type = EXT3 85 } 86 img.Partitions = append(img.Partitions, partition) 87 } 88 } else { 89 // anything else 90 if desc.Datatype != 0 { 91 data := Section{ 92 Offset: uint64(desc.Fileoff), 93 Size: uint64(desc.Filelen), 94 Type: uint32(desc.Datatype), 95 Name: desc.GetName(), 96 } 97 img.Sections = append(img.Sections, data) 98 } 99 } 100 } 101 102 img.Type = SIF 103 104 // UnloadContainer close image, just want to unmap image 105 // from memory 106 if fimg.Amodebuf == false { 107 if err := syscall.Munmap(fimg.Filedata); err != nil { 108 return fmt.Errorf("while calling unmapping SIF file") 109 } 110 } 111 112 return nil 113 } 114 115 func (f *sifFormat) openMode(writable bool) int { 116 if writable { 117 return os.O_RDWR 118 } 119 return os.O_RDONLY 120 }