@@ -6,118 +6,41 @@ package autostart
6
6
7
7
import (
8
8
"context"
9
- _ "embed"
10
- "errors"
11
- "fmt"
12
- "os"
13
- "os/exec"
14
- "path"
15
- "path/filepath"
16
- "strconv"
17
- "strings"
9
+ "runtime"
10
+ "sync"
18
11
19
- "github.com/lima-vm/lima/v2/pkg/textutil "
12
+ "github.com/lima-vm/lima/v2/pkg/limatype "
20
13
)
21
14
22
-
23
- var systemdTemplate string
24
-
25
- //go:embed io.lima-vm.autostart.INSTANCE.plist
26
- var launchdTemplate string
27
-
28
- // CreateStartAtLoginEntry respect host OS arch and create unit file.
29
- func CreateStartAtLoginEntry (ctx context.Context , hostOS , instName , workDir string ) error {
30
- unitPath := GetFilePath (hostOS , instName )
31
- if _ , err := os .Stat (unitPath ); err != nil && ! errors .Is (err , os .ErrNotExist ) {
32
- return err
33
- }
34
- tmpl , err := renderTemplate (hostOS , instName , workDir , os .Executable )
35
- if err != nil {
36
- return err
37
- }
38
- if err := os .MkdirAll (filepath .Dir (unitPath ), os .ModePerm ); err != nil {
39
- return err
40
- }
41
- if err := os .WriteFile (unitPath , tmpl , 0o644 ); err != nil {
42
- return err
43
- }
44
- return enableDisableService (ctx , "enable" , hostOS , GetFilePath (hostOS , instName ))
15
+ // IsRegistered checks if the instance is registered to start at login.
16
+ func IsRegistered (ctx context.Context , inst * limatype.Instance ) (bool , error ) {
17
+ return manager ().IsRegistered (ctx , inst )
45
18
}
46
19
47
- // DeleteStartAtLoginEntry respect host OS arch and delete unit file.
48
- // Return true, nil if unit file has been deleted.
49
- func DeleteStartAtLoginEntry (ctx context.Context , hostOS , instName string ) (bool , error ) {
50
- unitPath := GetFilePath (hostOS , instName )
51
- if _ , err := os .Stat (unitPath ); err != nil {
52
- return false , err
53
- }
54
- if err := enableDisableService (ctx , "disable" , hostOS , GetFilePath (hostOS , instName )); err != nil {
55
- return false , err
56
- }
57
- if err := os .Remove (unitPath ); err != nil {
58
- return false , err
59
- }
60
- return true , nil
20
+ // RegisterToStartAtLogin creates a start-at-login entry for the instance.
21
+ func RegisterToStartAtLogin (ctx context.Context , inst * limatype.Instance ) error {
22
+ return manager ().RegisterToStartAtLogin (ctx , inst )
61
23
}
62
24
63
- // GetFilePath returns the path to autostart file with respect of host.
64
- func GetFilePath (hostOS , instName string ) string {
65
- var fileTmpl string
66
- if hostOS == "darwin" { // launchd plist
67
- fileTmpl = fmt .Sprintf ("%s/Library/LaunchAgents/io.lima-vm.autostart.%s.plist" , os .Getenv ("HOME" ), instName )
68
- }
69
- if hostOS == "linux" { // systemd service
70
- // Use instance name as argument to systemd service
71
- // Instance name available in unit file as %i
72
- xdgConfigHome := os .Getenv ("XDG_CONFIG_HOME" )
73
- if xdgConfigHome == "" {
74
- xdgConfigHome = filepath .Join (os .Getenv ("HOME" ), ".config" )
75
- }
76
- fileTmpl = fmt .Sprintf ("%s/systemd/user/lima-vm@%s.service" , xdgConfigHome , instName )
77
- }
78
- return fileTmpl
25
+ // UnregisterFromStartAtLogin deletes the start-at-login entry for the instance.
26
+ func UnregisterFromStartAtLogin (ctx context.Context , inst * limatype.Instance ) error {
27
+ return manager ().UnregisterFromStartAtLogin (ctx , inst )
79
28
}
80
29
81
- func enableDisableService (ctx context.Context , action , hostOS , serviceWithPath string ) error {
82
- // Get filename without extension
83
- filename := strings .TrimSuffix (path .Base (serviceWithPath ), filepath .Ext (path .Base (serviceWithPath )))
84
-
85
- var args []string
86
- if hostOS == "darwin" {
87
- // man launchctl
88
- args = append (args , []string {
89
- "launchctl" ,
90
- action ,
91
- fmt .Sprintf ("gui/%s/%s" , strconv .Itoa (os .Getuid ()), filename ),
92
- }... )
93
- } else {
94
- args = append (args , []string {
95
- "systemctl" ,
96
- "--user" ,
97
- action ,
98
- filename ,
99
- }... )
100
- }
101
- cmd := exec .CommandContext (ctx , args [0 ], args [1 :]... )
102
- cmd .Stdout = os .Stdout
103
- cmd .Stderr = os .Stderr
104
- return cmd .Run ()
30
+ type autoStartManager interface {
31
+ // Registration
32
+ IsRegistered (ctx context.Context , inst * limatype.Instance ) (bool , error )
33
+ RegisterToStartAtLogin (ctx context.Context , inst * limatype.Instance ) error
34
+ UnregisterFromStartAtLogin (ctx context.Context , inst * limatype.Instance ) error
105
35
}
106
36
107
- func renderTemplate ( hostOS , instName , workDir string , getExecutable func () ( string , error )) ([] byte , error ) {
108
- selfExeAbs , err := getExecutable ()
109
- if err != nil {
110
- return nil , err
111
- }
112
- tmpToExecute := systemdTemplate
113
- if hostOS == "darwin" {
114
- tmpToExecute = launchdTemplate
37
+ var manager = sync . OnceValue ( func () autoStartManager {
38
+ switch runtime . GOOS {
39
+ case "darwin" :
40
+ return Launchd
41
+ case "linux" :
42
+ return Systemd
43
+ default :
44
+ return & notSupportedManager {}
115
45
}
116
- return textutil .ExecuteTemplate (
117
- tmpToExecute ,
118
- map [string ]string {
119
- "Binary" : selfExeAbs ,
120
- "Instance" : instName ,
121
- "WorkDir" : workDir ,
122
- })
123
- }
46
+ })
0 commit comments