Skip to content

Commit f5bac79

Browse files
heschigopherbot
authored andcommitted
buildlet: create gRPC client
As a first step to port relui over to the gRPC API, create a gRPC client implementation. This should be suitable for use in the gomote command, but I don't want to conflict with the giant stack in flight. Also add a GRPCClient function to iapclient for convenience. The gomote service was missing working directory information; added it. I also did some refactoring/cleanup. - The Client interface is used internally to the coordinator, and as such it has a lot of internal functions. The set used by remote clients is much more reasonable. Separate it out into a new RemoteClient interface. - AddCloseFn was only used in one place. Delete it. - DestroyVM was completely unused. Delete it. For golang/go#54344. Change-Id: I77344a8c27076e53f565e9af56f8d365ac89b487 Reviewed-on: https://go-review.googlesource.com/c/build/+/422095 Auto-Submit: Heschi Kreinick <[email protected]> Reviewed-by: Carlos Amedee <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Heschi Kreinick <[email protected]>
1 parent d03101a commit f5bac79

File tree

19 files changed

+483
-294
lines changed

19 files changed

+483
-294
lines changed

buildlet/buildletclient.go

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import (
2020
"strings"
2121
"sync"
2222
"time"
23-
24-
"golang.org/x/oauth2"
2523
)
2624

2725
var _ Client = (*client)(nil)
@@ -646,51 +644,6 @@ func (c *client) RemoveAll(ctx context.Context, paths ...string) error {
646644
return c.doOK(req.WithContext(ctx))
647645
}
648646

649-
// DestroyVM shuts down the buildlet and destroys the VM instance.
650-
func (c *client) DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error {
651-
// TODO(bradfitz): move GCE stuff out of this package?
652-
gceErrc := make(chan error, 1)
653-
buildletErrc := make(chan error, 1)
654-
go func() {
655-
gceErrc <- DestroyVM(ts, proj, zone, instance)
656-
}()
657-
go func() {
658-
buildletErrc <- c.Close()
659-
}()
660-
timeout := time.NewTimer(5 * time.Second)
661-
defer timeout.Stop()
662-
663-
var retErr error
664-
var gceDone, buildletDone bool
665-
for !gceDone || !buildletDone {
666-
select {
667-
case err := <-gceErrc:
668-
if err != nil {
669-
retErr = err
670-
}
671-
gceDone = true
672-
case err := <-buildletErrc:
673-
if err != nil {
674-
retErr = err
675-
}
676-
buildletDone = true
677-
case <-timeout.C:
678-
e := ""
679-
if !buildletDone {
680-
e = "timeout asking buildlet to shut down"
681-
}
682-
if !gceDone {
683-
if e != "" {
684-
e += " and "
685-
}
686-
e += "timeout asking GCE to delete builder VM"
687-
}
688-
return errors.New(e)
689-
}
690-
}
691-
return retErr
692-
}
693-
694647
// Status provides status information about the buildlet.
695648
//
696649
// A coordinator can use the provided information to decide what, if anything,
@@ -907,11 +860,6 @@ func (c *client) ConnectSSH(user, authorizedPubKey string) (net.Conn, error) {
907860
return conn, nil
908861
}
909862

