Example #1
0
// KBFSServiceStatus returns service status for KBFS
func KBFSServiceStatus(context Context, label string, wait time.Duration, log Log) (status keybase1.ServiceStatus) {
	if label == "" {
		status = keybase1.ServiceStatus{Status: keybase1.StatusFromCode(keybase1.StatusCode_SCServiceStatusError, "No service label")}
		return
	}
	kbfsService := launchd.NewService(label)

	status, err := serviceStatusFromLaunchd(kbfsService, context.GetKBFSInfoPath(), wait, log)
	if err != nil {
		return
	}
	bundleVersion, err := KBFSBundleVersion(context, "")
	if err != nil {
		status.Status = keybase1.StatusFromCode(keybase1.StatusCode_SCServiceStatusError, err.Error())
		return
	}
	status.BundleVersion = bundleVersion
	if status.InstallStatus == keybase1.InstallStatus_NOT_INSTALLED {
		return
	}

	installStatus, installAction, kbStatus := ResolveInstallStatus(status.Version, status.BundleVersion, status.LastExitStatus, log)
	status.InstallStatus = installStatus
	status.InstallAction = installAction
	status.Status = kbStatus
	return
}
Example #2
0
func keybaseServiceStatus(g *libkb.GlobalContext, label string, bundleVersion string) keybase1.ServiceStatus {
	if label == "" {
		label = defaultServiceLabel(g.Env.GetRunMode())
	}
	kbService := launchd.NewService(label)

	st, done := serviceStatusFromLaunchd(kbService, path.Join(g.Env.GetRuntimeDir(), "keybased.info"))
	st.BundleVersion = bundleVersion
	if done {
		return st
	}

	// Something must be wrong if this build doesn't match the package version.
	buildVersion := libkb.VersionString()
	if bundleVersion != "" && bundleVersion != buildVersion {
		st.InstallAction = keybase1.InstallAction_NONE
		st.InstallStatus = keybase1.InstallStatus_ERROR
		st.Status = errorStatus("INSTALL_ERROR", fmt.Sprintf("Version mismatch: %s != %s", bundleVersion, buildVersion))
		return st
	}

	installStatus, installAction, status := installStatus(st.Version, st.BundleVersion, st.LastExitStatus)
	st.InstallStatus = installStatus
	st.InstallAction = installAction
	st.Status = status
	return st
}
Example #3
0
func autoInstall(g *libkb.GlobalContext, binPath string, force bool) (newProc bool, componentResults []keybase1.ComponentResult, err error) {
	g.Log.Debug("+ AutoInstall for launchd")
	defer func() {
		g.Log.Debug("- AutoInstall -> %v, %v", newProc, err)
	}()
	label := DefaultServiceLabel(g.Env.GetRunMode())
	if label == "" {
		err = fmt.Errorf("No service label to install")
		return
	}
	resolvedBinPath, err := chooseBinPath(binPath)
	if err != nil {
		return
	}
	g.Log.Debug("Using binPath: %s", resolvedBinPath)

	service := launchd.NewService(label)
	plist := keybasePlist(g, resolvedBinPath, label)

	// Check if plist is valid. If so we're already installed and return.
	plistValid, err := service.CheckPlist(plist)
	if err != nil || plistValid {
		return
	}

	err = installService(g, binPath, true)
	componentResults = append(componentResults, componentResult(string(ComponentNameService), err))
	if err != nil {
		return
	}

	newProc = true
	return
}
Example #4
0
func KBFSServiceStatus(g *libkb.GlobalContext, label string) (status keybase1.ServiceStatus) {
	if label == "" {
		label = DefaultKBFSLabel(g.Env.GetRunMode())
	}
	kbfsService := launchd.NewService(label)

	status, err := serviceStatusFromLaunchd(g, kbfsService, path.Join(g.Env.GetRuntimeDir(), "kbfs.info"))
	if err != nil {
		return
	}
	bundleVersion, err := KBFSBundleVersion(g, "")
	if err != nil {
		status.Status = keybase1.StatusFromCode(keybase1.StatusCode_SCServiceStatusError, err.Error())
		return
	}
	status.BundleVersion = bundleVersion
	if status.InstallStatus == keybase1.InstallStatus_NOT_INSTALLED {
		return
	}

	installStatus, installAction, kbStatus := ResolveInstallStatus(status.Version, status.BundleVersion, status.LastExitStatus)
	status.InstallStatus = installStatus
	status.InstallAction = installAction
	status.Status = kbStatus
	return
}
Example #5
0
// UpdaterServiceStatus returns service status for the Updater service
func UpdaterServiceStatus(context Context, label string) keybase1.ServiceStatus {
	if label == "" {
		return keybase1.ServiceStatus{Status: keybase1.StatusFromCode(keybase1.StatusCode_SCServiceStatusError, "No service label")}
	}
	serviceStatus := keybase1.ServiceStatus{Label: label}
	updaterService := launchd.NewService(label)
	status, err := updaterService.WaitForStatus(defaultLaunchdWait, 500*time.Millisecond)
	if err != nil {
		serviceStatus.Status = keybase1.StatusFromCode(keybase1.StatusCode_SCServiceStatusError, err.Error())
		return serviceStatus
	}
	if status != nil {
		serviceStatus.Pid = status.Pid()
		serviceStatus.LastExitStatus = status.LastExitStatus()
	}
	if serviceStatus.Pid != "" {
		serviceStatus.InstallStatus = keybase1.InstallStatus_INSTALLED
		serviceStatus.InstallAction = keybase1.InstallAction_NONE
	} else {
		serviceStatus.InstallStatus = keybase1.InstallStatus_NOT_INSTALLED
		serviceStatus.InstallAction = keybase1.InstallAction_INSTALL
	}
	serviceStatus.Status = keybase1.StatusOK("")
	return serviceStatus
}
Example #6
0
func installKBFSService(g *libkb.GlobalContext, binPath string) (*keybase1.ServiceStatus, error) {
	runMode := g.Env.GetRunMode()
	label := defaultKBFSLabel(runMode)
	kbfsBinPath, err := kbfsBinPath(runMode, binPath)
	if err != nil {
		return nil, err
	}
	mountPath := kbfsMountPath(g.Env.GetHome(), runMode)

	// Create mount dir if it doesn't exist
	if _, err := os.Stat(mountPath); os.IsNotExist(err) {
		// TODO Make dir hidden so it only shows when mounted?
		err := os.MkdirAll(mountPath, libkb.PermDir)
		if err != nil {
			return nil, err
		}
	}

	plistArgs := []string{mountPath}
	envVars := defaultLaunchdEnvVars(g, label)

	plist := launchd.NewPlist(label, kbfsBinPath, plistArgs, envVars)
	err = launchd.Install(plist, os.Stdout)
	if err != nil {
		return nil, err
	}

	kbfsService := launchd.NewService(label)
	st, _ := serviceStatusFromLaunchd(kbfsService, "")

	return &st, nil
}
Example #7
0
func installKBFSService(g *libkb.GlobalContext, binPath string) (*keybase1.ServiceStatus, error) {
	runMode := g.Env.GetRunMode()
	label := defaultKBFSLabel(runMode)
	kbfsBinPath, err := kbfsBinPath(runMode, binPath)
	if err != nil {
		return nil, err
	}

	mountPath := kbfsMountPath(runMode)
	_, err = os.Stat(mountPath)
	if err != nil {
		return nil, err
	}

	// TODO: Remove when doing real release
	plistArgs := []string{"-debug", mountPath}
	envVars := DefaultLaunchdEnvVars(g, label)

	plist := launchd.NewPlist(label, kbfsBinPath, plistArgs, envVars)
	err = launchd.Install(plist, g.Log)
	if err != nil {
		return nil, err
	}

	kbfsService := launchd.NewService(label)
	st, err := serviceStatusFromLaunchd(kbfsService, "")
	return &st, err
}
Example #8
0
func restartLaunchdService(g *libkb.GlobalContext, label string, serviceInfoPath string) error {
	launchService := launchd.NewService(label)
	launchService.SetLogger(g.Log)
	err := launchService.Restart(defaultLaunchdWait)
	if err != nil {
		return err
	}
	return WaitForService(g, launchService, serviceInfoPath)
}
Example #9
0
func installUpdater(context Context, keybaseBinPath string, force bool, log Log) error {
	if context.GetRunMode() != libkb.ProductionRunMode {
		return fmt.Errorf("Updater not supported in this run mode")
	}
	keybaseBinPath, err := chooseBinPath(keybaseBinPath)
	if err != nil {
		return err
	}
	updaterBinPath := filepath.Join(filepath.Dir(keybaseBinPath), "updater")
	if err != nil {
		return err
	}
	log.Debug("Using updater path: %s", updaterBinPath)

	label := DefaultUpdaterLabel(context.GetRunMode())
	service := launchd.NewService(label)
	plist, err := updaterPlist(context, label, updaterBinPath, keybaseBinPath)
	if err != nil {
		return err
	}

	launchdStatus, err := service.LoadStatus()
	if err != nil {
		return err
	}

	needsInstall := false
	if launchdStatus == nil {
		log.Debug("No status, needs install")
		needsInstall = true
	}

	if !needsInstall {
		plistValid, err := service.CheckPlist(plist)
		if err != nil {
			return err
		}
		if !plistValid {
			log.Debug("Plist needs update: %s", service.PlistDestination())
			needsInstall = true
		}
	}

	if needsInstall || force {
		uninstallUpdater(context.GetRunMode(), log)
		log.Debug("Installing updater service")
		_, err := installUpdaterService(service, plist, defaultLaunchdWait, log)
		if err != nil {
			log.Errorf("Error installing updater service: %s", err)
			return err
		}
	}

	return nil
}
Example #10
0
func (c *CtlHandler) stopLaunchd() {
	status := install.KeybaseServiceStatus(c.G(), c.G().Env.GetLabel())
	if status.Pid == "" {
		c.G().Log.Debug("Service does not appear to be running via launchd (label = %q)", c.G().Env.GetLabel())
		return
	}

	c.G().Log.Debug("Removing %s from launchd", status.Label)
	svc := launchd.NewService(status.Label)
	if err := svc.Stop(false); err != nil {
		c.G().Log.Warning("error stopping launchd service:", err)
	}
}
Example #11
0
func installKeybaseService(g *libkb.GlobalContext, binPath string) (*keybase1.ServiceStatus, error) {
	label := defaultServiceLabel(g.Env.GetRunMode())
	plistArgs := []string{"service"}
	envVars := DefaultLaunchdEnvVars(g, label)

	plist := launchd.NewPlist(label, binPath, plistArgs, envVars)
	err := launchd.Install(plist, g.Log)
	if err != nil {
		return nil, err
	}

	kbService := launchd.NewService(label)
	st, err := serviceStatusFromLaunchd(kbService, serviceInfoPath(g))
	return &st, err
}
Example #12
0
func installKeybaseService(g *libkb.GlobalContext, binPath string) (*keybase1.ServiceStatus, error) {
	label := DefaultServiceLabel(g.Env.GetRunMode())
	// TODO: Remove -d when doing real release
	plistArgs := []string{"-d", "service"}
	envVars := DefaultLaunchdEnvVars(g, label)

	plist := launchd.NewPlist(label, binPath, plistArgs, envVars, libkb.ServiceLogFileName)
	err := launchd.Install(plist, g.Log)
	if err != nil {
		return nil, err
	}

	kbService := launchd.NewService(label)
	st, err := serviceStatusFromLaunchd(g, kbService, serviceInfoPath(g))
	return &st, err
}
Example #13
0
func kbfsServiceStatus(g *libkb.GlobalContext, label string, bundleVersion string) keybase1.ServiceStatus {
	if label == "" {
		label = defaultKBFSLabel(g.Env.GetRunMode())
	}
	kbfsService := launchd.NewService(label)

	st, done := serviceStatusFromLaunchd(kbfsService, path.Join(g.Env.GetRuntimeDir(), "kbfs.info"))
	st.BundleVersion = bundleVersion
	if done {
		return st
	}

	installStatus, installAction, status := installStatus(st.Version, st.BundleVersion, st.LastExitStatus)
	st.InstallStatus = installStatus
	st.InstallAction = installAction
	st.Status = status
	return st
}
Example #14
0
func KBFSServiceStatus(g *libkb.GlobalContext, bundleVersion string) keybase1.ServiceStatus {
	serviceLabel := libkb.DefaultServiceLabel(libkb.KBFSServiceID, libkb.DefaultRunMode)
	kbfsService := launchd.NewService(serviceLabel)
	kbfsLaunchdStatus, err := kbfsService.Status()
	if err != nil {
		return errorStatus(err)
	}

	if kbfsLaunchdStatus == nil {
		return keybase1.ServiceStatus{InstallStatus: keybase1.InstallStatus_NOT_INSTALLED}
	}

	var kbfsInfo *libkb.ServiceInfo
	if kbfsLaunchdStatus.Pid() != "" {
		runtimeDir := g.Env.GetRuntimeDir()
		kbfsInfo, err = libkb.WaitForServiceInfoFile(path.Join(runtimeDir, "kbfs.info"), kbfsLaunchdStatus.Pid(), 5, 500*time.Millisecond, "launchd status for kbfs")
		if err != nil {
			return errorStatus(err)
		}
	}

	// nil means not running or file wasn't found
	if kbfsInfo == nil {
		kbfsInfo = &libkb.ServiceInfo{}
	}

	version := kbfsInfo.Version

	st := keybase1.ServiceStatus{
		Version:        version,
		Label:          kbfsLaunchdStatus.Label(),
		Pid:            kbfsLaunchdStatus.Pid(),
		LastExitStatus: kbfsLaunchdStatus.LastExitStatus(),
		BundleVersion:  bundleVersion,
	}

	installStatus, installAction, se := installStatus(version, bundleVersion, st.LastExitStatus)
	st.InstallStatus = installStatus
	st.InstallAction = installAction
	st.Error = se
	return st
}
Example #15
0
func installService(context Context, binPath string, force bool, log Log) error {
	resolvedBinPath, err := chooseBinPath(binPath)
	if err != nil {
		return err
	}
	log.Debug("Using binPath: %s", resolvedBinPath)

	label := DefaultServiceLabel(context.GetRunMode())
	service := launchd.NewService(label)
	plist, err := keybasePlist(context, resolvedBinPath, label, log)
	if err != nil {
		return err
	}
	log.Debug("Checking service: %s", label)
	keybaseStatus := KeybaseServiceStatus(context, label, time.Second, log)
	log.Debug("Service: %s (Action: %s); %#v", keybaseStatus.InstallStatus.String(), keybaseStatus.InstallAction.String(), keybaseStatus)
	needsInstall := keybaseStatus.NeedsInstall()

	if !needsInstall {
		plistValid, err := service.CheckPlist(plist)
		if err != nil {
			return err
		}
		if !plistValid {
			log.Debug("Needs plist upgrade: %s", service.PlistDestination())
			needsInstall = true
		}
	}

	if needsInstall || force {
		uninstallKeybaseServices(context.GetRunMode(), log)
		log.Debug("Installing Keybase service")
		_, err := installKeybaseService(context, service, plist, defaultLaunchdWait, log)
		if err != nil {
			log.Errorf("Error installing Keybase service: %s", err)
			return err
		}
	}

	return nil
}
Example #16
0
func KeybaseServiceStatus(g *libkb.GlobalContext, label string) (status keybase1.ServiceStatus) {
	if label == "" {
		label = DefaultServiceLabel(g.Env.GetRunMode())
	}
	kbService := launchd.NewService(label)

	status, err := serviceStatusFromLaunchd(g, kbService, path.Join(g.Env.GetRuntimeDir(), "keybased.info"))
	status.BundleVersion = libkb.VersionString()
	if err != nil {
		return
	}
	if status.InstallStatus == keybase1.InstallStatus_NOT_INSTALLED {
		return
	}

	installStatus, installAction, kbStatus := ResolveInstallStatus(status.Version, status.BundleVersion, status.LastExitStatus)
	status.InstallStatus = installStatus
	status.InstallAction = installAction
	status.Status = kbStatus
	return
}
Example #17
0
// KBFS installs the KBFS service
func KBFS(context Context, binPath string, force bool, log Log) error {
	runMode := context.GetRunMode()
	label := DefaultKBFSLabel(runMode)
	kbfsService := launchd.NewService(label)
	kbfsBinPath, err := KBFSBinPath(runMode, binPath)
	if err != nil {
		return err
	}
	plist, err := kbfsPlist(context, kbfsBinPath, label)
	if err != nil {
		return err
	}

	log.Debug("Checking KBFS")
	kbfsStatus := KBFSServiceStatus(context, label, time.Second, log)
	log.Debug("KBFS: %s (Action: %s); %#v", kbfsStatus.InstallStatus.String(), kbfsStatus.InstallAction.String(), kbfsStatus)
	needsInstall := kbfsStatus.NeedsInstall()

	if !needsInstall {
		plistValid, err := kbfsService.CheckPlist(plist)
		if err != nil {
			return err
		}
		if !plistValid {
			log.Debug("Needs plist upgrade: %s", kbfsService.PlistDestination())
			needsInstall = true
		}
	}
	if needsInstall || force {
		uninstallKBFSServices(context.GetRunMode(), log)
		log.Debug("Installing KBFS")
		_, err := installKBFSService(context, kbfsService, plist, defaultLaunchdWait, log)
		if err != nil {
			log.Errorf("Error installing KBFS: %s", err)
			return err
		}
	}

	return nil
}
Example #18
0
func installKBFS(g *libkb.GlobalContext, binPath string, force bool) error {
	runMode := g.Env.GetRunMode()
	label := DefaultKBFSLabel(runMode)
	kbfsService := launchd.NewService(label)
	kbfsBinPath, err := kbfsBinPath(runMode, binPath)
	if err != nil {
		return err
	}
	plist, err := kbfsPlist(g, kbfsBinPath, label)
	if err != nil {
		return err
	}

	g.Log.Debug("Checking KBFS")
	kbfsStatus := KBFSServiceStatus(g, label)
	g.Log.Debug("KBFS: %s (Action: %s)", kbfsStatus.InstallStatus.String(), kbfsStatus.InstallAction.String())
	needsInstall := kbfsStatus.NeedsInstall()

	if !needsInstall {
		plistValid, err := kbfsService.CheckPlist(plist)
		if err != nil {
			return err
		}
		if !plistValid {
			g.Log.Debug("Needs plist upgrade: %s", kbfsService.PlistDestination())
			needsInstall = true
		}
	}
	if needsInstall || force {
		uninstallKBFSServices(g, g.Env.GetRunMode())
		g.Log.Debug("Installing KBFS")
		_, err := installKBFSService(g, kbfsService, plist)
		if err != nil {
			g.Log.Errorf("Error installing KBFS: %s", err)
			return err
		}
	}

	return nil
}
Example #19
0
func BrewAutoInstall(g *libkb.GlobalContext) (newProc bool, err error) {
	g.Log.Debug("+ BrewAutoInstall for launchd")
	defer func() {
		g.Log.Debug("- BrewAutoInstall -> %v, %v", newProc, err)
	}()
	label := defaultBrewServiceLabel(g.Env.GetRunMode())
	if label == "" {
		err = fmt.Errorf("No service label to install")
		return newProc, err
	}

	// Check if plist is installed. If so we're already installed and return.
	plistPath := launchd.PlistDestination(label)
	if _, err := os.Stat(plistPath); err == nil {
		g.Log.Debug("| already installed at %s", plistPath)
		return newProc, nil
	}

	// Get the full path to this executable using the brew opt bin directory.
	binName := filepath.Base(os.Args[0])
	binPath := filepath.Join("/usr/local/opt", binName, "bin", binName)
	g.Log.Debug("| assembled binPath = %s", binPath)
	plistArgs := []string{"service"}
	envVars := defaultEnvVars(g, label)

	plist := launchd.NewPlist(label, binPath, plistArgs, envVars)
	err = launchd.Install(plist, ioutil.Discard)
	if err != nil {
		return newProc, err
	}

	// Get service install status. This causes us to pause (with timeout) until
	// the service is up.
	kbService := launchd.NewService(label)
	ServiceStatusFromLaunchd(kbService, path.Join(g.Env.GetRuntimeDir(), "keybased.info"))

	newProc = true
	return newProc, nil
}
Example #20
0
func installService(g *libkb.GlobalContext, binPath string, force bool) error {
	resolvedBinPath, err := chooseBinPath(binPath)
	if err != nil {
		return err
	}
	g.Log.Debug("Using binPath: %s", resolvedBinPath)

	label := DefaultServiceLabel(g.Env.GetRunMode())
	service := launchd.NewService(label)
	plist := keybasePlist(g, resolvedBinPath, label)
	g.Log.Debug("Checking service")
	keybaseStatus := KeybaseServiceStatus(g, label)
	g.Log.Debug("Service: %s (Action: %s)", keybaseStatus.InstallStatus.String(), keybaseStatus.InstallAction.String())
	needsInstall := keybaseStatus.NeedsInstall()

	if !needsInstall {
		plistValid, err := service.CheckPlist(plist)
		if err != nil {
			return err
		}
		if !plistValid {
			g.Log.Debug("Needs plist upgrade: %s", service.PlistDestination())
			needsInstall = true
		}
	}

	if needsInstall || force {
		uninstallKeybaseServices(g, g.Env.GetRunMode())
		g.Log.Debug("Installing Keybase service")
		_, err := installKeybaseService(g, service, plist)
		if err != nil {
			g.Log.Errorf("Error installing Keybase service: %s", err)
			return err
		}
	}

	return nil
}
Example #21
0
func KeybaseServiceStatus(g *libkb.GlobalContext, bundleVersion string) keybase1.ServiceStatus {
	serviceLabel := libkb.DefaultServiceLabel(libkb.KeybaseServiceID, libkb.DefaultRunMode)
	kbService := launchd.NewService(serviceLabel)
	kbLaunchdStatus, err := kbService.Status()
	if err != nil {
		return errorStatus(err)
	}

	if kbLaunchdStatus == nil {
		return keybase1.ServiceStatus{InstallStatus: keybase1.InstallStatus_NOT_INSTALLED}
	}

	var config keybase1.Config
	if kbLaunchdStatus.Pid() != "" {

		runtimeDir := g.Env.GetRuntimeDir()
		_, err := libkb.WaitForServiceInfoFile(path.Join(runtimeDir, "keybased.info"), kbLaunchdStatus.Pid(), 5, 500*time.Millisecond, "launchd status for service")
		if err != nil {
			return errorStatus(err)
		}

		configClient, err := GetConfigClient(g)
		if err != nil {
			return errorStatus(err)
		}

		config, err = configClient.GetConfig(context.TODO(), 0)
		if err != nil {
			return errorStatus(err)
		}

		if config.Label != kbLaunchdStatus.Label() {
			return errorStatus(fmt.Errorf("Service label mismatch: %s != %s", config.Label, kbLaunchdStatus.Label()))
		}
	}

	version := config.Version
	buildVersion := libkb.VersionString()

	st := keybase1.ServiceStatus{
		Version:        config.Version,
		Label:          kbLaunchdStatus.Label(),
		Pid:            kbLaunchdStatus.Pid(),
		LastExitStatus: kbLaunchdStatus.LastExitStatus(),
		BundleVersion:  bundleVersion,
	}

	// Something must be wrong if this build doesn't match the package version.
	if bundleVersion != buildVersion {
		st.InstallStatus = keybase1.InstallStatus_ERROR
		st.InstallAction = keybase1.InstallAction_NONE
		st.Error = &keybase1.ServiceStatusError{Message: fmt.Sprintf("Version mismatch: %s != %s", bundleVersion, buildVersion)}
		return st
	}

	installStatus, installAction, se := installStatus(version, bundleVersion, st.LastExitStatus)
	st.InstallStatus = installStatus
	st.InstallAction = installAction
	st.Error = se
	return st
}