1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
package config
import (
"fmt"
"log"
"os"
"os/user"
"path/filepath"
"runtime"
"strings"
"time"
)
// version and buildTime are filled in during build by the Makefile
var (
name = "Smallstep CLI"
buildTime = "N/A"
commit = "N/A"
)
// StepPathEnv defines the name of the environment variable that can overwrite
// the default configuration path.
const StepPathEnv = "STEPPATH"
// HomeEnv defines the name of the environment variable that can overwrite the
// default home directory.
const HomeEnv = "HOME"
// stepPath will be populated in init() with the proper STEPPATH.
var stepPath string
// homePath will be populated in init() with the proper HOME.
var homePath string
// StepPath returns the path for the step configuration directory, this is
// defined by the environment variable STEPPATH or if this is not set it will
// default to '$HOME/.step'.
func StepPath() string {
return stepPath
}
// Home returns the user home directory using the environment variable HOME or
// the os/user package.
func Home() string {
return homePath
}
// StepAbs returns the given path relative to the StepPath if it's not an
// absolute path, relative to the home directory using the special string "~/",
// or relative to the working directory using "./"
//
// Relative paths like 'certs/root_ca.crt' will be converted to
// '$STEPPATH/certs/root_ca.crt', but paths like './certs/root_ca.crt' will be
// relative to the current directory. Home relative paths like
// ~/certs/root_ca.crt will be converted to '$HOME/certs/root_ca.crt'. And
// absolute paths like '/certs/root_ca.crt' will remain the same.
func StepAbs(path string) string {
if filepath.IsAbs(path) {
return path
}
// Windows accept both \ and /
slashed := filepath.ToSlash(path)
switch {
case strings.HasPrefix(slashed, "~/"):
return filepath.Join(homePath, path[2:])
case strings.HasPrefix(slashed, "./"), strings.HasPrefix(slashed, "../"):
if abs, err := filepath.Abs(path); err == nil {
return abs
}
return path
default:
return filepath.Join(stepPath, path)
}
}
func init() {
l := log.New(os.Stderr, "", 0)
// Get home path from environment or from the user object.
homePath = os.Getenv(HomeEnv)
if homePath == "" {
usr, err := user.Current()
if err == nil && usr.HomeDir != "" {
homePath = usr.HomeDir
} else {
l.Fatalf("Error obtaining home directory, please define environment variable %s.", HomeEnv)
}
}
// Get step path from environment or relative to home.
stepPath = os.Getenv(StepPathEnv)
if stepPath == "" {
stepPath = filepath.Join(homePath, ".step")
}
// Check for presence or attempt to create it if necessary.
//
// Some environments (e.g. third party docker images) might fail creating
// the directory, so this should not panic if it can't.
if fi, err := os.Stat(stepPath); err != nil {
os.MkdirAll(stepPath, 0700)
} else if !fi.IsDir() {
l.Fatalf("File '%s' is not a directory.", stepPath)
}
// cleanup
homePath = filepath.Clean(homePath)
stepPath = filepath.Clean(stepPath)
}
// Set updates the Version and ReleaseDate
func Set(n, v, t string) {
name = n
buildTime = t
commit = v
}
// Version returns the current version of the binary
func Version() string {
out := commit
if commit == "N/A" {
out = "0000000-dev"
}
return fmt.Sprintf("%s/%s (%s/%s)",
name, out, runtime.GOOS, runtime.GOARCH)
}
// ReleaseDate returns the time of when the binary was built
func ReleaseDate() string {
out := buildTime
if buildTime == "N/A" {
out = time.Now().UTC().Format("2006-01-02 15:04 MST")
}
return out
}
|