@@ -10,6 +10,32 @@ import (
1010 "github.com/deevus/pixels/sandbox"
1111)
1212
13+ // WriteFile writes content to a file inside the container via the TrueNAS
14+ // filesystem API (no SSH required) so uploads work even before SSH
15+ // provisioning has set up authorized_keys (e.g. during BuildBase).
16+ //
17+ // The TrueNAS filesystem API writes as root. When uid/gid are non-negative,
18+ // the file is chowned to uid:gid via SSH-as-root after the write so callers
19+ // (notably the MCP layer) can produce files owned by the configured exec
20+ // user. uid<0 or gid<0 leaves the file root-owned, matching the historical
21+ // BuildBase behaviour.
22+ func (t * TrueNAS ) WriteFile (ctx context.Context , name , path string , content []byte , mode os.FileMode , uid , gid int ) error {
23+ if err := t .client .WriteContainerFile (ctx , prefixed (name ), path , content , mode ); err != nil {
24+ return err
25+ }
26+ if uid < 0 || gid < 0 {
27+ return nil
28+ }
29+ owner := fmt .Sprintf ("%d:%d" , uid , gid )
30+ if _ , err := t .Run (ctx , name , sandbox.ExecOpts {
31+ Cmd : []string {"chown" , "--" , owner , path },
32+ Root : true ,
33+ }); err != nil {
34+ return fmt .Errorf ("chown %s to %s: %w" , path , owner , err )
35+ }
36+ return nil
37+ }
38+
1339// ReadFile reads the file (or first maxBytes) into memory. If maxBytes>0
1440// and the file is larger, returns truncated=true.
1541func (t * TrueNAS ) ReadFile (ctx context.Context , name , p string , maxBytes int64 ) ([]byte , bool , error ) {
0 commit comments