Statistics
| Branch: | Tag: | Revision:

root / scripts / gnt-backup @ 8b46606c

History | View | Annotate | Download (9.7 kB)

1 dd4b1106 Iustin Pop
#!/usr/bin/python
2 dd4b1106 Iustin Pop
#
3 dd4b1106 Iustin Pop
4 dd4b1106 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 dd4b1106 Iustin Pop
#
6 dd4b1106 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 dd4b1106 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 dd4b1106 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 dd4b1106 Iustin Pop
# (at your option) any later version.
10 dd4b1106 Iustin Pop
#
11 dd4b1106 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 dd4b1106 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 dd4b1106 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 dd4b1106 Iustin Pop
# General Public License for more details.
15 dd4b1106 Iustin Pop
#
16 dd4b1106 Iustin Pop
# You should have received a copy of the GNU General Public License
17 dd4b1106 Iustin Pop
# along with this program; if not, write to the Free Software
18 dd4b1106 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 dd4b1106 Iustin Pop
# 02110-1301, USA.
20 dd4b1106 Iustin Pop
21 dd4b1106 Iustin Pop
22 2f79bd34 Iustin Pop
# pylint: disable-msg=W0401,W0614
23 2f79bd34 Iustin Pop
# W0401: Wildcard import ganeti.cli
24 2f79bd34 Iustin Pop
# W0614: Unused import %s from wildcard import (since we need cli)
25 2f79bd34 Iustin Pop
26 dd4b1106 Iustin Pop
import sys
27 dd4b1106 Iustin Pop
from optparse import make_option
28 dd4b1106 Iustin Pop
29 dd4b1106 Iustin Pop
from ganeti.cli import *
30 dd4b1106 Iustin Pop
from ganeti import opcodes
31 dd4b1106 Iustin Pop
from ganeti import constants
32 50a707fa Iustin Pop
from ganeti import errors
33 50a707fa Iustin Pop
from ganeti import utils
34 dd4b1106 Iustin Pop
35 7c0d6283 Michael Hanselmann
36 e1d2aa39 Alexander Schreiber
_VALUE_TRUE = "true"
37 e1d2aa39 Alexander Schreiber
38 dd4b1106 Iustin Pop
def PrintExportList(opts, args):
39 dd4b1106 Iustin Pop
  """Prints a list of all the exported system images.
40 dd4b1106 Iustin Pop
41 48de3413 Iustin Pop
  @param opts: the command line options selected by the user
42 48de3413 Iustin Pop
  @type args: list
43 48de3413 Iustin Pop
  @param args: should be an empty list
44 48de3413 Iustin Pop
  @rtype: int
45 48de3413 Iustin Pop
  @return: the desired exit code
46 dd4b1106 Iustin Pop
47 dd4b1106 Iustin Pop
  """
48 77921a95 Iustin Pop
  exports = GetClient().QueryExports(opts.nodes, False)
49 d70b3058 Iustin Pop
  retcode = 0
50 dd4b1106 Iustin Pop
  for node in exports:
51 3a24c527 Iustin Pop
    ToStdout("Node: %s", node)
52 3a24c527 Iustin Pop
    ToStdout("Exports:")
53 461f0538 Guido Trotter
    if isinstance(exports[node], list):
54 461f0538 Guido Trotter
      for instance_name in exports[node]:
55 3a24c527 Iustin Pop
        ToStdout("\t%s", instance_name)
56 461f0538 Guido Trotter
    else:
57 3a24c527 Iustin Pop
      ToStdout("  Could not get exports list")
58 d70b3058 Iustin Pop
      retcode = 1
59 d70b3058 Iustin Pop
  return retcode
