Skip to content

Commit c8d3ab8

Browse files
Crash--claude
andcommitted
fix(appfs): move install marker to a distinct key in S3
s3Copier wrote a zero-byte "installation complete" marker at the same key the version's files live under (slug/version), with file contents stored at slug/version/<name>. S3 browsers render that as a folder and a file with the same name sitting side by side, which is misleading when admins inspect the bucket. Move the marker to <appObj>.cozy-installed so it sits on its own distinct key while keeping the file layout unchanged. Backward compat note: apps installed under the previous marker key will be re-copied on first access (Exist returns false for the new key → Start triggers a fresh install). This is a no-op cost for fresh deployments; for existing s3-test installations the app payload gets re-uploaded once. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 503e7dc commit c8d3ab8

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

pkg/appfs/s3.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ import (
2323
"github.com/minio/minio-go/v7"
2424
)
2525

26+
// installedMarkerSuffix is appended to the app's base key to form the
27+
// "installation complete" marker object. The suffix is chosen so the marker
28+
// can't collide with any file under <slug>/<version>/... — S3 browsers
29+
// would otherwise display the marker as a file sitting next to a folder of
30+
// the same name.
31+
const installedMarkerSuffix = ".cozy-installed"
32+
2633
// s3Copier implements the Copier interface backed by S3.
2734
type s3Copier struct {
2835
client *minio.Client
@@ -47,7 +54,7 @@ func (f *s3Copier) Exist(slug, version, shasum string) (bool, error) {
4754
if shasum != "" {
4855
f.appObj += "-" + shasum
4956
}
50-
_, err := f.client.StatObject(f.ctx, f.bucket, f.appObj, minio.StatObjectOptions{})
57+
_, err := f.client.StatObject(f.ctx, f.bucket, f.appObj+installedMarkerSuffix, minio.StatObjectOptions{})
5158
if err == nil {
5259
return true, nil
5360
}
@@ -120,8 +127,10 @@ func (f *s3Copier) Abort() error {
120127
}
121128

122129
func (f *s3Copier) Commit() (err error) {
123-
// Create the marker object that signals the version is complete.
124-
_, err = f.client.PutObject(f.ctx, f.bucket, f.appObj,
130+
// Create the marker object that signals the version is complete. The
131+
// suffix keeps it on a distinct key from the <slug>/<version>/... files,
132+
// so S3 browsers don't render a folder and a file with the same name.
133+
_, err = f.client.PutObject(f.ctx, f.bucket, f.appObj+installedMarkerSuffix,
125134
bytes.NewReader(nil), 0, minio.PutObjectOptions{
126135
ContentType: "text/plain",
127136
})

0 commit comments

Comments
 (0)