mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
golang: Add examples and guestfs-golang(3) man page.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -174,6 +174,8 @@ Makefile.in
|
||||
/gobject/guestfs-gobject*.c
|
||||
/gobject/guestfs-gobject*.h
|
||||
/golang/bindtests.go
|
||||
/golang/examples/guestfs-golang.3
|
||||
/golang/examples/stamp-guestfs-golang.pod
|
||||
/golang/pkg
|
||||
/guestfs-release-notes.1
|
||||
/guestfsd-in-wine.log
|
||||
@@ -188,6 +190,7 @@ Makefile.in
|
||||
/html/guestfs-erlang.3.html
|
||||
/html/guestfs-examples.3.html
|
||||
/html/guestfs-faq.1.html
|
||||
/html/guestfs-golang.3.html
|
||||
/html/guestfs-java.3.html
|
||||
/html/guestfs-lua.3.html
|
||||
/html/guestfs-ocaml.3.html
|
||||
|
||||
@@ -105,7 +105,7 @@ if HAVE_GOBJECT
|
||||
SUBDIRS += gobject
|
||||
endif
|
||||
if HAVE_GOLANG
|
||||
SUBDIRS += golang
|
||||
SUBDIRS += golang golang/examples
|
||||
endif
|
||||
|
||||
# Unconditional because nothing is built yet.
|
||||
@@ -184,6 +184,7 @@ HTMLFILES = \
|
||||
html/guestfs-examples.3.html \
|
||||
html/guestfs-erlang.3.html \
|
||||
html/guestfs-faq.1.html \
|
||||
html/guestfs-golang.3.html \
|
||||
html/guestfs-java.3.html \
|
||||
html/guestfs-lua.3.html \
|
||||
html/guestfs-ocaml.3.html \
|
||||
|
||||
@@ -1617,6 +1617,7 @@ AC_CONFIG_FILES([Makefile
|
||||
gobject/docs/Makefile
|
||||
gobject/docs/guestfs-docs.sgml
|
||||
golang/Makefile
|
||||
golang/examples/Makefile
|
||||
haskell/Makefile
|
||||
inspector/Makefile
|
||||
java/Makefile
|
||||
|
||||
@@ -98,6 +98,7 @@ C<Arg> is the name of the unknown argument.
|
||||
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
@@ -58,6 +58,7 @@ libguestfs, you also need to read L<guestfs(3)>.
|
||||
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
@@ -547,6 +547,7 @@ L<guestfs(3)>,
|
||||
L<guestfish(1)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
2
golang/examples/LICENSE
Normal file
2
golang/examples/LICENSE
Normal file
@@ -0,0 +1,2 @@
|
||||
All the examples in the golang/examples/ subdirectory may be freely
|
||||
copied without any restrictions.
|
||||
42
golang/examples/Makefile.am
Normal file
42
golang/examples/Makefile.am
Normal file
@@ -0,0 +1,42 @@
|
||||
# libguestfs Go examples
|
||||
# Copyright (C) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
include $(top_srcdir)/subdir-rules.mk
|
||||
|
||||
EXTRA_DIST = \
|
||||
LICENSE \
|
||||
create-disk.go \
|
||||
inspect-vm.go \
|
||||
guestfs-golang.pod
|
||||
|
||||
CLEANFILES = stamp-guestfs-golang.pod
|
||||
|
||||
man_MANS = guestfs-golang.3
|
||||
noinst_DATA = $(top_builddir)/html/guestfs-golang.3.html
|
||||
|
||||
guestfs-golang.3 $(top_builddir)/html/guestfs-golang.3.html: stamp-guestfs-golang.pod
|
||||
|
||||
stamp-guestfs-golang.pod: guestfs-golang.pod create-disk.go inspect-vm.go
|
||||
$(PODWRAPPER) \
|
||||
--section 3 \
|
||||
--man guestfs-golang.3 \
|
||||
--html $(top_builddir)/html/guestfs-golang.3.html \
|
||||
--verbatim $(srcdir)/create-disk.go:@EXAMPLE1@ \
|
||||
--verbatim $(srcdir)/inspect-vm.go:@EXAMPLE2@ \
|
||||
--license examples \
|
||||
$<
|
||||
touch $@
|
||||
122
golang/examples/create-disk.go
Normal file
122
golang/examples/create-disk.go
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Example showing how to create a disk image. */
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"libguestfs.org/guestfs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
output := "disk.img"
|
||||
|
||||
g, errno := guestfs.Create ()
|
||||
if errno != nil {
|
||||
panic (errno)
|
||||
}
|
||||
defer g.Close ()
|
||||
|
||||
/* Create a raw-format sparse disk image, 512 MB in size. */
|
||||
f, ferr := os.Create (output)
|
||||
if ferr != nil {
|
||||
panic (fmt.Sprintf ("could not create file: %s: %s",
|
||||
output, ferr))
|
||||
}
|
||||
defer f.Close ()
|
||||
|
||||
if ferr := f.Truncate (512 * 1024 * 1024); ferr != nil {
|
||||
panic (fmt.Sprintf ("could not truncate file: %s", ferr))
|
||||
}
|
||||
|
||||
/* Set the trace flag so that we can see each libguestfs call. */
|
||||
g.Set_trace (true)
|
||||
|
||||
/* Attach the disk image to libguestfs. */
|
||||
optargs := guestfs.OptargsAdd_drive{
|
||||
Format_is_set: true,
|
||||
Format: "raw",
|
||||
Readonly_is_set: true,
|
||||
Readonly: false,
|
||||
}
|
||||
if err := g.Add_drive (output, &optargs); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Run the libguestfs back-end. */
|
||||
if err := g.Launch (); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Get the list of devices. Because we only added one drive
|
||||
* above, we expect that this list should contain a single
|
||||
* element.
|
||||
*/
|
||||
devices, err := g.List_devices ()
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
if len(devices) != 1 {
|
||||
panic ("expected a single device from list-devices")
|
||||
}
|
||||
|
||||
/* Partition the disk as one single MBR partition. */
|
||||
err = g.Part_disk (devices[0], "mbr")
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Get the list of partitions. We expect a single element, which
|
||||
* is the partition we have just created.
|
||||
*/
|
||||
partitions, err := g.List_partitions ()
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
if len(partitions) != 1 {
|
||||
panic ("expected a single partition from list-partitions")
|
||||
}
|
||||
|
||||
/* Create a filesystem on the partition. */
|
||||
err = g.Mkfs ("ext4", partitions[0], nil)
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Now mount the filesystem so that we can add files. */
|
||||
err = g.Mount (partitions[0], "/")
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Create some files and directories. */
|
||||
err = g.Touch ("/empty")
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
message := []byte("Hello, world\n")
|
||||
err = g.Write ("/hello", message)
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
err = g.Mkdir ("/foo")
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* This one uploads the local file /etc/resolv.conf into
|
||||
* the disk image.
|
||||
*/
|
||||
err = g.Upload ("/etc/resolv.conf", "/foo/resolv.conf")
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
if err = g.Shutdown (); err != nil {
|
||||
panic (fmt.Sprintf ("write to disk failed: %s", err))
|
||||
}
|
||||
}
|
||||
99
golang/examples/guestfs-golang.pod
Normal file
99
golang/examples/guestfs-golang.pod
Normal file
@@ -0,0 +1,99 @@
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
guestfs-golang - How to use libguestfs from Go
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
import "libguestfs.org/guestfs"
|
||||
|
||||
g, errno := guestfs.Create ()
|
||||
if errno != nil {
|
||||
panic (fmt.Sprintf ("could not create handle: %s", errno))
|
||||
}
|
||||
defer g.Close ()
|
||||
if err := g.Add_drive ("test.img"); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
if err := g.Launch (); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
if err := g.Shutdown (); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This manual page documents how to call libguestfs from the Go
|
||||
programming language. This page just documents the differences from
|
||||
the C API and gives some examples. If you are not familiar with using
|
||||
libguestfs, you also need to read L<guestfs(3)>.
|
||||
|
||||
=head2 IMPORTING THE MODULE
|
||||
|
||||
The module is called C<guestfs>. The full package name to import is
|
||||
C<libguestfs.org/guestfs>.
|
||||
|
||||
=head2 CREATING AND CLOSING THE HANDLE
|
||||
|
||||
Use either C<guestfs.Create> or C<guestfs.Create_flags> to create the
|
||||
handle. The handle is closed implicitly if it is garbage collected.
|
||||
However it is probably a good idea to close it explicitly, either by
|
||||
calling S<C<g.Close ()>> or by deferring the same.
|
||||
|
||||
=head2 ERRORS
|
||||
|
||||
C<guestfs.Create> and C<guestfs.Create_flags> return a simple
|
||||
C<*error>, which is really just a C C<errno> wrapped up in the
|
||||
appropriate golang struct.
|
||||
|
||||
All other calls return a C<*GuestfsError> which (if non-nil) is a
|
||||
richer struct that contains the error string from libguestfs, the
|
||||
errno (if available) and the operation which failed. This can also be
|
||||
converted to a string for display.
|
||||
|
||||
=head2 LIMITATIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
No support for events (see L<guestfs(3)/EVENTS>).
|
||||
|
||||
=item *
|
||||
|
||||
UUIDs are not returned in structures.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLE 1: CREATE A DISK IMAGE
|
||||
|
||||
@EXAMPLE1@
|
||||
|
||||
=head1 EXAMPLE 2: INSPECT A VIRTUAL MACHINE DISK IMAGE
|
||||
|
||||
@EXAMPLE2@
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
L<guestfs-perl(3)>,
|
||||
L<guestfs-python(3)>,
|
||||
L<guestfs-recipes(1)>,
|
||||
L<guestfs-ruby(3)>,
|
||||
L<http://www.golang.org/>,
|
||||
L<http://libguestfs.org/>.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Richard W.M. Jones (C<rjones at redhat dot com>)
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2013 Red Hat Inc.
|
||||
65
golang/examples/inspect-vm.go
Normal file
65
golang/examples/inspect-vm.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/* Example showing how to inspect a virtual machine disk. */
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"libguestfs.org/guestfs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
panic ("usage: inspect-vm disk.img")
|
||||
}
|
||||
disk := os.Args[1]
|
||||
|
||||
g, errno := guestfs.Create ()
|
||||
if errno != nil {
|
||||
panic (fmt.Sprintf ("could not create handle: %s", errno))
|
||||
}
|
||||
|
||||
/* Attach the disk image read-only to libguestfs. */
|
||||
optargs := guestfs.OptargsAdd_drive{
|
||||
Format_is_set: true,
|
||||
Format: "raw",
|
||||
Readonly_is_set: true,
|
||||
Readonly: true,
|
||||
}
|
||||
if err := g.Add_drive (disk, &optargs); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Run the libguestfs back-end. */
|
||||
if err := g.Launch (); err != nil {
|
||||
panic (err)
|
||||
}
|
||||
|
||||
/* Ask libguestfs to inspect for operating systems. */
|
||||
roots, err := g.Inspect_os ()
|
||||
if err != nil {
|
||||
panic (err)
|
||||
}
|
||||
if len(roots) == 0 {
|
||||
panic ("inspect-vm: no operating systems found")
|
||||
}
|
||||
|
||||
for _, root := range roots {
|
||||
fmt.Printf ("Root device: %s\n", root)
|
||||
|
||||
/* Print basic information about the operating system. */
|
||||
s, _ := g.Inspect_get_product_name (root)
|
||||
fmt.Printf (" Product name: %s\n", s)
|
||||
major, _ := g.Inspect_get_major_version (root)
|
||||
minor, _ := g.Inspect_get_minor_version (root)
|
||||
fmt.Printf (" Version: %d.%d\n", major, minor)
|
||||
s, _ = g.Inspect_get_type (root)
|
||||
fmt.Printf (" Type: %s\n", s)
|
||||
s, _ = g.Inspect_get_distro (root)
|
||||
fmt.Printf (" Distro: %s\n", s)
|
||||
|
||||
/* XXX Incomplete example. Sorting the keys by length
|
||||
* is unnecessarily hard in golang.
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@ The output looks similar to this:
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
L<guestfs-perl(3)>,
|
||||
|
||||
@@ -140,6 +140,7 @@ returned when you registered the callback:
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
L<guestfs-perl(3)>,
|
||||
|
||||
@@ -80,6 +80,7 @@ function that you called.
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-perl(3)>,
|
||||
|
||||
@@ -43,6 +43,7 @@ L<Sys::Guestfs(3)>,
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
@@ -31,6 +31,7 @@ MANPAGES = \
|
||||
guestfs-erlang.3 \
|
||||
guestfs-examples.3 \
|
||||
guestfs-faq.1 \
|
||||
guestfs-golang.3 \
|
||||
guestfs-java.3 \
|
||||
guestfs-lua.3 \
|
||||
guestfs-ocaml.3 \
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
../format/virt-format.pod
|
||||
../fuse/guestmount.pod
|
||||
../fuse/guestunmount.pod
|
||||
../golang/examples/guestfs-golang.pod
|
||||
../guestfs-release-notes.pod
|
||||
../inspector/virt-inspector.pod
|
||||
../java/examples/guestfs-java.pod
|
||||
|
||||
@@ -31,6 +31,7 @@ MANPAGES = \
|
||||
guestfs-erlang.3 \
|
||||
guestfs-examples.3 \
|
||||
guestfs-faq.1 \
|
||||
guestfs-golang.3 \
|
||||
guestfs-java.3 \
|
||||
guestfs-lua.3 \
|
||||
guestfs-ocaml.3 \
|
||||
|
||||
@@ -55,6 +55,7 @@ Type:
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
@@ -38,6 +38,7 @@ string).
|
||||
L<guestfs(3)>,
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
@@ -1092,20 +1092,7 @@ available. See the C<gobject> directory in the source.
|
||||
|
||||
=item B<Go>
|
||||
|
||||
Experimental Go bindings are available. See the C<golang> directory
|
||||
in the source. These are incomplete:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
No support for L</EVENTS>.
|
||||
|
||||
=item *
|
||||
|
||||
UUIDs cannot be returned in structures.
|
||||
|
||||
=back
|
||||
See <guestfs-golang(3)>.
|
||||
|
||||
=item B<Haskell>
|
||||
|
||||
@@ -4507,6 +4494,7 @@ See L</LIBGUESTFS_CACHEDIR>, L</LIBGUESTFS_TMPDIR>.
|
||||
|
||||
L<guestfs-examples(3)>,
|
||||
L<guestfs-erlang(3)>,
|
||||
L<guestfs-golang(3)>,
|
||||
L<guestfs-java(3)>,
|
||||
L<guestfs-lua(3)>,
|
||||
L<guestfs-ocaml(3)>,
|
||||
|
||||
Reference in New Issue
Block a user