github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/storage/version.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package storage
    12  
    13  import (
    14  	"encoding/json"
    15  	"fmt"
    16  	"io/ioutil"
    17  	"os"
    18  	"path/filepath"
    19  )
    20  
    21  type storageVersion int
    22  
    23  const (
    24  	versionNoFile storageVersion = iota
    25  	versionBeta20160331
    26  	versionFileRegistry
    27  )
    28  
    29  const (
    30  	versionFilename     = "COCKROACHDB_VERSION"
    31  	versionFilenameTemp = "COCKROACHDB_VERSION_TEMP"
    32  	versionMinimum      = versionNoFile
    33  	versionCurrent      = versionFileRegistry
    34  )
    35  
    36  // Version stores all the version information for all stores and is used as
    37  // the format for the version file.
    38  type Version struct {
    39  	Version storageVersion
    40  }
    41  
    42  // getVersionFilename returns the filename for the version file stored in the
    43  // data directory.
    44  func getVersionFilename(dir string) string {
    45  	return filepath.Join(dir, versionFilename)
    46  }
    47  
    48  // getVersion returns the current on disk cockroach version from the version
    49  // file in the passed in directory. If there is no version file yet, it
    50  // returns 0.
    51  func getVersion(dir string) (storageVersion, error) {
    52  	filename := getVersionFilename(dir)
    53  	b, err := ioutil.ReadFile(filename)
    54  	if err != nil {
    55  		if os.IsNotExist(err) {
    56  			return versionNoFile, nil
    57  		}
    58  		return 0, err
    59  	}
    60  	var ver Version
    61  	if err := json.Unmarshal(b, &ver); err != nil {
    62  		return 0, fmt.Errorf("version file %s is not formatted correctly; %s", filename, err)
    63  	}
    64  	return ver.Version, nil
    65  }
    66  
    67  // writeVersionFile overwrites the version file to contain the specified version.
    68  func writeVersionFile(dir string, ver storageVersion) error {
    69  	tempFilename := filepath.Join(dir, versionFilenameTemp)
    70  	filename := getVersionFilename(dir)
    71  	b, err := json.Marshal(Version{ver})
    72  	if err != nil {
    73  		return err
    74  	}
    75  	// First write to a temp file.
    76  	if err := ioutil.WriteFile(tempFilename, b, 0644); err != nil {
    77  		return err
    78  	}
    79  	// Atomically rename the file to overwrite the version file on disk.
    80  	return os.Rename(tempFilename, filename)
    81  }