forked from hashicorp/packer-plugin-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig_file.go
More file actions
134 lines (113 loc) · 3.28 KB
/
config_file.go
File metadata and controls
134 lines (113 loc) · 3.28 KB
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
// Package pathing determines where to put the Packer config directory based on
// host OS architecture and user environment variables.
package pathing
import (
"log"
"os"
"os/user"
"path/filepath"
"strings"
)
// ConfigFile returns the default path to the configuration file. On
// Unix-like systems this is the ".packerconfig" file in the home directory.
// On Windows, this is the "packer.config" file in the application data
// directory.
func ConfigFile() (string, error) {
return configFile()
}
// ConfigDir returns the configuration directory for Packer.
func ConfigDir() (string, error) {
return configDir()
}
func homeDir() (string, error) {
// Prefer $APPDATA over $HOME in Windows.
// This makes it possible to use packer plugins (as installed by Chocolatey)
// in cmd/ps and msys2.
// See https://github.com/hashicorp/packer/issues/9795
if home := os.Getenv("APPDATA"); home != "" {
return home, nil
}
// Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
if home := os.Getenv("HOME"); home != "" {
return home, nil
}
// Fall back to the passwd database if not found which follows
// the same semantics as bourne shell
u, err := user.Current()
// Get homedir from specified username
// if it is set and different than what we have
if username := os.Getenv("USER"); username != "" && err == nil && u.Username != username {
u, err = user.Lookup(username)
}
// Fail if we were unable to read the record
if err != nil {
return "", err
}
return u.HomeDir, nil
}
func configFile() (string, error) {
var dir string
if cd := os.Getenv("PACKER_CONFIG_DIR"); cd != "" {
log.Printf("Detected config directory from env var: %s", cd)
dir = cd
} else {
homedir, err := homeDir()
if err != nil {
return "", err
}
dir = homedir
}
return filepath.Join(dir, defaultConfigFile), nil
}
func configDir() (path string, err error) {
var dir string
if cd := os.Getenv("PACKER_CONFIG_DIR"); cd != "" {
log.Printf("Detected config directory from env var: %s", cd)
dir = cd
} else {
homedir, err := homeDir()
if err != nil {
return "", err
}
dir = homedir
}
return filepath.Join(dir, getDefaultConfigDir()), nil
}
// Given a path, check to see if it's using ~ to reference a user directory.
// If so, then replace that component with the requested user directory.
// In "~/", "~" gets replaced by current user's home dir.
// In "~root/", "~user" gets replaced by root's home dir.
// ~ has to be the first character of path for ExpandUser change it.
func ExpandUser(path string) (string, error) {
var (
u *user.User
err error
)
// refuse to do anything with a zero-length path
if len(path) == 0 {
return path, nil
}
// If no expansion was specified, then refuse that too
if path[0] != '~' {
return path, nil
}
// Grab everything up to the first filepath.Separator
idx := strings.IndexAny(path, `/\`)
if idx == -1 {
idx = len(path)
}
// Now we should be able to extract the username
username := path[:idx]
// Check if the current user was requested
if username == "~" {
u, err = user.Current()
} else {
u, err = user.Lookup(username[1:])
}
// If we couldn't figure that out, then fail here
if err != nil {
return "", err
}
// Now we can replace the path with u.HomeDir
return filepath.Join(u.HomeDir, path[idx:]), nil
}