forked from markriggins/dockerfy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
args.go
131 lines (112 loc) · 3.46 KB
/
args.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
package main
import (
"log"
"os"
"os/exec"
"os/user"
"path/filepath"
"strconv"
"strings"
"syscall"
)
type Commands struct {
run []*exec.Cmd // list of commands to run BEFORE the primar
start []*exec.Cmd // list of services to start
credential *syscall.Credential // credentials for primary command
}
//
// Removes --start and --run commands options and arguments from os.Args
// Removes --user <uid|username> options and applies the credentials to following
// start or run commands and primary command
// Returns array of removed run commands, and an array of removed start commands
//
func removeCommandsFromOsArgs() Commands {
var newOsArgs = []string{}
var commands = Commands{}
var cmd *exec.Cmd
var cmd_user *user.User
if debugFlag {
log.Printf("")
log.Printf("dockerfy args BEFORE removing commands:\n")
for i := 0; i < len(os.Args); i++ {
log.Printf("\t%d: %s", i, os.Args[i])
}
}
for i := 0; i < len(os.Args); i++ {
// docker-compose.yml files are buggy on \ continuation characters
arg_i := strings.TrimSpace(os.Args[i])
switch {
case ("--start" == arg_i || "-start" == arg_i) && cmd == nil:
cmd = &exec.Cmd{Stdout: os.Stdout,
Stderr: os.Stderr,
SysProcAttr: &syscall.SysProcAttr{Credential: commands.credential}}
commands.start = append(commands.start, cmd)
case ("--run" == arg_i || "-run" == arg_i) && cmd == nil:
cmd = &exec.Cmd{Stdout: os.Stdout,
Stderr: os.Stderr,
SysProcAttr: &syscall.SysProcAttr{Credential: commands.credential}}
commands.run = append(commands.run, cmd)
case ("--user" == arg_i || "-user" == arg_i) && cmd == nil:
if os.Getuid() != 0 {
log.Fatalf("dockerfy must run as root to use the --user flag")
}
cmd_user = &user.User{}
case "--" == arg_i && cmd != nil: // End of args for this cmd
cmd = nil
default:
if cmd_user != nil {
// Expect a username or uid
var err1 error
user_name_or_id := arg_i
cmd_user, err1 = user.LookupId(user_name_or_id)
if cmd_user == nil {
// Not a userid, try as a username
cmd_user, err1 = user.Lookup(user_name_or_id)
if cmd_user == nil {
log.Fatalf("unknown user: '%s': %s", user_name_or_id, err1)
}
}
uid, _ := strconv.Atoi(cmd_user.Uid)
gid, _ := strconv.Atoi(cmd_user.Gid)
commands.credential = new(syscall.Credential)
commands.credential.Uid = uint32(uid)
commands.credential.Gid = uint32(gid)
cmd_user = nil
} else if cmd != nil {
// Expect a command first, then a series of arguments
if len(cmd.Path) == 0 {
cmd.Path = arg_i
if filepath.Base(cmd.Path) == cmd.Path {
cmd.Path, _ = exec.LookPath(cmd.Path)
}
}
// Only trim our own args, not --run cmd's or --start cmd's
cmd.Args = append(cmd.Args, os.Args[i])
} else {
newOsArgs = append(newOsArgs, arg_i)
}
}
}
if cmd_user != nil {
log.Fatalln("need a username or uid after the --user flag")
}
if cmd != nil {
log.Fatalf("need a command after the --start or --run flag")
}
os.Args = newOsArgs
if debugFlag {
log.Printf("")
log.Printf("dockerfy args AFTER removing commands:\n")
for i := 0; i < len(os.Args); i++ {
log.Printf("\t%d: %s", i, os.Args[i])
}
}
return commands
}
func toString(cmd *exec.Cmd) string {
s := ""
for _, arg := range cmd.Args {
s += arg + " "
}
return strings.TrimSpace(s)
}