{"id":24567560,"url":"https://github.com/suprasummus/ipfs-execute","last_synced_at":"2025-10-07T14:25:35.811Z","repository":{"id":95808172,"uuid":"108399507","full_name":"SupraSummus/ipfs-execute","owner":"SupraSummus","description":"Pure containers using Bubblewrap and IPFS","archived":false,"fork":false,"pushed_at":"2018-03-16T09:34:11.000Z","size":20,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T23:23:55.768Z","etag":null,"topics":["bubblewrap","containers","ipfs","pure-functional"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SupraSummus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2017-10-26T10:56:15.000Z","updated_at":"2024-07-09T09:50:21.000Z","dependencies_parsed_at":"2023-03-13T16:45:36.211Z","dependency_job_id":null,"html_url":"https://github.com/SupraSummus/ipfs-execute","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SupraSummus/ipfs-execute","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupraSummus%2Fipfs-execute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupraSummus%2Fipfs-execute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupraSummus%2Fipfs-execute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupraSummus%2Fipfs-execute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SupraSummus","download_url":"https://codeload.github.com/SupraSummus/ipfs-execute/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupraSummus%2Fipfs-execute/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278788377,"owners_count":26045962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"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":["bubblewrap","containers","ipfs","pure-functional"],"created_at":"2025-01-23T13:19:01.629Z","updated_at":"2025-10-07T14:25:35.806Z","avatar_url":"https://github.com/SupraSummus.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"IPFS execute!\n=============\n\n`ipfs-execute` is a simple script that combines sandboxing provided\nby [Bubblewrap](https://github.com/projectatomic/bubblewrap) with data\nstorage provided by [IPFS](https://ipfs.io/). The tool is proof of\nconcept for \"pure computations in IPFS\".\n\n`ipfs-execute` fetches description of what to do from IPFS, executes\ncomputation in sandbox and then pushes result back to IPFS.\n\nMore in depth description\n-------------------------\n\n`ipfs-execute` takes following arguments in order:\n * IPFS path of filesystem snapshot (`.tar.gz` file)\n * IPFS path of argument - it will be mounted at `/input` inside container.\n * arbitrary number of arguments which will be passed to `/sbin/init`\n\n`ipfs-execute` unpacks root fs, mounts input, mounts empty directory\nat `/output` and another one at `/tmp`. After that container is executed.\nEntry point is `/sbin/init`.\n\nWhen container finishes whole `/output` is added to IPFS. Final hash is\nwritten to stdout.\n\n`/` and `/input` is mounted read-only. All persistent efects must be\nlocated in `/output` tree. This potentially allows to reuse unpacked\nrootfs or input.\n\nContainers don't have access to internet. Output should be\ndeterministicaly computed from rootfs and input.\n\nDependencies\n------------\n\n* IPFS (daemonized)\n* Bubblewrap 2.0\n* [ipfs-api-mount](https://github.com/SupraSummus/ipfs-api-mount)\n* sh + tar + gzip + some other obvious things\n* GNU Make (only if you want to build example images or use install script)\n* [ipfs-shell-utlis](https://github.com/SupraSummus/ipfs-shell-utils) (only if you want to build example images)\n\nTry it\n------\n\n    [jan@aaa ipfs-execute]$ ipfs-execute $(cat examples/busybox) $(cat examples/alpine_repository) sh\n    / # ls /input\n    aarch64  armhf    x86_64\n    / # echo blabla \u003e /output/test\n    / # exit\n    QmeugpFaBp7aafV2uN7GC3E2GbAycnEU3c2Q3FS7mSLbo4\n\nWhat happened? Image located at path specified in `examples/busybox` got\nexecuted with IPFS path specified in `examples/alpine_repository`\nmounted at `/input`. When container finished `/output` was pushed to\nIPFS. Let's inspect:\n\n    [jan@kukla:~/ipfs-execute]$ ipfs cat QmeugpFaBp7aafV2uN7GC3E2GbAycnEU3c2Q3FS7mSLbo4/test\n    blabla\n\n### Next lets install some packages!\n\nFor this we need prepared directory with repository and base rootfs.\nI'll use `ipfs-mkdir` from [ipfs-shell-utils](https://github.com/SupraSummus/ipfs-shell-utils),\nbut you can do it different way. `ipfs-mkdir` usage is as follows:\n\n    ipfs-mkdir repository $(cat examples/alpine_repository) rootfs.tar.gz $(cat examples/busybox) \u003e /tmp/busybox-with-repo\n    cat /tmp/busybox-with-repo\n    # QmVLwnKjWMrxXdRdqwvR5h94uUdT2vqyWCypSWv2TDno98\n\nWe are ready to call `ipfs-execute`.\n\n    ipfs-execute $(cat examples/apk) $(cat /tmp/busybox-with-repo) file \u003e /tmp/alpine-file\n    ipfs ls $(cat /tmp/alpine-file)\n    # QmcNqqRByj6kbw11sbjxXrBASECh2JRg63W6iw3FGezJkU 1280118 rootfs.tar.gz\n    ipfs-execute $(cat /tmp/alpine-file)/rootfs.tar.gz $(cat examples/empty) sh\n\nand inside spawned container:\n\n    file /bin/busybox.static\n    # /bin/busybox.static: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped\n\n### Example images\n\nHashes and build scripts of example containers are listed in `examples/`.\n * `busybox` - just an unpacked busybox-static alpine package. Init is\n   set to call busybox with supplied args.\n * `apk` - alpine linux apk package with init pointing to script that\n   installs stuff. This container expects directory with `rootfs.tar.gz`\n   and `repository` (dir with alpine repo structure) as argument.\n\nIn order to build images you need to have scripts in your path.\n`make install PREFIX=~/.local/bin` will copy them to `~/.local/bin`.\n\nMakefile in `examples/` dir is just for building images. Do `make -C examples clean`\nto delete prebuilt images and then call `make -C examples`.\n\nTODOs\n-----\n\n * security considerations if mounting `/dev` and `/proc` is safe.\n * RAM, disk, CPU time limits\n * build consistency - don't depend on current time etc\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuprasummus%2Fipfs-execute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuprasummus%2Fipfs-execute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuprasummus%2Fipfs-execute/lists"}