github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/upgrade.go (about)

     1  // Copyright (c) 2013-2014 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package main
     7  
     8  import (
     9  	"io"
    10  	"os"
    11  	"path/filepath"
    12  )
    13  
    14  // dirEmpty returns whether or not the specified directory path is empty.
    15  func dirEmpty(dirPath string) (bool, error) {
    16  	f, err := os.Open(dirPath)
    17  	defer f.Close()
    18  
    19  	// Read the names of a max of one entry from the directory.  When the
    20  	// directory is empty, an io.EOF error will be returned, so allow it.
    21  	names, err := f.Readdirnames(1)
    22  	if err != nil && err != io.EOF {
    23  		return false, err
    24  	}
    25  
    26  	return len(names) == 0, nil
    27  }
    28  
    29  // oldBtcdHomeDir returns the OS specific home directory btcd used prior to
    30  // version 0.3.3.  This has since been replaced with godashutil.AppDataDir, but
    31  // this function is still provided for the automatic upgrade path.
    32  func oldBtcdHomeDir() string {
    33  	// Search for Windows APPDATA first.  This won't exist on POSIX OSes.
    34  	appData := os.Getenv("APPDATA")
    35  	if appData != "" {
    36  		return filepath.Join(appData, "btcd")
    37  	}
    38  
    39  	// Fall back to standard HOME directory that works for most POSIX OSes.
    40  	home := os.Getenv("HOME")
    41  	if home != "" {
    42  		return filepath.Join(home, ".btcd")
    43  	}
    44  
    45  	// In the worst case, use the current directory.
    46  	return "."
    47  }
    48  
    49  // upgradeDBPathNet moves the database for a specific network from its
    50  // location prior to btcd version 0.2.0 and uses heuristics to ascertain the old
    51  // database type to rename to the new format.
    52  func upgradeDBPathNet(oldDbPath, netName string) error {
    53  	// Prior to version 0.2.0, the database was named the same thing for
    54  	// both sqlite and leveldb.  Use heuristics to figure out the type
    55  	// of the database and move it to the new path and name introduced with
    56  	// version 0.2.0 accordingly.
    57  	fi, err := os.Stat(oldDbPath)
    58  	if err == nil {
    59  		oldDbType := "sqlite"
    60  		if fi.IsDir() {
    61  			oldDbType = "leveldb"
    62  		}
    63  
    64  		// The new database name is based on the database type and
    65  		// resides in a directory named after the network type.
    66  		newDbRoot := filepath.Join(filepath.Dir(cfg.DataDir), netName)
    67  		newDbName := blockDbNamePrefix + "_" + oldDbType
    68  		if oldDbType == "sqlite" {
    69  			newDbName = newDbName + ".db"
    70  		}
    71  		newDbPath := filepath.Join(newDbRoot, newDbName)
    72  
    73  		// Create the new path if needed.
    74  		err = os.MkdirAll(newDbRoot, 0700)
    75  		if err != nil {
    76  			return err
    77  		}
    78  
    79  		// Move and rename the old database.
    80  		err := os.Rename(oldDbPath, newDbPath)
    81  		if err != nil {
    82  			return err
    83  		}
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  // upgradeDBPaths moves the databases from their locations prior to btcd
    90  // version 0.2.0 to their new locations.
    91  func upgradeDBPaths() error {
    92  	// Prior to version 0.2.0, the databases were in the "db" directory and
    93  	// their names were suffixed by "testnet" and "regtest" for their
    94  	// respective networks.  Check for the old database and update it to the
    95  	// new path introduced with version 0.2.0 accordingly.
    96  	oldDbRoot := filepath.Join(oldBtcdHomeDir(), "db")
    97  	upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd.db"), "mainnet")
    98  	upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_testnet.db"), "testnet")
    99  	upgradeDBPathNet(filepath.Join(oldDbRoot, "btcd_regtest.db"), "regtest")
   100  
   101  	// Remove the old db directory.
   102  	err := os.RemoveAll(oldDbRoot)
   103  	if err != nil {
   104  		return err
   105  	}
   106  
   107  	return nil
   108  }
   109  
   110  // upgradeDataPaths moves the application data from its location prior to btcd
   111  // version 0.3.3 to its new location.
   112  func upgradeDataPaths() error {
   113  	// No need to migrate if the old and new home paths are the same.
   114  	oldHomePath := oldBtcdHomeDir()
   115  	newHomePath := btcdHomeDir
   116  	if oldHomePath == newHomePath {
   117  		return nil
   118  	}
   119  
   120  	// Only migrate if the old path exists and the new one doesn't.
   121  	if fileExists(oldHomePath) && !fileExists(newHomePath) {
   122  		// Create the new path.
   123  		btcdLog.Infof("Migrating application home path from '%s' to '%s'",
   124  			oldHomePath, newHomePath)
   125  		err := os.MkdirAll(newHomePath, 0700)
   126  		if err != nil {
   127  			return err
   128  		}
   129  
   130  		// Move old btcd.conf into new location if needed.
   131  		oldConfPath := filepath.Join(oldHomePath, defaultConfigFilename)
   132  		newConfPath := filepath.Join(newHomePath, defaultConfigFilename)
   133  		if fileExists(oldConfPath) && !fileExists(newConfPath) {
   134  			err := os.Rename(oldConfPath, newConfPath)
   135  			if err != nil {
   136  				return err
   137  			}
   138  		}
   139  
   140  		// Move old data directory into new location if needed.
   141  		oldDataPath := filepath.Join(oldHomePath, defaultDataDirname)
   142  		newDataPath := filepath.Join(newHomePath, defaultDataDirname)
   143  		if fileExists(oldDataPath) && !fileExists(newDataPath) {
   144  			err := os.Rename(oldDataPath, newDataPath)
   145  			if err != nil {
   146  				return err
   147  			}
   148  		}
   149  
   150  		// Remove the old home if it is empty or show a warning if not.
   151  		ohpEmpty, err := dirEmpty(oldHomePath)
   152  		if err != nil {
   153  			return err
   154  		}
   155  		if ohpEmpty {
   156  			err := os.Remove(oldHomePath)
   157  			if err != nil {
   158  				return err
   159  			}
   160  		} else {
   161  			btcdLog.Warnf("Not removing '%s' since it contains files "+
   162  				"not created by this application.  You may "+
   163  				"want to manually move them or delete them.",
   164  				oldHomePath)
   165  		}
   166  	}
   167  
   168  	return nil
   169  }
   170  
   171  // doUpgrades performs upgrades to btcd as new versions require it.
   172  func doUpgrades() error {
   173  	err := upgradeDBPaths()
   174  	if err != nil {
   175  		return err
   176  	}
   177  	return upgradeDataPaths()
   178  }