fix(sidecarassets): publish the extracted jar through a rename

Extract wrote a 96 MB jar with a plain WriteFile into a temp path every
sanderling process on the host shares. On a cold host several concurrent
workers all miss the checksum and all write the same path, and O_TRUNC lets one
spawn a JVM against another's half-written archive. A fresh experiment host is
exactly a cold host.

Claude-Session: https://claude.ai/code/session_01A5KmftdEJ49A9z5mF5ESrX
This commit is contained in:
pj committed 2026-08-12 21:38:09 +05:30
1 parent 557bd9d815
commit 808d607eac
2 files changed
+102 -2

No files matched your search

+26 -2
View File
@@ -39,11 +39,35 @@ func Extract(dir string) (string, error) {
}
}
if err := os.WriteFile(jarPath, embeddedJAR, 0o644); err != nil {
if err := writeAtomic(jarPath, embeddedJAR); err != nil {
return "", fmt.Errorf("write %s: %w", jarPath, err)
}
if err := os.WriteFile(checksumPath, []byte(checksum), 0o644); err != nil {
if err := writeAtomic(checksumPath, []byte(checksum)); err != nil {
return "", fmt.Errorf("write checksum: %w", err)
}
return jarPath, nil
}
// writeAtomic publishes content at path through a rename, so a reader never
// observes a partial file. dir is shared between every sanderling process on
// the host, so a campaign running one worker per device has several of them
// extracting the same JAR at once on a cold host; a plain write let one
// process spawn a JVM against another's half-written file.
func writeAtomic(path string, content []byte) error {
temporary, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path)+".*.partial")
if err != nil {
return err
}
defer os.Remove(temporary.Name())
if _, err := temporary.Write(content); err != nil {
temporary.Close()
return err
}
if err := temporary.Close(); err != nil {
return err
}
if err := os.Chmod(temporary.Name(), 0o644); err != nil {
return err
}
return os.Rename(temporary.Name(), path)
}