60 dd4b1106 Iustin Pop
61 dd4b1106 Iustin Pop
62 dd4b1106 Iustin Pop
def ExportInstance(opts, args):
63 dd4b1106 Iustin Pop
  """Export an instance to an image in the cluster.
64 dd4b1106 Iustin Pop
65 48de3413 Iustin Pop
  @param opts: the command line options selected by the user
66 48de3413 Iustin Pop
  @type args: list
67 48de3413 Iustin Pop
  @param args: should contain only one element, the name
68 48de3413 Iustin Pop
      of the instance to be exported
69 48de3413 Iustin Pop
  @rtype: int
70 48de3413 Iustin Pop
  @return: the desired exit code
71 dd4b1106 Iustin Pop
72 dd4b1106 Iustin Pop
  """
73 dd4b1106 Iustin Pop
  op = opcodes.OpExportInstance(instance_name=args[0],
74 dd4b1106 Iustin Pop
                                target_node=opts.node,
75 dd4b1106 Iustin Pop
                                shutdown=opts.shutdown)
76 dd4b1106 Iustin Pop
77 dd4b1106 Iustin Pop
  SubmitOpCode(op)
78 dd4b1106 Iustin Pop
79 60d49723 Michael Hanselmann
80 dd4b1106 Iustin Pop
def ImportInstance(opts, args):
81 dd4b1106 Iustin Pop
  """Add an instance to the cluster.
82 dd4b1106 Iustin Pop
83 48de3413 Iustin Pop
  @param opts: the command line options selected by the user
84 48de3413 Iustin Pop
  @type args: list
85 48de3413 Iustin Pop
  @param args: should contain only one element, the new instance name
86 48de3413 Iustin Pop
  @rtype: int
87 48de3413 Iustin Pop
  @return: the desired exit code
88 dd4b1106 Iustin Pop
89 dd4b1106 Iustin Pop
  """
90 dd4b1106 Iustin Pop
  instance = args[0]
91 dd4b1106 Iustin Pop
92 60d49723 Michael Hanselmann
  (pnode, snode) = SplitNodeOption(opts.node)
93 60d49723 Michael Hanselmann
94 b03efa30 Guido Trotter
  hypervisor = None
95 b03efa30 Guido Trotter
  hvparams = {}
96 b03efa30 Guido Trotter
  if opts.hypervisor:
97 b03efa30 Guido Trotter
    hypervisor, hvparams = opts.hypervisor
98 b03efa30 Guido Trotter
99 50a707fa Iustin Pop
  if opts.nics:
100 50a707fa Iustin Pop
    try:
101 50a707fa Iustin Pop
      nic_max = max(int(nidx[0])+1 for nidx in opts.nics)
102 50a707fa Iustin Pop
    except ValueError, err:
103 50a707fa Iustin Pop
      raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err))
104 50a707fa Iustin Pop
    nics = [{}] * nic_max
105 50a707fa Iustin Pop
    for nidx, ndict in opts.nics.items():
106 50a707fa Iustin Pop
      nidx = int(nidx)
107 8b46606c Guido Trotter
      if not isinstance(ndict, dict):
108 8b46606c Guido Trotter
        msg = "Invalid nic/%d value: expected dict, got %s" % (nidx, ndict)
109 8b46606c Guido Trotter
        raise errors.OpPrereqError(msg)
110 50a707fa Iustin Pop
      nics[nidx] = ndict
111 50a707fa Iustin Pop
  elif opts.no_nics:
112 50a707fa Iustin Pop
    # no nics
113 50a707fa Iustin Pop
    nics = []
114 50a707fa Iustin Pop
  else:
115 50a707fa Iustin Pop
    # default of one nic, all auto
116 50a707fa Iustin Pop
    nics = [{}]
117 50a707fa Iustin Pop
118 50a707fa Iustin Pop
  if opts.disk_template == constants.DT_DISKLESS:
119 c0e4a2c3 Iustin Pop
    if opts.disks or opts.sd_size is not None:
120 50a707fa Iustin Pop
      raise errors.OpPrereqError("Diskless instance but disk"
121 50a707fa Iustin Pop
                                 " information passed")
