From cb586b5591e7863e3531384571765bfad654887c Mon Sep 17 00:00:00 2001
From: Yorjander Hernandez Vergara <99102374+Kbayero@users.noreply.github.com>
Date: Fri, 5 Jan 2024 15:22:31 +0200
Subject: [PATCH] Update agent version and fix agent update based on master
version (#227)
---
agent/updater/configuration/config.go | 13 ++-
agent/updater/configuration/const.go | 70 ++++++++++++++
agent/updater/constants/const.go | 73 --------------
agent/updater/main.go | 34 ++++---
agent/updater/serv/config.go | 4 +-
agent/updater/serv/install.go | 9 +-
agent/updater/serv/run.go | 7 +-
agent/updater/serv/service.go | 8 +-
agent/updater/serv/uninstall.go | 13 +--
agent/updater/updates/compare.go | 51 ----------
agent/updater/updates/service.go | 96 ++++++++-----------
agent/updater/updates/update.go | 28 +++---
agent/updater/updates/version.go | 20 +++-
agent/updater/utils/cmd.go | 35 +++----
agent/updater/utils/delay.go | 1 +
agent/updater/utils/files.go | 43 +++++----
agent/updater/utils/lock.go | 2 +
agent/updater/utils/req.go | 1 +
agent/updater/utils/services.go | 2 +
agent/updater/utils/timestamp.go | 1 +
agent/updater/utils/tls.go | 1 +
.../guide-linux-agent.component.ts | 6 +-
22 files changed, 240 insertions(+), 278 deletions(-)
create mode 100644 agent/updater/configuration/const.go
delete mode 100644 agent/updater/constants/const.go
delete mode 100644 agent/updater/updates/compare.go
diff --git a/agent/updater/configuration/config.go b/agent/updater/configuration/config.go
index 3cd8adf52..c3e47b1a1 100644
--- a/agent/updater/configuration/config.go
+++ b/agent/updater/configuration/config.go
@@ -18,22 +18,25 @@ type Environment struct {
Branch string `yaml:"branch"`
}
-func ReadEnv() (*Environment, error) {
+// ReadEnv reads the environment file
+// If the file does not exist, it returns a default environment with release branch
+// If the file exists, it returns the environment
+func ReadEnv() (string, error) {
var env Environment
path, err := utils.GetMyPath()
if err != nil {
- return nil, err
+ return "", err
}
path = filepath.Join(path, "env.yml")
if _, err = os.Stat(path); os.IsNotExist(err) {
- return &Environment{Branch: "release"}, nil
+ return "release", nil
} else {
err = utils.ReadYAML(path, &env)
if err != nil {
- return nil, err
+ return "", err
}
}
- return &env, nil
+ return env.Branch, nil
}
diff --git a/agent/updater/configuration/const.go b/agent/updater/configuration/const.go
new file mode 100644
index 000000000..2e89a5c31
--- /dev/null
+++ b/agent/updater/configuration/const.go
@@ -0,0 +1,70 @@
+package configuration
+
+import (
+ "path/filepath"
+ "runtime"
+ "time"
+
+ "github.com/utmstack/UTMStack/agent/updater/utils"
+)
+
+const (
+ SERV_NAME = "UTMStackUpdater"
+ SERV_LOG = "utmstack_updater.log"
+ SERV_LOCK = "utmstack_updater.lock"
+ MASTERVERSIONENDPOINT = "/management/info"
+ Bucket = "https://cdn.utmstack.com/agent_updates/"
+ CHECK_EVERY = 5 * time.Minute
+)
+
+type ServiceAttribt struct {
+ ServName string
+ ServBin string
+ ServLock string
+}
+
+// GetServAttr returns a map of ServiceAttribt
+func GetServAttr() map[string]ServiceAttribt {
+ serAttr := map[string]ServiceAttribt{
+ "agent": {ServName: "UTMStackAgent", ServBin: "utmstack_agent_service", ServLock: "utmstack_agent.lock"},
+ "updater": {ServName: "UTMStackUpdater", ServBin: "utmstack_updater_self", ServLock: "utmstack_updater.lock"},
+ "redline": {ServName: "UTMStackRedline", ServBin: "utmstack_redline_service", ServLock: "utmstack_redline.lock"},
+ }
+
+ switch runtime.GOOS {
+ case "windows":
+ for code, att := range serAttr {
+ att.ServBin += ".exe"
+ serAttr[code] = att
+ }
+ }
+
+ return serAttr
+}
+
+// GetAgentBin returns the agent binary name
+func GetAgentBin() string {
+ bin := "utmstack_agent_service"
+ if runtime.GOOS == "windows" {
+ bin = bin + ".exe"
+ }
+ return bin
+}
+
+// GetCertPath returns the path to the certificate
+func GetCertPath() string {
+ path, _ := utils.GetMyPath()
+ return filepath.Join(path, "certs", "utm.crt")
+}
+
+// GetKeyPath returns the path to the key
+func GetKeyPath() string {
+ path, _ := utils.GetMyPath()
+ return filepath.Join(path, "certs", "utm.key")
+}
+
+// GetCaPath returns the path to the CA
+func GetCaPath() string {
+ path, _ := utils.GetMyPath()
+ return filepath.Join(path, "certs", "ca.crt")
+}
diff --git a/agent/updater/constants/const.go b/agent/updater/constants/const.go
deleted file mode 100644
index 9e3de6c17..000000000
--- a/agent/updater/constants/const.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package constants
-
-import (
- "path/filepath"
- "runtime"
- "time"
-
- "github.com/utmstack/UTMStack/agent/updater/utils"
-)
-
-const (
- SERV_NAME = "UTMStackUpdater"
- SERV_LOG = "utmstack_updater.log"
- SERV_LOCK = "utmstack_updater.lock"
- MASTERVERSIONENDPOINT = "/management/info"
- Bucket = "https://cdn.utmstack.com/agent_updates/"
-)
-
-type ServiceAttribt struct {
- ServName string
- ServBin string
- ServLock string
-}
-
-var (
- CheckUpdatesEvery = time.Duration(5 * time.Minute)
-)
-
-func GetServAttr() map[string]ServiceAttribt {
- serAttr := map[string]ServiceAttribt{}
-
- switch runtime.GOOS {
- case "windows":
- serAttr["agent"] = ServiceAttribt{ServName: "UTMStackAgent", ServBin: "utmstack_agent_service.exe", ServLock: "utmstack_agent.lock"}
- serAttr["filebeat"] = ServiceAttribt{ServName: "UTMStackModulesLogsCollector", ServBin: "utmstack_agent_service.exe", ServLock: "utmstack_modules_collector.lock"}
- serAttr["winlogbeat"] = ServiceAttribt{ServName: "UTMStackWindowsLogsCollector", ServBin: "utmstack_agent_service.exe", ServLock: "utmstack_windows_collector.lock"}
- serAttr["updater"] = ServiceAttribt{ServName: "UTMStackUpdater", ServBin: "utmstack_updater_self.exe", ServLock: "utmstack_updater.lock"}
- serAttr["redline"] = ServiceAttribt{ServName: "UTMStackRedline", ServBin: "utmstack_redline_service.exe", ServLock: "utmstack_redline.lock"}
- case "linux":
- serAttr["agent"] = ServiceAttribt{ServName: "UTMStackAgent", ServBin: "utmstack_agent_service", ServLock: "utmstack_agent.lock"}
- serAttr["filebeat"] = ServiceAttribt{ServName: "UTMStackModulesLogsCollector", ServBin: "utmstack_agent_service", ServLock: "utmstack_modules_collector.lock"}
- serAttr["winlogbeat"] = ServiceAttribt{ServName: "UTMStackWindowsLogsCollector", ServBin: "utmstack_agent_service", ServLock: "utmstack_windows_collector.lock"}
- serAttr["updater"] = ServiceAttribt{ServName: "UTMStackUpdater", ServBin: "utmstack_updater_self", ServLock: "utmstack_updater.lock"}
- serAttr["redline"] = ServiceAttribt{ServName: "UTMStackRedline", ServBin: "utmstack_redline_service", ServLock: "utmstack_redline.lock"}
- }
- return serAttr
-}
-
-func GetAgentBin() string {
- var bin string
- switch runtime.GOOS {
- case "windows":
- bin = "utmstack_agent_service.exe"
- case "linux":
- bin = "utmstack_agent_service"
- }
- return bin
-}
-
-func GetCertPath() string {
- path, _ := utils.GetMyPath()
- return filepath.Join(path, "certs", "utm.crt")
-}
-
-func GetKeyPath() string {
- path, _ := utils.GetMyPath()
- return filepath.Join(path, "certs", "utm.key")
-}
-
-func GetCaPath() string {
- path, _ := utils.GetMyPath()
- return filepath.Join(path, "certs", "ca.crt")
-}
diff --git a/agent/updater/main.go b/agent/updater/main.go
index 911cdc919..42ccb6641 100644
--- a/agent/updater/main.go
+++ b/agent/updater/main.go
@@ -8,23 +8,21 @@ import (
"time"
"github.com/quantfall/holmes"
- "github.com/utmstack/UTMStack/agent/updater/constants"
+ "github.com/utmstack/UTMStack/agent/updater/configuration"
"github.com/utmstack/UTMStack/agent/updater/serv"
"github.com/utmstack/UTMStack/agent/updater/utils"
)
-var h = holmes.New("debug", constants.SERV_NAME)
+var utmLogger = holmes.New("debug", configuration.SERV_NAME)
func main() {
- // Get current path
path, err := utils.GetMyPath()
if err != nil {
- fmt.Printf("Failed to get current path: %v", err)
- h.FatalError("Failed to get current path: %v", err)
+ fmt.Printf("failed to get current path: %v", err)
+ utmLogger.FatalError("failed to get current path: %v", err)
}
- // Configuring log saving
- var logger = utils.CreateLogger(filepath.Join(path, "logs", constants.SERV_LOG))
+ var logger = utils.CreateLogger(filepath.Join(path, "logs", configuration.SERV_LOG))
defer logger.Close()
log.SetOutput(logger)
@@ -32,25 +30,25 @@ func main() {
mode := os.Args[1]
switch mode {
case "run":
- serv.RunService(h)
+ serv.RunService(utmLogger)
case "install":
- h.Info("Installing UTMStack Updater service...")
+ utmLogger.Info("Installing UTMStack Updater service...")
- if isInstalled, err := utils.CheckIfServiceIsInstalled(constants.SERV_NAME); err != nil {
- h.FatalError("error checking %s service: %v", constants.SERV_NAME, err)
+ if isInstalled, err := utils.CheckIfServiceIsInstalled(configuration.SERV_NAME); err != nil {
+ utmLogger.FatalError("error checking %s service: %v", configuration.SERV_NAME, err)
} else if isInstalled {
- h.FatalError("%s is already installed", constants.SERV_NAME)
+ utmLogger.FatalError("%s is already installed", configuration.SERV_NAME)
}
- serv.InstallService(h)
- h.Info("UTMStack Updater service installed correctly.")
+ serv.InstallService(utmLogger)
+ utmLogger.Info("UTMStack Updater service installed correctly.")
time.Sleep(5 * time.Second)
os.Exit(0)
case "uninstall":
- h.Info("Uninstalling UTMStack Updater service...")
- serv.UninstallService(h)
- h.Info("UTMStack Updater service uninstalled correctly.")
+ utmLogger.Info("Uninstalling UTMStack Updater service...")
+ serv.UninstallService(utmLogger)
+ utmLogger.Info("UTMStack Updater service uninstalled correctly.")
time.Sleep(5 * time.Second)
os.Exit(0)
@@ -58,6 +56,6 @@ func main() {
fmt.Println("unknown option")
}
} else {
- serv.RunService(h)
+ serv.RunService(utmLogger)
}
}
diff --git a/agent/updater/serv/config.go b/agent/updater/serv/config.go
index 3971abf47..05c68ddf9 100644
--- a/agent/updater/serv/config.go
+++ b/agent/updater/serv/config.go
@@ -2,13 +2,13 @@ package serv
import (
"github.com/kardianos/service"
- "github.com/utmstack/UTMStack/agent/updater/constants"
+ "github.com/utmstack/UTMStack/agent/updater/configuration"
)
// GetConfigServ creates and returns a pointer to a service configuration structure.
func GetConfigServ() *service.Config {
svcConfig := &service.Config{
- Name: constants.SERV_NAME,
+ Name: configuration.SERV_NAME,
DisplayName: "UTMStack Updater",
Description: "UTMStack Updater Service",
}
diff --git a/agent/updater/serv/install.go b/agent/updater/serv/install.go
index 8bed64710..463b01432 100644
--- a/agent/updater/serv/install.go
+++ b/agent/updater/serv/install.go
@@ -7,24 +7,25 @@ import (
"github.com/quantfall/holmes"
)
-func InstallService(h *holmes.Logger) {
+// InstallService installs the service in the system and starts it
+func InstallService(utmLogger *holmes.Logger) {
svcConfig := GetConfigServ()
prg := new(program)
newService, err := service.New(prg, svcConfig)
if err != nil {
fmt.Printf("error creating new service: %v", err)
- h.FatalError("error creating new service: %v", err)
+ utmLogger.FatalError("error creating new service: %v", err)
}
err = newService.Install()
if err != nil {
fmt.Printf("error installing new service: %v", err)
- h.FatalError("error installing new service: %v", err)
+ utmLogger.FatalError("error installing new service: %v", err)
}
// Start the service after installing it
err = newService.Start()
if err != nil {
fmt.Printf("error starting new service: %v", err)
- h.FatalError("error starting new service: %v", err)
+ utmLogger.FatalError("error starting new service: %v", err)
}
}
diff --git a/agent/updater/serv/run.go b/agent/updater/serv/run.go
index e5bdecb56..c737c044e 100644
--- a/agent/updater/serv/run.go
+++ b/agent/updater/serv/run.go
@@ -5,15 +5,16 @@ import (
"github.com/quantfall/holmes"
)
-func RunService(h *holmes.Logger) {
+// RunService runs the service in the system
+func RunService(utmLogger *holmes.Logger) {
svcConfig := GetConfigServ()
prg := new(program)
newService, err := service.New(prg, svcConfig)
if err != nil {
- h.FatalError("error creating new service: %v", err)
+ utmLogger.FatalError("error creating new service: %v", err)
}
err = newService.Run()
if err != nil {
- h.FatalError("error running new service: %v", err)
+ utmLogger.FatalError("error running new service: %v", err)
}
}
diff --git a/agent/updater/serv/service.go b/agent/updater/serv/service.go
index 8dd2e5d77..319c5dbb0 100644
--- a/agent/updater/serv/service.go
+++ b/agent/updater/serv/service.go
@@ -10,12 +10,11 @@ import (
"github.com/kardianos/service"
"github.com/quantfall/holmes"
"github.com/utmstack/UTMStack/agent/updater/configuration"
- "github.com/utmstack/UTMStack/agent/updater/constants"
"github.com/utmstack/UTMStack/agent/updater/updates"
"github.com/utmstack/UTMStack/agent/updater/utils"
)
-var h = holmes.New("debug", constants.SERV_NAME)
+var h = holmes.New("debug", configuration.SERV_NAME)
type program struct{}
@@ -30,10 +29,10 @@ func (p *program) Stop(s service.Service) error {
func (p *program) run() {
for {
- isActive, err := utils.CheckIfServiceIsActive(constants.GetServAttr()["agent"].ServName)
+ isActive, err := utils.CheckIfServiceIsActive(configuration.GetServAttr()["agent"].ServName)
if err != nil {
time.Sleep(time.Second * 5)
- h.Error("error checking if %s service is active: %v", constants.GetServAttr()["agent"].ServName, err)
+ h.Error("error checking if %s service is active: %v", configuration.GetServAttr()["agent"].ServName, err)
continue
} else if !isActive {
time.Sleep(time.Second * 5)
@@ -47,7 +46,6 @@ func (p *program) run() {
h.FatalError("failed to get current path: %v", err)
}
- // Read config.yml
var cnf configuration.Config
err = utils.ReadYAML(filepath.Join(path, "config.yml"), &cnf)
if err != nil {
diff --git a/agent/updater/serv/uninstall.go b/agent/updater/serv/uninstall.go
index 7c9f5c1cd..a375ba1e5 100644
--- a/agent/updater/serv/uninstall.go
+++ b/agent/updater/serv/uninstall.go
@@ -2,18 +2,19 @@ package serv
import (
"github.com/quantfall/holmes"
- "github.com/utmstack/UTMStack/agent/updater/constants"
+ "github.com/utmstack/UTMStack/agent/updater/configuration"
"github.com/utmstack/UTMStack/agent/updater/utils"
)
-func UninstallService(h *holmes.Logger) {
+// UninstallService uninstalls the service in the system
+func UninstallService(utmLogger *holmes.Logger) {
// Uninstall service
- err := utils.StopService(constants.SERV_NAME)
+ err := utils.StopService(configuration.SERV_NAME)
if err != nil {
- h.FatalError("error stopping %s: %v", constants.SERV_NAME, err)
+ utmLogger.FatalError("error stopping %s: %v", configuration.SERV_NAME, err)
}
- err = utils.UninstallService(constants.SERV_NAME)
+ err = utils.UninstallService(configuration.SERV_NAME)
if err != nil {
- h.FatalError("error uninstalling %s: %v", constants.SERV_NAME, err)
+ utmLogger.FatalError("error uninstalling %s: %v", configuration.SERV_NAME, err)
}
}
diff --git a/agent/updater/updates/compare.go b/agent/updater/updates/compare.go
deleted file mode 100644
index 13236fa35..000000000
--- a/agent/updater/updates/compare.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package updates
-
-import (
- "sort"
- "strconv"
- "strings"
-)
-
-func GetLatestVersion(versions DataVersions, masterVersions string) Version {
- latestVersions := Version{}
-
- sort.Slice(versions.Versions, func(i, j int) bool {
- s1 := strings.Split(versions.Versions[i].MasterVersion, ".")
- s2 := strings.Split(versions.Versions[j].MasterVersion, ".")
- for k := 0; k < 3; k++ {
- if s1[k] > s2[k] {
- return true
- } else if s1[k] < s2[k] {
- return false
- }
- }
- return true
- })
-
- for _, vers := range versions.Versions {
- if isVersionGreaterOrEqual(vers.MasterVersion, masterVersions) {
- latestVersions = vers
- break
- }
- }
-
- return latestVersions
-}
-
-func isVersionGreaterOrEqual(version1 string, version2 string) bool {
- v1Parts := strings.Split(version1, ".")
- v2Parts := strings.Split(version2, ".")
-
- for i := 0; i < len(v1Parts) && i < len(v2Parts); i++ {
- v1, _ := strconv.Atoi(v1Parts[i])
- v2, _ := strconv.Atoi(v2Parts[i])
-
- if v1 > v2 {
- return true
- } else if v1 < v2 {
- return false
- }
- }
-
- return true
-}
diff --git a/agent/updater/updates/service.go b/agent/updater/updates/service.go
index 7b2864be8..49324c5e0 100644
--- a/agent/updater/updates/service.go
+++ b/agent/updater/updates/service.go
@@ -8,14 +8,23 @@ import (
"github.com/quantfall/holmes"
"github.com/utmstack/UTMStack/agent/updater/configuration"
- "github.com/utmstack/UTMStack/agent/updater/constants"
"github.com/utmstack/UTMStack/agent/updater/utils"
)
type UTMServices struct {
+ MasterVersion string
CurrentVersions Version
LatestVersions Version
- ServAttr map[string]constants.ServiceAttribt
+ ServAttr map[string]configuration.ServiceAttribt
+}
+
+func (u *UTMServices) UpdateCurrentMasterVersion(cnf configuration.Config) error {
+ masterVersion, err := getMasterVersion(cnf.Server, cnf.SkipCertValidation)
+ if err != nil {
+ return fmt.Errorf("error getting master version: %v", err)
+ }
+ u.MasterVersion = masterVersion
+ return nil
}
func (u *UTMServices) UpdateCurrentVersions() error {
@@ -24,7 +33,6 @@ func (u *UTMServices) UpdateCurrentVersions() error {
return fmt.Errorf("failed to get current path: %v", err)
}
- // Save data from versions.json
err = utils.ReadJson(filepath.Join(path, "versions.json"), &u.CurrentVersions)
if err != nil {
return fmt.Errorf("error reading current versions.json: %v", err)
@@ -33,32 +41,24 @@ func (u *UTMServices) UpdateCurrentVersions() error {
return nil
}
-func (u *UTMServices) UpdateLatestVersions() error {
- // Select environment
- env, err := configuration.ReadEnv()
- if err != nil {
- return fmt.Errorf("error reading environment configuration: %v", err)
- }
-
+func (u *UTMServices) UpdateLatestVersions(env string) error {
path, err := utils.GetMyPath()
if err != nil {
return fmt.Errorf("failed to get current path: %v", err)
}
- err = utils.DownloadFile(constants.Bucket+env.Branch+"/versions.json?time="+utils.GetCurrentTime(), filepath.Join(path, "versions.json"))
+ err = utils.DownloadFile(configuration.Bucket+env+"/versions.json", filepath.Join(path, "versions.json"))
if err != nil {
return fmt.Errorf("error downloading latest versions.json: %v", err)
}
- // Save data from versions.json
newData := DataVersions{}
err = utils.ReadJson(filepath.Join(path, "versions.json"), &newData)
if err != nil {
return fmt.Errorf("error reading latest versions.json: %v", err)
}
- // Save master versions
- u.LatestVersions = GetLatestVersion(newData, u.CurrentVersions.MasterVersion)
+ u.LatestVersions = getLatestVersion(newData, u.MasterVersion)
err = utils.WriteJSON(filepath.Join(path, "versions.json"), &u.LatestVersions)
if err != nil {
return fmt.Errorf("error writing versions.json: %v", err)
@@ -67,48 +67,40 @@ func (u *UTMServices) UpdateLatestVersions() error {
return nil
}
-func (u *UTMServices) CheckUpdates(masterVersion string, h *holmes.Logger) error {
- if isNewOrEqualVersion(u.LatestVersions.MasterVersion, masterVersion) {
- path, err := utils.GetMyPath()
- if err != nil {
- return fmt.Errorf("failed to get current path: %v", err)
- }
+func (u *UTMServices) CheckUpdates(env string, utmLogger *holmes.Logger) error {
+ path, err := utils.GetMyPath()
+ if err != nil {
+ return fmt.Errorf("failed to get current path: %v", err)
+ }
- // Select environment
- env, err := configuration.ReadEnv()
+ if isVersionGreater(u.CurrentVersions.RedlineVersion, u.LatestVersions.RedlineVersion) {
+ err := u.UpdateService(path, env, "redline", u.LatestVersions.RedlineVersion)
if err != nil {
- return fmt.Errorf("error reading environment configuration: %v", err)
- }
-
- if isVersionGreater(u.CurrentVersions.RedlineVersion, u.LatestVersions.RedlineVersion) {
- err := u.UpdateService(path, env.Branch, "redline")
- if err != nil {
- return fmt.Errorf("error updating UTMStackRedline service: %v", err)
- }
- h.Info("UTMStackRedline service updated correctly")
+ return fmt.Errorf("error updating UTMStackRedline service: %v", err)
}
+ utmLogger.Info("UTMStackRedline service updated correctly")
+ }
- if isVersionGreater(u.CurrentVersions.AgentVersion, u.LatestVersions.AgentVersion) {
- err := u.UpdateService(path, env.Branch, "agent")
- if err != nil {
- return fmt.Errorf("error updating UTMStackAgent service: %v", err)
- }
- h.Info("UTMStackAgent service updated correctly")
+ if isVersionGreater(u.CurrentVersions.AgentVersion, u.LatestVersions.AgentVersion) {
+ err := u.UpdateService(path, env, "agent", u.LatestVersions.AgentVersion)
+ if err != nil {
+ return fmt.Errorf("error updating UTMStackAgent service: %v", err)
}
+ utmLogger.Info("UTMStackAgent service updated correctly")
+ }
- if isVersionGreater(u.CurrentVersions.UpdaterVersion, u.LatestVersions.UpdaterVersion) {
- err := u.UpdateService(path, env.Branch, "updater")
- if err != nil {
- return fmt.Errorf("error updating UTMStackUpdater service: %v", err)
- }
- h.Info("UTMStackUpdater service updated correctly")
+ if isVersionGreater(u.CurrentVersions.UpdaterVersion, u.LatestVersions.UpdaterVersion) {
+ err := u.UpdateService(path, env, "updater", u.LatestVersions.UpdaterVersion)
+ if err != nil {
+ return fmt.Errorf("error updating UTMStackUpdater service: %v", err)
}
+ utmLogger.Info("UTMStackUpdater service updated correctly")
}
return nil
}
-func (u *UTMServices) UpdateService(path string, env string, servCode string) error {
+func (u *UTMServices) UpdateService(path string, env string, servCode string, newVers string) error {
attr := u.ServAttr[servCode]
err := utils.CreatePathIfNotExist(filepath.Join(path, "locks"))
if err != nil {
@@ -123,22 +115,12 @@ func (u *UTMServices) UpdateService(path string, env string, servCode string) er
if servCode == "updater" {
utils.Execute(filepath.Join(path, attr.ServBin), path)
} else {
- // Stop service
err = utils.StopService(attr.ServName)
if err != nil {
return fmt.Errorf("error stoping %s service: %v", attr.ServName, err)
}
- // Download new version
- vers := ""
- switch servCode {
- case "agent":
- vers = u.LatestVersions.AgentVersion
- case "redline":
- vers = u.LatestVersions.RedlineVersion
- }
-
- url := constants.Bucket + env + "/" + servCode + "_service/v" + vers + "/" + attr.ServBin + "?time=" + utils.GetCurrentTime()
+ url := configuration.Bucket + env + "/" + servCode + "_service/v" + newVers + "/" + attr.ServBin + "?time=" + utils.GetCurrentTime()
err = utils.DownloadFile(url, filepath.Join(path, attr.ServBin))
if err != nil {
return fmt.Errorf("error downloading new %s: %v", attr.ServBin, err)
@@ -150,7 +132,6 @@ func (u *UTMServices) UpdateService(path string, env string, servCode string) er
}
}
- // Restart service
err = utils.RestartService(attr.ServName)
if err != nil {
return fmt.Errorf("error restarting %s service: %v", attr.ServName, err)
@@ -173,9 +154,10 @@ var (
func GetUTMServicesInstance() UTMServices {
utmServOnce.Do(func() {
utmServ = UTMServices{
+ MasterVersion: "",
CurrentVersions: Version{},
LatestVersions: Version{},
- ServAttr: constants.GetServAttr(),
+ ServAttr: configuration.GetServAttr(),
}
})
return utmServ
diff --git a/agent/updater/updates/update.go b/agent/updater/updates/update.go
index 988849294..8819f56b7 100644
--- a/agent/updater/updates/update.go
+++ b/agent/updater/updates/update.go
@@ -5,38 +5,42 @@ import (
"github.com/quantfall/holmes"
"github.com/utmstack/UTMStack/agent/updater/configuration"
- "github.com/utmstack/UTMStack/agent/updater/constants"
)
-func UpdateServices(cnf configuration.Config, h *holmes.Logger) {
+func UpdateServices(cnf configuration.Config, utmLogger *holmes.Logger) {
utmServices := GetUTMServicesInstance()
+ env, err := configuration.ReadEnv()
+ if err != nil {
+ utmLogger.FatalError("error reading environment configuration: %v", err)
+ }
+
+ utmLogger.Info("enviroment: %v", env)
+
for {
- time.Sleep(constants.CheckUpdatesEvery)
+ time.Sleep(configuration.CHECK_EVERY)
- masterVersion, err := getMasterVersion(cnf.Server, cnf.SkipCertValidation)
+ err = utmServices.UpdateCurrentMasterVersion(cnf)
if err != nil {
- h.Error("error getting master version: %v", err)
+ utmLogger.Error("error updating current master version: %v", err)
continue
}
- // save current versions
err = utmServices.UpdateCurrentVersions()
if err != nil {
- h.Error("error updating current versions: %v", err)
+ utmLogger.Error("error updating current versions: %v", err)
continue
}
- // download new versions and save
- err = utmServices.UpdateLatestVersions()
+ err = utmServices.UpdateLatestVersions(env)
if err != nil {
- h.Error("error updating latest versions: %v", err)
+ utmLogger.Error("error updating latest versions: %v", err)
continue
}
- err = utmServices.CheckUpdates(masterVersion, h)
+ err = utmServices.CheckUpdates(env, utmLogger)
if err != nil {
- h.Error("error updating services: %v", err)
+ utmLogger.Error("error updating services: %v", err)
continue
}
diff --git a/agent/updater/updates/version.go b/agent/updater/updates/version.go
index 98ec3d138..5f1f6c078 100644
--- a/agent/updater/updates/version.go
+++ b/agent/updater/updates/version.go
@@ -7,20 +7,31 @@ import (
"strconv"
"strings"
- "github.com/utmstack/UTMStack/agent/updater/constants"
+ "github.com/utmstack/UTMStack/agent/updater/configuration"
"github.com/utmstack/UTMStack/agent/updater/utils"
)
+// getLatestVersion returns the latest version of the service
+func getLatestVersion(versions DataVersions, masterVersions string) Version {
+ for _, vers := range versions.Versions {
+ if vers.MasterVersion == masterVersions {
+ return vers
+ }
+ }
+ return Version{}
+}
+
+// getMasterVersion returns the master version of the service
func getMasterVersion(ip string, skip bool) (string, error) {
config := &tls.Config{InsecureSkipVerify: skip}
if !skip {
var err error
- config, err = utils.LoadTLSCredentials(constants.GetCertPath())
+ config, err = utils.LoadTLSCredentials(configuration.GetCertPath())
if err != nil {
return "", fmt.Errorf("error loading tls credentials: %v", err)
}
}
- resp, status, err := utils.DoReq[InfoResponse]("https://"+ip+constants.MASTERVERSIONENDPOINT, nil, http.MethodGet, map[string]string{}, config)
+ resp, status, err := utils.DoReq[InfoResponse]("https://"+ip+configuration.MASTERVERSIONENDPOINT, nil, http.MethodGet, map[string]string{}, config)
if err != nil {
return "", err
} else if status != http.StatusOK {
@@ -29,6 +40,7 @@ func getMasterVersion(ip string, skip bool) (string, error) {
return resp.Build.Version, nil
}
+// isVersionGreater returns true if newVersion is greater than oldVersion
func isVersionGreater(oldVersion, newVersion string) bool {
oldParts := strings.Split(oldVersion, ".")
newParts := strings.Split(newVersion, ".")
@@ -47,6 +59,7 @@ func isVersionGreater(oldVersion, newVersion string) bool {
return false
}
+/*
func isNewOrEqualVersion(oldVersion, newVersion string) bool {
oldParts := strings.Split(oldVersion, ".")
newParts := strings.Split(newVersion, ".")
@@ -69,3 +82,4 @@ func isNewOrEqualVersion(oldVersion, newVersion string) bool {
return len(newParts) >= len(oldParts)
}
+*/
diff --git a/agent/updater/utils/cmd.go b/agent/updater/utils/cmd.go
index b1881855f..686c93f95 100644
--- a/agent/updater/utils/cmd.go
+++ b/agent/updater/utils/cmd.go
@@ -6,21 +6,7 @@ import (
"unicode/utf8"
)
-func CleanString(s string) string {
- v := make([]rune, 0, len(s))
- for i, r := range s {
- if r == utf8.RuneError {
- _, size := utf8.DecodeRuneInString(s[i:])
- if size == 1 {
- v = append(v, '?')
- continue
- }
- }
- v = append(v, r)
- }
- return string(v)
-}
-
+// ExecuteWithResult executes a command and returns the output
func ExecuteWithResult(c string, dir string, arg ...string) (string, bool) {
cmd := exec.Command(c, arg...)
@@ -34,14 +20,31 @@ func ExecuteWithResult(c string, dir string, arg ...string) (string, bool) {
return string(out[:]) + err.Error(), true
}
- validUtf8Out := CleanString(string(out[:]))
+ validUtf8Out := cleanString(string(out[:]))
return validUtf8Out, false
}
+// Execute executes a command without returning the output
func Execute(c string, dir string, arg ...string) error {
cmd := exec.Command(c, arg...)
cmd.Dir = dir
return cmd.Run()
}
+
+// cleanString cleans a string from invalid utf8 characters
+func cleanString(s string) string {
+ v := make([]rune, 0, len(s))
+ for i, r := range s {
+ if r == utf8.RuneError {
+ _, size := utf8.DecodeRuneInString(s[i:])
+ if size == 1 {
+ v = append(v, '?')
+ continue
+ }
+ }
+ v = append(v, r)
+ }
+ return string(v)
+}
diff --git a/agent/updater/utils/delay.go b/agent/updater/utils/delay.go
index e3000ea71..61193d39b 100644
--- a/agent/updater/utils/delay.go
+++ b/agent/updater/utils/delay.go
@@ -2,6 +2,7 @@ package utils
import "time"
+// IncrementReconnectDelay increments the delay for reconnecting to the server
func IncrementReconnectDelay(delay time.Duration, maxReconnectDelay time.Duration) time.Duration {
delay *= 2
if delay > maxReconnectDelay {
diff --git a/agent/updater/utils/files.go b/agent/updater/utils/files.go
index 101231197..1006b2c0f 100644
--- a/agent/updater/utils/files.go
+++ b/agent/updater/utils/files.go
@@ -20,13 +20,6 @@ func GetMyPath() (string, error) {
return exPath, nil
}
-func CheckIfPathExist(path string) bool {
- if _, err := os.Stat(path); os.IsNotExist(err) {
- return false
- }
- return true
-}
-
// ReadYAML reads the YAML data from the specified file URL and deserializes it into the provided result interface{}.
// Returns an error if any error occurs during the process.
func ReadYAML(path string, result interface{}) error {
@@ -56,19 +49,7 @@ func ReadJson(fileName string, data interface{}) error {
return nil
}
-func writeToFile(fileName string, body string) error {
- file, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
-
- if err != nil {
- return err
- }
-
- defer file.Close()
-
- _, err = file.WriteString(body)
- return err
-}
-
+// WriteJSON writes the provided data interface{} to the specified file URL in JSON format.
func WriteJSON(path string, data interface{}) error {
jsonData, err := json.MarshalIndent(data, "", " ")
if err != nil {
@@ -94,3 +75,25 @@ func CreatePathIfNotExist(path string) error {
}
return nil
}
+
+// CheckIfPathExist checks if a specific path exists
+func CheckIfPathExist(path string) bool {
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ return false
+ }
+ return true
+}
+
+// writeToFile writes the provided body string to the specified file URL.
+func writeToFile(fileName string, body string) error {
+ file, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
+
+ if err != nil {
+ return err
+ }
+
+ defer file.Close()
+
+ _, err = file.WriteString(body)
+ return err
+}
diff --git a/agent/updater/utils/lock.go b/agent/updater/utils/lock.go
index 1f7e8ce54..261ee0415 100644
--- a/agent/updater/utils/lock.go
+++ b/agent/updater/utils/lock.go
@@ -5,6 +5,7 @@ import (
"os"
)
+// SetLock creates a lock file
func SetLock(lockdir string) error {
if !CheckIfPathExist(lockdir) {
file, err := os.OpenFile(lockdir, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm)
@@ -16,6 +17,7 @@ func SetLock(lockdir string) error {
return nil
}
+// RemoveLock removes a lock file
func RemoveLock(lockdir string) error {
if CheckIfPathExist(lockdir) {
err := os.Remove(lockdir)
diff --git a/agent/updater/utils/req.go b/agent/updater/utils/req.go
index 7b3a88ca6..5e8a639af 100644
--- a/agent/updater/utils/req.go
+++ b/agent/updater/utils/req.go
@@ -8,6 +8,7 @@ import (
"net/http"
)
+// DoReq makes a request to the specified URL with the specified data, method and headers.
func DoReq[response any](url string, data []byte, method string, headers map[string]string, config *tls.Config) (response, int, error) {
req, err := http.NewRequest(method, url, bytes.NewBuffer(data))
if err != nil {
diff --git a/agent/updater/utils/services.go b/agent/updater/utils/services.go
index d6404f52b..96d9b18f4 100644
--- a/agent/updater/utils/services.go
+++ b/agent/updater/utils/services.go
@@ -81,6 +81,7 @@ func RestartService(serv string) error {
return nil
}
+// StopService stops a service
func StopService(name string) error {
path, err := GetMyPath()
if err != nil {
@@ -101,6 +102,7 @@ func StopService(name string) error {
return nil
}
+// UninstallService uninstalls a service
func UninstallService(name string) error {
path, err := GetMyPath()
if err != nil {
diff --git a/agent/updater/utils/timestamp.go b/agent/updater/utils/timestamp.go
index e33aa0f2a..7fbb24f2e 100644
--- a/agent/updater/utils/timestamp.go
+++ b/agent/updater/utils/timestamp.go
@@ -2,6 +2,7 @@ package utils
import "time"
+// GetCurrentTime returns the current time in the format YYYYMMDDHHMMSS
func GetCurrentTime() string {
t := time.Now()
return t.Format("20060102150405")
diff --git a/agent/updater/utils/tls.go b/agent/updater/utils/tls.go
index 77fc7470e..d0a1bb693 100644
--- a/agent/updater/utils/tls.go
+++ b/agent/updater/utils/tls.go
@@ -7,6 +7,7 @@ import (
"os"
)
+// LoadTLSCredentials loads the TLS credentials from the specified certificate file.
func LoadTLSCredentials(crtName string) (*tls.Config, error) {
// Load the server's certificate
serverCert, err := os.ReadFile(crtName)
diff --git a/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts b/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts
index 91c73584b..a7fea8cfc 100644
--- a/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts
+++ b/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts
@@ -33,19 +33,19 @@ export class GuideLinuxAgentComponent implements OnInit {
getCommandUbuntu(): string {
const ip = window.location.host.includes(':') ? window.location.host.split(':')[0] : window.location.host;
return `sudo apt update -y && sudo apt install wget -y && mkdir -p /opt/utmstack-linux-agent && wget -P /opt/utmstack-linux-agent ` +
- `https://cdn.utmstack.com/agent_updates/release/installer/v10.1.2/utmstack_agent_installer && chmod -R 777 ` +
+ `https://cdn.utmstack.com/agent_updates/release/installer/v10.2.0/utmstack_agent_installer && chmod -R 777 ` +
`/opt/utmstack-linux-agent/utmstack_agent_installer && sudo /opt/utmstack-linux-agent/utmstack_agent_installer install ` + ip + ` ` + this.token + ` yes`;
}
getCommandCentos7RedHat(): string {
const ip = window.location.host.includes(':') ? window.location.host.split(':')[0] : window.location.host;
return `sudo yum install wget -y && mkdir /opt/utmstack-linux-agent && wget -P /opt/utmstack-linux-agent ` +
- `https://cdn.utmstack.com/agent_updates/release/installer/v10.1.2/utmstack_agent_installer && chmod -R 777 ` +
+ `https://cdn.utmstack.com/agent_updates/release/installer/v10.2.0/utmstack_agent_installer && chmod -R 777 ` +
`/opt/utmstack-linux-agent/utmstack_agent_installer && sudo /opt/utmstack-linux-agent/utmstack_agent_installer install ` + ip + ` ` + this.token + ` yes`;
}
getCommandCentos8Almalinux(): string {
const ip = window.location.host.includes(':') ? window.location.host.split(':')[0] : window.location.host;
return `sudo dnf install wget -y && mkdir /opt/utmstack-linux-agent && wget -P /opt/utmstack-linux-agent ` +
- `https://cdn.utmstack.com/agent_updates/release/installer/v10.1.2/utmstack_agent_installer && chmod -R 777 ` +
+ `https://cdn.utmstack.com/agent_updates/release/installer/v10.2.0/utmstack_agent_installer && chmod -R 777 ` +
`/opt/utmstack-linux-agent/utmstack_agent_installer && sudo /opt/utmstack-linux-agent/utmstack_agent_installer install ` + ip + ` ` + this.token + ` yes`;
}
getUninstallCommand(): string {