github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/install/libnativeinstaller/app.go (about) 1 // Copyright 2017 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libnativeinstaller 5 6 import ( 7 "errors" 8 "fmt" 9 "os/exec" 10 "path/filepath" 11 "strings" 12 13 "github.com/keybase/client/go/libkb" 14 "github.com/keybase/client/go/utils" 15 ) 16 17 // Log is the logging interface for this package 18 type Log interface { 19 Debug(s string, args ...interface{}) 20 Info(s string, args ...interface{}) 21 Warning(s string, args ...interface{}) 22 Errorf(s string, args ...interface{}) 23 } 24 25 // Context is the environment for install package. 26 type Context interface { 27 GetConfigDir() string 28 GetCacheDir() string 29 GetRuntimeDir() string 30 GetMountDir() (string, error) 31 GetLogDir() string 32 GetRunMode() libkb.RunMode 33 GetServiceInfoPath() string 34 GetKBFSInfoPath() string 35 } 36 37 // AppBundleForPath returns path to app bundle 38 func AppBundleForPath() (string, error) { 39 path, err := utils.BinPath() 40 if err != nil { 41 return "", err 42 } 43 if path == "" { 44 return "", errors.New("Could not get executable name") 45 } 46 paths := strings.SplitN(path, ".app", 2) 47 // If no match, return "" 48 if len(paths) <= 1 { 49 return "", fmt.Errorf("Unable to resolve bundle for valid path: %s", path) 50 } 51 52 appPath := paths[0] + ".app" 53 if exists, _ := libkb.FileExists(appPath); !exists { 54 return "", fmt.Errorf("App not found: %s", appPath) 55 } 56 57 return appPath, nil 58 } 59 60 func nativeInstallerAppBundlePath(appPath string) string { 61 return filepath.Join(appPath, "Contents/Resources/KeybaseInstaller.app") 62 } 63 64 func nativeInstallerAppBundleExecPath(appPath string) string { 65 return filepath.Join(nativeInstallerAppBundlePath(appPath), "Contents/MacOS/Keybase") 66 } 67 68 func execNativeInstallerWithArg(args []string, runMode libkb.RunMode, log Log) error { 69 appPath, err := AppBundleForPath() 70 if err != nil { 71 return err 72 } 73 includeArgs := []string{"--debug", fmt.Sprintf("--run-mode=%s", runMode), fmt.Sprintf("--app-path=%s", appPath), "--timeout=10"} 74 args = append(includeArgs, args...) 75 cmd := exec.Command(nativeInstallerAppBundleExecPath(appPath), args...) 76 output, err := cmd.CombinedOutput() 77 log.Debug("Output (%s): %s", args, string(output)) 78 return err 79 } 80 81 // InstallMountDir calls the installer with --install-mountdir. 82 func InstallMountDir(runMode libkb.RunMode, log Log) error { 83 log.Info("Creating mount directory") 84 return execNativeInstallerWithArg([]string{"--install-mountdir"}, runMode, log) 85 } 86 87 // UninstallMountDir calls the installer with --uninstall-mountdir. 88 func UninstallMountDir(runMode libkb.RunMode, log Log) error { 89 // We need the installer to remove the mount directory (since it's in the root, only the helper tool can do it) 90 return execNativeInstallerWithArg([]string{"--uninstall-mountdir"}, runMode, log) 91 } 92 93 // InstallRedirector calls the installer with --install-redirector. 94 func InstallRedirector(runMode libkb.RunMode, log Log) error { 95 log.Info("Starting redirector") 96 return execNativeInstallerWithArg([]string{"--install-redirector"}, runMode, log) 97 } 98 99 // UninstallRedirector calls the installer with --uninstall-redirector. 100 func UninstallRedirector(runMode libkb.RunMode, log Log) error { 101 return execNativeInstallerWithArg([]string{"--uninstall-redirector"}, runMode, log) 102 } 103 104 // InstallFuse calls the installer with --install-fuse. 105 func InstallFuse(runMode libkb.RunMode, log Log) error { 106 log.Info("Installing KBFuse") 107 return execNativeInstallerWithArg([]string{"--install-fuse"}, runMode, log) 108 } 109 110 // UninstallFuse calls the installer with --uninstall-fuse. 111 func UninstallFuse(runMode libkb.RunMode, log Log) error { 112 log.Info("Removing KBFuse") 113 return execNativeInstallerWithArg([]string{"--uninstall-fuse"}, runMode, log) 114 } 115 116 // InstallHelper calls the installer with --install-helper. 117 func InstallHelper(runMode libkb.RunMode, log Log) error { 118 log.Info("Installing Helper") 119 return execNativeInstallerWithArg([]string{"--install-helper"}, runMode, log) 120 } 121 122 // UninstallHelper calls the installer with --uninstall-helper. 123 func UninstallHelper(runMode libkb.RunMode, log Log) error { 124 log.Info("Removing privileged helper tool") 125 return execNativeInstallerWithArg([]string{"--uninstall-helper"}, runMode, log) 126 } 127 128 // InstallCommandLinePrivileged calls the installer with --install-cli. 129 func InstallCommandLinePrivileged(runMode libkb.RunMode, log Log) error { 130 log.Info("Installing command line (privileged)") 131 return execNativeInstallerWithArg([]string{"--install-cli"}, runMode, log) 132 } 133 134 // UninstallCommandLinePrivileged calls the installer with --uninstall-cli. 135 func UninstallCommandLinePrivileged(runMode libkb.RunMode, log Log) error { 136 log.Info("Removing command line (privileged)") 137 return execNativeInstallerWithArg([]string{"--uninstall-cli"}, runMode, log) 138 } 139 140 // InstallAppBundle calls the installer with --install-app-bundle. 141 func InstallAppBundle(context Context, sourcePath string, log Log) error { 142 log.Info("Install app bundle") 143 return execNativeInstallerWithArg([]string{"--install-app-bundle", fmt.Sprintf("--source-path=%s", sourcePath)}, context.GetRunMode(), log) 144 } 145 146 // UninstallApp calls the installer with --install-app. 147 func UninstallApp(runMode libkb.RunMode, log Log) error { 148 log.Info("Removing app") 149 return execNativeInstallerWithArg([]string{"--uninstall-app"}, runMode, log) 150 }