update/main.go (125 lines of code) (raw):
//go:generate goversioninfo -o=resource_windows.syso
package main
import (
"fmt"
"os"
"github.com/marcsauter/single"
"github.com/spf13/pflag"
"github.com/aliyun/aliyun_assist_client/agent/flagging"
"github.com/aliyun/aliyun_assist_client/agent/log"
"github.com/aliyun/aliyun_assist_client/agent/version"
"github.com/aliyun/aliyun_assist_client/common/envutil"
)
var SingleAppLock *single.Single
type Options struct {
GetHelp bool
GetVersion bool
GetGitHash bool
// Exclusive group: Check update option
CheckUpdate bool
// Exclusive group: Force update options
ForceUpdate bool
// Required options for force update
ForceUpdateURL string
ForceUpdateMD5 string
// Exclusive group: Local install (should be invisible for general users)
LocalInstall string
}
func parseOptions() Options {
options := Options{}
pflag.BoolVarP(&options.GetHelp, "help", "h", false, "print help")
pflag.BoolVarP(&options.GetVersion, "version", "v", false, "print version")
pflag.BoolVar(&options.GetGitHash, "githash", false, "print git hash")
// Exclusive group: Check update option
pflag.BoolVarP(&options.CheckUpdate, "check_update", "c", false, "Check and update if necessary")
// Exclusive group: Force update options
pflag.BoolVarP(&options.ForceUpdate, "force_update", "f", false, "Force update with specified package")
pflag.StringVarP(&options.ForceUpdateURL, "url", "u", "", "Download URL of specified update package")
pflag.StringVarP(&options.ForceUpdateMD5, "md5", "m", "", "MD5 checksum of specified update package")
// Exclusive group: Local install
pflag.StringVar(&options.LocalInstall, "local_install", "", "Invoke local install script of extracted update package")
pflag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [options]\n", os.Args[0])
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, "Aliyun Assist Copyright (c) 2017-2023 Alibaba Group Holding Limited")
fmt.Fprintln(os.Stderr)
fmt.Fprintln(os.Stderr, "Options:")
pflag.PrintDefaults()
}
pflag.Parse()
return options
}
func main() {
options := parseOptions()
if options.GetHelp {
pflag.Usage()
return
}
if options.GetVersion {
fmt.Println(version.AssistVersion)
return
}
if options.GetGitHash {
fmt.Println(version.GitCommitHash)
return
}
log.InitLog("aliyun_assist_update.log", "", false)
log.GetLogger().Infof("Starting...... version: %s githash: %s", version.AssistVersion, version.GitCommitHash)
SingleAppLock = single.New("AliyunAssistUpdateSingleLock")
if err := SingleAppLock.CheckLock(); err != nil && err == single.ErrAlreadyRunning {
fmt.Fprintln(os.Stderr, "Error: another instance of the app is already running")
os.Exit(1)
return
}
defer SingleAppLock.TryUnlock()
// Init config
flagging.InitConfig(log.GetLogger())
envutil.ClearExecErrDot()
if options.CheckUpdate {
// Exclusive options check
if options.ForceUpdate || options.LocalInstall != "" {
fmt.Fprintln(os.Stderr, "Invalid options: specified options in conflict")
pflag.Usage()
os.Exit(1)
return
}
if err := doCheckUpdate(); err != nil {
log.GetLogger().WithError(err).Errorln("Failed to check or update agent")
fmt.Fprintln(os.Stderr, "Error:", err.Error())
os.Exit(1)
}
return
} else if options.ForceUpdate {
// Exclusive options check
if options.CheckUpdate || options.LocalInstall != "" {
fmt.Fprintln(os.Stderr, "Invalid options: specified options in conflict")
pflag.Usage()
os.Exit(1)
return
}
if options.ForceUpdateURL == "" {
fmt.Fprintln(os.Stderr, "Invalid options: -f/--force_update option needs specifying update package URL via --url option")
pflag.Usage()
os.Exit(1)
return
}
if options.ForceUpdateMD5 == "" {
fmt.Fprintln(os.Stderr, "Invalid options: -f/--force_update option needs specifying MD5 checksum of update package via --md5 option")
pflag.Usage()
os.Exit(1)
return
}
log.GetLogger().Infof("Force update: url=%s, md5=%s", options.ForceUpdateURL, options.ForceUpdateMD5)
if err := doUpdate(options.ForceUpdateURL, options.ForceUpdateMD5, ""); err != nil {
log.GetLogger().WithError(err).Errorln("Failed to perform force updating")
fmt.Fprintln(os.Stderr, "Error:", err.Error())
os.Exit(1)
}
return
} else if options.LocalInstall != "" {
// Exclusive options check
if options.CheckUpdate || options.ForceUpdate {
fmt.Fprintln(os.Stderr, "Invalid options: specified options in conflict")
pflag.Usage()
os.Exit(1)
return
}
if err := doInstall(options.LocalInstall); err != nil {
log.GetLogger().WithError(err).Errorln("Failed to execute update script")
fmt.Fprintln(os.Stderr, "Error:", err.Error())
os.Exit(1)
return
}
} else {
pflag.Usage()
return
}
}