internal: Refactor immutable folder upload as an internal resource in direct engine - #6084
internal: Refactor immutable folder upload as an internal resource in direct engine#6084andrewnester wants to merge 36 commits into
Conversation
Approval status: pending
|
Integration test reportCommit: b60469f
6 interesting tests: 4 SKIP, 1 RECOVERED, 1 flaky
Top 8 slowest tests (at least 2 minutes):
|
| "deployments": [ | ||
| { | ||
| "command_path": "${workspace.snapshot_path}/files/src/main.py", | ||
| "command_path": "${internal.snapshot.full_path}/files/src/main.py", |
There was a problem hiding this comment.
Instead of custom path, can we keep using ${workspace.file_path}, just make it an alias internally to internal resource's snapshot path.
That way:
- users know what this means
- users can use the variable themselves and it'll work both in regular and immutable case.
There was a problem hiding this comment.
${workspace.file_path} is ${internal.snapshot.full_path}/files and because we resolve the variables ${workspace.file_path} resolved to this pass. I'd prefer not to change the way variable reslution works and introduce some custom aliases
| @@ -35,12 +36,15 @@ type ACLEntry struct { | |||
| // the same workspace location. | |||
| // This interface exists so the implementation can later be replaced with a Go SDK call. | |||
There was a problem hiding this comment.
This does not explain why we need the interface - do we plan on supporting multiple implementation at the same time?
There was a problem hiding this comment.
Strictly speaking we don't need it for SDK replacement later but we need this now in unit tests to replace the uploader with mock one
| All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/recreate-gone-genie-space-[UNIQUE_NAME]/default | ||
|
|
||
| Destroy: 1 deleted | ||
| Destroy: 0 deleted |
There was a problem hiding this comment.
There was a problem hiding this comment.
Could have been a separate PR if unrelated to this work.
| All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default | ||
|
|
||
| Destroy: 1 deleted | ||
| Destroy: 0 deleted |
There was a problem hiding this comment.
| All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/test-bundle/default | ||
|
|
||
| Destroy: 1 deleted | ||
| Destroy: 0 deleted |
There was a problem hiding this comment.
| // references resolved against the current bundle state. This is needed for immutable | ||
| // folder bundles where source_code_path contains a reference to the snapshot's | ||
| // full_path, which is only known after deploy. | ||
| func (a *appRunner) resolvedSourceCodePath() (string, error) { |
There was a problem hiding this comment.
This routine is a point solution for getting the fully resolved deployment state.
It feels like this belongs on a generic function that returns the state. Then the source_code_path will be pre-resolved and we don't need the check above at all; the path is usable as is.
| tag := resources.Type().Field(i).Tag.Get("bundle") | ||
| if tag == "internal" { | ||
| continue | ||
| } |
There was a problem hiding this comment.
The comment should explain why this is ignoring internal resources (I can't tell why).
| // mutators need informed consent if they are potentially destructive. | ||
| bundle.ApplySeqContext(ctx, b, | ||
| bundle.ApplySeqContext( | ||
| ctx, b, |
There was a problem hiding this comment.
This and the above diffs are nops.
| uploadPath := path.Join(b.Config.Workspace.ArtifactPath, InternalDirName) | ||
| uploadPath = ensureWorkspaceOrVolumesPrefix(uploadPath) | ||
| if b.IsImmutableFolder() { | ||
| uploadPath = path.Join("${resources.internal_immutable_snapshots.immutable.full_path}", "artifacts", InternalDirName) |
There was a problem hiding this comment.
The static variable ref should be a const.
| if targetPath == "workspace.snapshot_path" { | ||
| if targetNode == "" { | ||
| continue | ||
| } |
There was a problem hiding this comment.
Is this empty check still needed?
| // Skip fields configured in ignore_remote_changes. | ||
| if ignoreFilter.shouldIgnore(path.String()) { | ||
| return | ||
| } |
There was a problem hiding this comment.
Why was the move needed? Wondering if there is anything structural missing that makes the above code not work without the ignore check.
| Secrets map[string]*resources.Secret `json:"secrets,omitempty"` | ||
|
|
||
| // Internal resources | ||
| Snapshots map[string]*resources.Snapshot `json:"internal_immutable_snapshots,omitempty" bundle:"internal"` |
There was a problem hiding this comment.
WDYT about prefixing this with a _ to make it clearer it is internal just by looking at the state.
| All files and directories at the following location will be deleted: /Workspace/Users/[USERNAME]/.bundle/recreate-gone-genie-space-[UNIQUE_NAME]/default | ||
|
|
||
| Destroy: 1 deleted | ||
| Destroy: 0 deleted |
There was a problem hiding this comment.
Could have been a separate PR if unrelated to this work.
|
|
||
| >>> [CLI] bundle deploy | ||
| Uploading immutable bundle snapshot... | ||
| Created internal_immutable_snapshots.immutable |
There was a problem hiding this comment.
This should show up differently in the deploy output.
| artifactPath = ensureWorkspaceOrVolumesPrefix(artifactPath) | ||
| if b.IsImmutableFolder() { | ||
| artifactPath = path.Join("${resources.internal_immutable_snapshots.immutable.full_path}", "artifacts") | ||
| } |
There was a problem hiding this comment.
Cleanup is not done for immutable folders.
Separate note: should we write back the above artifactPath to workspace.artifact_path?
This is done already as a default in bundle/config/mutator/default_workspace_paths.go.
| // Reads (dynamic): resources.internal_immutable_snapshots (and other internal keys) | ||
| // Warns and removes any internal resource fields set by the user. | ||
| mutator.RejectInternalResources(), | ||
|
|
There was a problem hiding this comment.
Nit: not a dynamic but a typed read.
| // into the in-memory state cache entry for the snapshot resource. This is needed when | ||
| // deploying from a plan file: the plan JSON omits ZipContent (json:"-"), so InitForApply | ||
| // leaves it empty, causing DoCreate to upload an empty zip and derive a wrong snapshot ID. | ||
| func SyncZipContent(b *bundle.Bundle) { |
There was a problem hiding this comment.
Shouldn't this return an error on the !ok cases below?
|
|
||
| func (s *ResourceSnapshot) DoDelete(ctx context.Context, id string, state *SnapshotState) error { | ||
| return nil | ||
| } |
There was a problem hiding this comment.
I believe the adapter can deal with methods that don't apply being unspecified.
| type SnapshotState struct { | ||
| RemoteRoot string `json:"remote_root"` | ||
| RelativePath string `json:"relative_path"` | ||
| FullPath string `json:"full_path"` |
There was a problem hiding this comment.
Are RelativePath and FullPath refer to remote location? Why don't they have Remote prefix like RemoteRoot?
Can you add comments and example values for these fields? It feels like there is some redundancy between RemoteRoot, RelativePath, FullPath but I cannot tell for sure because I don't know what these mean exactly.
Changes
Refactor immutable folder upload as an internal resource in direct engine
Why
This enables us:
${internal.snapshot.full_path}and it's automatically resolved during deployTests
Existing tests pass