11package updater
22
33import (
4+ "fmt"
5+ "io"
6+ "os"
47 "time"
58
69 "github.com/kardianos/service"
@@ -14,6 +17,7 @@ func GetConfigServ() *service.Config {
1417 Name : "UTMStackComponentsUpdater" ,
1518 DisplayName : "UTMStack Components Updater" ,
1619 Description : "UTMStack Components Updater" ,
20+ Executable : config .InstallerBinPath ,
1721 Arguments : []string {"--run" },
1822 }
1923
@@ -32,6 +36,11 @@ func (p *program) Stop(s service.Service) error {
3236}
3337
3438func (p * program ) run () {
39+ // Migrate service to standard path if needed
40+ if migrated := migrateServiceIfNeeded (); migrated {
41+ return // Exit, new service will start from standard path
42+ }
43+
3544 go MonitorConnection (config .GetCMServer (), 30 * time .Second , 3 , & config .ConnectedToInternet )
3645 time .Sleep (5 * time .Second )
3746
@@ -73,6 +82,11 @@ func (p *program) run() {
7382}
7483
7584func InstallService () {
85+ // Copy current binary to standard location
86+ if err := copyInstallerToStandardPath (); err != nil {
87+ config .Logger ().Fatal ("error copying installer to standard path: %v" , err )
88+ }
89+
7690 svcConfig := GetConfigServ ()
7791 prg := new (program )
7892 newService , err := service .New (prg , svcConfig )
@@ -90,6 +104,90 @@ func InstallService() {
90104 }
91105}
92106
107+ func copyInstallerToStandardPath () error {
108+ currentExec , err := os .Executable ()
109+ if err != nil {
110+ return fmt .Errorf ("error getting current executable path: %v" , err )
111+ }
112+
113+ // If already at standard path, skip copy
114+ if currentExec == config .InstallerBinPath {
115+ return nil
116+ }
117+
118+ srcFile , err := os .Open (currentExec )
119+ if err != nil {
120+ return fmt .Errorf ("error opening source binary: %v" , err )
121+ }
122+ defer srcFile .Close ()
123+
124+ dstFile , err := os .Create (config .InstallerBinPath )
125+ if err != nil {
126+ return fmt .Errorf ("error creating destination binary: %v" , err )
127+ }
128+ defer dstFile .Close ()
129+
130+ if _ , err = io .Copy (dstFile , srcFile ); err != nil {
131+ return fmt .Errorf ("error copying binary: %v" , err )
132+ }
133+
134+ if err = os .Chmod (config .InstallerBinPath , 0755 ); err != nil {
135+ return fmt .Errorf ("error setting permissions on binary: %v" , err )
136+ }
137+
138+ return nil
139+ }
140+
141+ func migrateServiceIfNeeded () bool {
142+ currentExec , err := os .Executable ()
143+ if err != nil {
144+ config .Logger ().ErrorF ("error getting current executable path: %v" , err )
145+ return false
146+ }
147+
148+ // Already running from standard path, no migration needed
149+ if currentExec == config .InstallerBinPath {
150+ return false
151+ }
152+
153+ config .Logger ().Info ("Migrating service to standard path: %s" , config .InstallerBinPath )
154+
155+ // Copy current binary to standard location
156+ if err := copyInstallerToStandardPath (); err != nil {
157+ config .Logger ().ErrorF ("error copying installer during migration: %v" , err )
158+ return false
159+ }
160+
161+ // Uninstall old service
162+ serviceName := GetConfigServ ().Name
163+ if err := utils .UninstallService (serviceName ); err != nil {
164+ config .Logger ().ErrorF ("error uninstalling old service during migration: %v" , err )
165+ return false
166+ }
167+
168+ // Install new service pointing to standard path
169+ svcConfig := GetConfigServ ()
170+ prg := new (program )
171+ newService , err := service .New (prg , svcConfig )
172+ if err != nil {
173+ config .Logger ().ErrorF ("error creating new service during migration: %v" , err )
174+ return false
175+ }
176+
177+ if err := newService .Install (); err != nil {
178+ config .Logger ().ErrorF ("error installing new service during migration: %v" , err )
179+ return false
180+ }
181+
182+ if err := newService .Start (); err != nil {
183+ config .Logger ().ErrorF ("error starting new service during migration: %v" , err )
184+ return false
185+ }
186+
187+ config .Logger ().Info ("Service migrated successfully to %s" , config .InstallerBinPath )
188+ return true
189+ }
190+
93191func RunService () {
94192 svcConfig := GetConfigServ ()
95193 prg := new (program )
0 commit comments