Files
gocommon/azure/misc.go

240 lines
5.1 KiB
Go
Raw Permalink Normal View History

2023-05-24 15:10:15 +09:00
package azure
import (
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
"os/exec"
"path"
"runtime"
"sort"
"strconv"
"strings"
"syscall"
"time"
2023-06-21 14:13:30 +09:00
"repositories.action2quare.com/ayo/gocommon/flagx"
2023-05-24 15:10:15 +09:00
"repositories.action2quare.com/ayo/gocommon/logger"
)
2023-06-21 14:13:30 +09:00
var linkupdate = flagx.String("updatelink", "", "")
2023-05-24 15:10:15 +09:00
func SortVersions(versions []string) []string {
sort.Slice(versions, func(i, j int) bool {
leftnum := 0
for _, iv := range strings.Split(versions[i], ".") {
n, _ := strconv.Atoi(iv)
leftnum += leftnum<<8 + n
}
rightnum := 0
for _, iv := range strings.Split(versions[j], ".") {
n, _ := strconv.Atoi(iv)
rightnum += rightnum<<8 + n
}
return leftnum < rightnum
})
return versions
}
const (
HoustonStatPoolCount = int(10)
)
type HoustonStatReport struct {
Region string `json:"region"`
FreeMemory float64 `json:"freeMemory"`
FreePercent float64 `json:"freePercent"`
CPUUsage float64 `json:"cpuUsage"`
PlayingUsers int `json:"users"`
PlayingSessions int `json:"sessions"`
}
var ErrUpdateUnnecessary = errors.New("binary is already latest")
func SelfUpdateUsingScript(replycache *MessageReplyCache, graph *Graph, patchroot string, force bool) (err error) {
// 1. 다운로드
var linkfilearg string
if replycache != nil {
if replycache.ReplyWrap == nil {
hostname, _ := os.Hostname()
replycache.ReplyWrap = replycache.SourceActivity().MakeWrap().WithPrefix(hostname)
}
linkfile := replycache.Serialize()
linkfilearg = fmt.Sprintf("-updatelink=%s", linkfile)
}
currentexe, _ := os.Executable()
currentexe = strings.ReplaceAll(currentexe, "\\", "/")
exefile := path.Base(currentexe)
if runtime.GOOS == "windows" && !strings.HasSuffix(exefile, ".exe") {
exefile += ".exe"
}
newbinary := fmt.Sprintf("%s.%s", exefile, time.Now().Format("2006.01.02-15.04.05"))
downloadurl := path.Join(patchroot, exefile)
err = graph.DownloadFile(downloadurl, newbinary)
if err != nil {
return
}
_, err = os.Stat(newbinary)
if os.IsNotExist(err) {
err = errors.New("다운로드 실패 : " + newbinary)
return
}
if !force {
currentfile, e := os.Open(currentexe)
if e != nil {
return e
}
defer currentfile.Close()
hash1 := md5.New()
_, err = io.Copy(hash1, currentfile)
if err != nil {
return
}
currentHash := hex.EncodeToString(hash1.Sum(nil))
nextfile, e := os.Open(newbinary)
if e != nil {
return e
}
defer nextfile.Close()
hash2 := md5.New()
_, err = io.Copy(hash2, nextfile)
if err != nil {
return
}
nextHash := hex.EncodeToString(hash2.Sum(nil))
if currentHash == nextHash {
// 해시가 같으니까 업데이트 할 필요가 없다.
return ErrUpdateUnnecessary
}
}
var scriptfileName string
if runtime.GOOS == "linux" {
scriptfileName = "selfupdate.sh"
} else if runtime.GOOS == "windows" {
scriptfileName = "selfupdate.bat"
}
scripturl := path.Join(patchroot, scriptfileName)
if _, err = os.Stat(scriptfileName); os.IsExist(err) {
err = os.Remove(scriptfileName)
} else {
err = nil
}
if err != nil {
return
}
// 2. 스크립트 다운로드
err = graph.DownloadFile(scripturl, scriptfileName)
if err != nil {
return
}
var nextArgs []string
for _, arg := range os.Args[1:] {
// -updatelink : selfupdate시에
if !strings.HasPrefix(arg, "-updatelink=") && arg != "-prefetch" {
nextArgs = append(nextArgs, arg)
}
}
pid := strconv.Itoa(os.Getpid())
args := append([]string{
pid,
newbinary,
exefile,
}, nextArgs...)
if len(linkfilearg) > 0 {
args = append(args, linkfilearg)
}
// 3. 독립 실행
if runtime.GOOS == "linux" {
// 실행 가능한 권한 부여
err = os.Chmod(scriptfileName, 0777)
if err != nil {
return
}
// 실행
env := os.Environ()
currentpath := path.Dir(currentexe)
argv0 := path.Join(currentpath, scriptfileName)
args = append([]string{"/bin/bash", argv0}, args...)
err = syscall.Exec(args[0], args, env)
if err != nil {
return
}
} else if runtime.GOOS == "windows" {
windowsargs := append([]string{
"/C",
"start",
scriptfileName,
}, args...)
cmd := exec.Command("cmd.exe", windowsargs...)
err = cmd.Run()
if err != nil {
return
}
}
return
}
func ReplyUpdateComplete() {
defer func() {
r := recover()
if r != nil {
logger.Error(r)
}
}()
2023-06-21 14:13:30 +09:00
if len(*linkupdate) > 0 {
cache := DeserializeMessageReplyCache(*linkupdate)
2023-05-24 15:10:15 +09:00
if cache != nil {
2023-06-21 14:13:30 +09:00
os.Remove(*linkupdate)
2023-05-24 15:10:15 +09:00
if cache.ReplyWrap != nil {
cache.ReplyWrap.Update(cache.Replyaid, "업데이트 완료")
}
}
}
}
// var objectIDCounter = readRandomUint32()
// var processUnique = processUniqueBytes()
// func processUniqueBytes() [5]byte {
// var b [5]byte
// _, err := io.ReadFull(rand.Reader, b[:])
// if err != nil {
// panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %v", err))
// }
// return b
// }
// func readRandomUint32() uint32 {
// var b [4]byte
// _, err := io.ReadFull(rand.Reader, b[:])
// if err != nil {
// panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %v", err))
// }
// return (uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)
// }