122 50a707fa Iustin Pop
    disks = []
123 50a707fa Iustin Pop
  else:
124 c0e4a2c3 Iustin Pop
    if not opts.disks and not opts.sd_size:
125 50a707fa Iustin Pop
      raise errors.OpPrereqError("No disk information specified")
126 c0e4a2c3 Iustin Pop
    if opts.disks and opts.sd_size is not None:
127 c0e4a2c3 Iustin Pop
      raise errors.OpPrereqError("Please use either the '--disk' or"
128 c0e4a2c3 Iustin Pop
                                 " '-s' option")
129 c0e4a2c3 Iustin Pop
    if opts.sd_size is not None:
130 c0e4a2c3 Iustin Pop
      opts.disks = [(0, {"size": opts.sd_size})]
131 50a707fa Iustin Pop
    try:
132 50a707fa Iustin Pop
      disk_max = max(int(didx[0])+1 for didx in opts.disks)
133 50a707fa Iustin Pop
    except ValueError, err:
134 50a707fa Iustin Pop
      raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err))
135 50a707fa Iustin Pop
    disks = [{}] * disk_max
136 50a707fa Iustin Pop
    for didx, ddict in opts.disks:
137 50a707fa Iustin Pop
      didx = int(didx)
138 8b46606c Guido Trotter
      if not isinstance(ddict, dict):
139 8b46606c Guido Trotter
        msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
140 8b46606c Guido Trotter
        raise errors.OpPrereqError(msg)
141 8b46606c Guido Trotter
      elif "size" not in ddict:
142 50a707fa Iustin Pop
        raise errors.OpPrereqError("Missing size for disk %d" % didx)
143 50a707fa Iustin Pop
      try:
144 50a707fa Iustin Pop
        ddict["size"] = utils.ParseUnit(ddict["size"])
145 50a707fa Iustin Pop
      except ValueError, err:
146 50a707fa Iustin Pop
        raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
147 50a707fa Iustin Pop
                                   (didx, err))
148 50a707fa Iustin Pop
      disks[didx] = ddict
149 50a707fa Iustin Pop
150 a5728081 Guido Trotter
  utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES)
151 c0e4a2c3 Iustin Pop
  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
152 b03efa30 Guido Trotter
153 338e51e8 Iustin Pop
  op = opcodes.OpCreateInstance(instance_name=instance,
154 dd4b1106 Iustin Pop
                                disk_template=opts.disk_template,
155 50a707fa Iustin Pop
                                disks=disks,
156 50a707fa Iustin Pop
                                nics=nics,
157 098c0958 Michael Hanselmann
                                mode=constants.INSTANCE_IMPORT,
158 60d49723 Michael Hanselmann
                                pnode=pnode, snode=snode,
159 338e51e8 Iustin Pop
                                ip_check=opts.ip_check,
160 50a707fa Iustin Pop
                                start=False,
161 dd4b1106 Iustin Pop
                                src_node=opts.src_node, src_path=opts.src_dir,
162 50a707fa Iustin Pop
                                wait_for_sync=opts.wait_for_sync,
163 93cb65c5 Manuel Franceschini
                                file_storage_dir=opts.file_storage_dir,
164 93cb65c5 Manuel Franceschini
                                file_driver=opts.file_driver,
165 e1d2aa39 Alexander Schreiber
                                iallocator=opts.iallocator,
166 b03efa30 Guido Trotter
                                hypervisor=hypervisor,
167 b03efa30 Guido Trotter
                                hvparams=hvparams,
168 b03efa30 Guido Trotter
                                beparams=opts.beparams)
169 e1d2aa39 Alexander Schreiber
170 dd4b1106 Iustin Pop
  SubmitOpCode(op)
171 dd4b1106 Iustin Pop
  return 0
