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
130 lines (112 loc) · 3.88 KB
/
config_file.go
File metadata and controls
130 lines (112 loc) · 3.88 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
// 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.
// NOTE: config directory will change depending on operating system dependent
// For Windows:
// PACKER_CONFIG_DIR="" ConfigDir() => "/{homeDir()}/packer.config/
// PACKER_CONFIG_DIR="bar" ConfigDir() => "/bar/packer.config/
//
// NOTE: Default_config_present=TRUE means that there is configuration directory at old location => $HOME/.packer.d
// NOTE: This is not list all permutations, just some examples, view the
// configDir function for your OS for the exact logic
// For Unix:
// PACKER_CONFIG_DIR="" Default_config_present=FALSE XDG_CONFIG_HOME="" ConfigDir() => "$HOME/.config/packer
// PACKER_CONFIG_DIR="bar" Default_config_present=FALSE XDG_CONFIG_HOME="" ConfigDir() => "/bar/.packer.d/
// PACKER_CONFIG_DIR="" Default_config_present=TRUE XDG_CONFIG_HOME="" ConfigDir() => "/$HOME/.packer.d/
// PACKER_CONFIG_DIR="" Default_config_present=TRUE XDG_CONFIG_HOME="bar" ConfigDir() => "/bar/.packer.d/
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
}
// 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
}