-
Notifications
You must be signed in to change notification settings - Fork 143
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Cache workspace blob on tf-controller filesystem
- block stream encryption + remove non-stream endpoint - Nothing uses the feature yet. ``` ❯ kubectl exec -it -n flux-system chart-tf-controller-648fbc54f8-7sprc -- ls -la /blob-cache/ total 12 drwxrwsrwx 2 root 1337 4096 Dec 19 15:29 . drwxr-xr-x 1 root root 4096 Dec 19 15:29 .. -rw-r--r-- 1 controll 1337 800 Dec 20 09:41 terraform-helloworld-tf-priv.tar.gz ❯ kubectl exec -it -n flux-system chart-tf-controller-648fbc54f8-7sprc -- hexdump -C /blob-cache/terraform-helloworld-tf-priv.tar.gz | head -n 3 00000000 1b 3f 00 8d 25 67 17 79 87 04 d7 b9 03 f2 6c ba |.?..%g.y......l.| 00000010 bc 0c 7e 75 29 de 25 1f bb 99 c4 49 2d 99 1b e0 |..~u).%....I-...| 00000020 b3 72 2f ca ab fb 5f 93 ee b4 ba bd a6 76 83 38 |.r/..._......v.8| ``` with a small go temp app, after decryption and untar (the repo itself has only one file: `main.tf`): ``` ❯ kubectl cp -n flux-system chart-tf-controller-648fbc54f8-7sprc:/blob-cache/terraform-helloworld-tf-priv.tar.gz ./terraform-helloworld-tf-priv.tar.gz tar: removing leading '/' from member names ❯ go run . INFO[0000] /tmp/1417200660 ❯ tree /tmp/1417200660 /tmp/1417200660 ├── backend_override.tf ├── generated.auto.tfvars.json └── main.tf 1 directory, 3 files ``` Extra To Do items: - Add feature flag Signed-off-by: Balazs Nadasdi <[email protected]> Signed-off-by: Victoria Nadasdi <[email protected]>
- Loading branch information
Showing
14 changed files
with
399 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package controllers | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"path" | ||
) | ||
|
||
type Filesystem interface { | ||
GetWriter(filePath string) (io.WriteCloser, error) | ||
GetReader(filePath string) (io.ReadCloser, error) | ||
} | ||
|
||
type LocalFilesystem struct { | ||
root string | ||
} | ||
|
||
func NewLocalFilesystem(root string) *LocalFilesystem { | ||
return &LocalFilesystem{root: root} | ||
} | ||
|
||
func (fs *LocalFilesystem) GetWriter(filePath string) (io.WriteCloser, error) { | ||
return os.Create(path.Join(fs.root, filePath)) | ||
} | ||
func (fs *LocalFilesystem) GetReader(filePath string) (io.ReadCloser, error) { | ||
return os.Open(path.Join(fs.root, filePath)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package controllers | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"crypto/sha256" | ||
"fmt" | ||
"io" | ||
|
||
infrav1 "github.com/weaveworks/tf-controller/api/v1alpha2" | ||
"github.com/weaveworks/tf-controller/runner" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
) | ||
|
||
// TODO: This path is hard-coded in the Deployment of the controller as mount | ||
// point. Why not /tmp? Good question, it's a ro mount so we can't write there. | ||
const cacheDir = "/blob-cache" | ||
|
||
func (r *TerraformReconciler) GetWorkspaceBlobCache(ctx context.Context, runnerClient runner.RunnerClient, terraform *infrav1.Terraform, tfInstance, workdir string) error { | ||
log := ctrl.LoggerFrom(ctx).WithValues("step", "get workspace blob cache") | ||
|
||
log.Info("request workspace blob from runner", "workdir", workdir, "tfInstance", tfInstance) | ||
streamClient, err := runnerClient.CreateWorkspaceBlobStream(ctx, &runner.CreateWorkspaceBlobRequest{ | ||
TfInstance: tfInstance, | ||
WorkingDir: workdir, | ||
Namespace: terraform.Namespace, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fs := NewLocalFilesystem(cacheDir) | ||
sha := sha256.New() | ||
checksum := []byte{} | ||
|
||
// TODO: This file pattern needs some love, it's there as a placeholder. | ||
// It would be beneficial if we can add the commit hash to the filename, but | ||
// then it would be problematic to retrieve when the source is not available, | ||
// and that's one of the reasons why we do this in the first place, so we can | ||
// get the cached content even if source is not available. | ||
// | ||
// NOTE: We can use commit hash from Source and if it's not available use from | ||
// lastAppliedRevision, lastAttemptedRevision, or lastPlannedRevision. | ||
file, err := fs.GetWriter(fmt.Sprintf("%s-%s.tar.gz", terraform.GetNamespace(), terraform.GetName())) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
|
||
for { | ||
chunk, err := streamClient.Recv() | ||
if err != nil { | ||
if err == io.EOF { | ||
if err := streamClient.CloseSend(); err != nil { | ||
log.Error(err, "unabel to close stream") | ||
break | ||
} | ||
} | ||
|
||
return err | ||
} | ||
|
||
if len(chunk.Blob) > 0 { | ||
if _, err := sha.Write(chunk.Blob); err != nil { | ||
return err | ||
} | ||
|
||
if _, err := file.Write(chunk.Blob); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if len(chunk.Sha256Checksum) > 0 { | ||
checksum = chunk.GetSha256Checksum() | ||
} | ||
} | ||
|
||
log.Info("calculating checksum") | ||
sum := sha.Sum(nil) | ||
|
||
if !bytes.Equal(sum, checksum) { | ||
return fmt.Errorf("invalid checksum, got: '%x'; expected: '%x'", sum, checksum) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.