910-
// AddCloseFunc adds an optional extra code to run on close.
911-
func (c *client) AddCloseFunc(fn func()) {
912-
c.closeFuncs = append(c.closeFuncs, fn)
913-
}
914-
915863
func condRun(fn func()) {
916864
if fn != nil {
917865
fn()

buildlet/fakebuildletclient.go

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,37 @@ import (
1313
"net/http"
1414
"os"
1515
"strings"
16-
17-
"golang.org/x/oauth2"
1816
)
1917

18+
// RemoteClient is a subset of methods that can be used by a gomote client.
19+
type RemoteClient interface {
20+
Close() error
21+
Exec(ctx context.Context, cmd string, opts ExecOpts) (remoteErr, execErr error)
22+
GetTar(ctx context.Context, dir string) (io.ReadCloser, error)
23+
ListDir(ctx context.Context, dir string, opts ListDirOpts, fn func(DirEntry)) error
24+
Put(ctx context.Context, r io.Reader, path string, mode os.FileMode) error
25+
PutTar(ctx context.Context, r io.Reader, dir string) error
26+
PutTarFromURL(ctx context.Context, tarURL, dir string) error
27+
ProxyTCP(port int) (io.ReadWriteCloser, error)
28+
RemoteName() string
29+
RemoveAll(ctx context.Context, paths ...string) error
30+
WorkDir(ctx context.Context) (string, error)
31+
}
32+
2033
// Client is an interface that represent the methods exposed by client. The
2134
// fake buildlet client should be used instead of client when testing things that
2235
// use the client interface.
36+
// This includes a number of coordinator-internal details; users outside the
37+
// coordinator should use RemoteClient.
2338
type Client interface {
24-
AddCloseFunc(fn func())
25-
Close() error
39+
RemoteClient
2640
ConnectSSH(user, authorizedPubKey string) (net.Conn, error)
27-
DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error
28-
Exec(ctx context.Context, cmd string, opts ExecOpts) (remoteErr, execErr error)
2941
GCEInstanceName() string
30-
GetTar(ctx context.Context, dir string) (io.ReadCloser, error)
3142
IPPort() string
3243
IsBroken() bool
33-
ListDir(ctx context.Context, dir string, opts ListDirOpts, fn func(DirEntry)) error
3444
MarkBroken()
3545
Name() string
3646
ProxyRoundTripper() http.RoundTripper
37-
ProxyTCP(port int) (io.ReadWriteCloser, error)
38-
Put(ctx context.Context, r io.Reader, path string, mode os.FileMode) error
39-
PutTar(ctx context.Context, r io.Reader, dir string) error
40-
PutTarFromURL(ctx context.Context, tarURL, dir string) error
41-
RemoteName() string
42-
RemoveAll(ctx context.Context, paths ...string) error
4347
SetDescription(v string)
4448
SetDialer(dialer func(context.Context) (net.Conn, error))
4549
SetGCEInstanceName(v string)
@@ -49,7 +53,6 @@ type Client interface {
4953
Status(ctx context.Context) (Status, error)
5054
String() string
5155
URL() string
52-
WorkDir(ctx context.Context) (string, error)
5356
}
5457

5558
var errUnimplemented = errors.New("unimplemented function")
@@ -63,11 +66,6 @@ type FakeClient struct {
6366
name string
6467
}
6568

66-
// AddCloseFunc adds optional extra code to run on close for the fake buildlet.
67-
func (fc *FakeClient) AddCloseFunc(fn func()) {
68-
fc.closeFuncs = append(fc.closeFuncs, fn)
69-
}
70-
7169
// Close is a fake client closer.
7270
func (fc *FakeClient) Close() error {
7371
for _, f := range fc.closeFuncs {
@@ -81,11 +79,6 @@ func (fc *FakeClient) ConnectSSH(user, authorizedPubKey string) (net.Conn, error
8179
return nil, errUnimplemented
8280
}
8381

84-
// DestroyVM destroys a fake VM.
85-
func (fc *FakeClient) DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error {
86-
return errUnimplemented
87-
}
88-
8982
// Exec fakes the execution.
9083
func (fc *FakeClient) Exec(ctx context.Context, cmd string, opts ExecOpts) (remoteErr, execErr error) {
9184
if cmd == "" {
@@ -121,7 +114,7 @@ func (fc *FakeClient) IsBroken() bool { return false }
121114
// ListDir lists a directory on a fake buildlet.
122115
func (fc *FakeClient) ListDir(ctx context.Context, dir string, opts ListDirOpts, fn func(DirEntry)) error {
123116
if dir == "" || fn == nil {
124-
errors.New("invalid arguments")
117+
return errors.New("invalid arguments")
125118
}
126119
var lsOutput = `drwxr-xr-x gocache/
127120
drwxr-xr-x tmp/`
@@ -148,7 +141,7 @@ func (fc *FakeClient) ProxyTCP(port int) (io.ReadWriteCloser, error) { return ni
148141
func (fc *FakeClient) Put(ctx context.Context, r io.Reader, path string, mode os.FileMode) error {
149142
// TODO(go.dev/issue/48742) add a file system implementation which would enable proper testing.
150143
if path == "" {
151-
errors.New("invalid argument")
144+
return errors.New("invalid argument")
152145
}
153146
return nil
154147
}
@@ -199,7 +192,9 @@ func (fc *FakeClient) String() string { return "" }
199192
func (fc *FakeClient) URL() string { return "" }
200193

201194
// WorkDir is the working directory for the fake buildlet.
202-
func (fc *FakeClient) WorkDir(ctx context.Context) (string, error) { return "", errUnimplemented }
195+
func (fc *FakeClient) WorkDir(ctx context.Context) (string, error) {
196+
return "/work", nil
197+
}
203198

204199
// RemoveAll deletes the provided paths, relative to the work directory for a fake buildlet.
205200
func (fc *FakeClient) RemoveAll(ctx context.Context, paths ...string) error {

buildlet/gce.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -259,26 +259,37 @@ OpLoop:
259259
if opts.OnGotInstanceInfo != nil {
260260
opts.OnGotInstanceInfo(inst)
261261
}
262-
var closeFuncs []func()
262+
var closeFunc func()
263263
if opts.UseIAPTunnel {
264-
localPort, closeFunc, err := createIAPTunnel(ctx, inst)
264+
var localPort string
265+
var err error
266+
localPort, closeFunc, err = createIAPTunnel(ctx, inst)
265267
if err != nil {
266268
return nil, fmt.Errorf("creating IAP tunnel: %v", err)
267269
}
268270
buildletURL = "http://localhost:" + localPort
269271
ipPort = "127.0.0.1:" + localPort
270-
closeFuncs = append(closeFuncs, closeFunc)
271272
}
272273
client, err := buildletClient(ctx, buildletURL, ipPort, &opts)
273274
if err != nil {
274275
return nil, err
275276
}
276-
for _, cf := range closeFuncs {
277-
client.AddCloseFunc(cf)
277+
if closeFunc != nil {
278+
return &extraCloseClient{client, closeFunc}, nil
278279
}
279280
return client, nil
280281
}
281282

283+
type extraCloseClient struct {
284+
Client
285+
close func()
286+
}
287+
288+
func (e *extraCloseClient) Close() error {
289+
defer e.close()
290+
return e.Close()
291+
}
292+
282293
func createIAPTunnel(ctx context.Context, inst *compute.Instance) (string, func(), error) {
283294
// Allocate a local listening port.
284295
ln, err := net.Listen("tcp", "localhost:0")
@@ -350,16 +361,6 @@ func createIAPTunnel(ctx context.Context, inst *compute.Instance) (string, func(
350361
return "", nil, fmt.Errorf("iap tunnel startup timed out")
351362
}
352363

353-
// DestroyVM sends a request to delete a VM. Actual VM description is
354-
// currently (2015-01-19) very slow for no good reason. This function
355-
// returns once it's been requested, not when it's done.
356-
func DestroyVM(ts oauth2.TokenSource, proj, zone, instance string) error {
357-
computeService, _ := compute.New(oauth2.NewClient(context.TODO(), ts))
358-
apiGate()
359-
_, err := computeService.Instances.Delete(proj, zone, instance).Do()
360-
return err
361-
}
362-
363364
type VM struct {
364365
// Name is the name of the GCE VM instance.
365366
// For example, it's of the form "mote-bradfitz-plan9-386-foo",

0 commit comments

Comments
 (0)