Add the gnt-backup script and man-pages.
authorIustin Pop <iustin@google.com>
Mon, 23 Jul 2007 07:45:32 +0000 (07:45 +0000)
committerIustin Pop <iustin@google.com>
Mon, 23 Jul 2007 07:45:32 +0000 (07:45 +0000)
Reviewed-by: imsnah

man/Makefile.am
man/gnt-backup.sgml [new file with mode: 0644]
scripts/Makefile.am
scripts/gnt-backup [new file with mode: 0755]

index 0c6cdb7..1c062e8 100644 (file)
@@ -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 (file)
index 0000000..d628240
--- /dev/null
@@ -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:
+-->
index bbc53e4..3a62d29 100644 (file)
@@ -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 (executable)
index 0000000..aba46a4
--- /dev/null
@@ -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)