X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=edit%2Fvirt-edit;fp=edit%2Fvirt-edit;h=46e86a179202c5565008bb5da2196f2d5b53c911;hb=b488436cc54288fcae8988493749f2e6c87f274c;hp=0000000000000000000000000000000000000000;hpb=75b6338da3e6e33c02b931623f074ab5a76a1788;p=libguestfs.git diff --git a/edit/virt-edit b/edit/virt-edit new file mode 100755 index 0000000..46e86a1 --- /dev/null +++ b/edit/virt-edit @@ -0,0 +1,210 @@ +#!/usr/bin/perl -w +# virt-edit +# 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 warnings; +use strict; + +use Sys::Guestfs; +use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path + inspect_all_partitions inspect_partition + inspect_operating_systems mount_operating_system); +use Pod::Usage; +use Getopt::Long; +use File::Temp qw/tempfile/; +use Locale::TextDomain 'libguestfs'; + +=encoding utf8 + +=head1 NAME + +virt-edit - Edit a file in a virtual machine + +=head1 SYNOPSIS + + virt-edit [--options] domname file + + virt-edit [--options] disk.img [disk.img ...] file + +=head1 DESCRIPTION + +C is a command line tool to edit C where C +exists in the named virtual machine (or disk image). + +B you must I use virt-edit on live virtual machines. If +you do this, you risk disk corruption in the VM. + +If you want to just view a file, use L. For more complex +cases you should look at the L tool. + +=head1 EXAMPLES + + virt-edit mydomain /boot/grub/grub.conf + + virt-edit mydomain /etc/passwd + +=head1 OPTIONS + +=over 4 + +=cut + +my $help; + +=item B<--help> + +Display brief help. + +=cut + +my $version; + +=item B<--version> + +Display version number and exit. + +=cut + +my $uri; + +=item B<--connect URI> | B<-c URI> + +If using libvirt, connect to the given I. If omitted, then we +connect to the default libvirt hypervisor. + +If you specify guest block devices directly, then libvirt is not used +at all. + +=back + +=cut + +GetOptions ("help|?" => \$help, + "version" => \$version, + "connect|c=s" => \$uri, + ) or pod2usage (2); +pod2usage (1) if $help; +if ($version) { + my $g = Sys::Guestfs->new (); + my %h = $g->version (); + print "$h{major}.$h{minor}.$h{release}$h{extra}\n"; + exit +} + +pod2usage (__"virt-edit: no image, VM names or filenames to edit given") + if @ARGV <= 1; + +my $filename = pop @ARGV; + +my $g; +if ($uri) { + $g = open_guest (\@ARGV, address => $uri, rw => 1); +} else { + $g = open_guest (\@ARGV, rw => 1); +} + +$g->launch (); + +# List of possible filesystems. +my @partitions = get_partitions ($g); + +# Now query each one to build up a picture of what's in it. +my %fses = + inspect_all_partitions ($g, \@partitions, + use_windows_registry => 0); + +my $oses = inspect_operating_systems ($g, \%fses); + +my @roots = keys %$oses; +die __"no root device found in this operating system image" if @roots == 0; +die __"multiboot operating systems are not supported by virt-edit" if @roots > 1; +my $root_dev = $roots[0]; + +my $os = $oses->{$root_dev}; +mount_operating_system ($g, $os, 0); + +my ($fh, $tempname) = tempfile (); + +# Allow this to fail in case eg. the file does not exist. +$g->download($filename, $tempname); + +my $oldctime = (stat ($tempname))[10]; + +my $editor = $ENV{EDITOR}; +$editor ||= "vi"; +system ("$editor $tempname") == 0 + or die "edit failed: $editor: $?"; + +my $newctime = (stat ($tempname))[10]; + +if ($oldctime != $newctime) { + $g->upload ($tempname, $filename) +} else { + print __"File not changed.\n"; +} + +$g->sync (); +$g->umount_all (); + +undef $g; + +exit 0; + +=head1 ENVIRONMENT VARIABLES + +=over 4 + +=item C + +If set, this string is used as the editor. It may contain arguments, +eg. C<"emacs -nw"> + +If not set, C is used. + +=back + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L. + +=head1 AUTHOR + +Richard W.M. Jones L + +=head1 COPYRIGHT + +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.