This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
forked from cloudfoundry/bosh-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errands.go
147 lines (110 loc) · 3.21 KB
/
errands.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
139
140
141
142
143
144
145
146
147
package director
import (
"encoding/json"
"fmt"
"net/http"
"io"
"strings"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
)
type Errand struct {
Name string // e.g. "acceptance-tests"
}
type ErrandResult struct {
InstanceGroup string
InstanceID string
ExitCode int
Stdout string
Stderr string
LogsBlobstoreID string
LogsSHA1 string
}
type ErrandRunResp struct {
Instance struct {
Group string `json:"group"`
ID string `json:"id"`
} `json:"instance"`
ExitCode int `json:"exit_code"`
Stdout string
Stderr string
Logs struct {
BlobstoreID string `json:"blobstore_id"`
SHA1 string `json:"sha1"`
} `json:"logs"`
}
func (d DeploymentImpl) Errands() ([]Errand, error) {
return d.client.Errands(d.name)
}
func (d DeploymentImpl) RunErrand(name string, keepAlive bool, whenChanged bool, slugs []InstanceGroupOrInstanceSlug) ([]ErrandResult, error) {
resp, err := d.client.RunErrand(d.name, name, keepAlive, whenChanged, slugs)
if err != nil {
return []ErrandResult{}, err
}
var result []ErrandResult
for _, value := range resp {
errandResult := ErrandResult{
InstanceGroup: value.Instance.Group,
InstanceID: value.Instance.ID,
ExitCode: value.ExitCode,
Stdout: value.Stdout,
Stderr: value.Stderr,
LogsBlobstoreID: value.Logs.BlobstoreID,
LogsSHA1: value.Logs.SHA1,
}
result = append(result, errandResult)
}
return result, nil
}
func (c Client) Errands(deploymentName string) ([]Errand, error) {
var errands []Errand
if len(deploymentName) == 0 {
return errands, bosherr.Error("Expected non-empty deployment name")
}
path := fmt.Sprintf("/deployments/%s/errands", deploymentName)
err := c.clientRequest.Get(path, &errands)
if err != nil {
return errands, bosherr.WrapErrorf(err, "Finding errands")
}
return errands, nil
}
func (c Client) RunErrand(deploymentName, name string, keepAlive bool, whenChanged bool, instanceSlugs []InstanceGroupOrInstanceSlug) ([]ErrandRunResp, error) {
var resp []ErrandRunResp
if len(deploymentName) == 0 {
return resp, bosherr.Error("Expected non-empty deployment name")
}
if len(name) == 0 {
return resp, bosherr.Error("Expected non-empty errand name")
}
path := fmt.Sprintf("/deployments/%s/errands/%s/runs", deploymentName, name)
instances := []InstanceFilter{}
for _, slug := range instanceSlugs {
instances = append(instances, slug.DirectorHash())
}
body := map[string]interface{}{
"keep-alive": keepAlive,
"when-changed": whenChanged,
"instances": instances,
}
reqBody, err := json.Marshal(body)
if err != nil {
return resp, bosherr.WrapErrorf(err, "Marshaling request body")
}
setHeaders := func(req *http.Request) {
req.Header.Add("Content-Type", "application/json")
}
resultBytes, err := c.taskClientRequest.PostResult(path, reqBody, setHeaders)
if err != nil {
return resp, bosherr.WrapErrorf(err, "Running errand '%s'", name)
}
dec := json.NewDecoder(strings.NewReader(string(resultBytes)))
for {
var errandRunResponse ErrandRunResp
if err := dec.Decode(&errandRunResponse); err == io.EOF {
break
} else if err != nil {
return nil, bosherr.WrapErrorf(err, "Unmarshaling errand result")
}
resp = append(resp, errandRunResponse)
}
return resp, nil
}