Skip to content

Import a Tar Archive

The tar importer creates the same canonical filesystem object model as a filesystem import, without extracting untrusted paths to disk first. It accepts regular files, directories, symlinks, hard links, and old-GNU sparse files. PAX GNU sparse members are rejected because their logical expansion is not yet available in the underlying async tar reader.

import detects a tar file from its first valid header; import -i tar also accepts - for standard input. The stream must already be decompressed; for example, use a decompressor pipeline for a .tar.gz input. The named root is installed only after the whole archive is validated.

Terminal window
$ casita --repository ./cache import release.tar --root releases/current
$ gzip -cd release.tar.gz | casita --repository ./cache import -i tar - \
--root releases/current

The command defaults to the same finite archive, entry, pathname, file-byte, total-file-byte, and sparse-expansion limits as TarImportLimits. Override them with --tar-max-archive-bytes, --tar-max-entries, --tar-max-path-bytes, --tar-max-file-bytes, --tar-max-total-file-bytes, and --tar-max-sparse-expansion-bytes for a stricter deployment policy.

File finalization is pipelined while the next tar body is read. At most 16 files are being copied, queued, finalized, or verified at once. Set --tar-max-in-flight-files 1 for serial processing, or choose another positive limit to control the number of open writers. Archive parsing stays sequential; the importer does not buffer whole files. Compression and chunk hashing use the payload backend’s existing workers.

TarImport accepts an already-decompressed asynchronous tar stream, so a .tar.gz or similar input must be decompressed before it reaches Casita. The root is published only after the complete archive has been validated and converted to a canonical directory graph.

use casita::{Repository, RootName, import::TarImport, TarImportLimits};
use tokio::io::BufReader;
let repository = Repository::local("./cache").await?;
let archive = tokio::fs::File::open("release.tar").await?;
let report = repository
.import(
TarImport::new(BufReader::new(archive), RootName::try_from("releases/current")?)
.with_limits(TarImportLimits::default()),
)
.await?;
println!("{} entries in {}", report.entries, report.root);

TarImportLimits bounds archive bytes, entries, one file, total file bytes, sparse expansion, and in-flight files (max_in_flight_files, default 16). Set lower deployment-specific limits before accepting untrusted archives.