-
Notifications
You must be signed in to change notification settings - Fork 3
/
sample.go
138 lines (119 loc) · 3.04 KB
/
sample.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
134
135
136
137
138
// Copyright 2024 Harness Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"context"
"encoding/json"
"os"
"os/exec"
"strings"
"time"
"github.com/drone/go-task/task"
"github.com/drone/go-task/task/common"
"github.com/drone/go-task/task/masker"
)
type (
// input for exec task handler
execInput struct {
Shell string `json:"shell"`
Script []string `json:"script"`
Envs []string `json:"envs"`
}
// output for the exec task handler
execOutput struct {
Pid int `json:"pid"`
Exited bool `json:"exited"`
ExitCode int `json:"exit_code"`
UserTime time.Duration `json:"user_time"`
SysTime time.Duration `json:"sys_time"`
Output []string `json:"out"`
}
// input for the file task handler
fileInput struct {
Path string `json:"path"`
}
)
// Sample handler that exposes os/exec as a task. This is a
// sample only and is not meant for production use.
//
// Sample json input:
//
// {
// "task": {
// "id": "67c0938c-9348-4c5e-8624-28218984e09f",
// "type": "sample/exec",
// "data": {
// "script": [ "echo hello world" ],
// "shell": "sh"
// }
// }
// }
func execHandler(ctx context.Context, req *task.Request) task.Response {
var conf = new(execInput)
// decode the task configuration
if err := json.Unmarshal(req.Task.Data, &conf); err != nil {
return task.Error(err)
}
// create a buffer for stdout / stderr, wrapped
// in the secret masker
buf := new(bytes.Buffer)
buf_ := masker.New(
buf,
masker.Slice(req.Secrets),
)
// create the command
cmd := exec.CommandContext(ctx, "/bin/sh", "-c", strings.Join(conf.Script, "\n"))
cmd.Stdout = buf_
cmd.Stderr = buf_
cmd.Env = conf.Envs
// execute the command
if err := cmd.Run(); err != nil {
return task.Error(err)
}
// collect the output
out := &execOutput{
Pid: cmd.ProcessState.Pid(),
Exited: cmd.ProcessState.Exited(),
ExitCode: cmd.ProcessState.ExitCode(),
SysTime: cmd.ProcessState.SystemTime(),
UserTime: cmd.ProcessState.UserTime(),
// convert the buffer to log lines
Output: strings.Split(buf.String(), "\n"),
}
return task.Respond(out)
}
// Sample handler that reads a file as a task. This is a
// sample only and is not meant for production use.
//
// Sample json input:
//
// {
// "task": {
// "id": "67c0938c-9348-4c5e-8624-28218984e09f",
// "type": "sample/file",
// "data": {
// "path": "path/to/file.txt"
// }
// }
// }
func fileHandler(ctx context.Context, req *task.Request) task.Response {
conf := new(fileInput)
// decode the task configuration.
err := json.Unmarshal(req.Task.Data, conf)
if err != nil {
return task.Error(err)
}
// read the secret from the file.
contents, err := os.ReadFile(conf.Path)
if err != nil {
return task.Error(err)
}
// write the secret to the response.
return task.Respond(
&common.Secret{
Value: string(contents),
},
)
}