updates.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package updates
  2. import (
  3. "errors"
  4. "io"
  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. time.Sleep(300 * time.Millisecond)
  57. //Downlaod webpack
  58. go func() {
  59. for webpackDownloadComplete == 0 {
  60. webpackFileSize := getFileSize(webpackDownloadTarget)
  61. progress := (float64(webpackFileSize) / float64(webpackSize) * 100)
  62. progressUpdateFunction(1, progress, "Downloading webpack")
  63. time.Sleep(100 * time.Millisecond)
  64. }
  65. if webpackDownloadComplete == 1 {
  66. progressUpdateFunction(1, 100, "Webpack Download Completed")
  67. } else {
  68. progressUpdateFunction(1, 100, "Error: "+errorMessage)
  69. //Remove the update folder
  70. os.RemoveAll("./updates/")
  71. }
  72. }()
  73. err = downloadFile(webpackURL, webpackDownloadTarget)
  74. if err != nil {
  75. errorMessage = err.Error()
  76. webpackDownloadComplete = 2
  77. return err
  78. }
  79. webpackDownloadComplete = 1
  80. //Download completed.
  81. //check checksum if exists
  82. //just a small file, dont need progress bar
  83. if checksumURL != "" {
  84. err = downloadFile(checksumURL, checksumDownloadTarget)
  85. if err != nil {
  86. errorMessage = err.Error()
  87. return err
  88. }
  89. checksumFileContent, err := os.ReadFile(checksumDownloadTarget)
  90. if err != nil {
  91. errorMessage = err.Error()
  92. return err
  93. }
  94. binaryHash, err := getSHA1Hash(binaryDownloadTarget)
  95. if err != nil {
  96. errorMessage = err.Error()
  97. return err
  98. }
  99. webpackHash, err := getSHA1Hash(webpackDownloadTarget)
  100. if err != nil {
  101. errorMessage = err.Error()
  102. return err
  103. }
  104. binaryBool := readCheckSumFile(string(checksumFileContent), filepath.Base(binaryURL), binaryHash)
  105. webPackBool := readCheckSumFile(string(checksumFileContent), filepath.Base(webpackURL), webpackHash)
  106. os.Remove(checksumDownloadTarget)
  107. if !binaryBool {
  108. progressUpdateFunction(1, 100, "Binary checksum mismatch")
  109. errorMessage = "Binary checksum mismatch"
  110. return errors.New("Binary checksum mismatch")
  111. }
  112. if !webPackBool {
  113. progressUpdateFunction(1, 100, "Web pack checksum mismatch")
  114. errorMessage = "Web pack checksum mismatch"
  115. return errors.New("Web pack checksum mismatch")
  116. }
  117. }
  118. //Try unzip webpack
  119. gzipstrean, err := os.Open(webpackDownloadTarget)
  120. if err != nil {
  121. return err
  122. }
  123. progressUpdateFunction(2, 0, "Extracting webpack")
  124. err = extractTarGz(gzipstrean, "./updates/", progressUpdateFunction)
  125. if err != nil {
  126. return err
  127. }
  128. gzipstrean.Close()
  129. //Remove the webpack compressed file
  130. os.Remove(webpackDownloadTarget)
  131. progressUpdateFunction(3, 100, "Updates Downloaded")
  132. return nil
  133. }
  134. // Get the update sizes, return binary size, webpack size and error if any
  135. func GetUpdateSizes(binaryURL string, webpackURL string) (int, int, error) {
  136. bps, err := getDownloadFileSize(binaryURL)
  137. if err != nil {
  138. return -1, -1, err
  139. }
  140. wps, err := getDownloadFileSize(webpackURL)
  141. if err != nil {
  142. return -1, -1, err
  143. }
  144. return bps, wps, nil
  145. }
  146. func GetLauncherVersion() (string, error) {
  147. //Check if there is a launcher listening to port 25576
  148. client := http.Client{
  149. Timeout: 3 * time.Second,
  150. }
  151. resp, err := client.Get("http://127.0.0.1:25576/chk")
  152. if err != nil {
  153. return "", errors.New("No launcher found. Unable to restart")
  154. }
  155. content, err := io.ReadAll(resp.Body)
  156. if err != nil {
  157. return "", errors.New("Read launcher response failed")
  158. }
  159. return string(content), nil
  160. }
  161. func CheckLauncherPortResponsive() bool {
  162. client := http.Client{
  163. Timeout: 3 * time.Second,
  164. }
  165. _, err := client.Get("http://127.0.0.1:25576/chk")
  166. if err != nil {
  167. return false
  168. }
  169. return true
  170. }