{"id":50319491,"url":"https://github.com/arcboxlabs/oci2rootfs","last_synced_at":"2026-05-29T02:30:22.625Z","repository":{"id":337308866,"uuid":"1148101675","full_name":"arcboxlabs/oci2rootfs","owner":"arcboxlabs","description":"Convert OCI container images to ext4 rootfs filesystem images.","archived":false,"fork":false,"pushed_at":"2026-05-07T02:58:05.000Z","size":293,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-07T05:08:31.196Z","etag":null,"topics":["ext4","oci","rootfs"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arcboxlabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-02T15:25:06.000Z","updated_at":"2026-05-07T02:58:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/arcboxlabs/oci2rootfs","commit_stats":null,"previous_names":["arcbox-labs/oci2rootfs","arcboxlabs/oci2rootfs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/arcboxlabs/oci2rootfs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcboxlabs%2Foci2rootfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcboxlabs%2Foci2rootfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcboxlabs%2Foci2rootfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcboxlabs%2Foci2rootfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arcboxlabs","download_url":"https://codeload.github.com/arcboxlabs/oci2rootfs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcboxlabs%2Foci2rootfs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33634611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ext4","oci","rootfs"],"created_at":"2026-05-29T02:30:21.066Z","updated_at":"2026-05-29T02:30:22.608Z","avatar_url":"https://github.com/arcboxlabs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oci2rootfs\n\nConvert OCI container images to ext4 rootfs filesystem images.\n\n## Features\n\n- **Local conversion** — read from an OCI Image Layout directory on disk\n- **Docker cache paths** — convert directly from Docker `overlay2` chain-id directories\n- **Remote pull** — pull images directly from container registries (Docker Hub, GCR, etc.)\n- **Multi-arch support** — resolve platform-specific manifests from image indexes\n- **Layer handling** — apply tar layers in order with full OCI whiteout support (`.wh.*` deletes, `.wh..wh..opq` opaque)\n- **Compression** — gzip, zstd, and uncompressed layers\n- **Auth** — automatic credential resolution from Docker config\n\n## Usage\n\n```bash\n# From a local OCI layout directory\noci2rootfs ./oci-dir --output rootfs.ext4\n\n# From a remote registry\noci2rootfs nginx:1.21 --output rootfs.ext4\n\n# Custom size and platform\noci2rootfs ubuntu:22.04 --output rootfs.ext4 --size 1G --platform linux/arm64\n\n# Insecure (HTTP) registry\noci2rootfs localhost:5000/myapp:latest --output rootfs.ext4 --insecure\n```\n\n### Options\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--output`, `-o` | (required) | Output ext4 image path |\n| `--size` | `512M` | Image size (`128M`, `1G`, etc.) |\n| `--platform` | `linux/amd64` | Target platform |\n| `--insecure` | `false` | Allow HTTP registry connections |\n| `--label` | (none) | Volume label written to the superblock (≤16 bytes) |\n| `--uuid` | random | Filesystem UUID written to the superblock |\n\nSet `RUST_LOG=info` (or `debug`, `trace`) to see per-layer progress and\ntiming on stderr — the CLI installs a `tracing-subscriber` fmt layer\nwired to `RUST_LOG` via env-filter.\n\n## Library\n\n```rust\nuse oci2rootfs::{autodetect, Converter, OciLayoutSource, Platform};\n\n// Local OCI layout\nConverter::new(\"rootfs.ext4\")\n    .size(1024 * 1024 * 1024)\n    .convert(\n        OciLayoutSource::open(\"./oci-dir\")?\n            .platform(Platform::new(\"linux\", \"amd64\")),\n    )?;\n\n// Local auto-detect (OCI layout or overlay2 path)\nConverter::new(\"rootfs.ext4\").convert(autodetect(\"./some-path\")?)?;\n\n// Remote registry (default feature: `remote`)\n# #[cfg(feature = \"remote\")]\n# async fn example() -\u003e oci2rootfs::Result\u003c()\u003e {\nuse oci2rootfs::RemoteRef;\n\nlet source = RemoteRef::new(\"nginx:latest\")\n    .platform(Platform::default())\n    .fetch()\n    .await?;\n\n// Remote fetches also expose the resolved manifest digest.\nprintln!(\n    \"manifest: {}\",\n    source\n        .manifest_digest()\n        .expect(\"remote sources always resolve to a manifest\")\n);\n\n// Image config (entrypoint/cmd/env/...) is available on the source.\nif let Some(cfg) = source.config() {\n    if let Some(container) = \u0026cfg.config {\n        println!(\"entrypoint: {:?}\", container.entrypoint);\n    }\n}\n\nConverter::new(\"rootfs.ext4\").convert(source)?;\n# Ok(())\n# }\n```\n\n### ext4 image properties\n\n| Property         | Value                                  | Configurable |\n|------------------|----------------------------------------|--------------|\n| Block size       | 4 KiB                                  | No (arcbox-ext4 fixed) |\n| Journal          | none (effectively `mkfs.ext4 -O ^has_journal`) | No |\n| Feature flags    | `SPARSE_SUPER2 | EXT_ATTR`             | No |\n| Volume label     | empty                                  | `Ext4Options::label` / `--label` |\n| UUID             | random v4                              | `Ext4Options::uuid` / `--uuid` |\n| `ImageConfig`    | exposed via `ImageSource::config()` for OCI layout and remote pulls; `None` for overlay2 sources (Docker keeps the config outside the layer tree) | — |\n| Manifest digest  | exposed via `ImageSource::manifest_digest()` for OCI layout and remote pulls; `None` for overlay2 sources | — |\n\n### Feature flags\n\n| Feature | Default | Pulls in |\n|---------|---------|----------|\n| `remote` | yes | `containerregistry-registry`, `containerregistry-auth`, `tokio`, `reqwest`, TLS stack |\n\nAdd `default-features = false` on the library dependency to drop the remote\npull stack when you only need OCI layout and Docker overlay2 support:\n\n```toml\n[dependencies]\noci2rootfs = { version = \"0.2\", default-features = false }\n```\n\n### Known limitations\n\n- **Remote pull buffers every layer blob in memory** before applying. For\n  multi-gigabyte images this requires proportional heap; prefer spooling to an\n  OCI layout on disk for large images (e.g. via `skopeo copy docker://\u003cref\u003e\n  oci:./layout:latest`, then `OciLayoutSource::open`).\n- **Layer downloads are serial.** Parallel fetches could reduce wall time for\n  images with many small layers but would complicate progress reporting.\n- **No device-node support.** `mknod`-created entries in tar layers (char/\n  block/FIFO) are skipped silently; overlay2 `.wh.\u003cname\u003e` files cover deletion.\n- **Block size and inode ratio are not configurable.** `arcbox-ext4` hard-codes\n  4 KiB blocks and computes inode counts internally.\n\n## Build\n\n```bash\ncargo build --release\n```\n\n## Project Structure\n\n```\ncrates/\n├── oci2rootfs/          # Library\n│   └── src/\n│       ├── convert.rs   # High-level Converter API\n│       ├── error.rs     # Error types\n│       ├── ext4.rs      # ext4 image writer (arcbox-ext4)\n│       ├── layer.rs     # Tar layer application with whiteout support\n│       ├── oci.rs       # OCI Image Layout resolution\n│       ├── ext4_options.rs # UUID/label passed at format time\n│       ├── overlay2/    # Docker overlay2 resolution and apply\n│       ├── path.rs      # Shared path sanitation + whiteout parsing\n│       ├── pull.rs      # Remote registry pull (feature = \"remote\")\n│       └── tar_source.rs # Shared tar-layer source plumbing\n└── oci2rootfs-cli/      # CLI binary\n    └── src/\n        └── main.rs\n```\n\n## License\n\nLicensed under either of\n\n- [Apache License, Version 2.0](LICENSE-APACHE)\n- [MIT License](LICENSE-MIT)\n\nat your option.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcboxlabs%2Foci2rootfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcboxlabs%2Foci2rootfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcboxlabs%2Foci2rootfs/lists"}