guestfs-ruby(3)
π NAME π
okay so this is guestfs-ruby(3) β the manual page that teaches you how to call libguestfs from the Ruby programming language π«Ά literally your whole guide to making Ruby talk to libguestfs, bestie.
β¨ SYNOPSIS β¨
require 'guestfs'
g = Guestfs::Guestfs.new()
g.add_drive_opts("disk.img",
:readonly => true, :format => "raw")
g.launch()
that's the whole vibe right there β require, new, add a drive, launch. slay π
πΈ DESCRIPTION πΈ
So this page is only about how to call libguestfs from Ruby β it documents the differences from the C API plus some examples, no cap. If you've never used libguestfs before in your life, bestie you gotta go read guestfs(3) first, fr fr. This page expects you already know the basics π
π EXCEPTIONS
Errors coming out of libguestfs functions get mapped into the Error exception. It's got a single parameter, which is the error message (a string). That's it. One lil string. iconic.
π EXAMPLE 1: CREATE A DISK IMAGE π
the classic β making a disk image from scratch. here's the full thing, verbatim, don't touch a character:
# Example showing how to create a disk image.
require 'guestfs'
output = "disk.img"
g = Guestfs::Guestfs.new()
# Create a raw-format sparse disk image, 512 MB in size.
g.disk_create (output, "raw", 512 * 1024 * 1024)
# Set the trace flag so that we can see each libguestfs call.
g.set_trace(1)
# Attach the disk image to libguestfs.
g.add_drive_opts(output, :format => "raw")
# Run the libguestfs back-end.
g.launch();
# Get the list of devices. Because we only added one drive
# above, we expect that this list should contain a single
# element.
devices = g.list_devices()
if devices.length != 1 then
raise "error: expected a single device from list-devices"
end
# Partition the disk as one single MBR partition.
g.part_disk(devices[0], "mbr")
# Get the list of partitions. We expect a single element, which
# is the partition we have just created.
partitions = g.list_partitions()
if partitions.length != 1 then
raise "error: expected a single partition from list-partitions"
end
# Create a filesystem on the partition.
g.mkfs("ext4", partitions[0])
# Now mount the filesystem so that we can add files.
g.mount(partitions[0], "/")
# Create some files and directories.
g.touch("/empty")
message = "Hello, world\n"
g.write("/hello", message)
g.mkdir("/foo")
# This one uploads the local file /etc/resolv.conf into
# the disk image.
g.upload("/etc/resolv.conf", "/foo/resolv.conf")
# Because we wrote to the disk and we want to detect write
# errors, call g.shutdown. You don't need to do this:
# g.close will do it implicitly.
g.shutdown()
# Note also that handles are automatically closed if they are
# reaped by the garbage collector. You only need to call close
# if you want to close the handle right away.
g.close()
quick lil breakdown of the juicy bits:
g.disk_createmakes a raw-format sparse disk image that's 512 MB in size πΎg.set_trace(1)flips the trace flag so you can literally watch every libguestfs call go by. main character energy for debugging.g.list_devices()should give you exactly one element since you only added one drive above β hence theraiseif it doesn't.g.part_diskpartitions it as one single MBR partition, theng.list_partitions()should hand back one element too.g.mkfs("ext4", ...),g.mount(...), then the fun stuff:g.touch("/empty"),g.write("/hello", message)withmessage = "Hello, world\n", andg.mkdir("/foo")πΈg.upload("/etc/resolv.conf", "/foo/resolv.conf")uploads your local/etc/resolv.confinto the disk image. cute.- important caveat bestie β
g.shutdown()is there because we wrote to the disk and want to detect write errors. But you don't need to do this:g.closewill do it implicitly. π - also note: handles are automatically closed if they're reaped by the garbage collector. You only need to call
closeif you want to close the handle right away. periodt.
π¦ EXAMPLE 2: INSPECT A VIRTUAL MACHINE DISK IMAGE π¦
now we're snooping on a VM disk. here's the whole example:
# Example showing how to inspect a virtual machine disk.
require 'guestfs'
if ARGV.length == 0
puts "usage: inspect_vm disk.img"
exit 1
end
disk = ARGV[0]
g = Guestfs::Guestfs.new()
# Attach the disk image read-only to libguestfs.
g.add_drive_opts(disk, :readonly => true)
# Run the libguestfs back-end.
g.launch()
# Ask libguestfs to inspect for operating systems.
roots = g.inspect_os()
if roots.length == 0
puts "inspect_vm: no operating systems found"
exit 1
end
for root in roots do
printf("Root device: %s\n", root)
# Print basic information about the operating system.
printf(" Product name: %s\n", g.inspect_get_product_name(root))
printf(" Version: %d.%d\n",
g.inspect_get_major_version(root),
g.inspect_get_minor_version(root))
printf(" Type: %s\n", g.inspect_get_type(root))
printf(" Distro: %s\n", g.inspect_get_distro(root))
# Mount up the disks, like guestfish -i.
#
# Sort keys by length, shortest first, so that we end up
# mounting the filesystems in the correct order.
mps = g.inspect_get_mountpoints(root)
mps = mps.sort {|a,b| a[0].length <=> b[0].length}
for mp in mps do
begin
g.mount_ro(mp[1], mp[0])
rescue Guestfs::Error => msg
printf("%s (ignored)\n", msg)
end
end
# If /etc/issue.net file exists, print up to 3 lines.
filename = "/etc/issue.net"
if g.is_file filename then
printf("--- %s ---\n", filename)
lines = g.head_n(3, filename)
for line in lines do
puts line
end
end
# Unmount everything.
g.umount_all()
end
the tea β:
- no args? it prints
usage: inspect_vm disk.imgand bails withexit 1. respect the usage line bestie. g.add_drive_opts(disk, :readonly => true)β attached read-only, we're just looking, not touching πg.inspect_os()does the OS detection; zero roots meansinspect_vm: no operating systems foundandexit 1.- for each root it prints
Root device: %s\nplus the product name, version (%d.%dfrominspect_get_major_versionandinspect_get_minor_version), type, and distro π - then it mounts the disks like
guestfish -iβ and here's the trick: it sorts the keys by length, shortest first, so the filesystems get mounted in the correct order.mps.sort {|a,b| a[0].length <=> b[0].length}β that's the line, don't lose it π - the mount is
g.mount_ro(mp[1], mp[0])inside abegin/rescue Guestfs::Error => msgthat just prints%s (ignored)\n. errors get ignored, no drama. - if
/etc/issue.netexists (g.is_file filename), it prints--- %s ---\nand up to 3 lines viag.head_n(3, filename)β - finally
g.umount_all()β unmount everything, clean exit, we love to see it π§
π SEE ALSO π
literally the whole friend group:
guestfs(3)guestfs-examples(3)guestfs-erlang(3)guestfs-golang(3)guestfs-java(3)guestfs-lua(3)guestfs-ocaml(3)guestfs-perl(3)guestfs-python(3)guestfs-recipes(1)http://libguestfs.org/π₯
π AUTHORS π
Richard W.M. Jones ("rjones at redhat dot com") β the legend himself π«Ά
π COPYRIGHT π
Copyright (C) 2010-2025 Red Hat Inc.
β LICENSE β
This manual page contains examples which we hope you will use in your programs. The examples may be freely copied, modified and distributed for any purpose without any restrictions. ate and left no crumbs π
π BUGS π
got beef with libguestfs? here's where to take it:
- To get a list of bugs against libguestfs, use this link:
https://bugzilla.redhat.com/buglist.cgi?component=libguestfs&product=Virtualization+Tools - To report a new bug against libguestfs, use this link:
https://bugzilla.redhat.com/enter_bug.cgi?component=libguestfs&product=Virtualization+Tools
When reporting a bug, please supply (fr fr, all of it):
- The version of libguestfs.
- Where you got libguestfs (eg. which Linux distro, compiled from source, etc)
- Describe the bug accurately and give a way to reproduce it.
- Run
libguestfs-test-tool(1)and paste the complete, unedited output into the bug report. π
ngl an unedited paste is the whole thing β don't trim it, don't summarize it, just dump it in there π
that's the page, bestie πβ¨ brought to you by libguestfs-1.60.1, dated 2026-07-14, and yes this is still guestfs-ruby(3) β go write some Ruby, you got this ππ¦
π¦ where this page comes from
- arch rolling: ruby-libguestfs 1.60.1-2 Β· GPL-2.0-or-later AND LGPL-2.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms