func GetCurrentVersion() (string, error) { fix := func(s string) string { if !strings.HasPrefix(s, "v") { s = "v" + s } return s } // try checking a locally running daemon first apiurl, err := util.ApiEndpoint(util.IpfsDir()) if err == nil { sh := api.NewShell(apiurl) v, _, err := sh.Version() if err == nil { return fix(v), nil } } stump.VLog("daemon check failed: %s", err) _, err = exec.LookPath("ipfs") if err != nil { return "none", nil } // try running the ipfs binary in the users path out, err := exec.Command("ipfs", "version", "-n").CombinedOutput() if err != nil { return "", fmt.Errorf("version check failed: %s - %s", string(out), err) } return fix(strings.Trim(string(out), " \n\t")), nil }
func revertOldBinary(oldpath, version string) { stashpath := filepath.Join(util.IpfsDir(), "old-bin", "ipfs-"+version) rnerr := util.Move(stashpath, oldpath) if rnerr != nil { stump.Log("Error reverting") stump.Log("failed to replace binary after install fail: ", rnerr) stump.Log("sorry :(") stump.Log("your old ipfs binary should still be located at: ", stashpath) stump.Log("try: `mv %q %q`", stashpath, oldpath) } }
func selectRevertBin() (string, error) { oldbinpath := filepath.Join(util.IpfsDir(), "old-bin") _, err := os.Stat(oldbinpath) if os.IsNotExist(err) { return "", fmt.Errorf("No prior binary found at: %s", oldbinpath) } entries, err := ioutil.ReadDir(oldbinpath) if err != nil { return "", err } for i, e := range entries { if e.Name() == "path-old" { entries = append(entries[:i], entries[i+1:]...) break } } switch len(entries) { case 0: return "", fmt.Errorf("no prior binary found") case 1: return filepath.Join(oldbinpath, entries[0].Name()), nil default: } stump.Log("found multiple old binaries:") tw := tabwriter.NewWriter(stump.LogOut, 6, 4, 4, ' ', 0) for i, bin := range entries { fmt.Fprintf(tw, "%d)\t%s\t%s\n", i+1, bin.Name(), bin.ModTime().Format(time.ANSIC)) } tw.Flush() stump.Log("install which? (0 to exit)") scan := bufio.NewScanner(os.Stdin) for scan.Scan() { n, err := strconv.Atoi(scan.Text()) if n == 0 { return "", fmt.Errorf("exiting at user request") } if err != nil || n < 1 || n > len(entries) { stump.Log("please enter a number in the range 1-%d (0 to exit)", len(entries)) continue } stump.Log("installing %s...", entries[n-1].Name()) return filepath.Join(oldbinpath, entries[n-1].Name()), nil } return "", fmt.Errorf("failed to select binary") }
func CheckMigration() error { stump.Log("checking if repo migration is needed...") p := util.IpfsDir() vfilePath := filepath.Join(p, "version") _, err := os.Stat(vfilePath) if os.IsNotExist(err) { stump.VLog(" - no prexisting repo to migrate") return nil } oldverB, err := ioutil.ReadFile(vfilePath) if err != nil { return err } oldver := strings.Trim(string(oldverB), "\n \t") stump.VLog(" - old repo version is", oldver) nbinver, err := util.RunCmd("", "ipfs", "version", "--repo") if err != nil { stump.Log("Failed to check new binary repo version.") stump.VLog("Reason: ", err) stump.Log("This is not an error.") stump.Log("This just means that you may have to manually run the migration") stump.Log("You will be prompted to do so upon starting the ipfs daemon if necessary") return nil } stump.VLog(" - repo version of new binary is ", nbinver) if oldver != nbinver { stump.Log(" check complete, migration required.") return RunMigration(oldver, nbinver) } stump.VLog(" check complete, no migration required.") return nil }
// StashOldBinary moves the existing ipfs binary to a backup directory // and returns the path to the original location of the old binary func StashOldBinary(tag string, keep bool) (string, error) { loc, err := exec.LookPath("ipfs") if err != nil { return "", fmt.Errorf("could not find old binary: %s", err) } ipfsdir := util.IpfsDir() olddir := filepath.Join(ipfsdir, "old-bin") npath := filepath.Join(olddir, "ipfs-"+tag) pathpath := filepath.Join(olddir, "path-old") err = os.MkdirAll(olddir, 0700) if err != nil { return "", fmt.Errorf("could not create dir to backup old binary: %s", err) } // write the old path of the binary to the backup dir err = ioutil.WriteFile(pathpath, []byte(loc), 0644) if err != nil { return "", fmt.Errorf("couldnt stash path: ", err) } f := util.Move if keep { f = util.CopyTo } stump.VLog(" - moving %s to %s", loc, npath) err = f(loc, npath) if err != nil { return "", fmt.Errorf("could not move old binary: %s", err) } return loc, nil }
func TestBinary(bin, version string) error { _, err := os.Stat(bin) if err != nil { return err } // make sure binary is executable err = os.Chmod(bin, 0755) if err != nil { return err } staging := filepath.Join(util.IpfsDir(), "update-staging") err = os.MkdirAll(staging, 0755) if err != nil { return fmt.Errorf("error creating test staging directory: %s", err) } tdir, err := ioutil.TempDir(staging, "test") if err != nil { return err } err = os.MkdirAll(tdir, 0755) if err != nil { return fmt.Errorf("error creating test staging directory: %s", err) } defer func(dir string) { // defer cleanup, bound param to avoid mistakes err = os.RemoveAll(dir) if err != nil { stump.Error("error cleaning up staging directory: ", err) } }(tdir) stump.VLog(" - running init in '%s' with new binary", tdir) _, err = runCmd(tdir, bin, "init") if err != nil { return fmt.Errorf("error initializing with new binary: %s", err) } stump.VLog(" - checking new binary outputs correct version") rversion, err := runCmd(tdir, bin, "version") if err != nil { return err } parts := strings.Fields(rversion) if !versionMatch(parts[len(parts)-1], version[1:]) { return fmt.Errorf("version didnt match") } if util.BeforeVersion("v0.3.8", version) { stump.Log("== skipping tests with daemon, versions before 0.3.8 do not support port zero ==") return nil } // set up ports in config so we dont interfere with an already running daemon stump.VLog(" - tweaking test config to avoid external interference") err = tweakConfig(tdir) if err != nil { return err } stump.VLog(" - starting up daemon") daemon, err := StartDaemon(tdir, bin) if err != nil { return fmt.Errorf("error starting daemon: %s", err) } defer func() { stump.VLog(" - killing test daemon") err := daemon.Close() if err != nil { stump.VLog(" - error killing test daemon: %s (continuing anyway)", err) } stump.Log("success!") }() // test some basic things against the daemon err = testFileAdd(tdir, bin) if err != nil { return fmt.Errorf("test file add: %s", err) } err = testRefsList(tdir, bin) if err != nil { return fmt.Errorf("test refs list: %s", err) } return nil }
var cmdRevert = cli.Command{ Name: "revert", Usage: "Revert to previously installed version of ipfs.", ArgsUsage: " ", Description: `'revert' will check if a previous update left a stashed binary and overwrite the current ipfs binary with it. If multiple previous versions exist, you will be prompted to select the desired binary.`, Action: func(c *cli.Context) error { oldbinpath, err := selectRevertBin() if err != nil { return err } stump.Log("Reverting to %s.", oldbinpath) oldpath, err := ioutil.ReadFile(filepath.Join(util.IpfsDir(), "old-bin", "path-old")) if err != nil { stump.Fatal("path for previous installation could not be read: ", err) } binpath := string(oldpath) err = InstallBinaryTo(oldbinpath, binpath) if err != nil { stump.Error("failed to move old binary: %s", oldbinpath) stump.Error("to path: %s", binpath) stump.Fatal(err) } stump.Log("\nRevert complete.") return nil }, }