/
main_aliases.go
133 lines (112 loc) · 2.91 KB
/
main_aliases.go
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
package main
import (
"fmt"
"os"
"os/exec"
"os/user"
"path"
"path/filepath"
"strings"
"github.com/lxc/lxd/lxc/config"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/i18n"
)
// defaultAliases contains LXC's built-in command line aliases. The built-in
// aliases are checked only if no user-defined alias was found.
var defaultAliases = map[string]string{
"shell": "exec @ARGS@ -- su -l",
}
func findAlias(aliases map[string]string, origArgs []string) ([]string, []string, bool) {
foundAlias := false
aliasKey := []string{}
aliasValue := []string{}
for k, v := range aliases {
foundAlias = true
for i, key := range strings.Split(k, " ") {
if len(origArgs) <= i+1 || origArgs[i+1] != key {
foundAlias = false
break
}
}
if foundAlias {
aliasKey = strings.Split(k, " ")
aliasValue = strings.Split(v, " ")
break
}
}
return aliasKey, aliasValue, foundAlias
}
func expandAlias(conf *config.Config, origArgs []string) ([]string, bool) {
aliasKey, aliasValue, foundAlias := findAlias(conf.Aliases, origArgs)
if !foundAlias {
aliasKey, aliasValue, foundAlias = findAlias(defaultAliases, origArgs)
if !foundAlias {
return []string{}, false
}
}
var newArgs []string
if !strings.HasPrefix(aliasValue[0], "/") {
newArgs = append(newArgs, origArgs[0])
}
hasReplacedArgsVar := false
for i, aliasArg := range aliasValue {
if aliasArg == "@ARGS@" && len(origArgs) > i {
newArgs = append(newArgs, origArgs[i+1:]...)
hasReplacedArgsVar = true
} else {
newArgs = append(newArgs, aliasArg)
}
}
if !hasReplacedArgsVar {
// Add the rest of the arguments
newArgs = append(newArgs, origArgs[len(aliasKey)+1:]...)
}
return newArgs, true
}
func execIfAliases() error {
args := os.Args
// Avoid loops
if os.Getenv("LXC_ALIASES") == "1" {
return nil
}
// Figure out the config directory and config path
var configDir string
if os.Getenv("LXD_CONF") != "" {
configDir = os.Getenv("LXD_CONF")
} else if os.Getenv("HOME") != "" {
configDir = path.Join(os.Getenv("HOME"), ".config", "lxc")
} else {
user, err := user.Current()
if err != nil {
return nil
}
configDir = path.Join(user.HomeDir, ".config", "lxc")
}
confPath := os.ExpandEnv(path.Join(configDir, "config.yml"))
// Load the configuration
var conf *config.Config
var err error
if shared.PathExists(confPath) {
conf, err = config.LoadConfig(confPath)
if err != nil {
return nil
}
} else {
conf = config.NewConfig(filepath.Dir(confPath), true)
}
// Expand the aliases
newArgs, expanded := expandAlias(conf, args)
if !expanded {
return nil
}
// Look for the executable
path, err := exec.LookPath(newArgs[0])
if err != nil {
return fmt.Errorf(i18n.G("Processing aliases failed: %s"), err)
}
// Re-exec
environ := getEnviron()
environ = append(environ, "LXC_ALIASES=1")
ret := doExec(path, newArgs, environ)
return fmt.Errorf(i18n.G("Processing aliases failed: %s"), ret)
}