Browse Source

Add wait and log params for increasing reliability with calls from RXSM

master
NGnius (Graham) 5 years ago
parent
commit
009c97e4f4
1 changed files with 44 additions and 28 deletions
  1. +44
    -28
      rxsm-updater/rxsm-updater.go

+ 44
- 28
rxsm-updater/rxsm-updater.go View File

@@ -6,11 +6,12 @@ import (
"runtime"
"os"
"io"
"fmt"
"log"
"errors"
"archive/zip"
"path/filepath"
"flag"
"time"
)

const (
@@ -27,49 +28,64 @@ var (
PlatformStream string
UpdateServer string
TargetBinary string
Delay time.Duration
IsLogged bool
)

func init() {
fmt.Println("RXSM Updater version", RXSMUpdaterVersion)
fmt.Println("This program updates RXSM headlessly. Use rxsm-updater --help to view advanced features")
fmt.Println(os.Args)
log.Println("RXSM Updater version", RXSMUpdaterVersion)
log.Println("This program updates RXSM headlessly. Use rxsm-updater --help to view advanced features")
log.Println(os.Args)
flag.StringVar(&Zipfile, "zip", DefaultZipFile, "The zipfile to extract from (and download to, in unattended mode)")
flag.StringVar(&Target, "target", "", "The directory to target for the update (the directory containing RXSM)")
flag.BoolVar(&Unattended, "unattended", false, "Download & extract the RXSM update (WIP)")
flag.StringVar(&PlatformStream, "stream", "release", "The update stream to use when retrieving updates in unattended mode")
flag.StringVar(&UpdateServer, "server", DefaultUpdateServer, "The web server to use for retrieving update information")
flag.DurationVar(&Delay, "wait", 0, "Time to wait before starting")
flag.BoolVar(&IsLogged, "log", false, "Send output to log")
}

func main() {
flag.Parse()
if IsLogged {
f, _ := os.Create("rxsm-updater.log")
log.SetOutput(f)
log.Println("RXSM Updater version", RXSMUpdaterVersion)
log.Println("This program updates RXSM headlessly. Use rxsm-updater --help to view advanced features")
log.Println(os.Args)
}
if Delay != 0 {
log.Println("Waiting", Delay.Seconds(), "second(s)")
time.Sleep(Delay)
}
if Unattended {
fmt.Println("Attempting WIP Unattended update")
fmt.Println("This is not advised, and will fail if an updater update is necessary")
log.Println("Attempting WIP Unattended update")
log.Println("This is not advised, and will fail if an updater update is necessary")
URL, isUpdatable, ok := CheckForUpdate(UpdateServer, "", runtime.GOOS+"/"+runtime.GOARCH+"/"+PlatformStream)
if !(ok && isUpdatable && URL != "") {
fmt.Println("No update found")
log.Println("No update found")
return
}
downloadErr := DownloadRXSMUpdate(URL, func(int, string){})
if downloadErr != nil {
fmt.Println(downloadErr)
log.Println(downloadErr)
return
}
proc, forkErr := ForkRXSMUpdate()
if forkErr != nil {
fmt.Println(forkErr)
log.Println(forkErr)
return
}
fmt.Println("Extraction forked to", proc.Pid)
log.Println("Extraction forked to", proc.Pid)
} else {
fmt.Println("Installing from", Zipfile)
log.Println("Installing from", Zipfile)
installErr := InstallRXSMUpdate(func(int, string){})
if installErr != nil {
fmt.Println(installErr)
log.Println(installErr)
return
}
}
fmt.Println("Operation complete")
log.Println("Operation complete")
// TODO: implement callback for Qt window
}

@@ -80,17 +96,17 @@ func DownloadRXSMUpdateQuiet(URL string) {
func DownloadRXSMUpdate(URL string, statusCallback func(progress int, description string)) (error){
// progress is out of 100
statusCallback(25, "Downloading")
fmt.Println("Downloading update from "+URL)
log.Println("Downloading update from "+URL)
f, createErr := os.Create(Zipfile)
if createErr != nil {
fmt.Println("Error creating temporary update file")
log.Println("Error creating temporary update file")
statusCallback(-1, "Error creating update temporary file")
return createErr
}
defer f.Close()
ok := DownloadUpdate(URL, f)
if !ok {
fmt.Println("Error downloading update")
log.Println("Error downloading update")
statusCallback(-1, "Download failed")
return errors.New("download failed in update API")
}
@@ -99,16 +115,16 @@ func DownloadRXSMUpdate(URL string, statusCallback func(progress int, descriptio
f.Seek(0,0)
fStat, statErr := f.Stat()
if statErr != nil {
fmt.Println("Error getting download temp file stat")
log.Println("Error getting download temp file stat")
return statErr
}
fmt.Println("Downloaded", fStat.Size(), "bytes")
log.Println("Downloaded", fStat.Size(), "bytes")
statusCallback(75, "Extracting Updater")
// TODO: implement way to have this actually work
zipFile, zipErr := zip.NewReader(f, fStat.Size())
if zipErr != nil {
fmt.Println("Error creating zip reader")
fmt.Println(zipErr)
log.Println("Error creating zip reader")
log.Println(zipErr)
return zipErr
}
for _, f := range zipFile.File {
@@ -125,19 +141,19 @@ func DownloadRXSMUpdate(URL string, statusCallback func(progress int, descriptio
if len(filename) >= len(updaterFilename) && filename[:len(updaterFilename)] == updaterFilename {
fileReadCloser, openErr := f.Open()
if openErr != nil {
fmt.Println("Error opening updater in zip archive")
log.Println("Error opening updater in zip archive")
return openErr
}
defer fileReadCloser.Close()
destFile, createErr := os.Create(TargetBinary)
if createErr != nil {
fmt.Println("Error creating updater file")
log.Println("Error creating updater file")
return createErr
}
defer destFile.Close()
_, copyErr := io.Copy(destFile, fileReadCloser)
if copyErr != nil {
fmt.Println("Error copying/extracting updater")
log.Println("Error copying/extracting updater")
return copyErr
}
}
@@ -158,7 +174,7 @@ func ForkRXSMUpdate() (process *os.Process, err error) {
func InstallRXSMUpdate(statusCallback func(progress int, description string)) (error){
f, openErr := os.Open(Zipfile)
if openErr != nil {
fmt.Println("Error opening zip file")
log.Println("Error opening zip file")
statusCallback(-1, "Opening zip file failed")
return openErr
}
@@ -167,13 +183,13 @@ func InstallRXSMUpdate(statusCallback func(progress int, description string)) (e
f.Seek(0,0)
fStat, statErr := f.Stat()
if statErr != nil {
fmt.Println("Error retrieving file stats")
log.Println("Error retrieving file stats")
statusCallback(-1, "Extracting zip file failed")
return statErr
}
unpackErr := unpackRXSMInstall(f, fStat.Size(), func(p int, d string){statusCallback(1, d)})
if unpackErr != nil {
fmt.Println("Error extracting update")
log.Println("Error extracting update")
statusCallback(-1, "Unpacking failed")
return unpackErr
}
@@ -181,7 +197,7 @@ func InstallRXSMUpdate(statusCallback func(progress int, description string)) (e
// TODO: is there installation required?
rmErr := os.Remove(Zipfile)
if rmErr != nil {
fmt.Println("Error removing download file")
log.Println("Error removing download file")
statusCallback(-1, "Installing failed")
return rmErr
}
@@ -230,7 +246,7 @@ func unpackRXSMInstall(reader io.ReaderAt, size int64, statusCallback func(progr
filename = filepath.Join(Target, filename)
dirErr := os.MkdirAll(filepath.Dir(filename), os.ModeDir | os.ModePerm)
if dirErr != nil {
fmt.Println("Dir err "+filepath.Dir(filename))
log.Println("Dir err "+filepath.Dir(filename))
return dirErr
}
newFile, createErr := os.Create(filename)