@@ -101,6 +101,12 @@ func handleInstall(args []string) {
101101 binDst := installBinPath ()
102102
103103 if isInstalled () {
104+ // If the destination is a symlink (e.g. managed by mise), skip
105+ // the binary copy and register the service using the symlink path.
106+ if isSymlink (binDst ) {
107+ handleSymlinkInstall (binDst , force )
108+ return
109+ }
104110 handleReinstall (binSrc , binDst , force )
105111 return
106112 }
@@ -176,6 +182,74 @@ func handleBrewInstall(brewBin string, force bool) {
176182 fmt .Println ("\n Dashboard: http://localhost:43080" )
177183}
178184
185+ // isSymlink reports whether path is a symbolic link.
186+ func isSymlink (path string ) bool {
187+ fi , err := os .Lstat (path )
188+ if err != nil {
189+ return false
190+ }
191+ return fi .Mode ()& os .ModeSymlink != 0
192+ }
193+
194+ func handleSymlinkInstall (binDst string , force bool ) {
195+ target , _ := os .Readlink (binDst )
196+ label := serviceLabel ()
197+ fmt .Printf ("Symlink detected at %s -> %s\n " , binDst , target )
198+ fmt .Printf ("\n The binary will not be replaced. This will:\n " )
199+
200+ step := 1
201+ fmt .Printf (" %d. Stop the running service\n " , step )
202+ step ++
203+ fmt .Printf (" %d. Remove the current service registration\n " , step )
204+ step ++
205+ fmt .Printf (" %d. Re-register the %s\n " , step , label )
206+ step ++
207+ if _ , err := os .Stat (filepath .Join (greyproxyDataHome (), "ca-cert.pem" )); os .IsNotExist (err ) {
208+ fmt .Printf (" %d. Generate and trust CA certificate (requires sudo)\n " , step )
209+ step ++
210+ } else if ! isCertInstalled () {
211+ fmt .Printf (" %d. Install CA certificate into OS trust store (requires sudo)\n " , step )
212+ step ++
213+ }
214+ fmt .Printf (" %d. Start the service\n " , step )
215+
216+ if ! force {
217+ fmt .Printf ("\n Proceed? [Y/n] " )
218+ if ! askConfirm () {
219+ fmt .Println ("You can start the server manually with: greyproxy serve" )
220+ fmt .Println ("Dashboard: http://localhost:43080" )
221+ return
222+ }
223+ }
224+
225+ s , err := newServiceControl ()
226+ if err != nil {
227+ fmt .Fprintf (os .Stderr , "error: %v\n " , err )
228+ os .Exit (1 )
229+ }
230+
231+ _ = service .Control (s , "stop" )
232+ fmt .Println ("Service stopped" )
233+
234+ _ = service .Control (s , "uninstall" )
235+ fmt .Println ("Removed old service registration" )
236+
237+ if err := service .Control (s , "install" ); err != nil {
238+ fmt .Fprintf (os .Stderr , "error: registering service: %v\n " , err )
239+ os .Exit (1 )
240+ }
241+ fmt .Printf ("Registered %s\n " , label )
242+
243+ ensureCert ()
244+
245+ if err := service .Control (s , "start" ); err != nil {
246+ fmt .Fprintf (os .Stderr , "error: starting service: %v\n " , err )
247+ os .Exit (1 )
248+ }
249+ fmt .Println ("Service started" )
250+ fmt .Println ("\n Dashboard: http://localhost:43080" )
251+ }
252+
179253func handleReinstall (binSrc , binDst string , force bool ) {
180254 label := serviceLabel ()
181255 fmt .Printf ("An existing installation was found at %s\n " , binDst )
@@ -338,13 +412,22 @@ func handleUninstall(args []string) {
338412 label := serviceLabel ()
339413
340414 certInstalled := isCertInstalled ()
415+ symlink := isSymlink (binDst )
341416
417+ step := 1
342418 fmt .Printf ("Ready to uninstall greyproxy. This will:\n " )
343- fmt .Printf (" 1. Stop the greyproxy service\n " )
344- fmt .Printf (" 2. Remove the %s\n " , label )
345- fmt .Printf (" 3. Remove %s\n " , binDst )
419+ fmt .Printf (" %d. Stop the greyproxy service\n " , step )
420+ step ++
421+ fmt .Printf (" %d. Remove the %s\n " , step , label )
422+ step ++
423+ if symlink {
424+ fmt .Printf (" (Skipping binary removal: %s is a symlink)\n " , binDst )
425+ } else {
426+ fmt .Printf (" %d. Remove %s\n " , step , binDst )
427+ step ++
428+ }
346429 if certInstalled {
347- fmt .Printf (" 4 . Remove CA certificate from system trust store\n " )
430+ fmt .Printf (" %d . Remove CA certificate from system trust store\n " , step )
348431 }
349432
350433 if ! force {
@@ -371,12 +454,16 @@ func handleUninstall(args []string) {
371454 }
372455 fmt .Printf ("Removed %s\n " , label )
373456
374- // 3. Remove binary
375- if err := os .Remove (binDst ); err != nil && ! os .IsNotExist (err ) {
376- fmt .Fprintf (os .Stderr , "error: removing binary: %v\n " , err )
377- os .Exit (1 )
457+ // 3. Remove binary (skip if symlink -- managed externally)
458+ if ! symlink {
459+ if err := os .Remove (binDst ); err != nil && ! os .IsNotExist (err ) {
460+ fmt .Fprintf (os .Stderr , "error: removing binary: %v\n " , err )
461+ os .Exit (1 )
462+ }
463+ fmt .Printf ("Removed %s\n " , binDst )
464+ } else {
465+ fmt .Printf ("Symlink %s left intact\n " , binDst )
378466 }
379- fmt .Printf ("Removed %s\n " , binDst )
380467
381468 // 4. Remove CA certificate from trust store
382469 if certInstalled {
0 commit comments