-
Notifications
You must be signed in to change notification settings - Fork 929
do not merge: WIP provisionerd #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This modifies a prior migration which is typically forbidden, but because we're pre-production deployment I felt grouping would be helpful to future contributors. This adds database functions that are required for the provisioner daemon and job queue logic.
Adds a projectparameter package to compute build-time project values for a provided scope. This package will be used to return which variables are being used for a build, and can visually indicate the hierarchy to a user.
Provisionerd communicates with coderd over a multiplexed WebSocket serving dRPC. This adds a roughly accurate protocol definition. It shares definitions with "provisioner.proto" for simple interop with provisioners!
Creates the provisionerd service that interfaces with coderd to process provision jobs!
Codecov Report
@@ Coverage Diff @@
## main #84 +/- ##
==========================================
+ Coverage 72.06% 74.72% +2.66%
==========================================
Files 91 53 -38
Lines 3751 550 -3201
Branches 59 59
==========================================
- Hits 2703 411 -2292
+ Misses 829 127 -702
+ Partials 219 12 -207
Continue to review full report at Codecov.
|
codersdk/provisionerd.go
Outdated
} | ||
return nil, readBodyAsError(res) | ||
} | ||
session, err := yamux.Client(websocket.NetConn(context.Background(), conn, websocket.MessageBinary), nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, why is this using context.Background()
instead of ctx
?
coderd/coderd.go
Outdated
@@ -39,6 +42,7 @@ func New(options *Options) http.Handler { | |||
}) | |||
r.Post("/login", users.loginWithPassword) | |||
r.Post("/logout", users.logout) | |||
r.Get("/provisionerd", provisionerd.listen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At very first glance, I thought this was an endpoint the browser would listen to for updates over a socket - but after reading the PR, I realized this is for the provisionerd
process to establish a socket connection with coderd
.
It might be helpful to have a comment to this effect, like:
// Endpoint that facilitates connection with running `provisionerd` processes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we should change the endpoint? I genuinely wasn't sure what to call this!
provisionerd/provisionerd.go
Outdated
if a.isClosed() { | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why is this needed if we have this right below:
select {
case <-a.closed:
return
?
Is it for performance, or just to be explicit?
provisionerd/provisionerd.go
Outdated
func (a *API) acquireJob() { | ||
a.opts.Logger.Debug(context.Background(), "acquiring new job") | ||
var err error | ||
a.activeJobMutex.Lock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be using the
a.activeJobMutex.Lock()
defer a.activeJobMutex.Unlock()
pattern?
I see some cases below where we potentially modify activeJob
again, that isn't protected by the mutex - so I'd be worried about a potential race (like Line 147/148)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just we call into cancelActiveJob
later, which also acquires the mutex - go probably behaves like C, where it's an error to grab the mutex twice.
In that case - maybe we need to wrap Lines 147-150 in a mutex too?
coderd/provisionerd.go
Outdated
return nil, xerrors.Errorf("unmarshal job data: %w", err) | ||
} | ||
|
||
// Validate that all parameters send from the provisioner daemon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Validate that all parameters send from the provisioner daemon | |
// Validate that all parameters sent from the provisioner daemon |
codersdk/provisionerd.go
Outdated
// dRPC is a single-stream protocol by design. It's intended to operate | ||
// a single HTTP-request per invocation. This multiplexes the WebSocket | ||
// using yamux to enable multiple streams to function on a single connection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed comment; I wasn't sure why we were using yamux
and this helps answer it 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we're going to add this kind of multiplexing, why not use gRPC, which supports this kind of multiplexing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gRPC multiplexes with HTTP/2. So although it kinda supports multiplexing, we'd have to proxy an HTTP/2 server over this WebSocket. I also had difficulty finding examples of gRPC over a WebSocket.
A benefit of the dRPC library is the simple abstraction. We could easily split the requests out into separate connections if we needed.
Happy to elaborate further!
provisionerd/provisionerd.go
Outdated
|
||
switch jobType := a.activeJob.Type.(type) { | ||
case *proto.AcquiredJob_ProjectImport_: | ||
a.opts.Logger.Debug(context.Background(), "acquired job is project import", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the logging in this path
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exciting to see this all come together! Looks good to me, just some questions / thoughts
provisionerd/provisionerd_test.go
Outdated
projectHistory, err := client.CreateProjectHistory(context.Background(), user.Organization, project.Name, coderd.CreateProjectVersionRequest{ | ||
StorageMethod: database.ProjectStorageMethodInlineArchive, | ||
StorageSource: buffer.Bytes(), | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering how this flow will work on in the UI, to create new projects w/ the collateral necessary for the provisioner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test cases are helpful in understanding the API!
provisionerd/provisionerd_test.go
Outdated
err := terraform.Serve(ctx, &terraform.ServeOptions{ | ||
ServeOptions: &provisionersdk.ServeOptions{ | ||
Transport: serverPipe, | ||
}, | ||
}) | ||
require.NoError(t, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this test actually running against terraform?
provisionerd/provisionerd_test.go
Outdated
content := `resource "null_resource" "hi" {}` | ||
err := writer.WriteHeader(&tar.Header{ | ||
Name: "main.tf", | ||
Size: int64(len(content)), | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 😄
@bryphe-coder I shoulda made this a draft! I'm refactoring a ton of this code actively, so I'll have to tag you again. Most of the testing and logic was scaffold a few hours ago, but the entire system is pretty much hooked up. I'll need to add a few HTTP APIs, the workspace agent, and then I think we have the triangle! |
6440b6b
to
919572a
Compare
919572a
to
69003f4
Compare
69003f4
to
ab7fbec
Compare
48abd93
to
73bc4e6
Compare
Creates the provisionerd service that interfaces with
coderd to process provision jobs!