guestfs-perl(3)
๐
guestfs-perl โ like, how to drive libguestfs from Perl (the manual is called guestfs-perl(3), and it lives under the Virtualization Support umbrella, just so you know what you're looking at ๐ซถ)
okay bestie, buckle in โ this is the page that teaches you how to call libguestfs from Perl. It's giving "short but iconic." โจ
๐ธ SYNOPSIS
use Sys::Guestfs;
my $g = Sys::Guestfs->new ();
$g->add_drive_opts ('guest.img', format => 'raw');
$g->launch ();
$g->mount ('/dev/sda1', '/');
$g->touch ('/hello');
$g->shutdown ();
$g->close ();
like, that's the whole vibe right there. make a handle, add a drive, launch, mount, touch a file, shut down, close. slay. ๐
๐ฆ DESCRIPTION
This page is literally the "how do I use libguestfs from Perl" tutorial. It only covers the stuff that's different from the C API, plus a couple of examples to get you going. ๐
If you're not already comfy with libguestfs itself, go readguestfs(3)first, fr fr. And if you want the full Perl API โ every single method โ that'sSys::Guestfs(3). ๐
๐ ERRORS
When a libguestfs function fails, it turns into a call to croak โ check Carp(3) for the deets. So yeah, your errors come at you the Perl way. ๐ญ
โญ EXAMPLE 1: CREATE A DISK IMAGE
okay so this one is the glow-up: you're making a disk image from scratch, partitioning it, putting a filesystem on it, and dropping files in. main character energy. ๐
#!/usr/bin/env perl
# Example showing how to create a disk image.
use strict;
use warnings;
use Sys::Guestfs;
my $output = "disk.img";
my $g = new Sys::Guestfs ();
# 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", readonly => 0);
# 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.
my @devices = $g->list_devices ();
if (@devices != 1) {
die "error: expected a single device from list-devices";
}
# 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.
my @partitions = $g->list_partitions ();
if (@partitions != 1) {
die "error: expected a single partition from list-partitions";
}
# 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");
my $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 reference counting. You only need to call close
# if you want to close the handle right away.
$g->close ();
quick notes since the comments lowkey already spilled the tea โ:
- we make a
raw-format sparse disk image,512 * 1024 * 1024bytes (that's 512 MB, bestie ๐งฎ). $g->set_trace (1)so you can watch every single libguestfs call happen. nosy but make it valid. ๐- we attach the image with
format => "raw"andreadonly => 0, thenlaunch (). - only one drive added โ so
list_devices()should hand back exactly one element. wedieotherwise, obviously. part_disk ($devices[0], "mbr")โ one single MBR partition. iconic.list_partitions()should also be exactly one element โ the one we just made. dare I sayโฆ consistency? ๐mkfs ("ext4", $partitions[0]), thenmount ($partitions[0], "/").- then the fun part:
touch ("/empty"),write ("/hello", $message)with"Hello, world\n", andmkdir ("/foo"). upload ("/etc/resolv.conf", "/foo/resolv.conf")โ yes, it literally yeets your local/etc/resolv.confinto the image. ๐shutdown ()โ you call this because we wrote to the disk and we want to detect write errors. you don't have to:$g->closedoes it implicitly.- also!! handles get closed automatically if they're reaped by reference counting. you only need
closeif you want the handle gone right now. โจ
๐ EXAMPLE 2: INSPECT A VIRTUAL MACHINE DISK IMAGE
now we're snooping (respectfully) into an existing VM disk and asking libguestfs "bestie, what OS is this?" ๐๐ฆ
#!/usr/bin/env perl
# Example showing how to inspect a virtual machine disk.
use strict;
use warnings;
use Sys::Guestfs;
if (@ARGV < 1) {
die "usage: inspect_vm disk.img"
}
my $disk = $ARGV[0];
my $g = new Sys::Guestfs ();
# Attach the disk image read-only to libguestfs.
# You could also add an optional format => ... argument here. This is
# advisable since automatic format detection is insecure.
$g->add_drive_opts ($disk, readonly => 1);
# Run the libguestfs back-end.
$g->launch ();
# Ask libguestfs to inspect for operating systems.
my @roots = $g->inspect_os ();
if (@roots == 0) {
die "inspect_vm: no operating systems found";
}
for my $root (@roots) {
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.
my %mps = $g->inspect_get_mountpoints ($root);
my @mps = sort { length $a <=> length $b } (keys %mps);
for my $mp (@mps) {
eval { $g->mount_ro ($mps{$mp}, $mp) };
if ($@) {
print "$@ (ignored)\n"
}
}
# If /etc/issue.net file exists, print up to 3 lines.
my $filename = "/etc/issue.net";
if ($g->is_file ($filename)) {
printf "--- %s ---\n", $filename;
my @lines = $g->head_n (3, $filename);
print "$_\n" foreach @lines;
}
# Unmount everything.
$g->umount_all ()
}
okay the โจimportantโจ bits:
๐จ the comment says you could add an optional format => ... argument here, and that it's advisable โ because automatic format detection is insecure. not me warning you twice. ๐
- attach read-only:
add_drive_opts ($disk, readonly => 1). safety first, bestie. ๐ซถ inspect_os ()gives you the roots. zero roots โdie "inspect_vm: no operating systems found".- for each root we print
Root device: %s, then the product name, version (%d.%dfrom major + minor), type, and distro. very demure, very informative. ๐ inspect_get_mountpoints ($root)gives a hash, and then โ the trick โ we sort the keys by length, shortest first, so the filesystems get mounted in the right order. the way thatsort { length $a <=> length $b }ate. ๐- each mount is wrapped in
eval { $g->mount_ro ($mps{$mp}, $mp) }, and if$@is set we just print"$@ (ignored)\n". graceful. ๐ - if
/etc/issue.netis a file (checked withis_file), print a--- %s ---banner and up to3lines viahead_n (3, $filename). umount_all ()at the end to clean up. no leftover mounts in this house. ๐งน
๐ SEE ALSO
Sys::Guestfs(3), guestfs(3), guestfs-examples(3), guestfs-erlang(3), guestfs-golang(3), guestfs-java(3), guestfs-lua(3), guestfs-ocaml(3), guestfs-python(3), guestfs-recipes(1), guestfs-ruby(3), http://libguestfs.org/.
like, every language said "we're coming too." multilingual icons only. ๐
๐ AUTHORS
Richard W.M. Jones ("rjones at redhat dot com") โ the legend himself. ๐
๐ COPYRIGHT
Copyright (C) 2011-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.
no cap, take the code, it's yours. ๐ โจ
๐ BUGS
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:
- 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.
fr fr though โ complete and unedited output. do not crop it, do not paraphrase it, do not "clean it up." the maintainers want the whole thing. ๐ญ
and that's the page, bestie ๐ซถ this was guestfs-perl(3), from libguestfs-1.61.3, dated 2026-09-16. go forth and script. ๐ฆ๐ธ๐
๐ฆ where this page comes from
- centos-stream 10: perl-Sys-Guestfs 1:1.61.3-1.el10 ยท 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