172 dd4b1106 Iustin Pop
173 dd4b1106 Iustin Pop
174 9ac99fda Guido Trotter
def RemoveExport(opts, args):
175 9ac99fda Guido Trotter
  """Remove an export from the cluster.
176 9ac99fda Guido Trotter
177 48de3413 Iustin Pop
  @param opts: the command line options selected by the user
178 48de3413 Iustin Pop
  @type args: list
179 48de3413 Iustin Pop
  @param args: should contain only one element, the name of the
180 48de3413 Iustin Pop
      instance whose backup should be removed
181 48de3413 Iustin Pop
  @rtype: int
182 48de3413 Iustin Pop
  @return: the desired exit code
183 9ac99fda Guido Trotter
184 9ac99fda Guido Trotter
  """
185 9ac99fda Guido Trotter
  instance = args[0]
186 9ac99fda Guido Trotter
  op = opcodes.OpRemoveExport(instance_name=args[0])
187 9ac99fda Guido Trotter
188 9ac99fda Guido Trotter
  SubmitOpCode(op)
189 9ac99fda Guido Trotter
  return 0
190 9ac99fda Guido Trotter
191 9ac99fda Guido Trotter
192 dd4b1106 Iustin Pop
# this is defined separately due to readability only
193 dd4b1106 Iustin Pop
import_opts = [
194 dd4b1106 Iustin Pop
  DEBUG_OPT,
195 60d49723 Michael Hanselmann
  make_option("-n", "--node", dest="node",
196 60d49723 Michael Hanselmann
              help="Target node and optional secondary node",
197 60d49723 Michael Hanselmann
              metavar="<pnode>[:<snode>]"),
198 b03efa30 Guido Trotter
  keyval_option("-B", "--backend", dest="beparams",
199 b03efa30 Guido Trotter
                type="keyval", default={},
200 b03efa30 Guido Trotter
                help="Backend parameters"),
201 dd4b1106 Iustin Pop
  make_option("-t", "--disk-template", dest="disk_template",
202 726a7f7f Iustin Pop
              help="Custom disk setup (diskless, file, plain, drbd)",
203 abdf0113 Iustin Pop
              default=None, metavar="TEMPL"),
204 50a707fa Iustin Pop
  ikv_option("--disk", help="Disk information",
205 50a707fa Iustin Pop
             default=[], dest="disks",
206 50a707fa Iustin Pop
             action="append",
207 50a707fa Iustin Pop
             type="identkeyval"),
208 c0e4a2c3 Iustin Pop
  cli_option("-s", "--os-size", dest="sd_size", help="Disk size for a"
209 c0e4a2c3 Iustin Pop
             " single-disk configuration, when not using the --disk option,"
210 c0e4a2c3 Iustin Pop
             " in MiB unless a suffix is used",
211 c0e4a2c3 Iustin Pop
             default=None, type="unit", metavar="<size>"),
212 50a707fa Iustin Pop
  ikv_option("--net", help="NIC information",
213 50a707fa Iustin Pop
             default=[], dest="nics",
214 50a707fa Iustin Pop
             action="append",
215 50a707fa Iustin Pop
             type="identkeyval"),
216 50a707fa Iustin Pop
  make_option("--no-nics", default=False, action="store_true",
217 50a707fa Iustin Pop
              help="Do not create any network cards for the instance"),
218 dd4b1106 Iustin Pop
  make_option("--no-wait-for-sync", dest="wait_for_sync", default=True,
219 dd4b1106 Iustin Pop
              action="store_false", help="Don't wait for sync (DANGEROUS!)"),
220 dd4b1106 Iustin Pop
  make_option("--src-node", dest="src_node", help="Source node",
221 dd4b1106 Iustin Pop
              metavar="<node>"),
222 dd4b1106 Iustin Pop
  make_option("--src-dir", dest="src_dir", help="Source directory",
223 dd4b1106 Iustin Pop
              metavar="<dir>"),
224 bdd55f71 Iustin Pop
  make_option("--no-ip-check", dest="ip_check", default=True,
225 bdd55f71 Iustin Pop
              action="store_false", help="Don't check that the instance's IP"
226 bdd55f71 Iustin Pop
              " is alive"),
227 1325da74 Iustin Pop
  make_option("-I", "--iallocator", metavar="<NAME>",
228 538475ca Iustin Pop
              help="Select nodes for the instance automatically using the"
229 538475ca Iustin Pop
              " <NAME> iallocator plugin", default=None, type="string"),
230 93cb65c5 Manuel Franceschini
  make_option("--file-storage-dir", dest="file_storage_dir",
231 93cb65c5 Manuel Franceschini
              help="Relative path under default cluster-wide file storage dir"
232 93cb65c5 Manuel Franceschini
              " to store file-based disks", default=None,
233 93cb65c5 Manuel Franceschini
              metavar="<DIR>"),
234 93cb65c5 Manuel Franceschini
  make_option("--file-driver", dest="file_driver", help="Driver to use"
235 93cb65c5 Manuel Franceschini
              " for image files", default="loop", metavar="<DRIVER>"),
236 b03efa30 Guido Trotter
  ikv_option("-H", "--hypervisor", dest="hypervisor",
237 b03efa30 Guido Trotter
              help="Hypervisor and hypervisor options, in the format"
238 b03efa30 Guido Trotter
              " hypervisor:option=value,option=value,...", default=None,
239 b03efa30 Guido Trotter
              type="identkeyval"),
240 dd4b1106 Iustin Pop
  ]
