github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/containers/utils/image-creator/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "os" 7 "path" 8 "strconv" 9 "strings" 10 11 "github.com/emc-advanced-dev/pkg/errors" 12 13 log "github.com/sirupsen/logrus" 14 15 "io" 16 17 unikos "github.com/solo-io/unik/pkg/os" 18 "github.com/pborman/uuid" 19 ) 20 21 type volumeslice []unikos.RawVolume 22 23 func (m *volumeslice) String() string { 24 25 return fmt.Sprintf("%v", ([]unikos.RawVolume)(*m)) 26 } 27 28 // The second method is Set(value string) error 29 func (m *volumeslice) Set(value string) error { 30 31 volparts := strings.Split(value, ",") 32 33 if (len(volparts) != 1) && (len(volparts) != 2) { 34 return errors.New("bad format", nil) 35 } 36 37 folder := volparts[0] 38 39 var size int64 40 if len(volparts) >= 2 { 41 size, _ = strconv.ParseInt(volparts[1], 0, 64) 42 } 43 *m = append(*m, unikos.RawVolume{Path: folder, Size: size}) 44 45 return nil 46 } 47 48 func verifyPreConditions() { 49 _, err := os.Stat("/dev/loop0") 50 if os.IsNotExist(err) { 51 log.Fatal("No loop device found. if running from docker use \"--privileged -v /dev/:/dev/\"") 52 } 53 } 54 55 func main() { 56 log.SetLevel(log.DebugLevel) 57 58 var volumes volumeslice 59 partitionTable := flag.String("p", "true", "create partition table") 60 buildcontextdir := flag.String("d", "/opt/vol", "build context. relative volume names are relative to that") 61 volType := flag.String("t", "ext2", "type of volume 'mirage-fat', 'fat' or 'ext2'") 62 flag.Var(&volumes, "v", "volumes folder[,size]") 63 out := flag.String("o", "", "base name of output file") 64 65 flag.Parse() 66 67 if len(volumes) == 0 { 68 log.Fatal("No volumes provided") 69 } 70 71 imgFile := path.Join(*buildcontextdir, "data.image."+uuid.New()) 72 defer os.Remove(imgFile) 73 74 for i := range volumes { 75 volumes[i].Path = path.Join(*buildcontextdir, volumes[i].Path) 76 } 77 78 verifyPreConditions() 79 if *volType == "mirage-fat" { 80 if *partitionTable == "true" { 81 log.Fatal("Can't create mirage-fat volume with a partition table.") 82 } 83 84 if len(volumes) != 1 { 85 log.Fatal("Can only create one volume with no partition table") 86 } 87 volume := volumes[0] 88 if volume.Size == 0 { 89 var err error 90 volume.Size, err = unikos.GetDirSize(volume.Path) 91 if err != nil { 92 log.Panic(err) 93 } 94 } 95 96 sizeKb := volume.Size >> 10 97 // add 8 kb to handle edge cases 98 sizeKb += 8 99 100 log.WithFields(log.Fields{"sizeKb": sizeKb, "size": volume.Size}).Info("Creating mirage fat volume.") 101 102 err := unikos.RunLogCommand("fat", "create", imgFile, fmt.Sprintf("%d%s", sizeKb, "KiB")) 103 if err != nil { 104 log.Panic(err) 105 } 106 107 if volume.Path != "" { 108 err := unikos.RunLogCommand("/bin/bash", "-c", fmt.Sprintf("cd \"%s\" && fat add %s *", volume.Path, imgFile)) 109 if err != nil { 110 log.Panic(err) 111 } 112 } 113 114 } else { 115 116 if *partitionTable == "true" { 117 log.Info("Creating volume with partition table") 118 119 diskLabelGen := func(device string) unikos.Partitioner { return &unikos.DiskLabelPartioner{device} } 120 121 // rump so we use disklabel 122 err := unikos.CreateVolumes(imgFile, *volType, []unikos.RawVolume(volumes), diskLabelGen) 123 124 if err != nil { 125 panic(err) 126 } 127 } else { 128 log.Info("Creating volume with no partition table") 129 130 if len(volumes) != 1 { 131 log.Fatal("Can only create one volume with no partition table") 132 } 133 134 err := unikos.CreateSingleVolume(imgFile, *volType, volumes[0]) 135 136 if err != nil { 137 panic(err) 138 } 139 } 140 } 141 142 src, err := os.Open(imgFile) 143 if err != nil { 144 log.Fatal("failed to open produced image file "+imgFile, err) 145 } 146 outFile := path.Join(*buildcontextdir, *out) 147 dst, err := os.OpenFile(outFile, os.O_RDWR, 0) 148 if err != nil { 149 log.Fatal("failed to open target output file "+outFile, err) 150 } 151 n, err := io.Copy(dst, src) 152 if err != nil { 153 log.Fatal("failed copying produced image file to target output file", err) 154 } 155 log.Infof("wrote %d bytes to disk", n) 156 }