{"id":23364481,"url":"https://github.com/fission-codes/kubo-car-mirror","last_synced_at":"2025-10-18T07:09:34.686Z","repository":{"id":50505504,"uuid":"508079088","full_name":"fission-codes/kubo-car-mirror","owner":"fission-codes","description":"Implementation of the CAR Mirror protocol for Kubo","archived":false,"fork":false,"pushed_at":"2023-06-14T22:18:58.000Z","size":706,"stargazers_count":10,"open_issues_count":13,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-03T04:56:18.347Z","etag":null,"topics":["car-file","car-mirror","content-addressing","golang","ipfs","kubo"],"latest_commit_sha":null,"homepage":"","language":"Go","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/fission-codes.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"open_collective":"fission"}},"created_at":"2022-06-27T22:25:56.000Z","updated_at":"2024-05-30T11:49:28.000Z","dependencies_parsed_at":"2024-03-08T04:47:23.389Z","dependency_job_id":null,"html_url":"https://github.com/fission-codes/kubo-car-mirror","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"fission-codes/project-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fkubo-car-mirror","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fkubo-car-mirror/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fkubo-car-mirror/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fkubo-car-mirror/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fission-codes","download_url":"https://codeload.github.com/fission-codes/kubo-car-mirror/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247354874,"owners_count":20925515,"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","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":["car-file","car-mirror","content-addressing","golang","ipfs","kubo"],"created_at":"2024-12-21T13:16:27.739Z","updated_at":"2025-10-18T07:09:29.650Z","avatar_url":"https://github.com/fission-codes.png","language":"Go","funding_links":["https://opencollective.com/fission"],"categories":[],"sub_categories":[],"readme":"![](https://github.com/fission-codes/kubo-car-mirror/raw/master/assets/logo.png?sanitize=true)\n\n# kubo-car-mirror\n\n[![CI](https://github.com/fission-codes/kubo-car-mirror/actions/workflows/main.yml/badge.svg)](https://github.com/fission-codes/kubo-car-mirror/actions/workflows/main.yml)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/fission-codes/blob/master/LICENSE)\n[![Built by FISSION](https://img.shields.io/badge/⌘-Built_by_FISSION-purple.svg)](https://fission.codes)\n[![Discord](https://img.shields.io/discord/478735028319158273.svg)](https://discord.gg/zAQBDEq)\n[![Discourse](https://img.shields.io/discourse/https/talk.fission.codes/topics)](https://talk.fission.codes)\n\n🚧 WIP 🚧\n\nGo implementation of [CAR Mirror](https://github.com/fission-codes/spec/tree/main/car-pool).\n\nPresentation at IPFS Thing 2023, by @walkah https://www.youtube.com/watch?v=UeSb7vC0K7Y\n\n## Building\n\nkubo-car-mirror is implemented as a [Kubo Daemon Plugin](https://github.com/ipfs/kubo/blob/master/docs/plugins.md#daemon).\nIn order to avoid package versioning issues common with Go plugins, it needs to be built in-tree with Kubo.\n\nWe provide some make targets to simplify this process.\n\n```\n# Clone repos to same parent directory\ngit clone https://github.com/fission-codes/kubo-car-mirror\ngit clone https://github.com/ipfs/kubo\n\n# Change to the kubo-car-mirror directory to run make targets\ncd kubo-car-mirror\n\n# Build everything, including the kubo plugin\nmake build\n\n# Build everything, using a local go-car-mirror dependency in a sibling clone\nmake build-local\n```\n\n## Building from kubo without sibling repo\n\nIf you want to create a branch in your kubo fork that can be used to build kubo-car-mirror, first clone your kubo fork and checkout the branch you want to use.\nThen do the following.\n\n```\ncd kubo-car-mirror\nmake setup-kubo-build\ncd ../kubo\nmake build-carmirror\ngit add .\ngit commit -m \"Add build-carmirror make target\"\n```\n\nPush your changes to your branch.  Now you will be able to clone the branch of your kubo fork and just run `make build-carmirror` to build kubo with the kubo-car-mirror plugin and then your normal kubo make targets, like `make build` and `make install`.\n\nThe build will also install the `carmirror` CLI to `kubo/carmirror/cmd/carmirror/carmirror`.  This binary will be gitignore'd, similar to how the `ipfs` CLI's binary is gitignore'd, so you don't accidentally add a platform specific binary to Git.\n\nBy default the latest version of the main branch in kubo-car-mirror will be built.  If you want to build a specific version, you can set the `KUBO_CAR_MIRROR_GIT_VERSION` environment variable before building.\n\n## Updating to the latest version of go-car-mirror\nFirst make sure you have a sibling repo of go-car-mirror with the latest version on main pulled.  Then run the following command.\n\n```\nmake update-go-car-mirror\n```\n\nCheck in the changes to go.mod and go.sum.\n\n## Testing\n\n```\n# Run unit and sharness tests\nmake test\n\n# Run unit tests\nmake test-unit\n\n# Run sharness tests\nmake sharness\n\n# Run sharness tests verbosely\nmake sharness-v\n\n# Run sharness tests without downloading deps\nmake sharness-no-deps\n\n# Run sharness tests verbosely without downloading deps\nmake sharness-no-deps-v\n```\n\n## Running\n\nOnce built, the kubo daemon has the CAR Mirror plugin baked in.\n\n```\n# Start kubo daemon\n../kubo/cmd/ipfs/ipfs daemon\n```\n\nYou can interact with local CAR Mirror APIs using the `carmirror` CLI.\n\n```\n# Push\n./cmd/carmirror/carmirror push -c CID -a ADDR\n\n# Pull\n./cmd/carmirror/carmirror pull -c CID -a ADDR\n```\n\nDuring development, you might want to run in a testbed with [iptb](https://github.com/ipfs/iptb). This is essentially what happens in sharness tests, but gives you more flexibility in trying things out.\n\n```\n# Set up path, functions, etc\nsource test/lib/carmirror-lib.sh\n\n# Create a temp dir to redirect downloads to with -o.\n# Note, if you redirect to /dev/null instead, error messages will be silently swallowed.\nDATE=$(date +\"%Y-%m-%dT%H:%M:%SZ\")\nCM_TMP=$(mktemp -d \"/tmp/carmirror_tests.$DATE.XXXXXX\") || die \"could not 'mktemp -d /tmp/carmirror_tests.$DATE.XXXXXX'\"\n\n# Stop and remove current testbed if started\niptb_stop\niptb_remove\n\n# Create a 2 node testbed\niptb_new\n\n# Start the daemons\niptb_start\n\n# import test car file to node 0\nipfsi 0 dag import test/sharness/t0000-car-mirror-data/car-mirror.car\n\n# confirm CID is on node 0\nipfsi 0 get QmWXCR7ZwcQpvzJA5fjkQMJTe2rwJgYUtoSxBXFZ3uBY1W --offline -o $CM_TMP\n\n# confirm CID is not on node 1\nipfsi 1 get QmWXCR7ZwcQpvzJA5fjkQMJTe2rwJgYUtoSxBXFZ3uBY1W --offline -o $CM_TMP\n\n# push CID from node 0 to node 1, in background so we can see session with ls output\ncarmirrori 0 push -c QmWXCR7ZwcQpvzJA5fjkQMJTe2rwJgYUtoSxBXFZ3uBY1W -a $(cm_cli_remote_addr 1) -b\n\n# OR pull CID from node 0 to node 1\ncarmirrori 1 pull -c QmWXCR7ZwcQpvzJA5fjkQMJTe2rwJgYUtoSxBXFZ3uBY1W -a $(cm_cli_remote_addr 0) -b\n\n# Confirm push in logs from node 0\niptb_logs 0\n\n# Confirm push received in logs from node 1\niptb_logs 1\n\n# confirm CID is on node 1 now\nipfsi 1 get QmWXCR7ZwcQpvzJA5fjkQMJTe2rwJgYUtoSxBXFZ3uBY1W --offline -o $CM_TMP\n\n# See running sessions\ncarmirrori 0 ls\ncarmirrori 1 ls\n\n# Get all stats\ncarmirrori 0 stats\n\n# Get stats for specific session\ncarmirrori 0 stats -s http://localhost:2505\n\n# Close session\ncarmirrori 0 close -s http://localhost:2505\n\n# Cancel session, for forcibly closing\ncarmirrori 0 cancel -s http://localhost:2505\n\n# shutdown and cleanup\niptb_stop\niptb_remove\n```\n\n## Debugging\n\nYou can enable debugging in the logs using the `GOLOG_LOG_LEVEL` environment variable. This can help with running the daemon, the carmirror CLI, verbose sharness tests, or manual operations in a local testbed.\n\n```\n# Turn on debugging\nexport GOLOG_LOG_LEVEL=\"error,kubo-car-mirror=debug,go-car-mirror=debug\"\n\n# Start daemon, start testbed, run commands, ...\n```\n\n## Configuration\n\nCAR Mirror configuration currently resides in Kubo's plugin configuration.\n\n```\n# Configure port for locally accessible commands\n../kubo/cmd/ipfs/ipfs config --json Plugins.Plugins.car-mirror.Config.HTTPCommandsAddr '\"127.0.0.1:2502\"'\n\n# Configure port for remotely accessible commands (i.e. the actual protocol commands)\n../kubo/cmd/ipfs/ipfs config --json Plugins.Plugins.car-mirror.Config.HTTPRemoteAddr '\":2503\"'\n\n# Configure max batch size\n../kubo/cmd/ipfs/ipfs config --json Plugins.Plugins.car-mirror.Config.MaxBlocksPerRound 32\n\n# Configure max batch size for cold call push\n../kubo/cmd/ipfs/ipfs config --json Plugins.Plugins.car-mirror.Config.MaxBlocksPerColdCall 32\n\n# Disable the plugin\n../kubo/cmd/ipfs/ipfs config --json Plugins.Plugins.car-mirror.Disabled true\n```\n\n## Acknowledgements\n\nHuge thanks 🙏 to [Jonathan Essex](https://github.com/softwareplumber), whose design and implementation of [go-car-mirror](https://github.com/fission-codes/go-car-mirror) does all the heavy lifting for this project.\n\nA big thank you to the [Qri](https://github.com/qri-io) team, whose [Dsync](https://github.com/qri-io/dag) project helped save a ton of time in getting a Kubo plugin project like this up and running.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffission-codes%2Fkubo-car-mirror","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffission-codes%2Fkubo-car-mirror","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffission-codes%2Fkubo-car-mirror/lists"}