pkg/upgrade/upgrade.go
package upgrade
import (
"context"
"fmt"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
goversion "github.com/hashicorp/go-version"
log "github.com/sirupsen/logrus"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon"
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/elevate"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
// Main
// 1) get current binary version
// 2) get the latest version
// 3) compare two version decide needs to download or not
// 4) download newer version zip
// 5) unzip to temp file
// 6) check permission of putting new kubevpn back
// 7) chmod +x, move old to /temp, move new to CURRENT_FOLDER
func Main(ctx context.Context, client *http.Client, url string) error {
err := elevatePermission()
if err != nil {
return err
}
err = downloadAndInstall(client, url)
if err != nil {
return err
}
log.Infof("Upgrade daemon...")
err = daemon.StartupDaemon(context.Background())
log.Info("Done")
return err
}
func downloadAndInstall(client *http.Client, url string) error {
temp, err := os.CreateTemp("", "*.zip")
if err != nil {
return err
}
defer os.Remove(temp.Name())
err = temp.Close()
if err != nil {
return err
}
err = util.Download(client, url, temp.Name(), os.Stdout, os.Stderr)
if err != nil {
return err
}
var curFolder string
curFolder, err = os.Executable()
if err != nil {
return err
}
var file *os.File
file, err = os.CreateTemp(filepath.Dir(curFolder), "")
if err != nil {
return err
}
defer os.Remove(file.Name())
err = file.Close()
if err != nil {
return err
}
err = util.UnzipKubeVPNIntoFile(temp.Name(), file.Name())
if err != nil {
return err
}
err = os.Chmod(file.Name(), 0755)
if err != nil {
return err
}
var createTemp *os.File
createTemp, err = os.CreateTemp(filepath.Dir(curFolder), "")
if err != nil {
return err
}
defer os.Remove(createTemp.Name())
err = createTemp.Close()
if err != nil {
return err
}
err = os.Remove(createTemp.Name())
if err != nil {
return err
}
err = util.Move(curFolder, createTemp.Name())
if err != nil {
return err
}
err = util.Move(file.Name(), curFolder)
return err
}
func elevatePermission() error {
executable, err := os.Executable()
if err != nil {
return err
}
var tem *os.File
tem, err = os.Create(filepath.Join(filepath.Dir(executable), ".test"))
if tem != nil {
_ = tem.Close()
_ = os.Remove(tem.Name())
}
if err == nil {
return nil
}
if os.IsPermission(err) {
elevate.RunWithElevated()
os.Exit(0)
} else if err != nil {
return err
} else if !elevate.IsAdmin() {
elevate.RunWithElevated()
os.Exit(0)
}
return nil
}
func NeedsUpgrade(ctx context.Context, client *http.Client, version string) (url string, latestVersion string, upgrade bool, err error) {
latestVersion, url, err = util.GetManifest(client, runtime.GOOS, runtime.GOARCH)
if err != nil {
v := "https://github.com/kubenetworks/kubevpn/raw/master/plugins/stable.txt"
var stream []byte
stream, err = util.DownloadFileStream(v)
latestVersion = strings.TrimSpace(string(stream))
url = fmt.Sprintf("https://github.com/kubenetworks/kubevpn/releases/download/%s/kubevpn_%s_%s_%s.zip", latestVersion, latestVersion, runtime.GOOS, runtime.GOARCH)
}
if err != nil {
return
}
var currV, latestV *goversion.Version
currV, err = goversion.NewVersion(version)
if err != nil {
return
}
latestV, err = goversion.NewVersion(latestVersion)
if err != nil {
return
}
if currV.GreaterThanOrEqual(latestV) {
return
}
upgrade = true
return
}