@@ -12,17 +12,16 @@ use anyhow::{anyhow, Context};
12
12
use camino:: { Utf8Component , Utf8Path , Utf8PathBuf } ;
13
13
14
14
use cap_std:: io_lifetimes;
15
+ use cap_std_ext:: cap_std:: fs:: Dir ;
15
16
use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
16
17
use cap_std_ext:: { cap_std, cap_tempfile} ;
17
18
use fn_error_context:: context;
18
- use once_cell:: unsync:: OnceCell ;
19
19
use ostree:: gio;
20
20
use ostree:: prelude:: FileExt ;
21
21
use std:: collections:: { BTreeMap , HashMap } ;
22
22
use std:: io:: { BufWriter , Seek , Write } ;
23
23
use std:: path:: Path ;
24
24
use std:: process:: Stdio ;
25
-
26
25
use std:: sync:: Arc ;
27
26
use tokio:: io:: { AsyncRead , AsyncReadExt , AsyncWrite } ;
28
27
use tracing:: instrument;
@@ -196,6 +195,7 @@ pub(crate) fn filter_tar(
196
195
src : impl std:: io:: Read ,
197
196
dest : impl std:: io:: Write ,
198
197
config : & TarImportConfig ,
198
+ tmpdir : & Dir ,
199
199
) -> Result < BTreeMap < String , u32 > > {
200
200
let src = std:: io:: BufReader :: new ( src) ;
201
201
let mut src = tar:: Archive :: new ( src) ;
@@ -210,8 +210,6 @@ pub(crate) fn filter_tar(
210
210
// Lookaside data for dealing with hardlinked files into /sysroot; see below.
211
211
let mut changed_sysroot_objects = HashMap :: new ( ) ;
212
212
let mut new_sysroot_link_targets = HashMap :: < Utf8PathBuf , Utf8PathBuf > :: new ( ) ;
213
- // A temporary directory if needed
214
- let tmpdir = OnceCell :: new ( ) ;
215
213
216
214
for entry in ents {
217
215
let mut entry = entry?;
@@ -228,15 +226,6 @@ pub(crate) fn filter_tar(
228
226
// file instead.
229
227
if is_modified && is_regular {
230
228
tracing:: debug!( "Processing modified sysroot file {path}" ) ;
231
- // Lazily allocate a temporary directory
232
- let tmpdir = tmpdir. get_or_try_init ( || -> anyhow:: Result < _ > {
233
- let vartmp = & cap_std:: fs:: Dir :: open_ambient_dir (
234
- "/var/tmp" ,
235
- cap_std:: ambient_authority ( ) ,
236
- )
237
- . context ( "Allocating tmpdir" ) ?;
238
- cap_tempfile:: tempdir_in ( vartmp) . map_err ( anyhow:: Error :: msg)
239
- } ) ?;
240
229
// Create an O_TMPFILE (anonymous file) to use as a temporary store for the file data
241
230
let mut tmpf = cap_tempfile:: TempFile :: new_anonymous ( tmpdir)
242
231
. map ( BufWriter :: new)
@@ -304,6 +293,7 @@ async fn filter_tar_async(
304
293
src : impl AsyncRead + Send + ' static ,
305
294
mut dest : impl AsyncWrite + Send + Unpin ,
306
295
config : & TarImportConfig ,
296
+ repo_tmpdir : Dir ,
307
297
) -> Result < BTreeMap < String , u32 > > {
308
298
let ( tx_buf, mut rx_buf) = tokio:: io:: duplex ( 8192 ) ;
309
299
// The source must be moved to the heap so we know it is stable for passing to the worker thread
@@ -312,7 +302,7 @@ async fn filter_tar_async(
312
302
let tar_transformer = tokio:: task:: spawn_blocking ( move || {
313
303
let mut src = tokio_util:: io:: SyncIoBridge :: new ( src) ;
314
304
let dest = tokio_util:: io:: SyncIoBridge :: new ( tx_buf) ;
315
- let r = filter_tar ( & mut src, dest, & config) ;
305
+ let r = filter_tar ( & mut src, dest, & config, & repo_tmpdir ) ;
316
306
// Pass ownership of the input stream back to the caller - see below.
317
307
( r, src)
318
308
} ) ;
@@ -390,7 +380,10 @@ pub async fn write_tar(
390
380
let mut import_config = TarImportConfig :: default ( ) ;
391
381
import_config. allow_nonusr = options. allow_nonusr ;
392
382
import_config. remap_factory_var = !options. retain_var ;
393
- let filtered_result = filter_tar_async ( src, child_stdin, & import_config) ;
383
+ let repo_tmpdir = Dir :: reopen_dir ( & repo. dfd_borrow ( ) ) ?
384
+ . open_dir ( "tmp" )
385
+ . context ( "Getting repo tmpdir" ) ?;
386
+ let filtered_result = filter_tar_async ( src, child_stdin, & import_config, repo_tmpdir) ;
394
387
let output_copier = async move {
395
388
// Gather stdout/stderr to buffers
396
389
let mut child_stdout_buf = String :: new ( ) ;
@@ -512,6 +505,7 @@ mod tests {
512
505
async fn tar_filter ( ) -> Result < ( ) > {
513
506
let tempd = tempfile:: tempdir ( ) ?;
514
507
let rootfs = & tempd. path ( ) . join ( "rootfs" ) ;
508
+
515
509
std:: fs:: create_dir_all ( rootfs. join ( "etc/systemd/system" ) ) ?;
516
510
std:: fs:: write ( rootfs. join ( "etc/systemd/system/foo.service" ) , "fooservice" ) ?;
517
511
std:: fs:: write ( rootfs. join ( "blah" ) , "blah" ) ?;
@@ -522,7 +516,8 @@ mod tests {
522
516
let _ = rootfs_tar. into_inner ( ) ?;
523
517
let mut dest = Vec :: new ( ) ;
524
518
let src = tokio:: io:: BufReader :: new ( tokio:: fs:: File :: open ( rootfs_tar_path) . await ?) ;
525
- filter_tar_async ( src, & mut dest, & Default :: default ( ) ) . await ?;
519
+ let cap_tmpdir = Dir :: open_ambient_dir ( & tempd, cap_std:: ambient_authority ( ) ) ?;
520
+ filter_tar_async ( src, & mut dest, & Default :: default ( ) , cap_tmpdir) . await ?;
526
521
let dest = dest. as_slice ( ) ;
527
522
let mut final_tar = tar:: Archive :: new ( Cursor :: new ( dest) ) ;
528
523
let destdir = & tempd. path ( ) . join ( "destdir" ) ;
0 commit comments