-
Iustin Pop authored
When importing an instance, all the saved valued will be used as explicitly specified values, overriding the cluster defaults. This means export+import will change the status (from default to explicitly specified) of parameters. This patch adds a new option that changes the behaviour to identify parameter values which are equal to the current cluster defaults and mark them as such. It does this for hv, be and nic parameters. Signed-off-by:
Iustin Pop <iustin@google.com> Reviewed-by:
Michael Hanselmann <hansmi@google.com>
e588764d
gnt-backup 4.62 KiB
#!/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.
"""Backup related commands"""
# pylint: disable-msg=W0401,W0613,W0614,C0103
# W0401: Wildcard import ganeti.cli
# W0613: Unused argument, since all functions follow the same API
# W0614: Unused import %s from wildcard import (since we need cli)
# C0103: Invalid name gnt-backup
import sys
from ganeti.cli import *
from ganeti import opcodes
from ganeti import constants
_VALUE_TRUE = "true"
def PrintExportList(opts, args):
"""Prints a list of all the exported system images.
@param opts: the command line options selected by the user
@type args: list
@param args: should be an empty list
@rtype: int
@return: the desired exit code
"""
exports = GetClient().QueryExports(opts.nodes, False)
retcode = 0
for node in exports:
ToStdout("Node: %s", node)
ToStdout("Exports:")
if isinstance(exports[node], list):
for instance_name in exports[node]:
ToStdout("\t%s", instance_name)
else:
ToStdout(" Could not get exports list")
retcode = 1
return retcode
def ExportInstance(opts, args):
"""Export an instance to an image in the cluster.
@param opts: the command line options selected by the user
@type args: list
@param args: should contain only one element, the name
of the instance to be exported
@rtype: int
@return: the desired exit code
"""
op = opcodes.OpExportInstance(instance_name=args[0],
target_node=opts.node,
shutdown=opts.shutdown,
shutdown_timeout=opts.shutdown_timeout)
fin_resu, dlist = SubmitOpCode(op, opts=opts)
if not isinstance(dlist, list):
ToStderr("Cannot parse execution results")
return 1
# TODO: handle diskless instances
if dlist.count(False) == 0:
# all OK
rcode = 0
elif dlist.count(True) == 0:
ToStderr("Error: No disks were backed up successfully."
" The export doesn't have any valid data,"
" it is recommended to retry the operation.")
rcode = 1
else:
ToStderr("Partial export failure: %d disks backed up, %d disks failed.",
dlist.count(True), dlist.count(False))
rcode = 2
if not fin_resu:
rcode = 1
return rcode
def ImportInstance(opts, args):
"""Add an instance to the cluster.
This is just a wrapper over GenericInstanceCreate.
"""
return GenericInstanceCreate(constants.INSTANCE_IMPORT, opts, args)
def RemoveExport(opts, args):
"""Remove an export from the cluster.
@param opts: the command line options selected by the user
@type args: list
@param args: should contain only one element, the name of the
instance whose backup should be removed
@rtype: int
@return: the desired exit code
"""
op = opcodes.OpRemoveExport(instance_name=args[0])
SubmitOpCode(op, opts=opts)
return 0
# this is defined separately due to readability only
import_opts = [
BACKEND_OPT,
DISK_OPT,
DISK_TEMPLATE_OPT,
FILESTORE_DIR_OPT,
FILESTORE_DRIVER_OPT,
HYPERVISOR_OPT,
IALLOCATOR_OPT,
IDENTIFY_DEFAULTS_OPT,
NET_OPT,
NODE_PLACEMENT_OPT,
NOIPCHECK_OPT,
NONAMECHECK_OPT,
NONICS_OPT,
NWSYNC_OPT,
OS_SIZE_OPT,
SRC_DIR_OPT,
SRC_NODE_OPT,
SUBMIT_OPT,
]
commands = {
'list': (
PrintExportList, ARGS_NONE,
[NODE_LIST_OPT],
"", "Lists instance exports available in the ganeti cluster"),
'export': (
ExportInstance, ARGS_ONE_INSTANCE,
[FORCE_OPT, SINGLE_NODE_OPT, NOSHUTDOWN_OPT, SHUTDOWN_TIMEOUT_OPT],
"-n <target_node> [opts...] <name>",
"Exports an instance to an image"),
'import': (
ImportInstance, ARGS_ONE_INSTANCE, import_opts,
"[...] -t disk-type -n node[:secondary-node] <name>",
"Imports an instance from an exported image"),
'remove': (
RemoveExport, [ArgUnknown(min=1, max=1)], [],
"<name>", "Remove exports of named instance from the filesystem."),
}
if __name__ == '__main__':
sys.exit(GenericMain(commands))