github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/updater/service/main.go (about)

     1  // Copyright 2016 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  
    13  	"github.com/kardianos/osext"
    14  	"github.com/keybase/client/go/updater"
    15  	"github.com/keybase/client/go/updater/keybase"
    16  	"github.com/keybase/client/go/updater/util"
    17  )
    18  
    19  type flags struct {
    20  	version       bool
    21  	logToFile     bool
    22  	appName       string
    23  	pathToKeybase string
    24  	command       string
    25  }
    26  
    27  func main() {
    28  	f, args := loadFlags()
    29  	if len(args) > 0 {
    30  		f.command = args[0]
    31  	}
    32  	if err := run(f); err != nil {
    33  		os.Exit(1)
    34  	}
    35  }
    36  
    37  func loadFlags() (flags, []string) {
    38  	f := flags{}
    39  	flag.BoolVar(&f.version, "version", false, "Show version")
    40  	flag.BoolVar(&f.logToFile, "log-to-file", false, "Log to file")
    41  	flag.StringVar(&f.pathToKeybase, "path-to-keybase", "", "Path to keybase executable")
    42  	flag.StringVar(&f.appName, "app-name", defaultAppName(), "App name")
    43  	flag.Parse()
    44  	args := flag.Args()
    45  	return f, args
    46  }
    47  
    48  func defaultAppName() string {
    49  	if runtime.GOOS == "linux" {
    50  		return "keybase"
    51  	}
    52  	return "Keybase"
    53  }
    54  
    55  func run(f flags) error {
    56  	if f.version {
    57  		fmt.Printf("%s\n", updater.Version)
    58  		return nil
    59  	}
    60  	ulog := logger{}
    61  
    62  	if f.logToFile {
    63  		logFile, _, err := ulog.setLogToFile(f.appName, "keybase.updater.log")
    64  		if err != nil {
    65  			ulog.Errorf("Error setting logging to file: %s", err)
    66  		}
    67  		defer util.Close(logFile)
    68  	}
    69  
    70  	// Set default path to keybase if not set
    71  	if f.pathToKeybase == "" {
    72  		path, err := osext.Executable()
    73  		if err != nil {
    74  			ulog.Warning("Error determining our executable path: %s", err)
    75  		} else {
    76  			dir, _ := filepath.Split(path)
    77  			pathToKeybase := filepath.Join(dir, "keybase")
    78  			ulog.Debugf("Using default path to keybase: %s", pathToKeybase)
    79  			f.pathToKeybase = pathToKeybase
    80  		}
    81  	}
    82  
    83  	if f.pathToKeybase == "" {
    84  		ulog.Warning("Missing -path-to-keybase")
    85  	}
    86  
    87  	switch f.command {
    88  	case "need-update":
    89  		ctx, updater := keybase.NewUpdaterContext(f.appName, f.pathToKeybase, ulog, keybase.Check)
    90  		needUpdate, err := updater.NeedUpdate(ctx)
    91  		if err != nil {
    92  			ulog.Error(err)
    93  			return err
    94  		}
    95  		// Keybase service expects to parse this output as a boolean.
    96  		// Do not change unless changing in both locations
    97  		// https: //github.com/keybase/client/blob/master/go/client/cmd_update.go
    98  		fmt.Println(needUpdate)
    99  	case "check":
   100  		if err := updateCheckFromFlags(f, ulog); err != nil {
   101  			ulog.Error(err)
   102  			return err
   103  		}
   104  	case "download-latest":
   105  		ctx, updater := keybase.NewUpdaterContext(f.appName, f.pathToKeybase, ulog, keybase.CheckPassive)
   106  		updateAvailable, _, err := updater.CheckAndDownload(ctx)
   107  		if err != nil {
   108  			ulog.Error(err)
   109  			return err
   110  		}
   111  		// Keybase service expects to parse this output as a boolean.
   112  		// Do not change unless changing in both locations
   113  		// https: //github.com/keybase/client/blob/master/go/client/cmd_update.go
   114  		fmt.Println(updateAvailable)
   115  	case "apply-downloaded":
   116  		ctx, updater := keybase.NewUpdaterContext(f.appName, f.pathToKeybase, ulog, keybase.Check)
   117  		applied, err := updater.ApplyDownloaded(ctx)
   118  		if err != nil {
   119  			ulog.Error(err)
   120  			return err
   121  		}
   122  		fmt.Println(applied)
   123  	case "service", "":
   124  		svc := serviceFromFlags(f, ulog)
   125  		svc.Run()
   126  	case "clean":
   127  		if runtime.GOOS == "windows" {
   128  			ctx, _ := keybase.NewUpdaterContext(f.appName, f.pathToKeybase, ulog, keybase.CheckPassive)
   129  			fmt.Printf("Doing DeepClean\n")
   130  			ctx.DeepClean()
   131  		} else {
   132  			ulog.Errorf("Unknown command: %s", f.command)
   133  		}
   134  	default:
   135  		ulog.Errorf("Unknown command: %s", f.command)
   136  	}
   137  	return nil
   138  }
   139  
   140  func serviceFromFlags(f flags, ulog logger) *service {
   141  	ulog.Infof("Updater %s", updater.Version)
   142  	ctx, upd := keybase.NewUpdaterContext(f.appName, f.pathToKeybase, ulog, keybase.Service)
   143  	return newService(upd, ctx, ulog, f.appName)
   144  }
   145  
   146  func updateCheckFromFlags(f flags, ulog logger) error {
   147  	ctx, updater := keybase.NewUpdaterContext(f.appName, f.pathToKeybase, ulog, keybase.Check)
   148  	_, err := updater.Update(ctx)
   149  	return err
   150  }