From dd4b11064546472a5e950ac123728dc54b34a7b2 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Mon, 23 Jul 2007 07:45:32 +0000 Subject: [PATCH] Add the gnt-backup script and man-pages. Reviewed-by: imsnah --- man/Makefile.am | 7 +- man/gnt-backup.sgml | 246 ++++++++++++++++++++++++++++++++++++++++++++ scripts/Makefile.am | 2 +- scripts/gnt-backup | 160 ++++++++++++++++++++++++++++ 4 files changed, 412 insertions(+), 3 deletions(-) create mode 100644 man/gnt-backup.sgml create mode 100755 scripts/gnt-backup diff --git a/man/Makefile.am b/man/Makefile.am index 0c6cdb7d6..1c062e8d2 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,9 +1,12 @@ # Build man pages # -man_MANS = ganeti.7 ganeti-os-interface.7 gnt-cluster.8 gnt-node.8 gnt-os.8 gnt-instance.8 ganeti-noded.8 ganeti-watcher.8 +man_MANS = ganeti.7 ganeti-os-interface.7 gnt-cluster.8 gnt-node.8 gnt-os.8 \ + gnt-instance.8 ganeti-noded.8 ganeti-watcher.8 gnt-backup.8 + EXTRA_DIST = ganeti-os-interface.sgml gnt-cluster.sgml gnt-node.sgml \ - ganeti-watcher.sgml ganeti.sgml gnt-instance.sgml gnt-os.sgml ganeti-noded.sgml \ + ganeti-watcher.sgml ganeti.sgml gnt-instance.sgml gnt-os.sgml \ + gnt-backup.sgml ganeti-noded.sgml \ footer.sgml $(man_MANS) %.8: %.sgml footer.sgml diff --git a/man/gnt-backup.sgml b/man/gnt-backup.sgml new file mode 100644 index 000000000..d62824073 --- /dev/null +++ b/man/gnt-backup.sgml @@ -0,0 +1,246 @@ +<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ + + <!-- Fill in your name for FIRSTNAME and SURNAME. --> + <!-- Please adjust the date whenever revising the manpage. --> + <!ENTITY dhdate "<date>Jul 6, 2007</date>"> + <!-- SECTION should be 1-8, maybe w/ subsection other parameters are + allowed: see man(7), man(1). --> + <!ENTITY dhsection "<manvolnum>8</manvolnum>"> + <!ENTITY dhucpackage "<refentrytitle>gnt-backup</refentrytitle>"> + <!ENTITY dhpackage "gnt-backup"> + + <!ENTITY debian "<productname>Debian</productname>"> + <!ENTITY gnu "<acronym>GNU</acronym>"> + <!ENTITY gpl "&gnu; <acronym>GPL</acronym>"> + <!ENTITY footer SYSTEM "footer.sgml"> +]> + +<refentry> + <refentryinfo> + <copyright> + <year>2007</year> + <holder>Google Inc.</holder> + </copyright> + &dhdate; + </refentryinfo> + <refmeta> + &dhucpackage; + + &dhsection; + <refmiscinfo>ganeti 1.2</refmiscinfo> + </refmeta> + <refnamediv> + <refname>&dhpackage;</refname> + + <refpurpose>ganeti instance import/export</refpurpose> + </refnamediv> + <refsynopsisdiv> + <cmdsynopsis> + <command>&dhpackage; </command> + + <arg choice="req">command</arg> + <arg>arguments...</arg> + </cmdsynopsis> + </refsynopsisdiv> + <refsect1> + <title>DESCRIPTION</title> + + <para> + The <command>&dhpackage;</command> is used for importing and exporting + instances and their configuration from a ganeti system. It is useful for + backing instances up and also to migrate them between clusters. + </para> + + </refsect1> + <refsect1> + <title>COMMANDS</title> + + <refsect2> + <title>EXPORT</title> + + <cmdsynopsis> + <command>export</command> + <arg choice="req">-n <replaceable>node</replaceable></arg> + <arg>--noshutdown</arg> + <arg choice="req"><replaceable>instance</replaceable></arg> + </cmdsynopsis> + + <para> + Exports an instance to the target node. All the instance + data and its configuration will be exported under the + /srv/ganeti/exports/instance directory on the target node. + </para> + + <para> + The <option>--noshutdown</option> option will create a + snapshot disk of the instance without shutting it down first. + While this is faster and involves no downtime, it cannot be + guaranteed that the instance data will be in a consistent state + in the exported dump. + </para> + + <para> + Example: + <screen> +# gnt-instance export -n node1.example.com instance3.example.com + </screen> + </para> + </refsect2> + + <refsect2> + <title>IMPORT</title> + <cmdsynopsis> + <command>import</command> + <arg choice="req">-n <replaceable>node</replaceable></arg> + <arg>-s <replaceable>disksize</replaceable></arg> + <arg>-o <replaceable>os-type</replaceable></arg> + <arg>-m <replaceable>memsize</replaceable></arg> + <arg>-b <replaceable>bridge</replaceable></arg> + <sbr> + <arg choice="req">-t<group> + <arg>diskless</arg> + <arg>plain</arg> + <arg>local_raid1</arg> + <arg>remote_raid1</arg> + </group> + </arg> + <arg choice="req">--src-node=<replaceable>source-node</replaceable></arg> + <arg choice="req">--src-dir=<replaceable>source-dir</replaceable></arg> + <arg choice="req"><replaceable>instance</replaceable></arg> + </cmdsynopsis> + <para> + Imports a new instance from an export residing on + <replaceable>source-node</replaceable> in + <replaceable>source-dir</replaceable>. + <replaceable>instance</replaceable> must be in DNS and + resolve to a IP in the same network as the nodes in the + cluster. + </para> + + <para> + The <option>-s</option> option specifies the disk size for + the instance, in gigibytes (defaults to 20 GiB). + </para> + + <para> + The <option>-o</option> options specifies the operating + system to be installed. The available operating systems can + be listed with <command>gnt-os list</command>. + </para> + + <para> + The <option>-m</option> option specifies the memory size for + the instance, in megibytes (defaults to 128 MiB). + </para> + + <para> + The <option>-b</option> option specifies the bridge to which the + instance will be connected. (defaults to the cluster-wide default + bridge specified at cluster intialization time). + </para> + + <para> + The <option>-t</option> options specifies the disk layout type for + the instance. The available choices are: + <variablelist> + <varlistentry> + <term>diskless</term> + <listitem> + <para> + This creates an instance with no disks. Its useful for + testing only (or other special cases). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>plain</term> + <listitem> + <para>Disk devices will be logical volumes.</para> + </listitem> + </varlistentry> + <varlistentry> + <term>local_raid1</term> + <listitem> + <para> + Disk devices will be md raid1 arrays over two local + logical volumes. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term>remote_raid1</term> + <listitem> + <para> + Disk devices will be md raid1 arrays with one + component (so it's not actually raid1): a drbd device + between the instance's primary node and the node given + by the option <option>--secondary-node</option>. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + + <para> + The <option>--secondary-node</option> option is used with + the remote raid disk template type and specifies the remote + node. + </para> + + <para> + If you do not want gnt-instance to wait for the disk mirror + to be synced, use the <option>--no-wait-for-sync</option> + option. + </para> + + + <para> + Example: + <screen> +# gnt-backup import -t plain -s 30 -m 512 -n node1.example.com \ +> --src-node=node2.example.com \ +> --src-dir=/srv/ganeti/exports/instance3.example.com \ +> instance3.example.com + </screen> + </para> + + </refsect2> + + <refsect2> + <title>LIST</title> + + <cmdsynopsis> + <command>list</command> + <arg>--nodes=<replaceable>NODE-LIST</replaceable></arg> + </cmdsynopsis> + + <para> + Lists the exports currently available in the default directory in all + the nodes of the current cluster, or optionally only a subset of them + specified by the <option>--nodes</option> option. + </para> + + </refsect2> + + </refsect1> + + &footer; + +</refentry> + +<!-- Keep this comment at the end of the file +Local variables: +mode: sgml +sgml-omittag:t +sgml-shorttag:t +sgml-minimize-attributes:nil +sgml-always-quote-attributes:t +sgml-indent-step:2 +sgml-indent-data:t +sgml-parent-document:nil +sgml-default-dtd-file:nil +sgml-exposed-tags:nil +sgml-local-catalogs:nil +sgml-local-ecat-files:nil +End: +--> diff --git a/scripts/Makefile.am b/scripts/Makefile.am index bbc53e40a..3a62d29ad 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -1 +1 @@ -dist_sbin_SCRIPTS = gnt-instance gnt-cluster gnt-node gnt-os +dist_sbin_SCRIPTS = gnt-instance gnt-cluster gnt-node gnt-os gnt-backup diff --git a/scripts/gnt-backup b/scripts/gnt-backup new file mode 100755 index 000000000..aba46a4bc --- /dev/null +++ b/scripts/gnt-backup @@ -0,0 +1,160 @@ +#!/usr/bin/python +# + +# Copyright (C) 2006, 2007 Google 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. + + +import sys +from optparse import make_option + +from ganeti.cli import * +from ganeti import cmdlib +from ganeti import opcodes +from ganeti import constants + +def PrintExportList(opts, args): + """Prints a list of all the exported system images. + + Args: + opts - class with options as members (should be empty) + args - should be empty + + Returns: + nothing + + """ + + op = opcodes.OpQueryExports(nodes=opts.nodes) + exports = SubmitOpCode(op) + for node in exports: + print ("Node: %s" % node) + print ("Exports:") + for instance_name in exports[node]: + print ("\t%s" % instance_name) + + +def ExportInstance(opts, args): + """Export an instance to an image in the cluster. + + Args: + opts - class with options as members + args - list with a single element, the instance name + + Returns: + 1 in case of error, 0 otherwise + + """ + op = opcodes.OpExportInstance(instance_name=args[0], + target_node=opts.node, + shutdown=opts.shutdown) + + SubmitOpCode(op) + +def ImportInstance(opts, args): + """Add an instance to the cluster. + + Args: + opts - class with options as members + args - list with a single element, the new instance name + Opts used: + memory - amount of memory to allocate to instance (MiB) + size - amount of disk space to allocate to instance (MiB) + os - which OS to run on instance + node - node to run new instance on + src_node - node containing the export + src_dir - directory on the old node with the export in it + + Returns: + 1 in case of error, 0 otherwise + + """ + + instance = args[0] + + op = opcodes.OpCreateInstance(instance_name=instance, mem_size=opts.mem, + disk_size=opts.size, swap_size=opts.swap, + disk_template=opts.disk_template, + mode=constants.INSTANCE_IMPORT, pnode=opts.node, + snode=opts.snode, vcpus=opts.vcpus, + ip=opts.ip, bridge=opts.bridge, start=False, + src_node=opts.src_node, src_path=opts.src_dir, + wait_for_sync=opts.wait_for_sync) + SubmitOpCode(op) + return 0 + + +# options used in more than one cmd +node_opt = make_option("-n", "--node", dest="node", help="Target node", + metavar="<node>") +force_opt = make_option("-f", "--force", dest="force", action="store_true", + default=False, help="Force the operation") + +# this is defined separately due to readability only +import_opts = [ + DEBUG_OPT, + node_opt, + cli_option("-s", "--os-size", dest="size", help="Disk size", + default=20 * 1024, type="unit", metavar="<size>"), + cli_option("--swap-size", dest="swap", help="Swap size", + default=4 * 1024, type="unit", metavar="<size>"), + cli_option("-m", "--memory", dest="mem", help="Memory size", + default=128, type="unit", metavar="<mem>"), + make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs", + default=1, type="int", metavar="<PROC>"), + make_option("-t", "--disk-template", dest="disk_template", + help="Custom disk setup (diskless, plain, local_raid1 or" + " remote_raid1)", default=None, metavar="TEMPL"), + make_option("-i", "--ip", dest="ip", + help="IP address ('none' [default], 'auto', or specify address)", + default='none', type="string", metavar="<ADDRESS>"), + make_option("--no-wait-for-sync", dest="wait_for_sync", default=True, + action="store_false", help="Don't wait for sync (DANGEROUS!)"), + make_option("--secondary-node", dest="snode", + help="Secondary node for remote_raid1 disk layout", + metavar="<node>"), + make_option("-b", "--bridge", dest="bridge", + help="Bridge to connect this instance to", + default=None, metavar="<bridge>"), + make_option("--src-node", dest="src_node", help="Source node", + metavar="<node>"), + make_option("--src-dir", dest="src_dir", help="Source directory", + metavar="<dir>"), + ] + + +commands = { + 'list': (PrintExportList, ARGS_NONE, + [DEBUG_OPT, + make_option("--nodes", dest="nodes", default=[], action="append", + help="List only backups stored on these nodes"), + ], + "", "Lists instance exports available in the ganeti cluster"), + 'export': (ExportInstance, ARGS_ONE, + [node_opt, DEBUG_OPT, force_opt, + make_option("","--noshutdown", dest="shutdown", + action="store_false", default=True, + help="Don't shutdown the instance (unsafe)"), ], + "[opts...] <name>", + "Exports an instance to an image"), + 'import': (ImportInstance, ARGS_ONE, import_opts, "[opts...] <name>", + "Imports an instance from an exported image"), + } + +if __name__ == '__main__': + retcode = GenericMain(commands) + sys.exit(retcode) -- GitLab