Skip to content

Commit 71e145f

Browse files
committedDec 3, 2020
Add context in functions to make debugging easier
if "debug" been set in context, will dump response data including body. we can pass logger in context in the future Signed-off-by: Hui Luo <luoh@vmware.com>
1 parent aa8503c commit 71e145f

17 files changed

+442
-370
lines changed
 

‎artifact.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package gojenkins
1616

1717
import (
18+
"context"
1819
"crypto/md5"
1920
"errors"
2021
"fmt"
@@ -33,9 +34,9 @@ type Artifact struct {
3334
}
3435

3536
// Get raw byte data of Artifact
36-
func (a Artifact) GetData() ([]byte, error) {
37+
func (a Artifact) GetData(ctx context.Context) ([]byte, error) {
3738
var data string
38-
response, err := a.Jenkins.Requester.Get(a.Path, &data, nil)
39+
response, err := a.Jenkins.Requester.Get(ctx, a.Path, &data, nil)
3940

4041
if err != nil {
4142
return nil, err
@@ -50,19 +51,19 @@ func (a Artifact) GetData() ([]byte, error) {
5051
}
5152

5253
// Save artifact to a specific path, using your own filename.
53-
func (a Artifact) Save(path string) (bool, error) {
54-
data, err := a.GetData()
54+
func (a Artifact) Save(ctx context.Context, path string) (bool, error) {
55+
data, err := a.GetData(ctx)
5556

5657
if err != nil {
57-
return false, errors.New("No Data received, not saving file.")
58+
return false, errors.New("no Data received, not saving file")
5859
}
5960

6061
if _, err = os.Stat(path); err == nil {
6162
Warning.Println("Local Copy already exists, Overwriting...")
6263
}
6364

6465
err = ioutil.WriteFile(path, data, 0644)
65-
a.validateDownload(path)
66+
a.validateDownload(ctx, path)
6667

6768
if err != nil {
6869
return false, err
@@ -71,25 +72,25 @@ func (a Artifact) Save(path string) (bool, error) {
7172
}
7273

7374
// Save Artifact to directory using Artifact filename.
74-
func (a Artifact) SaveToDir(dir string) (bool, error) {
75+
func (a Artifact) SaveToDir(ctx context.Context, dir string) (bool, error) {
7576
if _, err := os.Stat(dir); err != nil {
7677
Error.Printf("can't save artifact: directory %s does not exist", dir)
7778
return false, fmt.Errorf("can't save artifact: directory %s does not exist", dir)
7879
}
79-
saved, err := a.Save(path.Join(dir, a.FileName))
80+
saved, err := a.Save(ctx, path.Join(dir, a.FileName))
8081
if err != nil {
8182
return saved, nil
8283
}
8384
return saved, nil
8485
}
8586

8687
// Compare Remote and local MD5
87-
func (a Artifact) validateDownload(path string) (bool, error) {
88+
func (a Artifact) validateDownload(ctx context.Context, path string) (bool, error) {
8889
localHash := a.getMD5local(path)
8990

9091
fp := FingerPrint{Jenkins: a.Jenkins, Base: "/fingerprint/", Id: localHash, Raw: new(FingerPrintResponse)}
9192

92-
valid, err := fp.ValidateForBuild(a.FileName, a.Build)
93+
valid, err := fp.ValidateForBuild(ctx, a.FileName, a.Build)
9394

9495
if err != nil {
9596
return false, err

‎build.go

+43-42
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package gojenkins
1616

1717
import (
1818
"bytes"
19+
"context"
1920
"errors"
2021
"net/url"
2122
"regexp"
@@ -225,9 +226,9 @@ func (b *Build) GetCulprits() []Culprit {
225226
return b.Raw.Culprits
226227
}
227228

228-
func (b *Build) Stop() (bool, error) {
229-
if b.IsRunning() {
230-
response, err := b.Jenkins.Requester.Post(b.Base+"/stop", nil, nil, nil)
229+
func (b *Build) Stop(ctx context.Context) (bool, error) {
230+
if b.IsRunning(ctx) {
231+
response, err := b.Jenkins.Requester.Post(ctx, b.Base+"/stop", nil, nil, nil)
231232
if err != nil {
232233
return false, err
233234
}
@@ -236,22 +237,22 @@ func (b *Build) Stop() (bool, error) {
236237
return true, nil
237238
}
238239

239-
func (b *Build) GetConsoleOutput() string {
240+
func (b *Build) GetConsoleOutput(ctx context.Context) string {
240241
url := b.Base + "/consoleText"
241242
var content string
242-
b.Jenkins.Requester.GetXML(url, &content, nil)
243+
b.Jenkins.Requester.GetXML(ctx, url, &content, nil)
243244
return content
244245
}
245246

246-
func (b *Build) GetConsoleOutputFromIndex(startID int64) (consoleResponse, error) {
247+
func (b *Build) GetConsoleOutputFromIndex(ctx context.Context, startID int64) (consoleResponse, error) {
247248
strstart := strconv.FormatInt(startID, 10)
248249
url := b.Base + "/logText/progressiveText"
249250

250251
var console consoleResponse
251252

252253
querymap := make(map[string]string)
253254
querymap["start"] = strstart
254-
rsp, err := b.Jenkins.Requester.Get(url, &console.Content, querymap)
255+
rsp, err := b.Jenkins.Requester.Get(ctx, url, &console.Content, querymap)
255256
if err != nil {
256257
return console, err
257258
}
@@ -266,8 +267,8 @@ func (b *Build) GetConsoleOutputFromIndex(startID int64) (consoleResponse, error
266267
return console, err
267268
}
268269

269-
func (b *Build) GetCauses() ([]map[string]interface{}, error) {
270-
_, err := b.Poll()
270+
func (b *Build) GetCauses(ctx context.Context) ([]map[string]interface{}, error) {
271+
_, err := b.Poll(ctx, 3)
271272
if err != nil {
272273
return nil, err
273274
}
@@ -288,35 +289,35 @@ func (b *Build) GetParameters() []parameter {
288289
return nil
289290
}
290291

291-
func (b *Build) GetInjectedEnvVars() (map[string]string, error) {
292+
func (b *Build) GetInjectedEnvVars(ctx context.Context) (map[string]string, error) {
292293
var envVars struct {
293294
EnvMap map[string]string `json:"envMap"`
294295
}
295296
endpoint := b.Base + "/injectedEnvVars"
296-
_, err := b.Jenkins.Requester.GetJSON(endpoint, &envVars, nil)
297+
_, err := b.Jenkins.Requester.GetJSON(ctx, endpoint, &envVars, nil)
297298
if err != nil {
298299
return envVars.EnvMap, err
299300
}
300301
return envVars.EnvMap, nil
301302
}
302303

303-
func (b *Build) GetDownstreamBuilds() ([]*Build, error) {
304+
func (b *Build) GetDownstreamBuilds(ctx context.Context) ([]*Build, error) {
304305
result := make([]*Build, 0)
305-
downstreamJobs, err := b.Job.GetDownstreamJobs()
306+
downstreamJobs, err := b.Job.GetDownstreamJobs(ctx)
306307
if err != nil {
307308
return nil, err
308309
}
309310
for _, job := range downstreamJobs {
310-
allBuildIDs, err := job.GetAllBuildIds()
311+
allBuildIDs, err := job.GetAllBuildIds(ctx)
311312
if err != nil {
312313
return nil, err
313314
}
314315
for _, buildID := range allBuildIDs {
315-
build, err := job.GetBuild(buildID.Number)
316+
build, err := job.GetBuild(ctx, buildID.Number)
316317
if err != nil {
317318
return nil, err
318319
}
319-
upstreamBuild, err := build.GetUpstreamBuild()
320+
upstreamBuild, err := build.GetUpstreamBuild(ctx)
320321
// older build may no longer exist, so simply ignore these
321322
// cannot compare only id, it can be from different job
322323
if err == nil && b.GetUrl() == upstreamBuild.GetUrl() {
@@ -328,10 +329,10 @@ func (b *Build) GetDownstreamBuilds() ([]*Build, error) {
328329
return result, nil
329330
}
330331

331-
func (b *Build) GetDownstreamJobNames() []string {
332+
func (b *Build) GetDownstreamJobNames(ctx context.Context) []string {
332333
result := make([]string, 0)
333334
downstreamJobs := b.Job.GetDownstreamJobsMetadata()
334-
fingerprints := b.GetAllFingerPrints()
335+
fingerprints := b.GetAllFingerPrints(ctx)
335336
for _, fingerprint := range fingerprints {
336337
for _, usage := range fingerprint.Raw.Usage {
337338
for _, job := range downstreamJobs {
@@ -344,31 +345,31 @@ func (b *Build) GetDownstreamJobNames() []string {
344345
return result
345346
}
346347

347-
func (b *Build) GetAllFingerPrints() []*FingerPrint {
348-
b.Poll(3)
348+
func (b *Build) GetAllFingerPrints(ctx context.Context) []*FingerPrint {
349+
b.Poll(ctx)
349350
result := make([]*FingerPrint, len(b.Raw.FingerPrint))
350351
for i, f := range b.Raw.FingerPrint {
351352
result[i] = &FingerPrint{Jenkins: b.Jenkins, Base: "/fingerprint/", Id: f.Hash, Raw: &f}
352353
}
353354
return result
354355
}
355356

356-
func (b *Build) GetUpstreamJob() (*Job, error) {
357-
causes, err := b.GetCauses()
357+
func (b *Build) GetUpstreamJob(ctx context.Context) (*Job, error) {
358+
causes, err := b.GetCauses(ctx)
358359
if err != nil {
359360
return nil, err
360361
}
361362

362363
for _, cause := range causes {
363364
if job, ok := cause["upstreamProject"]; ok {
364-
return b.Jenkins.GetJob(job.(string))
365+
return b.Jenkins.GetJob(ctx, job.(string))
365366
}
366367
}
367368
return nil, errors.New("Unable to get Upstream Job")
368369
}
369370

370-
func (b *Build) GetUpstreamBuildNumber() (int64, error) {
371-
causes, err := b.GetCauses()
371+
func (b *Build) GetUpstreamBuildNumber(ctx context.Context) (int64, error) {
372+
causes, err := b.GetCauses(ctx)
372373
if err != nil {
373374
return 0, err
374375
}
@@ -385,22 +386,22 @@ func (b *Build) GetUpstreamBuildNumber() (int64, error) {
385386
return 0, nil
386387
}
387388

388-
func (b *Build) GetUpstreamBuild() (*Build, error) {
389-
job, err := b.GetUpstreamJob()
389+
func (b *Build) GetUpstreamBuild(ctx context.Context) (*Build, error) {
390+
job, err := b.GetUpstreamJob(ctx)
390391
if err != nil {
391392
return nil, err
392393
}
393394
if job != nil {
394-
buildNumber, err := b.GetUpstreamBuildNumber()
395+
buildNumber, err := b.GetUpstreamBuildNumber(ctx)
395396
if err == nil && buildNumber != 0 {
396-
return job.GetBuild(buildNumber)
397+
return job.GetBuild(ctx, buildNumber)
397398
}
398399
}
399400
return nil, errors.New("Build not found")
400401
}
401402

402-
func (b *Build) GetMatrixRuns() ([]*Build, error) {
403-
_, err := b.Poll(0)
403+
func (b *Build) GetMatrixRuns(ctx context.Context) ([]*Build, error) {
404+
_, err := b.Poll(ctx, 0)
404405
if err != nil {
405406
return nil, err
406407
}
@@ -410,17 +411,17 @@ func (b *Build) GetMatrixRuns() ([]*Build, error) {
410411

411412
for i, run := range runs {
412413
result[i] = &Build{Jenkins: b.Jenkins, Job: b.Job, Raw: new(BuildResponse), Depth: 1, Base: "/" + r.FindString(run.URL)}
413-
result[i].Poll()
414+
result[i].Poll(ctx)
414415
}
415416
return result, nil
416417
}
417418

418-
func (b *Build) GetResultSet() (*TestResult, error) {
419+
func (b *Build) GetResultSet(ctx context.Context) (*TestResult, error) {
419420

420421
url := b.Base + "/testReport"
421422
var report TestResult
422423

423-
_, err := b.Jenkins.Requester.GetJSON(url, &report, nil)
424+
_, err := b.Jenkins.Requester.GetJSON(ctx, url, &report, nil)
424425
if err != nil {
425426
return nil, err
426427
}
@@ -470,28 +471,28 @@ func (b *Build) GetRevisionBranch() string {
470471
return ""
471472
}
472473

473-
func (b *Build) IsGood() bool {
474-
return (!b.IsRunning() && b.Raw.Result == STATUS_SUCCESS)
474+
func (b *Build) IsGood(ctx context.Context) bool {
475+
return (!b.IsRunning(ctx) && b.Raw.Result == STATUS_SUCCESS)
475476
}
476477

477-
func (b *Build) IsRunning() bool {
478-
_, err := b.Poll()
478+
func (b *Build) IsRunning(ctx context.Context) bool {
479+
_, err := b.Poll(ctx)
479480
if err != nil {
480481
return false
481482
}
482483
return b.Raw.Building
483484
}
484485

485-
func (b *Build) SetDescription(description string) error {
486+
func (b *Build) SetDescription(ctx context.Context, description string) error {
486487
data := url.Values{}
487488
data.Set("description", description)
488-
_, err := b.Jenkins.Requester.Post(b.Base+"/submitDescription", bytes.NewBufferString(data.Encode()), nil, nil)
489+
_, err := b.Jenkins.Requester.Post(ctx, b.Base+"/submitDescription", bytes.NewBufferString(data.Encode()), nil, nil)
489490
return err
490491
}
491492

492493
// Poll for current data. Optional parameter - depth.
493494
// More about depth here: https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API
494-
func (b *Build) Poll(options ...interface{}) (int, error) {
495+
func (b *Build) Poll(ctx context.Context, options ...interface{}) (int, error) {
495496
depth := "-1"
496497

497498
for _, o := range options {
@@ -511,7 +512,7 @@ func (b *Build) Poll(options ...interface{}) (int, error) {
511512
qr := map[string]string{
512513
"depth": depth,
513514
}
514-
response, err := b.Jenkins.Requester.GetJSON(b.Base, b.Raw, qr)
515+
response, err := b.Jenkins.Requester.GetJSON(ctx, b.Base, b.Raw, qr)
515516
if err != nil {
516517
return 0, err
517518
}

‎credentials.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gojenkins
22

33
import (
4+
"context"
45
"encoding/xml"
56
"fmt"
67
"net/http"
@@ -107,11 +108,11 @@ func (cm CredentialsManager) fillURL(url string, params ...interface{}) string {
107108
}
108109

109110
//List ids if credentials stored inside provided domain
110-
func (cm CredentialsManager) List(domain string) ([]string, error) {
111+
func (cm CredentialsManager) List(ctx context.Context, domain string) ([]string, error) {
111112

112113
idsResponse := credentialIDs{}
113114
ids := make([]string, 0)
114-
err := cm.handleResponse(cm.J.Requester.Get(cm.fillURL(credentialsListURL, domain), &idsResponse, listQuery))
115+
err := cm.handleResponse(cm.J.Requester.Get(ctx, cm.fillURL(credentialsListURL, domain), &idsResponse, listQuery))
115116
if err != nil {
116117
return ids, err
117118
}
@@ -125,9 +126,9 @@ func (cm CredentialsManager) List(domain string) ([]string, error) {
125126

126127
//GetSingle searches for credential in given domain with given id, if credential is found
127128
//it will be parsed as xml to creds parameter(creds must be pointer to struct)
128-
func (cm CredentialsManager) GetSingle(domain string, id string, creds interface{}) error {
129+
func (cm CredentialsManager) GetSingle(ctx context.Context, domain string, id string, creds interface{}) error {
129130
str := ""
130-
err := cm.handleResponse(cm.J.Requester.Get(cm.fillURL(configCredentialURL, domain, id), &str, map[string]string{}))
131+
err := cm.handleResponse(cm.J.Requester.Get(ctx, cm.fillURL(configCredentialURL, domain, id), &str, map[string]string{}))
131132
if err != nil {
132133
return err
133134
}
@@ -136,27 +137,27 @@ func (cm CredentialsManager) GetSingle(domain string, id string, creds interface
136137
}
137138

138139
//Add credential to given domain, creds must be struct which is parsable to xml
139-
func (cm CredentialsManager) Add(domain string, creds interface{}) error {
140-
return cm.postCredsXML(cm.fillURL(createCredentialsURL, domain), creds)
140+
func (cm CredentialsManager) Add(ctx context.Context, domain string, creds interface{}) error {
141+
return cm.postCredsXML(ctx, cm.fillURL(createCredentialsURL, domain), creds)
141142
}
142143

143144
//Delete credential in given domain with given id
144-
func (cm CredentialsManager) Delete(domain string, id string) error {
145-
return cm.handleResponse(cm.J.Requester.Post(cm.fillURL(deleteCredentialURL, domain, id), nil, cm.J.Raw, map[string]string{}))
145+
func (cm CredentialsManager) Delete(ctx context.Context, domain string, id string) error {
146+
return cm.handleResponse(cm.J.Requester.Post(ctx, cm.fillURL(deleteCredentialURL, domain, id), nil, cm.J.Raw, map[string]string{}))
146147
}
147148

148149
//Update credential in given domain with given id, creds must be pointer to struct which is parsable to xml
149-
func (cm CredentialsManager) Update(domain string, id string, creds interface{}) error {
150-
return cm.postCredsXML(cm.fillURL(configCredentialURL, domain, id), creds)
150+
func (cm CredentialsManager) Update(ctx context.Context, domain string, id string, creds interface{}) error {
151+
return cm.postCredsXML(ctx, cm.fillURL(configCredentialURL, domain, id), creds)
151152
}
152153

153-
func (cm CredentialsManager) postCredsXML(url string, creds interface{}) error {
154+
func (cm CredentialsManager) postCredsXML(ctx context.Context, url string, creds interface{}) error {
154155
payload, err := xml.Marshal(creds)
155156
if err != nil {
156157
return err
157158
}
158159

159-
return cm.handleResponse(cm.J.Requester.PostXML(url, string(payload), cm.J.Raw, map[string]string{}))
160+
return cm.handleResponse(cm.J.Requester.PostXML(ctx, url, string(payload), cm.J.Raw, map[string]string{}))
160161
}
161162

162163
func (cm CredentialsManager) handleResponse(resp *http.Response, err error) error {

‎credentials_test.go

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package gojenkins
22

33
import (
4-
"github.com/stretchr/testify/assert"
4+
"context"
55
"os"
66
"testing"
7+
8+
"github.com/stretchr/testify/assert"
79
)
810

911
var (
@@ -24,11 +26,12 @@ func TestCreateUsernameCredentials(t *testing.T) {
2426
Password: "pass",
2527
}
2628

27-
err := cm.Add(domain, cred)
29+
ctx := context.Background()
30+
err := cm.Add(ctx, domain, cred)
2831
assert.Nil(t, err, "Could not create credential")
2932

3033
getCred := UsernameCredentials{}
31-
err = cm.GetSingle(domain, cred.ID, &getCred)
34+
err = cm.GetSingle(ctx, domain, cred.ID, &getCred)
3235
assert.Nil(t, err, "Could not get credential")
3336

3437
assert.Equal(t, cred.Scope, getCred.Scope, "Scope is not equal")
@@ -46,11 +49,12 @@ func TestCreateDockerCredentials(t *testing.T) {
4649
ClientKey: "client key",
4750
}
4851

49-
err := cm.Add(domain, cred)
52+
ctx := context.Background()
53+
err := cm.Add(ctx, domain, cred)
5054
assert.Nil(t, err, "Could not create credential")
5155

5256
getCred := DockerServerCredentials{}
53-
err = cm.GetSingle(domain, cred.ID, &getCred)
57+
err = cm.GetSingle(ctx, domain, cred.ID, &getCred)
5458
assert.Nil(t, err, "Could not get credential")
5559

5660
assert.Equal(t, cred.Scope, getCred.Scope, "Scope is not equal")
@@ -73,31 +77,33 @@ func TestCreateSSHCredentialsFullFlow(t *testing.T) {
7377
},
7478
}
7579

76-
err := cm.Add(domain, sshCred)
80+
ctx := context.Background()
81+
err := cm.Add(ctx, domain, sshCred)
7782
assert.Nil(t, err, "Could not create credential")
7883

7984
sshCred.Username = "new_username"
80-
err = cm.Update(domain, sshCred.ID, sshCred)
85+
err = cm.Update(ctx, domain, sshCred.ID, sshCred)
8186
assert.Nil(t, err, "Could not update credential")
8287

8388
getSSH := SSHCredentials{}
84-
err = cm.GetSingle(domain, sshCred.ID, &getSSH)
89+
err = cm.GetSingle(ctx, domain, sshCred.ID, &getSSH)
8590
assert.Nil(t, err, "Could not get ssh credential")
8691

8792
assert.Equal(t, sshCred.Scope, getSSH.Scope, "Scope is not equal")
8893
assert.Equal(t, sshCred.ID, getSSH.ID, "ID is not equal")
8994
assert.Equal(t, sshCred.Username, getSSH.Username, "Username is not equal")
9095
assert.Equal(t, sshCred.Scope, getSSH.Scope, "Scope is not equal")
9196

92-
err = cm.Delete(domain, getSSH.ID)
97+
err = cm.Delete(ctx, domain, getSSH.ID)
9398
assert.Nil(t, err, "Could not delete credentials")
9499

95100
}
96101

97102
func TestMain(m *testing.M) {
98103
//setup
104+
ctx := context.Background()
99105
jenkins := CreateJenkins(nil, "http://localhost:8080", "admin", "admin")
100-
jenkins.Init()
106+
jenkins.Init(ctx)
101107

102108
cm = CredentialsManager{J: jenkins}
103109

‎fingerprint.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package gojenkins
1616

1717
import (
18+
"context"
1819
"errors"
1920
"fmt"
2021
)
@@ -45,8 +46,8 @@ type FingerPrintResponse struct {
4546
} `json:"usage"`
4647
}
4748

48-
func (f FingerPrint) Valid() (bool, error) {
49-
status, err := f.Poll()
49+
func (f FingerPrint) Valid(ctx context.Context) (bool, error) {
50+
status, err := f.Poll(ctx)
5051

5152
if err != nil {
5253
return false, err
@@ -58,8 +59,8 @@ func (f FingerPrint) Valid() (bool, error) {
5859
return true, nil
5960
}
6061

61-
func (f FingerPrint) ValidateForBuild(filename string, build *Build) (bool, error) {
62-
valid, err := f.Valid()
62+
func (f FingerPrint) ValidateForBuild(ctx context.Context, filename string, build *Build) (bool, error) {
63+
valid, err := f.Valid(ctx)
6364
if err != nil {
6465
return false, err
6566
}
@@ -78,16 +79,16 @@ func (f FingerPrint) ValidateForBuild(filename string, build *Build) (bool, erro
7879
return false, nil
7980
}
8081

81-
func (f FingerPrint) GetInfo() (*FingerPrintResponse, error) {
82-
_, err := f.Poll()
82+
func (f FingerPrint) GetInfo(ctx context.Context) (*FingerPrintResponse, error) {
83+
_, err := f.Poll(ctx)
8384
if err != nil {
8485
return nil, err
8586
}
8687
return f.Raw, nil
8788
}
8889

89-
func (f FingerPrint) Poll() (int, error) {
90-
response, err := f.Jenkins.Requester.GetJSON(f.Base+f.Id, f.Raw, nil)
90+
func (f FingerPrint) Poll(ctx context.Context) (int, error) {
91+
response, err := f.Jenkins.Requester.GetJSON(ctx, f.Base+f.Id, f.Raw, nil)
9192
if err != nil {
9293
return 0, err
9394
}

‎folder.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package gojenkins
1616

1717
import (
18+
"context"
1819
"errors"
1920
"strconv"
2021
"strings"
@@ -45,7 +46,7 @@ func (f *Folder) GetName() string {
4546
return f.Raw.Name
4647
}
4748

48-
func (f *Folder) Create(name string) (*Folder, error) {
49+
func (f *Folder) Create(ctx context.Context, name string) (*Folder, error) {
4950
mode := "com.cloudbees.hudson.plugins.folder.Folder"
5051
data := map[string]string{
5152
"name": name,
@@ -56,19 +57,19 @@ func (f *Folder) Create(name string) (*Folder, error) {
5657
"mode": mode,
5758
}),
5859
}
59-
r, err := f.Jenkins.Requester.Post(f.parentBase()+"/createItem", nil, f.Raw, data)
60+
r, err := f.Jenkins.Requester.Post(ctx, f.parentBase()+"/createItem", nil, f.Raw, data)
6061
if err != nil {
6162
return nil, err
6263
}
6364
if r.StatusCode == 200 {
64-
f.Poll()
65+
f.Poll(ctx)
6566
return f, nil
6667
}
6768
return nil, errors.New(strconv.Itoa(r.StatusCode))
6869
}
6970

70-
func (f *Folder) Poll() (int, error) {
71-
response, err := f.Jenkins.Requester.GetJSON(f.Base, f.Raw, nil)
71+
func (f *Folder) Poll(ctx context.Context) (int, error) {
72+
response, err := f.Jenkins.Requester.GetJSON(ctx, f.Base, f.Raw, nil)
7273
if err != nil {
7374
return 0, err
7475
}

‎go.sum

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
6+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
7+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
8+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
9+
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
10+
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
11+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
12+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
13+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
14+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
15+
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
16+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

‎jenkins.go

+78-77
Large diffs are not rendered by default.

‎jenkins_test.go

+71-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gojenkins
22

33
import (
4+
"context"
45
"io/ioutil"
56
"os"
67
"testing"
@@ -15,8 +16,9 @@ var (
1516
)
1617

1718
func TestInit(t *testing.T) {
19+
ctx := context.Background()
1820
jenkins = CreateJenkins(nil, "http://localhost:8080", "admin", "admin")
19-
_, err := jenkins.Init()
21+
_, err := jenkins.Init(ctx)
2022
assert.Nil(t, err, "Jenkins Initialization should not fail")
2123
}
2224

@@ -25,19 +27,19 @@ func TestCreateJobs(t *testing.T) {
2527
job2ID := "job2_test"
2628
job_data := getFileAsString("job.xml")
2729

28-
job1, err := jenkins.CreateJob(job_data, job1ID)
30+
ctx := context.Background()
31+
job1, err := jenkins.CreateJob(ctx, job_data, job1ID)
2932
assert.Nil(t, err)
3033
assert.NotNil(t, job1)
3134
assert.Equal(t, "Some Job Description", job1.GetDescription())
3235
assert.Equal(t, job1ID, job1.GetName())
3336

34-
job2, _ := jenkins.CreateJob(job_data, job2ID)
37+
job2, _ := jenkins.CreateJob(ctx, job_data, job2ID)
3538
assert.NotNil(t, job2)
3639
assert.Equal(t, "Some Job Description", job2.GetDescription())
3740
assert.Equal(t, job2ID, job2.GetName())
3841
}
3942

40-
4143
func TestCreateNodes(t *testing.T) {
4244

4345
id1 := "node1_test"
@@ -48,41 +50,46 @@ func TestCreateNodes(t *testing.T) {
4850
jnlp := map[string]string{"method": "JNLPLauncher"}
4951
//ssh := map[string]string{"method": "SSHLauncher"}
5052

51-
node1, _ := jenkins.CreateNode(id1, 1, "Node 1 Description", "/var/lib/jenkins", "", jnlp)
53+
ctx := context.Background()
54+
node1, _ := jenkins.CreateNode(ctx, id1, 1, "Node 1 Description", "/var/lib/jenkins", "", jnlp)
5255
assert.Equal(t, id1, node1.GetName())
5356

5457
//node2, _ := jenkins.CreateNode(id2, 1, "Node 2 Description", "/var/lib/jenkins", "jdk8 docker", ssh)
5558
//assert.Equal(t, id2, node2.GetName())
5659

57-
node3, _ := jenkins.CreateNode(id3, 1, "Node 3 Description", "/var/lib/jenkins", "jdk7")
60+
node3, _ := jenkins.CreateNode(ctx, id3, 1, "Node 3 Description", "/var/lib/jenkins", "jdk7")
5861
assert.Equal(t, id3, node3.GetName())
59-
node4, _ := jenkins.CreateNode(id4, 1, "Node 4 Description", "/var/lib/jenkins", "jdk7")
62+
node4, _ := jenkins.CreateNode(ctx, id4, 1, "Node 4 Description", "/var/lib/jenkins", "jdk7")
6063
assert.Equal(t, id4, node4.GetName())
6164
}
6265

6366
func TestDeleteNodes(t *testing.T) {
6467
id := "node4_test"
65-
node, _ := jenkins.DeleteNode(id)
68+
69+
ctx := context.Background()
70+
node, _ := jenkins.DeleteNode(ctx, id)
6671
assert.NotNil(t, node)
6772
}
6873

6974
func TestCreateBuilds(t *testing.T) {
70-
jobs, _ := jenkins.GetAllJobs()
75+
ctx := context.Background()
76+
jobs, _ := jenkins.GetAllJobs(ctx)
7177
for _, item := range jobs {
72-
queueID, _ = item.InvokeSimple(map[string]string{"params1": "param1"})
73-
item.Poll()
74-
isQueued, _ := item.IsQueued()
78+
queueID, _ = item.InvokeSimple(ctx, map[string]string{"params1": "param1"})
79+
item.Poll(ctx)
80+
isQueued, _ := item.IsQueued(ctx)
7581
assert.Equal(t, true, isQueued)
7682
time.Sleep(10 * time.Second)
77-
builds, _ := item.GetAllBuildIds()
83+
builds, _ := item.GetAllBuildIds(ctx)
7884

7985
assert.True(t, (len(builds) > 0))
8086

8187
}
8288
}
8389

8490
func TestGetQueueItem(t *testing.T) {
85-
task, err := jenkins.GetQueueItem(queueID)
91+
ctx := context.Background()
92+
task, err := jenkins.GetQueueItem(ctx, queueID)
8693
if err != nil {
8794
t.Fatal(err)
8895
}
@@ -101,13 +108,14 @@ func TestParseBuildHistory(t *testing.T) {
101108
}
102109

103110
func TestCreateViews(t *testing.T) {
104-
list_view, err := jenkins.CreateView("test_list_view", LIST_VIEW)
111+
ctx := context.Background()
112+
list_view, err := jenkins.CreateView(ctx, "test_list_view", LIST_VIEW)
105113
assert.Nil(t, err)
106114
assert.Equal(t, "test_list_view", list_view.GetName())
107115
assert.Equal(t, "", list_view.GetDescription())
108116
assert.Equal(t, 0, len(list_view.GetJobs()))
109117

110-
my_view, err := jenkins.CreateView("test_my_view", MY_VIEW)
118+
my_view, err := jenkins.CreateView(ctx, "test_my_view", MY_VIEW)
111119
assert.Nil(t, err)
112120
assert.Equal(t, "test_my_view", my_view.GetName())
113121
assert.Equal(t, "", my_view.GetDescription())
@@ -116,33 +124,37 @@ func TestCreateViews(t *testing.T) {
116124
}
117125

118126
func TestGetAllJobs(t *testing.T) {
119-
jobs, _ := jenkins.GetAllJobs()
127+
ctx := context.Background()
128+
jobs, _ := jenkins.GetAllJobs(ctx)
120129
assert.Equal(t, 2, len(jobs))
121130
assert.Equal(t, jobs[0].Raw.Color, "blue")
122131
}
123132

124133
func TestGetAllNodes(t *testing.T) {
125-
nodes, _ := jenkins.GetAllNodes()
134+
ctx := context.Background()
135+
nodes, _ := jenkins.GetAllNodes(ctx)
126136
assert.Equal(t, 3, len(nodes))
127137
assert.Equal(t, nodes[0].GetName(), "master")
128138
}
129139

130140
func TestGetAllBuilds(t *testing.T) {
131-
builds, _ := jenkins.GetAllBuildIds("Job1_test")
141+
ctx := context.Background()
142+
builds, _ := jenkins.GetAllBuildIds(ctx, "Job1_test")
132143
for _, b := range builds {
133-
build, _ := jenkins.GetBuild("Job1_test", b.Number)
144+
build, _ := jenkins.GetBuild(ctx, "Job1_test", b.Number)
134145
assert.Equal(t, "SUCCESS", build.GetResult())
135146
}
136147
assert.Equal(t, 1, len(builds))
137148
}
138149

139150
func TestGetLabel(t *testing.T) {
140-
label, err := jenkins.GetLabel("test_label")
151+
ctx := context.Background()
152+
label, err := jenkins.GetLabel(ctx, "test_label")
141153
assert.Nil(t, err)
142154
assert.Equal(t, label.GetName(), "test_label")
143155
assert.Equal(t, 0, len(label.GetNodes()))
144156

145-
label, err = jenkins.GetLabel("jdk7")
157+
label, err = jenkins.GetLabel(ctx, "jdk7")
146158
assert.Nil(t, err)
147159
assert.Equal(t, label.GetName(), "jdk7")
148160
assert.Equal(t, 1, len(label.GetNodes()))
@@ -162,115 +174,127 @@ func TestGetLabel(t *testing.T) {
162174
}
163175

164176
func TestBuildMethods(t *testing.T) {
165-
job, _ := jenkins.GetJob("Job1_test")
166-
build, _ := job.GetLastBuild()
177+
ctx := context.Background()
178+
job, _ := jenkins.GetJob(ctx, "Job1_test")
179+
build, _ := job.GetLastBuild(ctx)
167180
params := build.GetParameters()
168181
assert.Equal(t, "params1", params[0].Name)
169182
}
170183

171184
func TestGetSingleJob(t *testing.T) {
172-
job, _ := jenkins.GetJob("Job1_test")
173-
isRunning, _ := job.IsRunning()
174-
config, err := job.GetConfig()
185+
ctx := context.Background()
186+
job, _ := jenkins.GetJob(ctx, "Job1_test")
187+
isRunning, _ := job.IsRunning(ctx)
188+
config, err := job.GetConfig(ctx)
175189
assert.Nil(t, err)
176190
assert.Equal(t, false, isRunning)
177191
assert.Contains(t, config, "<project>")
178192
}
179193

180194
func TestEnableDisableJob(t *testing.T) {
181-
job, _ := jenkins.GetJob("Job1_test")
182-
result, _ := job.Disable()
195+
ctx := context.Background()
196+
job, _ := jenkins.GetJob(ctx, "Job1_test")
197+
result, _ := job.Disable(ctx)
183198
assert.Equal(t, true, result)
184-
result, _ = job.Enable()
199+
result, _ = job.Enable(ctx)
185200
assert.Equal(t, true, result)
186201
}
187202

188203
func TestCopyDeleteJob(t *testing.T) {
189-
job, _ := jenkins.GetJob("Job1_test")
190-
jobCopy, _ := job.Copy("Job1_test_copy")
204+
ctx := context.Background()
205+
job, _ := jenkins.GetJob(ctx, "Job1_test")
206+
jobCopy, _ := job.Copy(ctx, "Job1_test_copy")
191207
assert.Equal(t, jobCopy.GetName(), "Job1_test_copy")
192-
jobDelete, _ := job.Delete()
208+
jobDelete, _ := job.Delete(ctx)
193209
assert.Equal(t, true, jobDelete)
194210
}
195211

196212
func TestGetPlugins(t *testing.T) {
197-
plugins, _ := jenkins.GetPlugins(3)
213+
ctx := context.Background()
214+
plugins, _ := jenkins.GetPlugins(ctx, 3)
198215
assert.Equal(t, 10, plugins.Count())
199216
}
200217

201218
func TestGetViews(t *testing.T) {
202-
views, _ := jenkins.GetAllViews()
219+
ctx := context.Background()
220+
views, _ := jenkins.GetAllViews(ctx)
203221
assert.Equal(t, len(views), 3)
204222
assert.Equal(t, len(views[0].Raw.Jobs), 2)
205223
}
206224

207225
func TestGetSingleView(t *testing.T) {
208-
view, _ := jenkins.GetView("All")
209-
view2, _ := jenkins.GetView("test_list_view")
226+
ctx := context.Background()
227+
view, _ := jenkins.GetView(ctx, "All")
228+
view2, _ := jenkins.GetView(ctx, "test_list_view")
210229
assert.Equal(t, len(view.Raw.Jobs), 2)
211230
assert.Equal(t, len(view2.Raw.Jobs), 0)
212231
assert.Equal(t, view2.Raw.Name, "test_list_view")
213232
}
214233

215234
func TestCreateFolder(t *testing.T) {
235+
ctx := context.Background()
216236
folder1ID := "folder1_test"
217237
folder2ID := "folder2_test"
218238

219-
folder1, err := jenkins.CreateFolder(folder1ID)
239+
folder1, err := jenkins.CreateFolder(ctx, folder1ID)
220240
assert.Nil(t, err)
221241
assert.NotNil(t, folder1)
222242
assert.Equal(t, folder1ID, folder1.GetName())
223243

224-
folder2, err := jenkins.CreateFolder(folder2ID, folder1ID)
244+
folder2, err := jenkins.CreateFolder(ctx, folder2ID, folder1ID)
225245
assert.Nil(t, err)
226246
assert.NotNil(t, folder2)
227247
assert.Equal(t, folder2ID, folder2.GetName())
228248
}
229249

230250
func TestCreateJobInFolder(t *testing.T) {
251+
ctx := context.Background()
231252
jobName := "Job_test"
232253
job_data := getFileAsString("job.xml")
233254

234-
job1, err := jenkins.CreateJobInFolder(job_data, jobName, "folder1_test")
255+
job1, err := jenkins.CreateJobInFolder(ctx, job_data, jobName, "folder1_test")
235256
assert.Nil(t, err)
236257
assert.NotNil(t, job1)
237258
assert.Equal(t, "Some Job Description", job1.GetDescription())
238259
assert.Equal(t, jobName, job1.GetName())
239260

240-
job2, err := jenkins.CreateJobInFolder(job_data, jobName, "folder1_test", "folder2_test")
261+
job2, err := jenkins.CreateJobInFolder(ctx, job_data, jobName, "folder1_test", "folder2_test")
241262
assert.Nil(t, err)
242263
assert.NotNil(t, job2)
243264
assert.Equal(t, "Some Job Description", job2.GetDescription())
244265
assert.Equal(t, jobName, job2.GetName())
245266
}
246267

247268
func TestGetFolder(t *testing.T) {
269+
ctx := context.Background()
248270
folder1ID := "folder1_test"
249271
folder2ID := "folder2_test"
250272

251-
folder1, err := jenkins.GetFolder(folder1ID)
273+
folder1, err := jenkins.GetFolder(ctx, folder1ID)
252274
assert.Nil(t, err)
253275
assert.NotNil(t, folder1)
254276
assert.Equal(t, folder1ID, folder1.GetName())
255277

256-
folder2, err := jenkins.GetFolder(folder2ID, folder1ID)
278+
folder2, err := jenkins.GetFolder(ctx, folder2ID, folder1ID)
257279
assert.Nil(t, err)
258280
assert.NotNil(t, folder2)
259281
assert.Equal(t, folder2ID, folder2.GetName())
260282
}
261283
func TestInstallPlugin(t *testing.T) {
284+
ctx := context.Background()
262285

263-
err := jenkins.InstallPlugin("packer", "1.4")
286+
err := jenkins.InstallPlugin(ctx, "packer", "1.4")
264287

265288
assert.Nil(t, err, "Could not install plugin")
266289
}
267290

268291
func TestConcurrentRequests(t *testing.T) {
292+
ctx := context.Background()
269293
for i := 0; i <= 16; i++ {
270294
go func() {
271-
jenkins.GetAllJobs()
272-
jenkins.GetAllViews()
273-
jenkins.GetAllNodes()
295+
jenkins.GetAllJobs(ctx)
296+
jenkins.GetAllViews(ctx)
297+
jenkins.GetAllNodes(ctx)
274298
}()
275299
}
276300
}

‎job.go

+76-75
Large diffs are not rendered by default.

‎label.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package gojenkins
1616

17+
import "context"
18+
1719
type Label struct {
1820
Raw *LabelResponse
1921
Jenkins *Jenkins
@@ -53,8 +55,8 @@ func (l *Label) GetNodes() []LabelNode {
5355
return l.Raw.Nodes
5456
}
5557

56-
func (l *Label) Poll() (int, error) {
57-
response, err := l.Jenkins.Requester.GetJSON(l.Base, l.Raw, nil)
58+
func (l *Label) Poll(ctx context.Context) (int, error) {
59+
response, err := l.Jenkins.Requester.GetJSON(ctx, l.Base, l.Raw, nil)
5860
if err != nil {
5961
return 0, err
6062
}

‎node.go

+34-31
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414

1515
package gojenkins
1616

17-
import "errors"
17+
import (
18+
"context"
19+
"errors"
20+
)
1821

1922
// Nodes
2023

@@ -80,8 +83,8 @@ type NodeResponse struct {
8083
TemporarilyOffline bool `json:"temporarilyOffline"`
8184
}
8285

83-
func (n *Node) Info() (*NodeResponse, error) {
84-
_, err := n.Poll()
86+
func (n *Node) Info(ctx context.Context) (*NodeResponse, error) {
87+
_, err := n.Poll(ctx)
8588
if err != nil {
8689
return nil, err
8790
}
@@ -92,48 +95,48 @@ func (n *Node) GetName() string {
9295
return n.Raw.DisplayName
9396
}
9497

95-
func (n *Node) Delete() (bool, error) {
96-
resp, err := n.Jenkins.Requester.Post(n.Base+"/doDelete", nil, nil, nil)
98+
func (n *Node) Delete(ctx context.Context) (bool, error) {
99+
resp, err := n.Jenkins.Requester.Post(ctx, n.Base+"/doDelete", nil, nil, nil)
97100
if err != nil {
98101
return false, err
99102
}
100103
return resp.StatusCode == 200, nil
101104
}
102105

103-
func (n *Node) IsOnline() (bool, error) {
104-
_, err := n.Poll()
106+
func (n *Node) IsOnline(ctx context.Context) (bool, error) {
107+
_, err := n.Poll(ctx)
105108
if err != nil {
106109
return false, err
107110
}
108111
return !n.Raw.Offline, nil
109112
}
110113

111-
func (n *Node) IsTemporarilyOffline() (bool, error) {
112-
_, err := n.Poll()
114+
func (n *Node) IsTemporarilyOffline(ctx context.Context) (bool, error) {
115+
_, err := n.Poll(ctx)
113116
if err != nil {
114117
return false, err
115118
}
116119
return n.Raw.TemporarilyOffline, nil
117120
}
118121

119-
func (n *Node) IsIdle() (bool, error) {
120-
_, err := n.Poll()
122+
func (n *Node) IsIdle(ctx context.Context) (bool, error) {
123+
_, err := n.Poll(ctx)
121124
if err != nil {
122125
return false, err
123126
}
124127
return n.Raw.Idle, nil
125128
}
126129

127-
func (n *Node) IsJnlpAgent() (bool, error) {
128-
_, err := n.Poll()
130+
func (n *Node) IsJnlpAgent(ctx context.Context) (bool, error) {
131+
_, err := n.Poll(ctx)
129132
if err != nil {
130133
return false, err
131134
}
132135
return n.Raw.JnlpAgent, nil
133136
}
134137

135-
func (n *Node) SetOnline() (bool, error) {
136-
_, err := n.Poll()
138+
func (n *Node) SetOnline(ctx context.Context) (bool, error) {
139+
_, err := n.Poll(ctx)
137140

138141
if err != nil {
139142
return false, err
@@ -144,33 +147,33 @@ func (n *Node) SetOnline() (bool, error) {
144147
}
145148

146149
if n.Raw.Offline && n.Raw.TemporarilyOffline {
147-
return n.ToggleTemporarilyOffline()
150+
return n.ToggleTemporarilyOffline(ctx)
148151
}
149152

150153
return true, nil
151154
}
152155

153-
func (n *Node) SetOffline(options ...interface{}) (bool, error) {
156+
func (n *Node) SetOffline(ctx context.Context, options ...interface{}) (bool, error) {
154157
if !n.Raw.Offline {
155-
return n.ToggleTemporarilyOffline(options...)
158+
return n.ToggleTemporarilyOffline(ctx, options...)
156159
}
157160
return false, errors.New("Node already Offline")
158161
}
159162

160-
func (n *Node) ToggleTemporarilyOffline(options ...interface{}) (bool, error) {
161-
state_before, err := n.IsTemporarilyOffline()
163+
func (n *Node) ToggleTemporarilyOffline(ctx context.Context, options ...interface{}) (bool, error) {
164+
state_before, err := n.IsTemporarilyOffline(ctx)
162165
if err != nil {
163166
return false, err
164167
}
165168
qr := map[string]string{"offlineMessage": "requested from gojenkins"}
166169
if len(options) > 0 {
167170
qr["offlineMessage"] = options[0].(string)
168171
}
169-
_, err = n.Jenkins.Requester.Post(n.Base+"/toggleOffline", nil, nil, qr)
172+
_, err = n.Jenkins.Requester.Post(ctx, n.Base+"/toggleOffline", nil, nil, qr)
170173
if err != nil {
171174
return false, err
172175
}
173-
new_state, err := n.IsTemporarilyOffline()
176+
new_state, err := n.IsTemporarilyOffline(ctx)
174177
if err != nil {
175178
return false, err
176179
}
@@ -180,49 +183,49 @@ func (n *Node) ToggleTemporarilyOffline(options ...interface{}) (bool, error) {
180183
return true, nil
181184
}
182185

183-
func (n *Node) Poll() (int, error) {
184-
response, err := n.Jenkins.Requester.GetJSON(n.Base, n.Raw, nil)
186+
func (n *Node) Poll(ctx context.Context) (int, error) {
187+
response, err := n.Jenkins.Requester.GetJSON(ctx, n.Base, n.Raw, nil)
185188
if err != nil {
186189
return 0, err
187190
}
188191
return response.StatusCode, nil
189192
}
190193

191-
func (n *Node) LaunchNodeBySSH() (int, error) {
194+
func (n *Node) LaunchNodeBySSH(ctx context.Context) (int, error) {
192195
qr := map[string]string{
193196
"json": "",
194197
"Submit": "Launch slave agent",
195198
}
196-
response, err := n.Jenkins.Requester.Post(n.Base+"/launchSlaveAgent", nil, nil, qr)
199+
response, err := n.Jenkins.Requester.Post(ctx, n.Base+"/launchSlaveAgent", nil, nil, qr)
197200
if err != nil {
198201
return 0, err
199202
}
200203
return response.StatusCode, nil
201204
}
202205

203-
func (n *Node) Disconnect() (int, error) {
206+
func (n *Node) Disconnect(ctx context.Context) (int, error) {
204207
qr := map[string]string{
205208
"offlineMessage": "",
206209
"json": makeJson(map[string]string{"offlineMessage": ""}),
207210
"Submit": "Yes",
208211
}
209-
response, err := n.Jenkins.Requester.Post(n.Base+"/doDisconnect", nil, nil, qr)
212+
response, err := n.Jenkins.Requester.Post(ctx, n.Base+"/doDisconnect", nil, nil, qr)
210213
if err != nil {
211214
return 0, err
212215
}
213216
return response.StatusCode, nil
214217
}
215218

216-
func (n *Node) GetLogText() (string, error) {
219+
func (n *Node) GetLogText(ctx context.Context) (string, error) {
217220
var log string
218221

219-
_, err := n.Jenkins.Requester.Post(n.Base+"/log", nil, nil, nil)
222+
_, err := n.Jenkins.Requester.Post(ctx, n.Base+"/log", nil, nil, nil)
220223
if err != nil {
221224
return "", err
222225
}
223226

224227
qr := map[string]string{"start": "0"}
225-
_, err = n.Jenkins.Requester.GetJSON(n.Base+"/logText/progressiveHtml/", &log, qr)
228+
_, err = n.Jenkins.Requester.GetJSON(ctx, n.Base+"/logText/progressiveHtml/", &log, qr)
226229
if err != nil {
227230
return "", nil
228231
}

‎pipeline.go

+13-12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package gojenkins
1919

2020
import (
21+
"context"
2122
"fmt"
2223
"regexp"
2324
)
@@ -97,8 +98,8 @@ func (run *PipelineRun) update() {
9798
}
9899
}
99100

100-
func (job *Job) GetPipelineRuns() (pr []PipelineRun, err error) {
101-
_, err = job.Jenkins.Requester.GetJSON(job.Base+"/wfapi/runs", &pr, nil)
101+
func (job *Job) GetPipelineRuns(ctx context.Context) (pr []PipelineRun, err error) {
102+
_, err = job.Jenkins.Requester.GetJSON(ctx, job.Base+"/wfapi/runs", &pr, nil)
102103
if err != nil {
103104
return nil, err
104105
}
@@ -110,10 +111,10 @@ func (job *Job) GetPipelineRuns() (pr []PipelineRun, err error) {
110111
return pr, nil
111112
}
112113

113-
func (job *Job) GetPipelineRun(id string) (pr *PipelineRun, err error) {
114+
func (job *Job) GetPipelineRun(ctx context.Context, id string) (pr *PipelineRun, err error) {
114115
pr = new(PipelineRun)
115116
href := job.Base + "/" + id + "/wfapi/describe"
116-
_, err = job.Jenkins.Requester.GetJSON(href, pr, nil)
117+
_, err = job.Jenkins.Requester.GetJSON(ctx, href, pr, nil)
117118
if err != nil {
118119
return nil, err
119120
}
@@ -123,44 +124,44 @@ func (job *Job) GetPipelineRun(id string) (pr *PipelineRun, err error) {
123124
return pr, nil
124125
}
125126

126-
func (pr *PipelineRun) GetPendingInputActions() (PIAs []PipelineInputAction, err error) {
127+
func (pr *PipelineRun) GetPendingInputActions(ctx context.Context) (PIAs []PipelineInputAction, err error) {
127128
PIAs = make([]PipelineInputAction, 0, 1)
128129
href := pr.Base + "/wfapi/pendingInputActions"
129-
_, err = pr.Job.Jenkins.Requester.GetJSON(href, &PIAs, nil)
130+
_, err = pr.Job.Jenkins.Requester.GetJSON(ctx, href, &PIAs, nil)
130131
if err != nil {
131132
return nil, err
132133
}
133134

134135
return PIAs, nil
135136
}
136137

137-
func (pr *PipelineRun) GetArtifacts() (artifacts []PipelineArtifact, err error) {
138+
func (pr *PipelineRun) GetArtifacts(ctx context.Context) (artifacts []PipelineArtifact, err error) {
138139
artifacts = make([]PipelineArtifact, 0, 0)
139140
href := pr.Base + "/wfapi/artifacts"
140-
_, err = pr.Job.Jenkins.Requester.GetJSON(href, artifacts, nil)
141+
_, err = pr.Job.Jenkins.Requester.GetJSON(ctx, href, artifacts, nil)
141142
if err != nil {
142143
return nil, err
143144
}
144145

145146
return artifacts, nil
146147
}
147148

148-
func (pr *PipelineRun) GetNode(id string) (node *PipelineNode, err error) {
149+
func (pr *PipelineRun) GetNode(ctx context.Context, id string) (node *PipelineNode, err error) {
149150
node = new(PipelineNode)
150151
href := pr.Base + "/execution/node/" + id + "/wfapi/describe"
151-
_, err = pr.Job.Jenkins.Requester.GetJSON(href, node, nil)
152+
_, err = pr.Job.Jenkins.Requester.GetJSON(ctx, href, node, nil)
152153
if err != nil {
153154
return nil, err
154155
}
155156

156157
return node, nil
157158
}
158159

159-
func (node *PipelineNode) GetLog() (log *PipelineNodeLog, err error) {
160+
func (node *PipelineNode) GetLog(ctx context.Context) (log *PipelineNodeLog, err error) {
160161
log = new(PipelineNodeLog)
161162
href := node.Base + "/wfapi/log"
162163
fmt.Println(href)
163-
_, err = node.Run.Job.Jenkins.Requester.GetJSON(href, log, nil)
164+
_, err = node.Run.Job.Jenkins.Requester.GetJSON(ctx, href, log, nil)
164165
if err != nil {
165166
return nil, err
166167
}

‎plugin.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package gojenkins
1616

1717
import (
18+
"context"
1819
"strconv"
1920
)
2021

@@ -63,11 +64,11 @@ func (p *Plugins) Contains(name string) *Plugin {
6364
return nil
6465
}
6566

66-
func (p *Plugins) Poll() (int, error) {
67+
func (p *Plugins) Poll(ctx context.Context) (int, error) {
6768
qr := map[string]string{
6869
"depth": strconv.Itoa(p.Depth),
6970
}
70-
response, err := p.Jenkins.Requester.GetJSON(p.Base, p.Raw, qr)
71+
response, err := p.Jenkins.Requester.GetJSON(ctx, p.Base, p.Raw, qr)
7172
if err != nil {
7273
return 0, err
7374
}

‎queue.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package gojenkins
1616

1717
import (
18+
"context"
1819
"strconv"
1920
)
2021

@@ -90,24 +91,24 @@ func (q *Queue) GetTasksForJob(name string) []*Task {
9091
return tasks
9192
}
9293

93-
func (q *Queue) CancelTask(id int64) (bool, error) {
94+
func (q *Queue) CancelTask(ctx context.Context, id int64) (bool, error) {
9495
task := q.GetTaskById(id)
95-
return task.Cancel()
96+
return task.Cancel(ctx)
9697
}
9798

98-
func (t *Task) Cancel() (bool, error) {
99+
func (t *Task) Cancel(ctx context.Context) (bool, error) {
99100
qr := map[string]string{
100101
"id": strconv.FormatInt(t.Raw.ID, 10),
101102
}
102-
response, err := t.Jenkins.Requester.Post(t.Jenkins.GetQueueUrl()+"/cancelItem", nil, t.Raw, qr)
103+
response, err := t.Jenkins.Requester.Post(ctx, t.Jenkins.GetQueueUrl()+"/cancelItem", nil, t.Raw, qr)
103104
if err != nil {
104105
return false, err
105106
}
106107
return response.StatusCode == 200, nil
107108
}
108109

109-
func (t *Task) GetJob() (*Job, error) {
110-
return t.Jenkins.GetJob(t.Raw.Task.Name)
110+
func (t *Task) GetJob(ctx context.Context) (*Job, error) {
111+
return t.Jenkins.GetJob(ctx, t.Raw.Task.Name)
111112
}
112113

113114
func (t *Task) GetWhy() string {
@@ -132,16 +133,16 @@ func (t *Task) GetCauses() []map[string]interface{} {
132133
return nil
133134
}
134135

135-
func (q *Queue) Poll() (int, error) {
136-
response, err := q.Jenkins.Requester.GetJSON(q.Base, q.Raw, nil)
136+
func (q *Queue) Poll(ctx context.Context) (int, error) {
137+
response, err := q.Jenkins.Requester.GetJSON(ctx, q.Base, q.Raw, nil)
137138
if err != nil {
138139
return 0, err
139140
}
140141
return response.StatusCode, nil
141142
}
142143

143-
func (t *Task) Poll() (int, error) {
144-
response, err := t.Jenkins.Requester.GetJSON(t.Base, t.Raw, nil)
144+
func (t *Task) Poll(ctx context.Context) (int, error) {
145+
response, err := t.Jenkins.Requester.GetJSON(ctx, t.Base, t.Raw, nil)
145146
if err != nil {
146147
return 0, err
147148
}

‎request.go

+31-21
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ package gojenkins
1616

1717
import (
1818
"bytes"
19+
"context"
1920
"encoding/json"
2021
"errors"
2122
"fmt"
2223
"io"
2324
"io/ioutil"
25+
"log"
2426
"mime/multipart"
2527
"net/http"
28+
"net/http/httputil"
2629
"net/url"
2730
"os"
2831
"path/filepath"
@@ -59,9 +62,9 @@ type Requester struct {
5962
SslVerify bool
6063
}
6164

62-
func (r *Requester) SetCrumb(ar *APIRequest) error {
65+
func (r *Requester) SetCrumb(ctx context.Context, ar *APIRequest) error {
6366
crumbData := map[string]string{}
64-
response, _ := r.GetJSON("/crumbIssuer/api/json", &crumbData, nil)
67+
response, _ := r.GetJSON(ctx, "/crumbIssuer/api/json", &crumbData, nil)
6568

6669
if response.StatusCode == 200 && crumbData["crumbRequestField"] != "" {
6770
ar.SetHeader(crumbData["crumbRequestField"], crumbData["crumb"])
@@ -71,63 +74,63 @@ func (r *Requester) SetCrumb(ar *APIRequest) error {
7174
return nil
7275
}
7376

74-
func (r *Requester) PostJSON(endpoint string, payload io.Reader, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
77+
func (r *Requester) PostJSON(ctx context.Context, endpoint string, payload io.Reader, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
7578
ar := NewAPIRequest("POST", endpoint, payload)
76-
if err := r.SetCrumb(ar); err != nil {
79+
if err := r.SetCrumb(ctx, ar); err != nil {
7780
return nil, err
7881
}
7982
ar.SetHeader("Content-Type", "application/x-www-form-urlencoded")
8083
ar.Suffix = "api/json"
81-
return r.Do(ar, &responseStruct, querystring)
84+
return r.Do(ctx, ar, &responseStruct, querystring)
8285
}
8386

84-
func (r *Requester) Post(endpoint string, payload io.Reader, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
87+
func (r *Requester) Post(ctx context.Context, endpoint string, payload io.Reader, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
8588
ar := NewAPIRequest("POST", endpoint, payload)
86-
if err := r.SetCrumb(ar); err != nil {
89+
if err := r.SetCrumb(ctx, ar); err != nil {
8790
return nil, err
8891
}
8992
ar.SetHeader("Content-Type", "application/x-www-form-urlencoded")
9093
ar.Suffix = ""
91-
return r.Do(ar, &responseStruct, querystring)
94+
return r.Do(ctx, ar, &responseStruct, querystring)
9295
}
9396

94-
func (r *Requester) PostFiles(endpoint string, payload io.Reader, responseStruct interface{}, querystring map[string]string, files []string) (*http.Response, error) {
97+
func (r *Requester) PostFiles(ctx context.Context, endpoint string, payload io.Reader, responseStruct interface{}, querystring map[string]string, files []string) (*http.Response, error) {
9598
ar := NewAPIRequest("POST", endpoint, payload)
96-
if err := r.SetCrumb(ar); err != nil {
99+
if err := r.SetCrumb(ctx, ar); err != nil {
97100
return nil, err
98101
}
99-
return r.Do(ar, &responseStruct, querystring, files)
102+
return r.Do(ctx, ar, &responseStruct, querystring, files)
100103
}
101104

102-
func (r *Requester) PostXML(endpoint string, xml string, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
105+
func (r *Requester) PostXML(ctx context.Context, endpoint string, xml string, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
103106
payload := bytes.NewBuffer([]byte(xml))
104107
ar := NewAPIRequest("POST", endpoint, payload)
105-
if err := r.SetCrumb(ar); err != nil {
108+
if err := r.SetCrumb(ctx, ar); err != nil {
106109
return nil, err
107110
}
108111
ar.SetHeader("Content-Type", "application/xml")
109112
ar.Suffix = ""
110-
return r.Do(ar, &responseStruct, querystring)
113+
return r.Do(ctx, ar, &responseStruct, querystring)
111114
}
112115

113-
func (r *Requester) GetJSON(endpoint string, responseStruct interface{}, query map[string]string) (*http.Response, error) {
116+
func (r *Requester) GetJSON(ctx context.Context, endpoint string, responseStruct interface{}, query map[string]string) (*http.Response, error) {
114117
ar := NewAPIRequest("GET", endpoint, nil)
115118
ar.SetHeader("Content-Type", "application/json")
116119
ar.Suffix = "api/json"
117-
return r.Do(ar, &responseStruct, query)
120+
return r.Do(ctx, ar, &responseStruct, query)
118121
}
119122

120-
func (r *Requester) GetXML(endpoint string, responseStruct interface{}, query map[string]string) (*http.Response, error) {
123+
func (r *Requester) GetXML(ctx context.Context, endpoint string, responseStruct interface{}, query map[string]string) (*http.Response, error) {
121124
ar := NewAPIRequest("GET", endpoint, nil)
122125
ar.SetHeader("Content-Type", "application/xml")
123126
ar.Suffix = ""
124-
return r.Do(ar, responseStruct, query)
127+
return r.Do(ctx, ar, responseStruct, query)
125128
}
126129

127-
func (r *Requester) Get(endpoint string, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
130+
func (r *Requester) Get(ctx context.Context, endpoint string, responseStruct interface{}, querystring map[string]string) (*http.Response, error) {
128131
ar := NewAPIRequest("GET", endpoint, nil)
129132
ar.Suffix = ""
130-
return r.Do(ar, responseStruct, querystring)
133+
return r.Do(ctx, ar, responseStruct, querystring)
131134
}
132135

133136
func (r *Requester) SetClient(client *http.Client) *Requester {
@@ -143,7 +146,7 @@ func (r *Requester) redirectPolicyFunc(req *http.Request, via []*http.Request) e
143146
return nil
144147
}
145148

146-
func (r *Requester) Do(ar *APIRequest, responseStruct interface{}, options ...interface{}) (*http.Response, error) {
149+
func (r *Requester) Do(ctx context.Context, ar *APIRequest, responseStruct interface{}, options ...interface{}) (*http.Response, error) {
147150
if !strings.HasSuffix(ar.Endpoint, "/") && ar.Method != "POST" {
148151
ar.Endpoint += "/"
149152
}
@@ -227,6 +230,13 @@ func (r *Requester) Do(ar *APIRequest, responseStruct interface{}, options ...in
227230
if response, err := r.Client.Do(req); err != nil {
228231
return nil, err
229232
} else {
233+
if v := ctx.Value("debug"); v != nil {
234+
dump, err := httputil.DumpResponse(response, true)
235+
if err != nil {
236+
log.Fatal(err)
237+
}
238+
log.Printf("DEBUG %q\n", dump)
239+
}
230240
errorText := response.Header.Get("X-Error")
231241
if errorText != "" {
232242
return nil, errors.New(errorText)

‎views.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package gojenkins
1616

1717
import (
18+
"context"
1819
"errors"
1920
"strconv"
2021
)
@@ -42,10 +43,10 @@ var (
4243
)
4344

4445
// Returns True if successfully added Job, otherwise false
45-
func (v *View) AddJob(name string) (bool, error) {
46+
func (v *View) AddJob(ctx context.Context, name string) (bool, error) {
4647
url := "/addJobToView"
4748
qr := map[string]string{"name": name}
48-
resp, err := v.Jenkins.Requester.Post(v.Base+url, nil, nil, qr)
49+
resp, err := v.Jenkins.Requester.Post(ctx, v.Base+url, nil, nil, qr)
4950
if err != nil {
5051
return false, err
5152
}
@@ -56,10 +57,10 @@ func (v *View) AddJob(name string) (bool, error) {
5657
}
5758

5859
// Returns True if successfully deleted Job, otherwise false
59-
func (v *View) DeleteJob(name string) (bool, error) {
60+
func (v *View) DeleteJob(ctx context.Context, name string) (bool, error) {
6061
url := "/removeJobFromView"
6162
qr := map[string]string{"name": name}
62-
resp, err := v.Jenkins.Requester.Post(v.Base+url, nil, nil, qr)
63+
resp, err := v.Jenkins.Requester.Post(ctx, v.Base+url, nil, nil, qr)
6364
if err != nil {
6465
return false, err
6566
}
@@ -85,8 +86,8 @@ func (v *View) GetUrl() string {
8586
return v.Raw.URL
8687
}
8788

88-
func (v *View) Poll() (int, error) {
89-
response, err := v.Jenkins.Requester.GetJSON(v.Base, v.Raw, nil)
89+
func (v *View) Poll(ctx context.Context) (int, error) {
90+
response, err := v.Jenkins.Requester.GetJSON(ctx, v.Base, v.Raw, nil)
9091
if err != nil {
9192
return 0, err
9293
}

0 commit comments

Comments
 (0)
Please sign in to comment.