github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/deploy/main.go (about) 1 package main 2 3 import ( 4 "archive/tar" 5 "archive/zip" 6 "bytes" 7 "compress/gzip" 8 "encoding/json" 9 "flag" 10 "io" 11 "io/ioutil" 12 "log" 13 "os" 14 "path/filepath" 15 "runtime" 16 "strings" 17 18 "github.com/benoitkugler/goACVE/deploy/upload" 19 20 "github.com/benoitkugler/goACVE/client/version" 21 22 "github.com/benoitkugler/goACVE/server/core/apiserver" 23 "github.com/benoitkugler/goACVE/server/core/utils" 24 "github.com/benoitkugler/goACVE/deploy/store" 25 ) 26 27 type fullArchive interface { 28 addFile(info os.FileInfo, sourcePath string) 29 close() []byte 30 } 31 32 type zipArchive struct { 33 buffer *bytes.Buffer 34 archive *zip.Writer 35 } 36 37 func (z zipArchive) addFile(info os.FileInfo, sourcePath string) { 38 if info.IsDir() { 39 return 40 } 41 wr, err := z.archive.Create(sourcePath) 42 if err != nil { 43 log.Fatal(err) 44 } 45 f, err := os.Open(sourcePath) 46 defer f.Close() 47 if err != nil { 48 log.Fatal(err) 49 } 50 if _, err := io.Copy(wr, f); err != nil { 51 log.Fatal(err) 52 } 53 } 54 55 func (z zipArchive) close() []byte { 56 if err := z.archive.Close(); err != nil { 57 log.Fatal(err) 58 } 59 return z.buffer.Bytes() 60 } 61 62 type tarArchive struct { 63 buffer *bytes.Buffer 64 compressed *gzip.Writer 65 archive *tar.Writer 66 full bool // for full logiciel 67 } 68 69 func newTarArchive() tarArchive { 70 buf := new(bytes.Buffer) 71 compressed, err := gzip.NewWriterLevel(buf, gzip.BestCompression) 72 if err != nil { 73 log.Fatal(err) 74 } 75 tw := tar.NewWriter(compressed) 76 return tarArchive{buffer: buf, archive: tw, compressed: compressed} 77 } 78 79 func (t tarArchive) addFile(info os.FileInfo, sourcePath string) { 80 archive := t.archive 81 82 var ( 83 link string 84 err error 85 ) 86 if info.Mode()&os.ModeSymlink == os.ModeSymlink { 87 if link, err = os.Readlink(sourcePath); err != nil { 88 log.Fatal(err) 89 } 90 } 91 92 hdr, err := tar.FileInfoHeader(info, link) 93 if err != nil { 94 log.Fatal(err) 95 } 96 97 if t.full { 98 hdr.Name = sourcePath // pack complet 99 } else { 100 if hdr.Name+"/" == store.DarwinApp { 101 return 102 } 103 hdr.Name = strings.TrimPrefix(sourcePath, store.DarwinApp) // pour darwin, on se place à l'intérieur de l'app.. 104 } 105 106 if err := archive.WriteHeader(hdr); err != nil { 107 log.Fatal(err) 108 } 109 110 if !info.Mode().IsRegular() { //nothing more to do for non-regular 111 return 112 } 113 114 f, err := os.Open(sourcePath) 115 defer f.Close() 116 if err != nil { 117 log.Fatal(err) 118 } 119 if _, err := io.Copy(archive, f); err != nil { 120 log.Fatal(err) 121 } 122 } 123 124 func (t tarArchive) close() []byte { 125 if err := t.archive.Close(); err != nil { 126 log.Fatal(err) 127 } 128 if err := t.compressed.Close(); err != nil { 129 log.Fatal(err) 130 } 131 return t.buffer.Bytes() 132 } 133 134 // On suppose qu'on a déjà build avec qt deploy 135 // et copié les ressources. 136 func main() { 137 noUpload := flag.Bool("noup", false, "disable uploading to the server") 138 noPack := flag.Bool("nopack", false, "disable packing") 139 flag.Parse() 140 141 if !*noPack { 142 Pack() 143 } 144 145 if !*noUpload { 146 Upload() 147 } 148 } 149 150 func Pack() { 151 newVersion := version.VERSION 152 log.Printf("Utilitaire de déployement pour la version %s", newVersion) 153 storePaths := store.GetPaths(runtime.GOOS) 154 155 checkLogicielDir() 156 oldVersion := readVersion(storePaths.Versions) 157 158 currentDir, err := os.Getwd() 159 if err != nil { 160 log.Fatal(err) 161 } 162 root := "client/deploy/" + runtime.GOOS 163 log.Println("Moving to", root) 164 if err := os.Chdir(root); err != nil { 165 log.Fatal(err) 166 } 167 168 log.Println("Packing datas...") 169 client, fullArch, nbFiles := parcourtFolder() 170 171 log.Println("Going back to", currentDir) 172 if err := os.Chdir(currentDir); err != nil { 173 log.Fatal(err) 174 } 175 176 log.Println("Saving full archive...") 177 if err = ioutil.WriteFile(storePaths.Full, fullArch, 0666); err != nil { 178 log.Fatal(err) 179 } 180 log.Println("UP -> Logiciel copié dans", storePaths.Full) 181 182 if newVersion == oldVersion.Version { 183 log.Fatal("La version du client n'a pas été mise à jour !") 184 } 185 log.Println("Mise à jour du client...") 186 187 oldVersion.Version = newVersion 188 hash, err := utils.HashBytes(client) 189 if err != nil { 190 log.Fatal(err) 191 } 192 oldVersion.Hash = hash 193 oldVersion.NbFiles = nbFiles 194 if err = ioutil.WriteFile(storePaths.Client, client, 0666); err != nil { 195 log.Fatal(err) 196 } 197 log.Println("UP -> Client copié dans", storePaths.Client) 198 199 b, err := json.MarshalIndent(oldVersion, " ", " ") 200 if err != nil { 201 log.Fatal(err) 202 } 203 if err := ioutil.WriteFile(storePaths.Versions, b, 0666); err != nil { 204 log.Fatal(err) 205 } 206 log.Println("UP -> Versions copiées dans", storePaths.Versions) 207 } 208 209 func Upload() { 210 storePaths := store.GetPaths(runtime.GOOS) 211 toUpload := []upload.Up{ 212 upload.NewUp(storePaths.Full), 213 upload.NewUp(storePaths.Client), 214 upload.NewUp(storePaths.Versions), 215 } 216 s := upload.OpenFTP() 217 if err := upload.Upload(s, toUpload); err != nil { 218 log.Fatal(err) 219 } 220 log.Println("Upload done.") 221 } 222 223 func readVersion(path string) apiserver.VersionInfos { 224 b, _ := ioutil.ReadFile(path) 225 var v apiserver.VersionInfos 226 err := json.Unmarshal(b, &v) 227 if err != nil { 228 v.Version = "0.0.0" 229 log.Println("Fichier de version introuvable (ancienne version => 0.0.0)") 230 } 231 return v 232 } 233 234 func checkLogicielDir() { 235 path := filepath.Join(store.BasePathExport, runtime.GOOS) 236 _, err := os.Stat(path) 237 if err == nil { 238 return 239 } 240 if err = os.Mkdir(path, 0777); err != nil { 241 log.Fatalf("Impossible de créer le dossier d'export : %s", err) 242 } 243 } 244 245 func initFullArchive() fullArchive { 246 var fullArch fullArchive 247 buf := new(bytes.Buffer) 248 if runtime.GOOS == "windows" { 249 fullArch = zipArchive{buffer: buf, archive: zip.NewWriter(buf)} 250 } else { 251 t := newTarArchive() 252 t.full = true 253 fullArch = t 254 } 255 return fullArch 256 } 257 258 func parcourtFolder() ([]byte, []byte, int) { 259 nbFiles := 0 260 client := newTarArchive() 261 fullArch := initFullArchive() 262 walkF := func(filePath string, info os.FileInfo, err error) error { 263 if filePath == "." { 264 return nil 265 } 266 if err != nil { 267 log.Fatal(err) 268 } 269 nbFiles += 1 270 client.addFile(info, filePath) 271 fullArch.addFile(info, filePath) 272 return nil 273 } 274 err := filepath.Walk(".", walkF) 275 if err != nil { 276 log.Fatal(err) 277 } 278 return client.close(), fullArch.close(), nbFiles 279 }