241 dd4b1106 Iustin Pop
242 dd4b1106 Iustin Pop
commands = {
243 dd4b1106 Iustin Pop
  'list': (PrintExportList, ARGS_NONE,
244 dd4b1106 Iustin Pop
           [DEBUG_OPT,
245 1e020d1b Michael Hanselmann
            make_option("--node", dest="nodes", default=[], action="append",
246 59885275 Guido Trotter
                        help="List only backups stored on this node"
247 59885275 Guido Trotter
                             " (can be used multiple times)"),
248 dd4b1106 Iustin Pop
            ],
249 9a033156 Iustin Pop
           "", "Lists instance exports available in the ganeti cluster"),
250 dd4b1106 Iustin Pop
  'export': (ExportInstance, ARGS_ONE,
251 60d49723 Michael Hanselmann
             [DEBUG_OPT, FORCE_OPT,
252 60d49723 Michael Hanselmann
              make_option("-n", "--node", dest="node", help="Target node",
253 60d49723 Michael Hanselmann
                          metavar="<node>"),
254 dd4b1106 Iustin Pop
              make_option("","--noshutdown", dest="shutdown",
255 dd4b1106 Iustin Pop
                          action="store_false", default=True,
256 dd4b1106 Iustin Pop
                          help="Don't shutdown the instance (unsafe)"), ],
257 9a033156 Iustin Pop
             "-n <target_node> [opts...] <name>",
258 dd4b1106 Iustin Pop
             "Exports an instance to an image"),
259 bdb7d4e8 Michael Hanselmann
  'import': (ImportInstance, ARGS_ONE, import_opts,
260 bdb7d4e8 Michael Hanselmann
             ("[...] -t disk-type -n node[:secondary-node]"
261 bdb7d4e8 Michael Hanselmann
              " <name>"),
262 dd4b1106 Iustin Pop
             "Imports an instance from an exported image"),
263 9ac99fda Guido Trotter
  'remove': (RemoveExport, ARGS_ONE,
264 9ac99fda Guido Trotter
             [DEBUG_OPT],
265 9a033156 Iustin Pop
             "<name>",
266 9ac99fda Guido Trotter
             "Remove exports of named instance from the filesystem."),
267 dd4b1106 Iustin Pop
  }
268 dd4b1106 Iustin Pop
269 dd4b1106 Iustin Pop
if __name__ == '__main__':
270 3ecf6786 Iustin Pop
  sys.exit(GenericMain(commands))