Example #1
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 #2
0
func PrintOutOfDateWarnings(g *libkb.GlobalContext) {
	g.Log.Debug("+ PrintOutOfDateWarnings")
	defer g.Log.Debug("- PrintOutOfDateWarnings")

	cli, err := GetConfigClient(g)
	if err != nil {
		g.Log.Debug("Ignoring error in printOutOfDateWarnings: %s", err)
		return
	}

	info, err := cli.CheckAPIServerOutOfDateWarning(context.TODO())
	if err != nil {
		g.Log.Debug("Ignoring error in printOutOfDateWarnings: %s", err)
		return
	}
	g.Log.Debug("Got OutOfDateInfo: %#v", info)

	if info.CustomMessage != "" {
		printCustomMessage(g, info.CustomMessage)
	}
	if info.UpgradeTo != "" {
		g.Log.Warning("Upgrade recommended to client version %s or above (you have v%s)",
			info.UpgradeTo, libkb.VersionString())
	}
	if info.UpgradeURI != "" {
		libkb.PlatformSpecificUpgradeInstructions(g, info.UpgradeURI)
	}
}
Example #3
0
func (h ConfigHandler) GetConfig(_ context.Context, sessionID int) (keybase1.Config, error) {
	var c keybase1.Config

	c.ServerURI = h.G().Env.GetServerURI()
	c.RunMode = string(h.G().Env.GetRunMode())
	var err error
	c.SocketFile, err = h.G().Env.GetSocketFile()
	if err != nil {
		return c, err
	}

	gpg := h.G().GetGpgClient()
	canExec, err := gpg.CanExec()
	if err == nil {
		c.GpgExists = canExec
		c.GpgPath = gpg.Path()
	}

	c.Version = libkb.VersionString()

	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		c.Path = dir
	}

	c.ConfigPath = h.G().Env.GetConfigFilename()
	c.Label = h.G().Env.GetLabel()

	return c, nil
}
Example #4
0
// DefaultUpdaterOptions returns update config for this environment
func DefaultUpdaterOptions(g *libkb.GlobalContext) *keybase1.UpdateOptions {
	ret := &keybase1.UpdateOptions{
		Version:  libkb.VersionString(),
		Channel:  "main", // The default channel
		Platform: runtime.GOOS,
		Source:   string(sources.DefaultUpdateSourceName()),
	}
	switch {
	case runtime.GOOS == "darwin" && g.Env.GetRunMode() == libkb.ProductionRunMode:
		ret.DestinationPath = "/Applications/Keybase.app"
	}
	return ret
}
Example #5
0
func (v *CmdVersion) runLocal() {
	dui := v.G().UI.GetDumbOutputUI()
	prfx := ""
	if v.svc {
		prfx = "Client:  "
	}
	switch v.mode {
	case modeShort:
		dui.Printf("%s%s\n", prfx, libkb.Version)
	case modeNormal:
		dui.Printf("%s%s\n", prfx, libkb.VersionString())
	case modeVerbose:
		libkb.VersionMessage(func(s string) { dui.Printf("%s\n", s) })
	}
}
Example #6
0
func (h ConfigHandler) GetConfig(_ context.Context, sessionID int) (keybase1.Config, error) {
	var c keybase1.Config

	c.ServerURI = h.G().Env.GetServerURI()
	c.RunMode = string(h.G().Env.GetRunMode())
	var err error
	c.SocketFile, err = h.G().Env.GetSocketFile()
	if err != nil {
		return c, err
	}

	gpg := h.G().GetGpgClient()
	canExec, err := gpg.CanExec()
	if err == nil {
		c.GpgExists = canExec
		c.GpgPath = gpg.Path()
	}

	c.Version = libkb.VersionString()
	c.VersionShort = libkb.Version

	var v []string
	libkb.VersionMessage(func(s string) {
		v = append(v, s)
	})
	c.VersionFull = strings.Join(v, "\n")

	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		c.Path = dir
	}

	c.ConfigPath = h.G().Env.GetConfigFilename()
	c.Label = h.G().Env.GetLabel()
	if h.svc != nil {
		if h.svc.ForkType == keybase1.ForkType_AUTO {
			c.IsAutoForked = true
		}
		c.ForkType = h.svc.ForkType
	}

	return c, nil
}
Example #7
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 #8
0
// KeybaseServiceStatus returns service status for Keybase service
func KeybaseServiceStatus(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
	}
	kbService := launchd.NewService(label)

	status, err := serviceStatusFromLaunchd(kbService, context.GetServiceInfoPath(), wait, log)
	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, log)
	status.InstallStatus = installStatus
	status.InstallAction = installAction
	status.Status = kbStatus
	return
}
Example #9
0
func NewCmdVersion(cl *libcmdline.CommandLine) cli.Command {
	return cli.Command{
		Name:  "version",
		Usage: "Print out version and build information",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "f, format",
				Usage: "Alternate format for version output. Specify 's' for simple (1.2.3) or 'v' for verbose. Default (blank) includes build number (1.2.3-400).",
			},
		},
		Action: func(c *cli.Context) {
			switch c.String("format") {
			case "":
				GlobUI.Println(libkb.VersionString())
			case "s":
				GlobUI.Println(libkb.Version)
			case "v":
				libkb.VersionMessage(func(s string) { GlobUI.Println(s) })
			}
			os.Exit(0)
		},
	}
}
Example #10
0
func (p *CommandLine) PopulateApp(addHelp bool, extraFlags []cli.Flag) {
	app := p.app
	app.Name = "keybase"
	app.Version = libkb.VersionString()
	app.Usage = "Keybase command line client."

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "home, H",
			Usage: "Specify an (alternate) home directory.",
		},
		cli.StringFlag{
			Name:  "server, s",
			Usage: "Specify server API.",
		},
		cli.StringFlag{
			Name:  "config-file, c",
			Usage: "Specify an (alternate) master config file.",
		},
		cli.StringFlag{
			Name:  "session-file",
			Usage: "Specify an alternate session data file.",
		},
		cli.StringFlag{
			Name:  "db",
			Usage: "Specify an alternate local DB location.",
		},
		cli.StringFlag{
			Name:  "api-uri-path-prefix",
			Usage: "Specify an alternate API URI path prefix.",
		},
		cli.StringFlag{
			Name:  "pinentry",
			Usage: "Specify a path to find a pinentry program.",
		},
		cli.StringFlag{
			Name:  "secret-keyring",
			Usage: "Location of the Keybase secret-keyring (P3SKB-encoded).",
		},
		cli.StringFlag{
			Name:  "socket-file",
			Usage: "Location of the keybased socket-file.",
		},
		cli.StringFlag{
			Name:  "pid-file",
			Usage: "Location of the keybased pid-file (to ensure only one running daemon).",
		},
		cli.StringFlag{
			Name:  "proxy",
			Usage: "Specify an HTTP(s) proxy to ship all Web requests over.",
		},
		cli.BoolFlag{
			Name:  "debug, d",
			Usage: "Enable debugging mode.",
		},
		cli.StringFlag{
			Name:  "run-mode",
			Usage: "Run mode (devel, staging, prod).", // These are defined in libkb/constants.go
		},
		cli.StringFlag{
			Name:  "log-format",
			Usage: "Log format (default, plain, file, fancy).",
		},
		cli.StringFlag{
			Name:  "pgpdir, gpgdir",
			Usage: "Specify a PGP directory (default is ~/.gnupg).",
		},
		cli.BoolFlag{
			Name:  "api-dump-unsafe",
			Usage: "Dump API call internals (may leak secrets).",
		},
		cli.StringFlag{
			Name:  "merkle-key-fingerprints",
			Usage: "Set of admissable Merkle Tree fingerprints (colon-separated).",
		},
		cli.IntFlag{
			Name:  "user-cache-size",
			Usage: "Number of User entries to cache.",
		},
		cli.IntFlag{
			Name:  "proof-cache-size",
			Usage: "Number of proof entries to cache.",
		},
		cli.StringFlag{
			Name:  "gpg",
			Usage: "Path to GPG client (optional for exporting keys).",
		},
		cli.StringFlag{
			Name:  "gpg-options",
			Usage: "Options to use when calling GPG.",
		},
		cli.BoolFlag{
			Name:  "standalone",
			Usage: "Use the client without any daemon support.",
		},
		cli.StringFlag{
			Name:  "local-rpc-debug-unsafe",
			Usage: "Use to debug local RPC (may leak secrets).",
		},
		cli.StringFlag{
			Name:  "log-file",
			Usage: "Specify a log file for the keybase service.",
		},
		cli.BoolFlag{
			Name:  "split-log-output",
			Usage: "Output service log messages to current terminal.",
		},
		cli.StringFlag{
			Name:  "timers",
			Usage: "Specify 'a' for API; 'r' for RPCs; and 'x' for eXternal API calls",
		},
		cli.StringFlag{
			Name:  "scraper-timeout",
			Usage: "set the HTTP timeout for external proof scrapers",
		},
		cli.StringFlag{
			Name:  "api-timeout",
			Usage: "set the HTTP timeout for API calls to the keybase API server",
		},
	}
	if extraFlags != nil {
		app.Flags = append(app.Flags, extraFlags...)
	}

	app.Commands = []cli.Command{}
}
Example #11
0
func FixVersionClash(g *libkb.GlobalContext, cl libkb.CommandLine) (err error) {
	var cli keybase1.ConfigClient
	var ctlCli keybase1.CtlClient
	var serviceConfig keybase1.Config
	var socket net.Conn

	g.Log.Debug("+ FixVersionClash")
	defer func() {
		if socket != nil {
			socket.Close()
			socket = nil
		}
		g.Log.Debug("- FixVersionClash -> %v", err)
	}()

	// Make our own stack here, circumventing all of our libraries, so
	// as not to introduce any incompatibilities with earlier services
	// (like 1.0.8)
	socket, err = g.SocketInfo.DialSocket()
	if err != nil {
		g.Log.Debug("| Failed to DialSocket, but ignoring error: %s\n", err)
		return nil
	}
	xp := libkb.NewTransportFromSocket(g, socket)
	srv := rpc.NewServer(xp, libkb.WrapError)
	gcli := rpc.NewClient(xp, libkb.ErrorUnwrapper{})
	cli = keybase1.ConfigClient{Cli: gcli}
	srv.Register(NewLogUIProtocol())

	serviceConfig, err = cli.GetConfig(context.TODO(), 0)
	if err != nil {
		return err
	}
	g.Log.Debug("| Contacted service; got version: %s", serviceConfig.Version)

	// We'll check and restart the service if there is a new version.
	var semverClient, semverService semver.Version

	cliVersion := libkb.VersionString()
	if g.Env.GetRunMode() == libkb.DevelRunMode {
		tmp := os.Getenv("KEYBASE_SET_VERSION")
		if len(tmp) > 0 {
			cliVersion = tmp
		}
	}

	semverClient, err = semver.Make(cliVersion)
	if err != nil {
		return err
	}
	semverService, err = semver.Make(serviceConfig.Version)
	if err != nil {
		return err
	}

	g.Log.Debug("| version check %s v %s", semverClient, semverService)
	if semverClient.EQ(semverService) {
		g.Log.Debug("| versions check out")
		return nil
	} else if semverClient.LT(semverService) && semverClient.Major < semverService.Major {
		return fmt.Errorf("Unexpected version clash; client is at v%s, which is significantly *less than* server at v%s",
			semverClient, semverService)
	}

	g.Log.Warning("Restarting after upgrade; service is running v%s, while v%s is available",
		semverService, semverClient)

	origPid, err := getPid(g)
	if err != nil {
		g.Log.Warning("Failed to find pid for service: %v\n", err)
	}

	if serviceConfig.ForkType == keybase1.ForkType_LAUNCHD {
		return restartLaunchdService(g, serviceConfig.Label, g.Env.GetServiceInfoPath())
	}

	ctlCli = keybase1.CtlClient{Cli: gcli}
	err = ctlCli.Stop(context.TODO(), keybase1.StopArg{})
	if err != nil && origPid >= 0 {
		// A fallback approach. I haven't seen a need for it, but it can't really hurt.
		// If we fail to restart via Stop() then revert to kill techniques.

		g.Log.Warning("Error in Stopping %d via RPC: %v; trying fallback (kill via pidfile)", origPid, err)
		time.Sleep(time.Second)
		var newPid int
		newPid, err = getPid(g)
		if err != nil {
			g.Log.Warning("No pid; shutdown must have worked (%v)", err)
		} else if newPid != origPid {
			g.Log.Warning("New service found with pid=%d; assuming restart", newPid)
			return nil
		} else {
			if err = killPid(origPid); err != nil {
				g.Log.Warning("Kill via pidfile failed: %v\n", err)
				return err
			}
			g.Log.Warning("Successful kill() on pid=%d", origPid)
		}
	}

	socket.Close()
	socket = nil

	time.Sleep(10 * time.Millisecond)
	g.Log.Debug("Waiting for shutdown...")
	time.Sleep(1 * time.Second)

	if serviceConfig.ForkType == keybase1.ForkType_AUTO {
		g.Log.Info("Restarting service...")
		_, err = AutoForkServer(g, cl)
	}

	return err
}
Example #12
0
func (c *CmdStatus) load() (*fstatus, error) {
	var status fstatus

	status.Client.Version = libkb.VersionString()

	cli, err := GetConfigClient(c.G())
	if err != nil {
		return nil, err
	}

	curStatus, err := cli.GetCurrentStatus(context.TODO(), 0)
	if err != nil {
		return nil, err
	}

	status.LoggedInProvisioned = curStatus.LoggedIn
	if curStatus.User != nil {
		status.Username = curStatus.User.Username
		status.UserID = curStatus.User.Uid.String()
	}

	extStatus, err := cli.GetExtendedStatus(context.TODO(), 0)
	if err != nil {
		return nil, err
	}

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

	status.ConfigPath = config.ConfigPath
	status.Service.Version = config.Version

	status.Device = extStatus.Device

	if extStatus.Standalone {
		status.Service.Running = false
	} else {
		status.Service.Running = true
		status.Service.Log = path.Join(extStatus.LogDir, c.serviceLogFilename())
	}

	status.SessionStatus = c.sessionStatus(extStatus.Session)
	status.PassphraseStreamCached = extStatus.PassphraseStreamCached

	kbfsVersion, err := install.KBFSBundleVersion(c.G(), "")
	if err == nil {
		status.KBFS.Version = kbfsVersion
	}
	status.KBFS.Log = path.Join(extStatus.LogDir, c.kbfsLogFilename())

	status.Desktop.Running = extStatus.DesktopUIConnected
	status.Desktop.Log = path.Join(extStatus.LogDir, c.desktopLogFilename())

	status.DefaultUsername = extStatus.DefaultUsername
	status.ProvisionedUsernames = extStatus.ProvisionedUsernames
	status.Clients = extStatus.Clients
	status.PlatformInfo = extStatus.PlatformInfo

	// set anything os-specific:
	if err := c.osSpecific(&status); err != nil {
		return nil, err
	}

	return &status, nil
}
Example #13
0
func (c *CmdStatus) client() {
	dui := c.G().UI.GetDumbOutputUI()
	dui.Printf("Client:\n")
	dui.Printf("\tversion:\t%s\n", libkb.VersionString())
}
Example #14
0
// Create the syso file
func main() {

	outPtr := flag.String("o", "rsrc_windows.syso", "resource output pathname")
	printverPtr := flag.Bool("v", false, "print version to console (no .syso output)")
	printWinVerPtr := flag.Bool("w", false, "print windows format version to console (no .syso output)")
	iconPtr := flag.String("i", "../../../keybase/public/images/favicon.ico", "icon pathname")

	flag.Parse()

	var fv goversioninfo.FileVersion

	if int, err := fmt.Sscanf(libkb.Version, "%d.%d.%d", &fv.Major, &fv.Minor, &fv.Patch); int != 3 || err != nil {
		log.Printf("Error parsing version %v", err)
		os.Exit(3)
	}
	if int, err := fmt.Sscanf(libkb.Build(), "%d", &fv.Build); int != 1 || err != nil {
		log.Printf("Error parsing build %v", err)
		os.Exit(3)
	}

	if *printverPtr {
		fmt.Printf("%d.%d.%d-%d", fv.Major, fv.Minor, fv.Patch, fv.Build)
		return
	}

	if *printWinVerPtr {
		fmt.Printf("%d.%d.%d.%d", fv.Major, fv.Minor, fv.Patch, fv.Build)
		return
	}

	// Create a new container
	vi := &goversioninfo.VersionInfo{
		FixedFileInfo: goversioninfo.FixedFileInfo{
			FileVersion:    fv,
			ProductVersion: fv,
			FileFlagsMask:  "3f",
			FileFlags:      "00",
			FileOS:         "040004",
			FileType:       "01",
			FileSubType:    "00",
		},
		StringFileInfo: goversioninfo.StringFileInfo{
			CompanyName:      "Keybase, Inc.",
			FileDescription:  "Keybase utility",
			InternalName:     "Keybase",
			LegalCopyright:   "Copyright (c) 2015, Keybase",
			OriginalFilename: "keybase.exe",
			ProductName:      "Keybase",
			ProductVersion:   libkb.VersionString(),
		},
		VarFileInfo: goversioninfo.VarFileInfo{
			Translation: goversioninfo.Translation{
				LangID:    0x409, // english
				CharsetID: 0x4B0, // unicode
			},
		},
	}

	// Fill the structures with config data
	vi.Build()

	// Write the data to a buffer
	vi.Walk()

	// Optionally, embed an icon by path
	// If the icon has multiple sizes, all of the sizes will be embedded
	vi.IconPath = *iconPtr

	// Create the file
	if err := vi.WriteSyso(*outPtr); err != nil {
		log.Printf("Error writing %s: %v", *outPtr, err)
		os.Exit(3)
	}
}
Example #15
0
func (c *CmdStatus) load() (*fstatus, error) {
	var status fstatus

	status.Client.Version = libkb.VersionString()

	cli, err := GetConfigClient(c.G())
	if err != nil {
		return nil, err
	}

	curStatus, err := cli.GetCurrentStatus(context.TODO(), 0)
	if err != nil {
		return nil, err
	}

	status.LoggedInProvisioned = curStatus.LoggedIn
	status.SessionIsValid = curStatus.SessionIsValid
	if curStatus.User != nil {
		status.Username = curStatus.User.Username
		status.UserID = curStatus.User.Uid.String()
	}

	extStatus, err := cli.GetExtendedStatus(context.TODO(), 0)
	if err != nil {
		return nil, err
	}

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

	status.ConfigPath = config.ConfigPath
	status.Service.Version = config.Version

	status.Device = extStatus.Device

	if extStatus.Standalone {
		status.Service.Running = false
	} else {
		status.Service.Running = true
		status.Service.Log = filepath.Join(extStatus.LogDir, libkb.ServiceLogFileName)
	}

	status.SessionStatus = c.sessionStatus(extStatus.Session)
	status.PassphraseStreamCached = extStatus.PassphraseStreamCached
	status.TsecCached = extStatus.TsecCached
	status.DeviceSigKeyCached = extStatus.DeviceSigKeyCached
	status.DeviceEncKeyCached = extStatus.DeviceEncKeyCached
	status.PaperSigKeyCached = extStatus.PaperSigKeyCached
	status.PaperEncKeyCached = extStatus.PaperEncKeyCached
	status.StoredSecret = extStatus.StoredSecret
	status.SecretPromptSkip = extStatus.SecretPromptSkip

	if kbfs := getFirstClient(extStatus.Clients, keybase1.ClientType_KBFS); kbfs != nil {
		status.KBFS.Version = kbfs.Version
		status.KBFS.Running = true
	} else {
		kbfsVersion, err := install.KBFSBundleVersion(c.G(), "")
		if err == nil {
			status.KBFS.Version = kbfsVersion
		}
	}

	if desktop := getFirstClient(extStatus.Clients, keybase1.ClientType_GUI); desktop != nil {
		status.Desktop.Running = true
		status.Desktop.Version = desktop.Version
	}

	status.KBFS.Log = filepath.Join(extStatus.LogDir, libkb.KBFSLogFileName)
	status.Desktop.Log = filepath.Join(extStatus.LogDir, libkb.DesktopLogFileName)
	status.Updater.Log = filepath.Join(extStatus.LogDir, libkb.UpdaterLogFileName)

	status.Start.Log = filepath.Join(extStatus.LogDir, libkb.StartLogFileName)

	status.DefaultUsername = extStatus.DefaultUsername
	status.ProvisionedUsernames = extStatus.ProvisionedUsernames
	status.Clients = extStatus.Clients
	status.PlatformInfo = extStatus.PlatformInfo

	// set anything os-specific:
	if err := c.osSpecific(&status); err != nil {
		return nil, err
	}

	return &status, nil
}
Example #16
0
func FixVersionClash(g *libkb.GlobalContext, cl libkb.CommandLine) (err error) {
	var cli keybase1.ConfigClient
	var ctlCli keybase1.CtlClient
	var serviceConfig keybase1.Config

	g.Log.Debug("+ FixVersionClash")
	defer func() {
		g.Log.Debug("- FixVersionClash -> %v", err)
	}()
	cli, err = GetConfigClient(g)
	if err != nil {
		return err
	}
	serviceConfig, err = cli.GetConfig(context.TODO(), 0)
	if err != nil {
		return err
	}
	g.Log.Debug("| Contacted service; got version: %s", serviceConfig.Version)

	// We'll check and restart the service if there is a new version.
	var semverClient, semverService semver.Version

	cliVersion := libkb.VersionString()
	if g.Env.GetRunMode() == libkb.DevelRunMode {
		tmp := os.Getenv("KEYBASE_SET_VERSION")
		if len(tmp) > 0 {
			cliVersion = tmp
		}
	}

	semverClient, err = semver.Make(cliVersion)
	if err != nil {
		return err
	}
	semverService, err = semver.Make(serviceConfig.Version)
	if err != nil {
		return err
	}

	g.Log.Debug("| version check %s v %s", semverClient, semverService)
	if semverClient.EQ(semverService) {
		g.Log.Debug("| versions check out")
		return nil
	} else if semverClient.LT(semverService) {
		return fmt.Errorf("Unexpected version clash; client is at v%s, which *less than* server at v%s",
			semverClient, semverService)
	}

	g.Log.Warning("Restarting after upgrade; service is running v%s, while v%s is available",
		semverService, semverClient)
	ctlCli, err = GetCtlClient(g)
	if err != nil {
		return err
	}
	err = ctlCli.Stop(context.TODO(), 0)
	if err != nil {
		return err
	}
	time.Sleep(10 * time.Millisecond)
	g.Log.Info("Waiting for shutdown...")
	time.Sleep(1 * time.Second)

	if serviceConfig.IsAutoForked {
		g.Log.Info("Restarting service...")
		_, err = AutoForkServer(g, cl)
	}

	return err
}
Example #17
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
}
Example #18
0
func (p *CommandLine) PopulateApp(addHelp bool, extraFlags []cli.Flag) {
	app := p.app
	app.Name = "keybase"
	app.Version = libkb.VersionString()
	app.Usage = "Keybase command line client."

	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "api-dump-unsafe",
			Usage: "Dump API call internals (may leak secrets).",
		},
		cli.StringFlag{
			Name:  "api-timeout",
			Usage: "set the HTTP timeout for API calls to the keybase API server",
		},
		cli.StringFlag{
			Name:  "api-uri-path-prefix",
			Usage: "Specify an alternate API URI path prefix.",
		},
		cli.StringFlag{
			Name:  "app-start-mode",
			Usage: "Specify 'service' to auto-start UI app, or anything else to disable",
		},
		cli.StringFlag{
			Name:  "code-signing-kids",
			Usage: "Set of code signing key IDs (colon-separated).",
		},
		cli.StringFlag{
			Name:  "config-file, c",
			Usage: "Specify an (alternate) master config file.",
		},
		cli.StringFlag{
			Name:  "db",
			Usage: "Specify an alternate local DB location.",
		},
		cli.BoolFlag{
			Name:  "debug, d",
			Usage: "Enable debugging mode.",
		},
		cli.StringFlag{
			Name:  "gpg",
			Usage: "Path to GPG client (optional for exporting keys).",
		},
		cli.StringFlag{
			Name:  "gpg-options",
			Usage: "Options to use when calling GPG.",
		},
		cli.StringFlag{
			Name:  "home, H",
			Usage: "Specify an (alternate) home directory.",
		},
		cli.StringFlag{
			Name:  "local-rpc-debug-unsafe",
			Usage: "Use to debug local RPC (may leak secrets).",
		},
		cli.StringFlag{
			Name:  "log-file",
			Usage: "Specify a log file for the keybase service.",
		},
		cli.StringFlag{
			Name:  "log-format",
			Usage: "Log format (default, plain, file, fancy).",
		},
		cli.StringFlag{
			Name:  "merkle-kids",
			Usage: "Set of admissable Merkle Tree fingerprints (colon-separated).",
		},
		cli.BoolFlag{
			Name:  "no-debug",
			Usage: "Suppress debugging mode; takes precedence over --debug.",
		},
		cli.StringFlag{
			Name:  "pgpdir, gpgdir",
			Usage: "Specify a PGP directory (default is ~/.gnupg).",
		},
		cli.StringFlag{
			Name:  "pinentry",
			Usage: "Specify a path to find a pinentry program.",
		},
		cli.StringFlag{
			Name:  "pid-file",
			Usage: "Location of the keybased pid-file (to ensure only one running daemon).",
		},
		cli.IntFlag{
			Name:  "proof-cache-size",
			Usage: "Number of proof entries to cache.",
		},
		cli.StringFlag{
			Name:  "proxy",
			Usage: "Specify an HTTP(s) proxy to ship all Web requests over.",
		},
		cli.BoolFlag{
			Name:  "push-disabled",
			Usage: "Disable push server connection (which is on by default)",
		},
		cli.IntFlag{
			Name:  "push-save-interval",
			Usage: "Set the interval between saves of the push cache (in seconds)",
		},
		cli.StringFlag{
			Name:  "push-server-uri",
			Usage: "Specify a URI for contacting the Keybase push server",
		},
		cli.StringFlag{
			Name:  "run-mode",
			Usage: "Run mode (devel, staging, prod).", // These are defined in libkb/constants.go
		},
		cli.StringFlag{
			Name:  "scraper-timeout",
			Usage: "set the HTTP timeout for external proof scrapers",
		},
		cli.StringFlag{
			Name:  "secret-keyring",
			Usage: "Location of the Keybase secret-keyring (P3SKB-encoded).",
		},
		cli.StringFlag{
			Name:  "server, s",
			Usage: "Specify server API.",
		},
		cli.StringFlag{
			Name:  "session-file",
			Usage: "Specify an alternate session data file.",
		},
		cli.StringFlag{
			Name:  "socket-file",
			Usage: "Location of the keybased socket-file.",
		},
		cli.BoolFlag{
			Name:  "standalone",
			Usage: "Use the client without any daemon support.",
		},
		cli.StringFlag{
			Name:  "timers",
			Usage: "Specify 'a' for API; 'r' for RPCs; and 'x' for eXternal API calls",
		},
		cli.StringFlag{
			Name:  "tor-hidden-address",
			Usage: fmt.Sprintf("set TOR address of keybase server; defaults to %s", libkb.TorServerURI),
		},
		cli.StringFlag{
			Name:  "tor-mode",
			Usage: "set TOR mode to be 'leaky', 'none', or 'strict'. 'none' by default. See 'help tor' for more details.",
		},
		cli.StringFlag{
			Name:  "tor-proxy",
			Usage: fmt.Sprintf("set TOR proxy; when Tor mode is on; defaults to %s when TOR is enabled", libkb.TorProxy),
		},
		cli.StringFlag{
			Name:  "updater-config-file",
			Usage: "Specify a path to the updater config file",
		},
		cli.IntFlag{
			Name:  "user-cache-size",
			Usage: "Number of User entries to cache.",
		},
		cli.StringFlag{
			Name:  "vdebug",
			Usage: "Verbose debugging; takes a comma-joined list of levels and tags",
		},
	}
	if extraFlags != nil {
		app.Flags = append(app.Flags, extraFlags...)
	}

	app.Commands = []cli.Command{}
}