chore!: send modules archive over the proto messages#21398
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
3a1cf4a to
f68e058
Compare
301568a to
dea6d25
Compare
d7c2bf0 to
add8b5a
Compare
d35a9f1 to
eae738d
Compare
fe1156c to
408096b
Compare
eae738d to
b180036
Compare
b180036 to
f65837d
Compare
f65837d to
b54a67a
Compare
5d2e3d6 to
a3c50b5
Compare
b54a67a to
9ea352f
Compare
a3c50b5 to
1d3e35e
Compare
9ea352f to
035f01e
Compare
1d3e35e to
83c73d9
Compare
7529e06 to
8e1a315
Compare
83c73d9 to
6e60c5f
Compare
8e1a315 to
5e7de71
Compare
ecac30d to
2df9ca9
Compare
f708df5 to
8af46fb
Compare
9344fd5 to
dc40539
Compare
259ab00 to
19a5a3b
Compare
dc40539 to
16d9aac
Compare
c2c8425 to
5b0df75
Compare
1aaa81b to
715e5a1
Compare
5b0df75 to
ecf4457
Compare
johnstcn
left a comment
There was a problem hiding this comment.
This does make template versions lock a specific set of module versions. Which is a behavior change for the better.
So if I understand correctly, this means that a template version that references one or more modules will always refer to the same versions of those modules that were resolved at template import time? This seems like a pretty big behavioural change that merits being called out in the release notes.
| // This check is not perfect. If these conditions are not true, then the file is not a modules file. | ||
| if file.CreatedBy != uuid.Nil || file.Mimetype != tarMimeType { | ||
| return fail(xerrors.Errorf("file %s is not a modules file", fid)) | ||
| } |
There was a problem hiding this comment.
Is there a particular set of files for which we could check the presence that would indicate that it is, in fact, a modules archive?
There was a problem hiding this comment.
Yes, but that would require reading over the archive, which is however large. I do not think it's worth it.
Ideally maybe we could have some mimetype for our archives that indicate what kind of archive it is?
We could maybe do like application/x-tar;coder_type=modules or something?
There was a problem hiding this comment.
Oh nice; I forgot about the parameter values you could stuff into mimetypes. That could work nicely.
There was a problem hiding this comment.
If I do that, then it would not be backwards compatible. So all previous templates would not use this, since the mime types would be wrong
There was a problem hiding this comment.
We also do not parse mime types right now, we just do direct string comparisons:
Lines 306 to 316 in e54f92b
I do think it is a good idea, I just think we need to fix mime type handling in our codebase
There was a problem hiding this comment.
That's fair, would be a good follow-up for later.
|
|
||
| var cachedModulesTar []byte | ||
| // Download modules if cached in coderd | ||
| if r.job.GetWorkspaceBuild().Metadata.TemplateVersionModulesFile != "" { |
There was a problem hiding this comment.
(Not necessary in this PR, potential followup) I'm nervous about this unconditional calling of r.job.GetWorkspaceBuild() that potentially returns nil. Can we add a top-level check e.g.
jobWorkspaceBuild := r.job.GetWorkspaceBuild()
if jobWorkspaceBuild == nil {
// whoopsiedoodle
}
There was a problem hiding this comment.
That is a good point. Protobuf handling these union types is unfortunate.
715e5a1 to
e54f92b
Compare
ecf4457 to
9f5aab4
Compare
I will mark this a breaking change and mention that 👍. You do understand correctly. This is a positive change, because without this, a template can break from module changes. |
| versionModulesFile := "" | ||
| tfvals, err := s.Database.GetTemplateVersionTerraformValues(ctx, templateVersion.ID) | ||
| if err != nil && !xerrors.Is(err, sql.ErrNoRows) { | ||
| // Older templates (before dynamic parameters) will not have cached module files. |
There was a problem hiding this comment.
There shouldn't be any left though, right?
There was a problem hiding this comment.
There are old template versions. They will be around forever.
Experiment is no longer required, the new method will be released without an experiment and without a toggle Main PR is: #21398
**This is just the protobuf changes for the PR #21398 Moved `UploadFileRequest` from `provisionerd.proto` -> `provisioner.proto`. Renamed to `FileUpload` because it is now bi-directional. This **is backwards compatible**. I tested it to confirm the payloads are identical. Types were just renamed and moved around. ```golang func TestTypeUpgrade(t *testing.T) { t.Parallel() x := &proto2.UploadFileRequest{ Type: &proto2.UploadFileRequest_ChunkPiece{ ChunkPiece: &proto.ChunkPiece{ Data: []byte("Hello World!"), FullDataHash: []byte("Foobar"), PieceIndex: 42, }, }, } data, err := protobuf.Marshal(x) require.NoError(t, err) // Exactly the same output // EhgKDEhlbGxvIFdvcmxkIRIGRm9vYmFyGCo= on `main` // EhgKDEhlbGxvIFdvcmxkIRIGRm9vYmFyGCo= on this branch fmt.Println(base64.StdEncoding.EncodeToString(data)) } ``` # What this does This allows provisioner daemons to download files from `coderd`'s `files` table. This is used to send over cached module files and prevent the need of downloading these modules on each workspace build.
Serializing modules to disk prevents an external download
e54f92b to
ced4ebd
Compare

What this does
Dynamic parameters caches the
./terraform/modulesdirectory for parameter usage. What this PR does is send over this archive to the provisioner when building workspaces.This allow terraform to skip downloading modules from their registries, a step that takes seconds.
Wire protocol
The wire protocol reuses the same mechanism used to download the modules
provisoner -> coder. It splits up large archives into multiple protobuf messages so larger archives can be sent under the message size limit.🚨 Behavior Change (Breaking Change) 🚨
Before this PR modules were downloaded on every workspace build. This means unpinned modules always fetched the latest version
After this PR modules are cached at template import time, and their versions are effectively pinned for all subsequent workspace builds.