Skip to content

Commit 6cbed98

Browse files
jeanp413roboquat
authored andcommitted
credentialHelper minor refactor
1 parent f3300f0 commit 6cbed98

File tree

1 file changed

+88
-56
lines changed

1 file changed

+88
-56
lines changed

components/gitpod-cli/cmd/credential-helper.go

Lines changed: 88 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,29 @@ var credentialHelper = &cobra.Command{
5454
fmt.Printf("username=%s\npassword=%s\n", user, token)
5555
}()
5656

57-
gitCommandData := parseProcessTree()
58-
if gitCommandData == nil {
57+
gitCmdInfo := &gitCommandInfo{}
58+
err = walkProcessTree(os.Getpid(), func(pid int) bool {
59+
cmdLine, err := readProc(pid, "cmdline")
60+
if err != nil {
61+
log.WithError(err).Print("error reading proc cmdline")
62+
return true
63+
}
64+
65+
cmdLineString := strings.ReplaceAll(cmdLine, string(byte(0)), " ")
66+
gitCmdInfo.parseGitCommandAndOriginRemote(cmdLineString)
67+
68+
return gitCmdInfo.Ok()
69+
})
70+
if err != nil {
71+
log.WithError(err).Print("error walking process tree")
72+
return
73+
}
74+
if !gitCmdInfo.Ok() {
5975
return
6076
}
6177

6278
// Starts another process which tracks the executed git event
63-
gitCommandTracker := exec.Command("/proc/self/exe", "git-track-command", "--gitCommand", gitCommandData.GitCommand)
79+
gitCommandTracker := exec.Command("/proc/self/exe", "git-track-command", "--gitCommand", gitCmdInfo.GitCommand)
6480
err = gitCommandTracker.Start()
6581
if err != nil {
6682
log.WithError(err).Print("error spawning tracker")
@@ -98,7 +114,7 @@ var credentialHelper = &cobra.Command{
98114

99115
validator := exec.Command("/proc/self/exe", "git-token-validator",
100116
"--user", resp.User, "--token", resp.Token, "--scopes", strings.Join(resp.Scope, ","),
101-
"--host", host, "--repoURL", gitCommandData.RepoUrl, "--gitCommand", gitCommandData.GitCommand)
117+
"--host", host, "--repoURL", gitCmdInfo.RepoUrl, "--gitCommand", gitCmdInfo.GitCommand)
102118
err = validator.Start()
103119
if err != nil {
104120
log.WithError(err).Print("error spawning validator")
@@ -134,85 +150,101 @@ func parseHostFromStdin() string {
134150
return host
135151
}
136152

137-
func parseProcessTree() (result *struct {
153+
type gitCommandInfo struct {
138154
RepoUrl string
139155
GitCommand string
140-
}) {
141-
gitCommandRegExp := regexp.MustCompile(`git(,\d+\s+|\s+)(push|clone|fetch|pull|diff)`)
142-
repoUrlRegExp := regexp.MustCompile(`\sorigin\s*(https:[^\s]*)\s`)
143-
pid := os.Getpid()
144-
for {
145-
cmdLine := readProc(pid, "cmdline")
146-
if cmdLine == "" {
147-
return
148-
}
149-
cmdLineString := strings.ReplaceAll(cmdLine, string(byte(0)), " ")
156+
}
150157

151-
var gitCommand string
152-
matchCommand := gitCommandRegExp.FindStringSubmatch(cmdLineString)
153-
if len(matchCommand) == 3 {
154-
gitCommand = matchCommand[2]
155-
}
158+
func (g *gitCommandInfo) Ok() bool {
159+
return g.RepoUrl != "" && g.GitCommand != ""
160+
}
156161

157-
var repoUrl string
158-
matchRepo := repoUrlRegExp.FindStringSubmatch(cmdLineString)
159-
if len(matchRepo) == 2 {
160-
repoUrl = matchRepo[1]
161-
if !strings.HasSuffix(repoUrl, ".git") {
162-
repoUrl = repoUrl + ".git"
163-
}
164-
}
162+
var gitCommandRegExp = regexp.MustCompile(`git(,\d+\s+|\s+)(push|clone|fetch|pull|diff)`)
163+
var repoUrlRegExp = regexp.MustCompile(`\sorigin\s*(https:[^\s]*)\s`)
164+
165+
// This method needs to be called multiple times to fill all the required info
166+
// from different git commands
167+
// For example from first command below the `RepoUrl` will be parsed and from
168+
// the second command the `GitCommand` will be parsed
169+
// `/usr/lib/git-core/git-remote-https origin https://github.com/jeanp413/test-gp-bug.git`
170+
// `/usr/lib/git-core/git push`
171+
func (g *gitCommandInfo) parseGitCommandAndOriginRemote(cmdLineString string) {
172+
matchCommand := gitCommandRegExp.FindStringSubmatch(cmdLineString)
173+
if len(matchCommand) == 3 {
174+
g.GitCommand = matchCommand[2]
175+
}
165176

166-
if repoUrl != "" && gitCommand != "" {
167-
result = &struct {
168-
RepoUrl string
169-
GitCommand string
170-
}{
171-
RepoUrl: repoUrl,
172-
GitCommand: gitCommand,
173-
}
174-
return
177+
matchRepo := repoUrlRegExp.FindStringSubmatch(cmdLineString)
178+
if len(matchRepo) == 2 {
179+
g.RepoUrl = matchRepo[1]
180+
if !strings.HasSuffix(g.RepoUrl, ".git") {
181+
g.RepoUrl = g.RepoUrl + ".git"
175182
}
183+
}
184+
}
176185

177-
statsString := readProc(pid, "stat")
178-
if statsString == "" {
179-
return
180-
}
181-
stats := strings.Fields(statsString)
182-
if len(stats) < 3 {
183-
log.Printf("Couldn't parse 3rd element from stats: '%s'", statsString)
184-
return
186+
type pidCallbackFn func(int) bool
187+
188+
func walkProcessTree(pid int, fn pidCallbackFn) error {
189+
for {
190+
stop := fn(pid)
191+
if stop {
192+
return nil
185193
}
186-
ppid, err := strconv.Atoi(stats[3])
194+
195+
ppid, err := getProcesParentId(pid)
187196
if err != nil {
188-
log.Printf("ppid '%s' is not a number", stats[3])
189-
return
197+
return err
190198
}
191-
if ppid == pid {
192-
return
199+
if ppid == pid || ppid == 1 /* supervisor pid*/ {
200+
return nil
193201
}
194202
pid = ppid
195203
}
196204
}
197205

198-
func readProc(pid int, file string) string {
206+
func getProcesParentId(pid int) (ppid int, err error) {
207+
statsString, err := readProc(pid, "stat")
208+
if err != nil {
209+
return
210+
}
211+
212+
stats := strings.Fields(statsString)
213+
if len(stats) < 3 {
214+
err = fmt.Errorf("CredentialHelper error cannot parse stats string: %s", statsString)
215+
return
216+
}
217+
218+
parentId, err := strconv.Atoi(stats[3])
219+
if err != nil {
220+
err = fmt.Errorf("CredentialHelper error cannot parse ppid: %s", stats[3])
221+
return
222+
}
223+
224+
ppid = parentId
225+
return
226+
}
227+
228+
func readProc(pid int, file string) (data string, err error) {
199229
procFile := fmt.Sprintf("/proc/%d/%s", pid, file)
200230
// read file not using os.Stat
201231
// see https://github.com/prometheus/procfs/blob/5162bec877a860b5ff140b5d13db31ebb0643dd3/internal/util/readfile.go#L27
202232
const maxBufferSize = 1024 * 512
203233
f, err := os.Open(procFile)
204234
if err != nil {
205-
log.WithError(err).Printf("Error opening %s", procFile)
206-
return ""
235+
err = fmt.Errorf("CredentialHelper error opening proc file: %v", err)
236+
return
207237
}
208238
defer f.Close()
209239
reader := io.LimitReader(f, maxBufferSize)
210240
buffer, err := ioutil.ReadAll(reader)
211241
if err != nil {
212-
log.WithError(err).Printf("Error reading %s", procFile)
213-
return ""
242+
err = fmt.Errorf("CredentialHelper error reading proc file: %v", err)
243+
return
214244
}
215-
return string(buffer)
245+
246+
data = string(buffer)
247+
return
216248
}
217249

218250
func init() {

0 commit comments

Comments
 (0)