updates.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package updates
  2. import (
  3. "errors"
  4. "io/ioutil"
  5. "net/http"
  6. "os"
  7. "path/filepath"
  8. "time"
  9. )
  10. //Download updates from given URL, return real time progress of stage (int), progress (int) and status text (string)
  11. func DownloadUpdatesFromURL(binaryURL string, webpackURL string, checksumURL string, progressUpdateFunction func(int, float64, string)) error {
  12. //Create the update download folder
  13. os.RemoveAll("./updates")
  14. os.MkdirAll("./updates", 0755)
  15. //Get the total size of download expected
  16. binarySize, webpackSize, err := GetUpdateSizes(binaryURL, webpackURL)
  17. if err != nil {
  18. return errors.New("Unable to access given URL")
  19. }
  20. //Generate the download position
  21. binaryDownloadTarget := "./updates/" + filepath.Base(binaryURL)
  22. webpackDownloadTarget := "./updates/" + filepath.Base(webpackURL)
  23. checksumDownloadTarget := "./updates/" + filepath.Base(checksumURL)
  24. //Check if the webpack is .tar.gz
  25. if filepath.Ext(webpackDownloadTarget) != ".gz" {
  26. //This is not a gzip file
  27. return errors.New("Webpack in invalid compression format")
  28. }
  29. //Start the download of binary
  30. //0 = false, 1 = true, 2 = error
  31. binaryDownloadComplete := 0
  32. webpackDownloadComplete := 0
  33. errorMessage := ""
  34. go func() {
  35. for binaryDownloadComplete == 0 {
  36. binaryFileSize := getFileSize(binaryDownloadTarget)
  37. progress := (float64(binaryFileSize) / float64(binarySize) * 100)
  38. progressUpdateFunction(0, progress, "Downloading binary")
  39. time.Sleep(100 * time.Millisecond)
  40. }
  41. if binaryDownloadComplete == 1 {
  42. progressUpdateFunction(0, 100, "Binary Download Completed")
  43. } else {
  44. progressUpdateFunction(0, 100, "Error: "+errorMessage)
  45. //Remove the update folder
  46. os.RemoveAll("./updates/")
  47. }
  48. }()
  49. err = downloadFile(binaryURL, binaryDownloadTarget)
  50. if err != nil {
  51. errorMessage = err.Error()
  52. binaryDownloadComplete = 2
  53. return err
  54. }
  55. binaryDownloadComplete = 1
  56. //Downlaod webpack
  57. go func() {
  58. for webpackDownloadComplete == 0 {
  59. webpackFileSize := getFileSize(webpackDownloadTarget)
  60. progress := (float64(webpackFileSize) / float64(webpackSize) * 100)
  61. progressUpdateFunction(1, progress, "Downloading webpack")
  62. time.Sleep(100 * time.Millisecond)
  63. }
  64. if webpackDownloadComplete == 1 {
  65. progressUpdateFunction(1, 100, "Webpack Download Completed")
  66. } else {
  67. progressUpdateFunction(1, 100, "Error: "+errorMessage)
  68. //Remove the update folder
  69. os.RemoveAll("./updates/")
  70. }
  71. }()
  72. err = downloadFile(webpackURL, webpackDownloadTarget)
  73. if err != nil {
  74. errorMessage = err.Error()
  75. webpackDownloadComplete = 2
  76. return err
  77. }
  78. webpackDownloadComplete = 1
  79. //Download completed.
  80. //check checksum if exists
  81. //just a small file, dont need progress bar
  82. if checksumURL != "" {
  83. err = downloadFile(checksumURL, checksumDownloadTarget)
  84. if err != nil {
  85. errorMessage = err.Error()
  86. return err
  87. }
  88. checksumFileContent, err := ioutil.ReadFile(checksumDownloadTarget)
  89. if err != nil {
  90. errorMessage = err.Error()
  91. return err
  92. }
  93. binaryHash, err := getSHA1Hash(binaryDownloadTarget)
  94. if err != nil {
  95. errorMessage = err.Error()
  96. return err
  97. }
  98. webpackHash, err := getSHA1Hash(webpackDownloadTarget)
  99. if err != nil {
  100. errorMessage = err.Error()
  101. return err
  102. }
  103. binaryBool := readCheckSumFile(string(checksumFileContent), filepath.Base(binaryURL), binaryHash)
  104. webPackBool := readCheckSumFile(string(checksumFileContent), filepath.Base(webpackURL), webpackHash)
  105. os.Remove(checksumDownloadTarget)
  106. if !binaryBool {
  107. progressUpdateFunction(1, 100, "Binary checksum mismatch")
  108. errorMessage = "Binary checksum mismatch"
  109. return errors.New("Binary checksum mismatch")
  110. }
  111. if !webPackBool {
  112. progressUpdateFunction(1, 100, "Web pack checksum mismatch")
  113. errorMessage = "Web pack checksum mismatch"
  114. return errors.New("Web pack checksum mismatch")
  115. }
  116. }
  117. //Try unzip webpack
  118. gzipstrean, err := os.Open(webpackDownloadTarget)
  119. if err != nil {
  120. return err
  121. }
  122. progressUpdateFunction(2, 0, "Extracting webpack")
  123. err = extractTarGz(gzipstrean, "./updates/", progressUpdateFunction)
  124. if err != nil {
  125. return err
  126. }
  127. gzipstrean.Close()
  128. //Remove the webpack compressed file
  129. os.Remove(webpackDownloadTarget)
  130. progressUpdateFunction(3, 100, "Updates Downloaded")
  131. return nil
  132. }
  133. //Get the update sizes, return binary size, webpack size and error if any
  134. func GetUpdateSizes(binaryURL string, webpackURL string) (int, int, error) {
  135. bps, err := getDownloadFileSize(binaryURL)
  136. if err != nil {
  137. return -1, -1, err
  138. }
  139. wps, err := getDownloadFileSize(webpackURL)
  140. if err != nil {
  141. return -1, -1, err
  142. }
  143. return bps, wps, nil
  144. }
  145. func GetLauncherVersion() (string, error) {
  146. //Check if there is a launcher listening to port 25576
  147. client := http.Client{
  148. Timeout: 3 * time.Second,
  149. }
  150. resp, err := client.Get("http://127.0.0.1:25576/chk")
  151. if err != nil {
  152. return "", errors.New("No launcher found. Unable to restart")
  153. }
  154. content, err := ioutil.ReadAll(resp.Body)
  155. if err != nil {
  156. return "", errors.New("Read launcher response failed")
  157. }
  158. return string(content), nil
  159. }
  160. func CheckLauncherPortResponsive() bool {
  161. client := http.Client{
  162. Timeout: 3 * time.Second,
  163. }
  164. _, err := client.Get("http://127.0.0.1:25576/chk")
  165. if err != nil {
  166. return false
  167. }
  168. return true
  169. }