github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/install/install_unix.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 //go:build linux || freebsd || netbsd || openbsd 5 // +build linux freebsd netbsd openbsd 6 7 package install 8 9 import ( 10 "fmt" 11 "os" 12 "path" 13 "time" 14 15 "github.com/keybase/client/go/libkb" 16 keybase1 "github.com/keybase/client/go/protocol/keybase1" 17 ) 18 19 // Similar to the Brew install on OSX, the Unix install happens in two steps. 20 // First, the system package manager installs all the binaries as root. Second, 21 // an autostart file needs to be written to the user's home dir, so that 22 // Keybase launches when that user logs in. The second step is done the first 23 // time the user starts Keybase. 24 // 25 // ".desktop" files and the ~/.config/autostart directory are part of the 26 // freedesktop.org set of standards, which the popular desktop environments 27 // like Gnome and KDE all support. See 28 // http://standards.freedesktop.org/desktop-entry-spec/latest/. 29 30 const backtick = "`" 31 32 const autostartFileText = `# This file is generated by Keybase, along with a sentinel 33 # file at ~/.config/keybase/autostart_created. As long as the sentinel exists, 34 # this file won't be changed automatically, so you can edit it or delete it 35 # as you like. 36 37 # To toggle autostart on, run 38 # ` + backtick + `keybase ctl autostart --enable` + backtick + ` 39 # or to toggle off, 40 # ` + backtick + `keybase ctl autostart --disable` + backtick + `. 41 # Note that this will overwrite any changes you have made. 42 43 [Desktop Entry] 44 Name=Keybase 45 Comment=Keybase Filesystem Service and GUI 46 Type=Application 47 Exec=env KEYBASE_AUTOSTART=1 run_keybase 48 ` 49 50 const disabledAutostartFileText = autostartFileText + ` 51 Hidden=true 52 X-GNOME-Autostart-enabled=false 53 ` 54 55 const sentinelFileText = `This file is created the first time Keybase starts, along with 56 ~/.config/autostart/keybase_autostart.desktop. As long as this 57 file exists, the autostart file won't be automatically recreated. 58 ` 59 60 func autostartDir(context Context) string { 61 // strip off the "keybase" folder on the end of the config dir 62 return path.Join(context.GetConfigDir(), "..", "autostart") 63 } 64 65 func autostartFilePath(context Context) string { 66 return path.Join(autostartDir(context), "keybase_autostart.desktop") 67 } 68 69 func sentinelFilePath(context Context) string { 70 return path.Join(context.GetConfigDir(), "autostart_created") 71 } 72 73 func ToggleAutostart(context Context, on bool, forAutoinstall bool) error { 74 if forAutoinstall { 75 _, err := os.Stat(sentinelFilePath(context)) 76 if err == nil { 77 // The sentinel exists. Don't recreate the autostart file. 78 return nil 79 } else if !os.IsNotExist(err) { 80 // The error is something unexpected. Return it. 81 return err 82 } 83 // The sentinel doesn't exist. Create the autostart file, and then create 84 // the sentinel. This might stomp on old user edits one time, but we need 85 // to do that to add in the KEYBASE_AUTOSTART variable. 86 } 87 88 err := os.MkdirAll(autostartDir(context), 0755) 89 if err != nil { 90 return err 91 } 92 93 var text string 94 if on { 95 text = autostartFileText 96 } else { 97 text = disabledAutostartFileText 98 } 99 100 if forAutoinstall { 101 fmt.Println(`Installing autostart file. Manage autostart settings with ` + backtick + `keybase ctl autostart` + backtick + `.`) 102 } 103 104 err = os.WriteFile(autostartFilePath(context), []byte(text), 0644) 105 if err != nil { 106 return err 107 } 108 109 if forAutoinstall { 110 err = os.WriteFile(sentinelFilePath(context), []byte(sentinelFileText), 0644) 111 if err != nil { 112 return err 113 } 114 } 115 116 return nil 117 } 118 119 func GetAutostart(context Context) keybase1.OnLoginStartupStatus { 120 bs, _ := os.ReadFile(autostartFilePath(context)) 121 switch string(bs) { 122 case autostartFileText: 123 return keybase1.OnLoginStartupStatus_ENABLED 124 case disabledAutostartFileText: 125 return keybase1.OnLoginStartupStatus_DISABLED 126 } 127 return keybase1.OnLoginStartupStatus_UNKNOWN 128 } 129 130 // AutoInstall installs auto start on unix 131 func AutoInstall(context Context, _ string, _ bool, timeout time.Duration, log Log) (newProc bool, err error) { 132 err = os.MkdirAll(context.GetConfigDir(), 0755) 133 if err != nil { 134 return false, err 135 } 136 137 err = ToggleAutostart(context, true, true) 138 if err != nil { 139 // Ignore if we couldn't write to autostart 140 log.Errorf("Autoinstall failed: %s.", err) 141 } 142 143 return false, nil 144 } 145 146 // CheckIfValidLocation is not used on unix 147 func CheckIfValidLocation() error { 148 return nil 149 } 150 151 // KBFSBinPath returns the path to the KBFS executable 152 func KBFSBinPath(runMode libkb.RunMode, binPath string) (string, error) { 153 return kbfsBinPathDefault(runMode, binPath) 154 } 155 156 // kbfsBinName returns the name for the KBFS executable 157 func kbfsBinName() string { 158 return "kbfsfuse" 159 } 160 161 func updaterBinName() (string, error) { 162 return "", fmt.Errorf("Updater isn't supported on unix") 163 } 164 165 // RunApp starts the app 166 func RunApp(context Context, log Log) error { 167 // TODO: Start app, see run_keybase: /opt/keybase/Keybase 168 return nil 169 } 170 171 func InstallLogPath() (string, error) { 172 return "", nil 173 } 174 175 // WatchdogLogPath doesn't exist on linux as an independent log file 176 func WatchdogLogPath(string) (string, error) { 177 return "", nil 178 } 179 180 func SystemLogPath() string { 181 return "" 182 }