{"id":17383338,"url":"https://github.com/bkahlert/libguestfs","last_synced_at":"2025-06-27T15:07:09.425Z","repository":{"id":40479474,"uuid":"324920808","full_name":"bkahlert/libguestfs","owner":"bkahlert","description":"Containerized libguestfs including virt-customize, guestfish, etc.","archived":false,"fork":false,"pushed_at":"2023-11-29T20:30:26.000Z","size":27649,"stargazers_count":25,"open_issues_count":5,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-27T15:06:01.334Z","etag":null,"topics":["docker","guestfish","libguestfs","shellscript","virt-builder","virt-customize"],"latest_commit_sha":null,"homepage":"","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/bkahlert.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":"paypal.me/bkahlert"}},"created_at":"2020-12-28T05:33:11.000Z","updated_at":"2025-04-28T19:31:18.000Z","dependencies_parsed_at":"2024-10-16T07:41:32.475Z","dependency_job_id":"db5d48f6-efbc-4f38-a1b7-4aa9d8f72261","html_url":"https://github.com/bkahlert/libguestfs","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/bkahlert/libguestfs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkahlert%2Flibguestfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkahlert%2Flibguestfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkahlert%2Flibguestfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkahlert%2Flibguestfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bkahlert","download_url":"https://codeload.github.com/bkahlert/libguestfs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bkahlert%2Flibguestfs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262279106,"owners_count":23286548,"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":["docker","guestfish","libguestfs","shellscript","virt-builder","virt-customize"],"created_at":"2024-10-16T07:41:19.651Z","updated_at":"2025-06-27T15:07:09.396Z","avatar_url":"https://github.com/bkahlert.png","language":"Shell","funding_links":["paypal.me/bkahlert","https://www.paypal.me/bkahlert"],"categories":[],"sub_categories":[],"readme":"# bkahlert/libguestfs [![Build Status](https://img.shields.io/github/actions/workflow/status/bkahlert/libguestfs/build.yml?label=Build\u0026logo=github\u0026logoColor=fff)](https://github.com/bkahlert/libguestfs/actions/workflows/build.yml) [![Repository Size](https://img.shields.io/github/repo-size/bkahlert/libguestfs?color=01818F\u0026label=Repo%20Size\u0026logo=Git\u0026logoColor=fff)](https://github.com/bkahlert/libguestfs) [![Repository Size](https://img.shields.io/github/license/bkahlert/libguestfs?color=29ABE2\u0026label=License\u0026logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1OTAgNTkwIiAgeG1sbnM6dj0iaHR0cHM6Ly92ZWN0YS5pby9uYW5vIj48cGF0aCBkPSJNMzI4LjcgMzk1LjhjNDAuMy0xNSA2MS40LTQzLjggNjEuNC05My40UzM0OC4zIDIwOSAyOTYgMjA4LjljLTU1LjEtLjEtOTYuOCA0My42LTk2LjEgOTMuNXMyNC40IDgzIDYyLjQgOTQuOUwxOTUgNTYzQzEwNC44IDUzOS43IDEzLjIgNDMzLjMgMTMuMiAzMDIuNCAxMy4yIDE0Ny4zIDEzNy44IDIxLjUgMjk0IDIxLjVzMjgyLjggMTI1LjcgMjgyLjggMjgwLjhjMCAxMzMtOTAuOCAyMzcuOS0xODIuOSAyNjEuMWwtNjUuMi0xNjcuNnoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxOS4yMTIiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz48L3N2Zz4%3D)](https://github.com/bkahlert/libguestfs/blob/master/LICENSE)\n\n## About\n\n**Containerized libguestfs including virt-customize, guestfish, etc.**\n\n* Runs as non-root user\n* Multi-platform image\n* Helper scripts\n    * [`guestfish` *Manipulate a virtual machine / image using the guest filesystem shell*\n      ![recorded terminal session demonstrating guestfish](docs/guestfish.svg \"guestfish\")](../../raw/master/docs/guestfish.svg)\n    * [`virt-builder` *Build virtual machine images quickly*  \n      ![recorded terminal session demonstrating virt-builder](docs/virt-builder.svg \"virt-builder\")](../../raw/master/docs/virt-builder.svg)\n    * [`virt-customize` *Customize a virtual machine / image*  \n      ![recorded terminal session demonstrating virt-customize](docs/virt-customize.svg \"virt-customize\")](../../raw/master/docs/virt-customize.svg)\n    * [`pi` *Boot a virtual machine / image using a dockerized ARM emulator that emulates a Raspberry Pi*  \n      ![recorded terminal session demonstrating pi](docs/pi.svg \"pi\")](../../raw/master/docs/pi.svg)\n    * [`copy-out` *Copy files out of a virtual machine / image*  \n      ![recorded terminal session demonstrating copy-out](docs/copy-out.svg \"copy-out\")](../../raw/master/docs/copy-out.svg)\n\n## Build locally\n\n```shell\ngit clone https://github.com/bkahlert/libguestfs.git\ncd libguestfs\n\n# Build image and output to docker (default)\ndocker buildx bake\n\n# Build multi-platform image\ndocker buildx bake image-all\n```\n\n## Image\n\n* [Docker Hub](https://hub.docker.com/r/bkahlert/libguestfs/) `bkahlert/libguestfs`\n* [GitHub Container Registry](https://github.com/users/bkahlert/packages/container/package/libguestfs) `ghcr.io/bkahlert/libguestfs`\n\nFollowing platforms for this image are available:\n\n- linux/amd64\n- linux/arm/v7\n- linux/arm64/v8\n- linux/ppc64le\n- linux/riscv64\n- linux/s390x\n\n## Usage\n\n### Interactively\n\n```shell\ndocker run -it --rm \\\n  -v \"$PWD\":\"$PWD\" \\\n  -w \"$PWD\" \\\n  bkahlert/libguestfs:edge \\\n  guestfish\n\n\u003e\u003cfs\u003e add disk.img format:raw\n\u003e\u003cfs\u003e launch\n\u003e\u003cfs\u003e mount /dev/sda ./\n\u003e\u003cfs\u003e ls /\n\u003e\u003cfs\u003e copy-out /boot data\n\u003e\u003cfs\u003e umount-all\n\u003e\u003cfs\u003e exit\n```\n\n### Automatically\n\n```shell\ndocker run -i --rm \\\n  -v \"$PWD\":\"$PWD\" \\\n  -w \"$PWD\" \\\n  bkahlert/libguestfs:edge \\\n  guestfish \\\n  --ro \\\n  --add disk.img format:raw \\\n  --mount /dev/sda:/ \\\n\u003c\u003cCOMMANDS\nls /\n-copy-out /boot ./\numount-all\nexit\nCOMMANDS\n```\n\nThe command requires `disk.img` in this directory, mounts it with the `guestfish` tool and executes all guestfish commands enclosed by `COMMANDS` on the\nmounted `disk.img`.\n\nIn this case the directory `/boot` and its contents is copied to the current working directory.\n\n\u003e 💡 Did you notice the leading dash in front of the `copy-out` command? Running guestfish non-interactively the first command that gives an error causes the\n\u003e whole shell to exit. By prefixing a command with `-` guestfish will not exit if an error is encountered.\n\n\u003e 💡 If you prefix a command with `!` (e.g. `!id`) the command will run on the host instead of the mounted guest. Since the libguestfs tools are containerized\n\u003e themselves, \"host\" signifies the containerized libguestfs hosting Ubuntu installation — and not you actual OS.\n\n## Configuration\n\nThis image can be configured using the following options of which all but `APP_USER` and `APP_GROUP` exist as both—build argument and environment variable.  \nYou should go for build arguments if you want to set custom defaults you don't intend to change (often). Environment variables will overrule any existing\nconfiguration on each container start.\n\n- `APP_USER` Name of the main user (default: `libguestfs`)\n- `APP_GROUP` Name of the main user's group (default: `libguestfs`)\n- `DEBUG` Whether to log debug information (default: `0`)\n- `TZ` Timezone the container runs in (default: `UTC`)\n- `LANG` Language/locale to use (default: `C.UTF-8`)\n- `PUID` User ID of the `libguestfs` user (default: `1000`)\n- `PGID` Group ID of the `libguestfs` group (default: `1000`)\n- `LIBGUESTFS_DEBUG` Set this to 1 in order to enable massive amounts of debug messages. If you think there is some problem inside the libguestfs appliance,\n  then you should use this option. (default: `0`)\n- `LIBGUESTFS_TRACE` Set this to 1 and libguestfs will print out each command / API call in a format which is similar to guestfish commands. (default: `0`)\n\n```shell\n# Build single image with build argument TZ\ndocker buildx bake --set \"*.args.TZ=$(date +\"%Z\")\"\n\n# Build multi-platform image with build argument TZ\ndocker buildx bake image-all --set \"*.args.TZ=$(date +\"%Z\")\"\n\n# Start container with environment variable TZ\ndocker run --rm \\\n  -e TZ=\"$(date +\"%Z\")\" \\\n  -v \"$(pwd):$(pwd)\" \\\n  -w \"$(pwd)\" \\\n  libguestfs:local\n```\n\n## Testing\n\n```shell\ngit clone https://github.com/bkahlert/libguestfs.git\ncd libguestfs\n\n# Use Bats wrapper to run tests\ncurl -LfsS https://git.io/batsw |\n DOCKER_BAKE=\"--set '*.tags=test'\" bash -s -- --batsw:-e --batsw:BUILD_TAG=test test\n```\n\n[Bats Wrapper](https://github.com/bkahlert/bats-wrapper) is a self-contained wrapper to run tests based on the Bash testing\nframework [Bats](https://github.com/bats-core/bats-core).\n\n\u003e 💡 To accelerate testing, the Bats Wrapper checks if any test is prefixed with a capital X and if so, only runs those tests.\n\n## Troubleshooting\n\nIf you run into problems, try running your intended steps interactively with verbose logging turned on:\n\n```shell\ndocker run -it --rm \\\n  -e \"LIBGUESTFS_DEBUG=1\" \\\n  -e \"LIBGUESTFS_TRACE=1\" \\\n  -v \"$PWD\":\"$PWD\" \\\n  -w \"$PWD\" \\\n  bkahlert/libguestfs:edge \\\n  guestfish\n```\n\nTo debug the image the following lines might become handy:\n\n```shell\n# build local image with specified tag\ndocker buildx bake --set '*.tags=test'\n\n# copy something to test with\ncp test/fixtures/tinycore.iso disk.img\n\n# start container interactively with a bash\ndocker run \\\n  -e LIBGUESTFS_DEBUG=1 \\\n  -e LIBGUESTFS_TRACE=1 \\\n  -e DEBUG=1 \\\n  -e TZ=CET \\\n  -e PUID=68039910 \\\n  -e PGID=584555228 \\\n  -e TERM=xterm-256color \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -v \"$PWD\":\"$PWD\" \\\n  -w \"$PWD\" \\\n  --interactive \\\n  --tty \\\n  --rm \\\n  --entrypoint /bin/bash \\\n  --name libguestfs-test \\\n  test\n\n# fixes (normally performed by entrypoint.sh)\nchmod 0644 /boot/vmlinuz*\nusermod -a -G kvm \"$(whoami)\"\n\n# run guestfish interactively\nguestfish\n# or as root: (see entrypoint_user.sh for details)\nLIBGUESTFS_BACKEND=direct guestfish\n\n# run guestfish using the original entrypoint\nentrypoint.sh guestfish \\\n  --ro \\\n  --add disk.img format:raw \\\n  --mount /dev/sda:/ \\\n\u003c\u003cCOMMANDS\nls /\n-copy-out /boot ./\numount-all\nexit\nCOMMANDS \n```\n\n## Contributing\n\nWant to contribute? Awesome! The most basic way to show your support is to star the project, or to raise issues. You can also support this project by making\na [PayPal donation](https://www.paypal.me/bkahlert) to ensure this journey continues indefinitely!\n\nThanks again for your support, it's much appreciated! :pray:\n\n## License\n\nMIT. See [LICENSE](LICENSE) for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkahlert%2Flibguestfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbkahlert%2Flibguestfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkahlert%2Flibguestfs/lists"}