diff options
author | Richard Jones <rjones@redhat.com> | 2009-04-08 13:44:13 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2009-04-08 13:44:13 +0100 |
commit | 1ee6da96efe8340a7d3904a865d80cd59d9d3fde (patch) | |
tree | 41b5b106d06c65d24bd8216b88005654abc0e98d /perl | |
parent | 8dcc88f867ab0bed24df49d8c0f347f1357bfffd (diff) | |
download | libguestfs-1ee6da96efe8340a7d3904a865d80cd59d9d3fde.tar.gz libguestfs-1ee6da96efe8340a7d3904a865d80cd59d9d3fde.tar.xz libguestfs-1ee6da96efe8340a7d3904a865d80cd59d9d3fde.zip |
First version of Perl bindings, compiled but not tested.
Diffstat (limited to 'perl')
-rw-r--r-- | perl/Guestfs.xs | 361 | ||||
-rw-r--r-- | perl/Makefile.PL.in | 28 | ||||
-rw-r--r-- | perl/Makefile.am | 20 | ||||
-rw-r--r-- | perl/lib/Sys/Guestfs.pm | 235 | ||||
-rw-r--r-- | perl/typemap | 17 |
5 files changed, 661 insertions, 0 deletions
diff --git a/perl/Guestfs.xs b/perl/Guestfs.xs new file mode 100644 index 00000000..e3f17c25 --- /dev/null +++ b/perl/Guestfs.xs @@ -0,0 +1,361 @@ +/* libguestfs generated file + * WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'. + * ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST. + * + * Copyright (C) 2009 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include <guestfs.h> + +/* #include cannot be used for local files in XS */ + +#ifndef PRId64 +#define PRId64 "lld" +#endif + +static SV * +my_newSVll(long long val) { +#ifdef USE_64_BIT_ALL + return newSViv(val); +#else + char buf[100]; + int len; + len = snprintf(buf, 100, "%" PRId64, val); + return newSVpv(buf, len); +#endif +} + +#ifndef PRIu64 +#define PRIu64 "llu" +#endif + +static SV * +my_newSVull(unsigned long long val) { +#ifdef USE_64_BIT_ALL + return newSVuv(val); +#else + char buf[100]; + int len; + len = snprintf(buf, 100, "%" PRIu64, val); + return newSVpv(buf, len); +#endif +} + +/* XXX Not thread-safe, and in general not safe if the caller is + * issuing multiple requests in parallel (on different guestfs + * handles). We should use the guestfs_h handle passed to the + * error handle to distinguish these cases. + */ +static char *last_error = NULL; + +static void +error_handler (guestfs_h *g, + void *data, + const char *msg) +{ + if (last_error != NULL) free (last_error); + last_error = strdup (msg); +} + +MODULE = Sys::Guestfs PACKAGE = Sys::Guestfs + +guestfs_h * +_create () +CODE: + RETVAL = guestfs_create (); + if (!RETVAL) + croak ("could not create guestfs handle"); + guestfs_set_error_handler (RETVAL, error_handler, NULL); +OUTPUT: + RETVAL + +void +DESTROY (g) + guestfs_h *g; +PPCODE: + guestfs_close (g); + +void +mount (g, device, mountpoint) + guestfs_h *g; + char *device; + char *mountpoint; + PPCODE: + if (guestfs_mount (g, device, mountpoint) == -1) + croak ("mount: %s", last_error); + +void +sync (g) + guestfs_h *g; + PPCODE: + if (guestfs_sync (g) == -1) + croak ("sync: %s", last_error); + +void +touch (g, path) + guestfs_h *g; + char *path; + PPCODE: + if (guestfs_touch (g, path) == -1) + croak ("touch: %s", last_error); + +SV * +cat (g, path) + guestfs_h *g; + char *path; +PREINIT: + char *content; + CODE: + content = guestfs_cat (g, path); + if (content == NULL) + croak ("cat: %s", last_error); + RETVAL = newSVpv (content, 0); + free (content); + OUTPUT: + RETVAL + +SV * +ll (g, directory) + guestfs_h *g; + char *directory; +PREINIT: + char *listing; + CODE: + listing = guestfs_ll (g, directory); + if (listing == NULL) + croak ("ll: %s", last_error); + RETVAL = newSVpv (listing, 0); + free (listing); + OUTPUT: + RETVAL + +void +ls (g, directory) + guestfs_h *g; + char *directory; +PREINIT: + char **listing; + int i, n; + PPCODE: + listing = guestfs_ls (g, directory); + if (listing == NULL) + croak ("ls: %s", last_error); + for (n = 0; listing[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (listing[i], 0))); + free (listing[i]); + } + free (listing); + +void +list_devices (g) + guestfs_h *g; +PREINIT: + char **devices; + int i, n; + PPCODE: + devices = guestfs_list_devices (g); + if (devices == NULL) + croak ("list_devices: %s", last_error); + for (n = 0; devices[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (devices[i], 0))); + free (devices[i]); + } + free (devices); + +void +list_partitions (g) + guestfs_h *g; +PREINIT: + char **partitions; + int i, n; + PPCODE: + partitions = guestfs_list_partitions (g); + if (partitions == NULL) + croak ("list_partitions: %s", last_error); + for (n = 0; partitions[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (partitions[i], 0))); + free (partitions[i]); + } + free (partitions); + +void +pvs (g) + guestfs_h *g; +PREINIT: + char **physvols; + int i, n; + PPCODE: + physvols = guestfs_pvs (g); + if (physvols == NULL) + croak ("pvs: %s", last_error); + for (n = 0; physvols[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (physvols[i], 0))); + free (physvols[i]); + } + free (physvols); + +void +vgs (g) + guestfs_h *g; +PREINIT: + char **volgroups; + int i, n; + PPCODE: + volgroups = guestfs_vgs (g); + if (volgroups == NULL) + croak ("vgs: %s", last_error); + for (n = 0; volgroups[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (volgroups[i], 0))); + free (volgroups[i]); + } + free (volgroups); + +void +lvs (g) + guestfs_h *g; +PREINIT: + char **logvols; + int i, n; + PPCODE: + logvols = guestfs_lvs (g); + if (logvols == NULL) + croak ("lvs: %s", last_error); + for (n = 0; logvols[n] != NULL; ++n) /**/; + EXTEND (SP, n); + for (i = 0; i < n; ++i) { + PUSHs (sv_2mortal (newSVpv (logvols[i], 0))); + free (logvols[i]); + } + free (logvols); + +void +pvs_full (g) + guestfs_h *g; +PREINIT: + struct guestfs_lvm_pv_list *physvols; + int i; + HV *hv; + PPCODE: + physvols = guestfs_pvs_full (g); + if (physvols == NULL) + croak ("pvs_full: %s", last_error); + EXTEND (SP, physvols->len); + for (i = 0; i < physvols->len; ++i) { + hv = newHV (); + (void) hv_store (hv, "pv_name", 7, newSVpv (physvols->val[i].pv_name, 0), 0); + (void) hv_store (hv, "pv_uuid", 7, newSVpv (physvols->val[i].pv_uuid, 32), 0); + (void) hv_store (hv, "pv_fmt", 6, newSVpv (physvols->val[i].pv_fmt, 0), 0); + (void) hv_store (hv, "pv_size", 7, my_newSVull (physvols->val[i].pv_size), 0); + (void) hv_store (hv, "dev_size", 8, my_newSVull (physvols->val[i].dev_size), 0); + (void) hv_store (hv, "pv_free", 7, my_newSVull (physvols->val[i].pv_free), 0); + (void) hv_store (hv, "pv_used", 7, my_newSVull (physvols->val[i].pv_used), 0); + (void) hv_store (hv, "pv_attr", 7, newSVpv (physvols->val[i].pv_attr, 0), 0); + (void) hv_store (hv, "pv_pe_count", 11, my_newSVll (physvols->val[i].pv_pe_count), 0); + (void) hv_store (hv, "pv_pe_alloc_count", 17, my_newSVll (physvols->val[i].pv_pe_alloc_count), 0); + (void) hv_store (hv, "pv_tags", 7, newSVpv (physvols->val[i].pv_tags, 0), 0); + (void) hv_store (hv, "pe_start", 8, my_newSVull (physvols->val[i].pe_start), 0); + (void) hv_store (hv, "pv_mda_count", 12, my_newSVll (physvols->val[i].pv_mda_count), 0); + (void) hv_store (hv, "pv_mda_free", 11, my_newSVull (physvols->val[i].pv_mda_free), 0); + PUSHs (sv_2mortal ((SV *) hv)); + } + guestfs_free_lvm_pv_list (physvols); + +void +vgs_full (g) + guestfs_h *g; +PREINIT: + struct guestfs_lvm_vg_list *volgroups; + int i; + HV *hv; + PPCODE: + volgroups = guestfs_vgs_full (g); + if (volgroups == NULL) + croak ("vgs_full: %s", last_error); + EXTEND (SP, volgroups->len); + for (i = 0; i < volgroups->len; ++i) { + hv = newHV (); + (void) hv_store (hv, "vg_name", 7, newSVpv (volgroups->val[i].vg_name, 0), 0); + (void) hv_store (hv, "vg_uuid", 7, newSVpv (volgroups->val[i].vg_uuid, 32), 0); + (void) hv_store (hv, "vg_fmt", 6, newSVpv (volgroups->val[i].vg_fmt, 0), 0); + (void) hv_store (hv, "vg_attr", 7, newSVpv (volgroups->val[i].vg_attr, 0), 0); + (void) hv_store (hv, "vg_size", 7, my_newSVull (volgroups->val[i].vg_size), 0); + (void) hv_store (hv, "vg_free", 7, my_newSVull (volgroups->val[i].vg_free), 0); + (void) hv_store (hv, "vg_sysid", 8, newSVpv (volgroups->val[i].vg_sysid, 0), 0); + (void) hv_store (hv, "vg_extent_size", 14, my_newSVull (volgroups->val[i].vg_extent_size), 0); + (void) hv_store (hv, "vg_extent_count", 15, my_newSVll (volgroups->val[i].vg_extent_count), 0); + (void) hv_store (hv, "vg_free_count", 13, my_newSVll (volgroups->val[i].vg_free_count), 0); + (void) hv_store (hv, "max_lv", 6, my_newSVll (volgroups->val[i].max_lv), 0); + (void) hv_store (hv, "max_pv", 6, my_newSVll (volgroups->val[i].max_pv), 0); + (void) hv_store (hv, "pv_count", 8, my_newSVll (volgroups->val[i].pv_count), 0); + (void) hv_store (hv, "lv_count", 8, my_newSVll (volgroups->val[i].lv_count), 0); + (void) hv_store (hv, "snap_count", 10, my_newSVll (volgroups->val[i].snap_count), 0); + (void) hv_store (hv, "vg_seqno", 8, my_newSVll (volgroups->val[i].vg_seqno), 0); + (void) hv_store (hv, "vg_tags", 7, newSVpv (volgroups->val[i].vg_tags, 0), 0); + (void) hv_store (hv, "vg_mda_count", 12, my_newSVll (volgroups->val[i].vg_mda_count), 0); + (void) hv_store (hv, "vg_mda_free", 11, my_newSVull (volgroups->val[i].vg_mda_free), 0); + PUSHs (sv_2mortal ((SV *) hv)); + } + guestfs_free_lvm_vg_list (volgroups); + +void +lvs_full (g) + guestfs_h *g; +PREINIT: + struct guestfs_lvm_lv_list *logvols; + int i; + HV *hv; + PPCODE: + logvols = guestfs_lvs_full (g); + if (logvols == NULL) + croak ("lvs_full: %s", last_error); + EXTEND (SP, logvols->len); + for (i = 0; i < logvols->len; ++i) { + hv = newHV (); + (void) hv_store (hv, "lv_name", 7, newSVpv (logvols->val[i].lv_name, 0), 0); + (void) hv_store (hv, "lv_uuid", 7, newSVpv (logvols->val[i].lv_uuid, 32), 0); + (void) hv_store (hv, "lv_attr", 7, newSVpv (logvols->val[i].lv_attr, 0), 0); + (void) hv_store (hv, "lv_major", 8, my_newSVll (logvols->val[i].lv_major), 0); + (void) hv_store (hv, "lv_minor", 8, my_newSVll (logvols->val[i].lv_minor), 0); + (void) hv_store (hv, "lv_kernel_major", 15, my_newSVll (logvols->val[i].lv_kernel_major), 0); + (void) hv_store (hv, "lv_kernel_minor", 15, my_newSVll (logvols->val[i].lv_kernel_minor), 0); + (void) hv_store (hv, "lv_size", 7, my_newSVull (logvols->val[i].lv_size), 0); + (void) hv_store (hv, "seg_count", 9, my_newSVll (logvols->val[i].seg_count), 0); + (void) hv_store (hv, "origin", 6, newSVpv (logvols->val[i].origin, 0), 0); + (void) hv_store (hv, "snap_percent", 12, newSVnv (logvols->val[i].snap_percent), 0); + (void) hv_store (hv, "copy_percent", 12, newSVnv (logvols->val[i].copy_percent), 0); + (void) hv_store (hv, "move_pv", 7, newSVpv (logvols->val[i].move_pv, 0), 0); + (void) hv_store (hv, "lv_tags", 7, newSVpv (logvols->val[i].lv_tags, 0), 0); + (void) hv_store (hv, "mirror_log", 10, newSVpv (logvols->val[i].mirror_log, 0), 0); + (void) hv_store (hv, "modules", 7, newSVpv (logvols->val[i].modules, 0), 0); + PUSHs (sv_2mortal ((SV *) hv)); + } + guestfs_free_lvm_lv_list (logvols); + diff --git a/perl/Makefile.PL.in b/perl/Makefile.PL.in new file mode 100644 index 00000000..423b4a18 --- /dev/null +++ b/perl/Makefile.PL.in @@ -0,0 +1,28 @@ +# libguestfs Perl bindings +# Copyright (C) 2009 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +use ExtUtils::MakeMaker; + +WriteMakefile ( + FIRST_MAKEFILE => 'Makefile-pl', + + NAME => 'Sys::Guestfs', + VERSION => '@PACKAGE_VERSION@', + + LIBS => '-L@abs_top_builddir@/src/.libs -lguestfs', + INC => '-Wall @CFLAGS@ -I@abs_top_builddir@/src', + ); diff --git a/perl/Makefile.am b/perl/Makefile.am index 6b12064a..ea9835b0 100644 --- a/perl/Makefile.am +++ b/perl/Makefile.am @@ -14,3 +14,23 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +EXTRA_DIST = \ + Makefile.PL.in \ + Guestfs.xs \ + guestfs_perl.c \ + typemap \ + perl/lib/Sys/Guestfs.pm + +if HAVE_PERL + +# Interfacing automake and ExtUtils::MakeMaker known to be +# a nightmare, news at 11. +all: + perl Makefile.PL + make -f Makefile-pl + +install-data-hook: + make -f Makefile-pl DESTDIR=$(DESTDIR) install + +endif diff --git a/perl/lib/Sys/Guestfs.pm b/perl/lib/Sys/Guestfs.pm new file mode 100644 index 00000000..c0a9b79f --- /dev/null +++ b/perl/lib/Sys/Guestfs.pm @@ -0,0 +1,235 @@ +# libguestfs generated file +# WARNING: THIS FILE IS GENERATED BY 'src/generator.ml'. +# ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST. +# +# Copyright (C) 2009 Red Hat Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +=pod + +=head1 NAME + +Sys::Guestfs - Perl bindings for libguestfs + +=head1 SYNOPSIS + + use Sys::Guestfs; + + my $h = Sys::Guestfs->new (); + $h->add_drive ('guest.img'); + $h->launch (); + $h->wait_ready (); + $h->mount ('/dev/sda1', '/'); + $h->touch ('/hello'); + $h->sync (); + +=head1 DESCRIPTION + +The C<Sys::Guestfs> module provides a Perl XS binding to the +libguestfs API for examining and modifying virtual machine +disk images. + +Amongst the things this is good for: making batch configuration +changes to guests, getting disk used/free statistics (see also: +virt-df), migrating between virtualization systems (see also: +virt-p2v), performing partial backups, performing partial guest +clones, cloning guests and changing registry/UUID/hostname info, and +much else besides. + +Libguestfs uses Linux kernel and qemu code, and can access any type of +guest filesystem that Linux and qemu can, including but not limited +to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition +schemes, qcow, qcow2, vmdk. + +Libguestfs provides ways to enumerate guest storage (eg. partitions, +LVs, what filesystem is in each LV, etc.). It can also run commands +in the context of the guest. Also you can access filesystems over FTP. + +=head1 ERRORS + +All errors turn into calls to C<croak> (see L<Carp(3)>). + +=head1 METHODS + +=over 4 + +=cut + +package Sys::Guestfs; + +use strict; +use warnings; + +require XSLoader; +XSLoader::load ('Sys::Guestfs'); + +=item $h = Sys::Guestfs->new (); + +Create a new guestfs handle. + +=cut + +sub new { + my $proto = shift; + my $class = ref ($proto) || $proto; + + my $self = Sys::Guestfs::_create (); + bless $self, $class; + return $self; +} + +=item $content = $h->cat (path); + +Return the contents of the file named C<path>. + +Note that this function cannot correctly handle binary files +(specifically, files containing C<\0> character which is treated +as end of string). For those you need to use the C<$h-E<gt>read_file> +function which has a more complex interface. + +Because of the message protocol, there is a transfer limit +of somewhere between 2MB and 4MB. To transfer large files you should use +FTP. + +=item @devices = $h->list_devices (); + +List all the block devices. + +The full block device names are returned, eg. C</dev/sda> + +=item @partitions = $h->list_partitions (); + +List all the partitions detected on all block devices. + +The full partition device names are returned, eg. C</dev/sda1> + +This does not return logical volumes. For that you will need to +call C<$h-E<gt>lvs>. + +=item $listing = $h->ll (directory); + +List the files in C<directory> (relative to the root directory, +there is no cwd) in the format of 'ls -la'. + +This command is mostly useful for interactive sessions. It +is I<not> intended that you try to parse the output string. + +=item @listing = $h->ls (directory); + +List the files in C<directory> (relative to the root directory, +there is no cwd). The '.' and '..' entries are not returned, but +hidden files are shown. + +This command is mostly useful for interactive sessions. Programs +should probably use C<$h-E<gt>readdir> instead. + +=item @logvols = $h->lvs (); + +List all the logical volumes detected. This is the equivalent +of the L<lvs(8)> command. + +This returns a list of the logical volume device names +(eg. C</dev/VolGroup00/LogVol00>). + +See also C<$h-E<gt>lvs_full>. + +=item @logvols = $h->lvs_full (); + +List all the logical volumes detected. This is the equivalent +of the L<lvs(8)> command. The "full" version includes all fields. + +=item $h->mount (device, mountpoint); + +Mount a guest disk at a position in the filesystem. Block devices +are named C</dev/sda>, C</dev/sdb> and so on, as they were added to +the guest. If those block devices contain partitions, they will have +the usual names (eg. C</dev/sda1>). Also LVM C</dev/VG/LV>-style +names can be used. + +The rules are the same as for L<mount(2)>: A filesystem must +first be mounted on C</> before others can be mounted. Other +filesystems can only be mounted on directories which already +exist. + +The mounted filesystem is writable, if we have sufficient permissions +on the underlying device. + +The filesystem options C<sync> and C<noatime> are set with this +call, in order to improve reliability. + +=item @physvols = $h->pvs (); + +List all the physical volumes detected. This is the equivalent +of the L<pvs(8)> command. + +This returns a list of just the device names that contain +PVs (eg. C</dev/sda2>). + +See also C<$h-E<gt>pvs_full>. + +=item @physvols = $h->pvs_full (); + +List all the physical volumes detected. This is the equivalent +of the L<pvs(8)> command. The "full" version includes all fields. + +=item $h->sync (); + +This syncs the disk, so that any writes are flushed through to the +underlying disk image. + +You should always call this if you have modified a disk image, before +closing the handle. + +=item $h->touch (path); + +Touch acts like the L<touch(1)> command. It can be used to +update the timestamps on a file, or, if the file does not exist, +to create a new zero-length file. + +=item @volgroups = $h->vgs (); + +List all the volumes groups detected. This is the equivalent +of the L<vgs(8)> command. + +This returns a list of just the volume group names that were +detected (eg. C<VolGroup00>). + +See also C<$h-E<gt>vgs_full>. + +=item @volgroups = $h->vgs_full (); + +List all the volumes groups detected. This is the equivalent +of the L<vgs(8)> command. The "full" version includes all fields. + +=cut + +1; + +=back + +=head1 COPYRIGHT + +Copyright (C) 2009 Red Hat Inc. + +=head1 LICENSE + +Please see the file COPYING.LIB for the full license. + +=head1 SEE ALSO + +L<guestfs(3)>, L<guestfish(1)>. + +=cut diff --git a/perl/typemap b/perl/typemap new file mode 100644 index 00000000..421e73a2 --- /dev/null +++ b/perl/typemap @@ -0,0 +1,17 @@ +TYPEMAP +char * T_PV +const char * T_PV +guestfs_h * O_OBJECT_guestfs_h + +INPUT +O_OBJECT_guestfs_h + if (sv_isobject ($arg) && SvTYPE (SvRV ($arg)) == SVt_PVMG) + $var = ($type) SvIV ((SV *) SvRV ($arg)); + else { + warn (\"${Package}::$func_name(): $var is not a blessed SV reference\"); + XSRETURN_UNDEF; + } + +OUTPUT +O_OBJECT_guestfs_h + sv_setref_pv ($arg, "Sys::Guestfs", (void *) $var); |