Commit 8d8d650c authored by Michael Hanselmann's avatar Michael Hanselmann

Add command line options for instance removal on export

Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent faba00cb
......@@ -70,6 +70,7 @@ __all__ = [
"IALLOCATOR_OPT",
"IGNORE_CONSIST_OPT",
"IGNORE_FAILURES_OPT",
"IGNORE_REMOVE_FAILURES_OPT",
"IGNORE_SECONDARIES_OPT",
"IGNORE_SIZE_OPT",
"MAC_PREFIX_OPT",
......@@ -101,6 +102,7 @@ __all__ = [
"OS_SIZE_OPT",
"READD_OPT",
"REBOOT_TYPE_OPT",
"REMOVE_INSTANCE_OPT",
"SECONDARY_IP_OPT",
"SELECT_OS_OPT",
"SEP_OPT",
......@@ -684,6 +686,18 @@ IGNORE_FAILURES_OPT = cli_option("--ignore-failures", dest="ignore_failures",
" configuration even if there are failures"
" during the removal process")
IGNORE_REMOVE_FAILURES_OPT = cli_option("--ignore-remove-failures",
dest="ignore_remove_failures",
action="store_true", default=False,
help="Remove the instance from the"
" cluster configuration even if there"
" are failures during the removal"
" process")
REMOVE_INSTANCE_OPT = cli_option("--remove-instance", dest="remove_instance",
action="store_true", default=False,
help="Remove the instance from the cluster")
NEW_SECONDARY_OPT = cli_option("-n", "--new-secondary", dest="dst_node",
help="Specifies the new secondary node",
metavar="NODE", default=None,
......
......@@ -48,6 +48,7 @@ __all__ = ["ConfigObject", "ConfigData", "NIC", "Disk", "Instance",
_TIMESTAMPS = ["ctime", "mtime"]
_UUID = ["uuid"]
def FillDict(defaults_dict, custom_dict, skip_keys=None):
"""Basic function to apply settings on top a default dict.
......
......@@ -65,6 +65,8 @@
<arg choice="req">-n <replaceable>node</replaceable></arg>
<arg>--shutdown-timeout=<replaceable>N</replaceable></arg>
<arg>--noshutdown</arg>
<arg>--remove-instance</arg>
<arg>--ignore-remove-failures</arg>
<arg choice="req"><replaceable>instance</replaceable></arg>
</cmdsynopsis>
......@@ -91,6 +93,12 @@
in the exported dump.
</para>
<para>
The <option>--remove</option> option can be used to remove the
instance after it was exported. This is useful to make one last
backup before removing the instance.
</para>
<para>
The exit code of the command is 0 if all disks were backed up
successfully, 1 if no data was backed up or if the
......
......@@ -169,6 +169,7 @@ def RunCommonInstanceTests(instance):
if qa_rapi.Enabled():
RunTest(qa_rapi.TestInstance, instance)
def RunExportImportTests(instance, pnode):
"""Tries to export and import the instance.
......@@ -312,6 +313,18 @@ def main():
finally:
qa_config.ReleaseNode(snode)
if (qa_config.TestEnabled('instance-add-plain-disk') and
qa_config.TestEnabled("instance-export")):
instance = RunTest(qa_instance.TestInstanceAddWithPlainDisk, pnode)
expnode = qa_config.AcquireNode(exclude=pnode)
try:
RunTest(qa_instance.TestInstanceExportWithRemove, instance, expnode)
RunTest(qa_instance.TestBackupList, expnode)
finally:
qa_config.ReleaseNode(expnode)
del expnode
del instance
finally:
qa_config.ReleaseNode(pnode)
......
......@@ -249,6 +249,16 @@ def TestInstanceExport(instance, node):
return qa_utils.ResolveInstanceName(instance)
def TestInstanceExportWithRemove(instance, node):
"""gnt-backup export --remove-instance"""
master = qa_config.GetMasterNode()
cmd = ['gnt-backup', 'export', '-n', node['primary'], "--remove-instance",
instance['name']]
AssertEqual(StartSSH(master['primary'],
utils.ShellQuoteArgs(cmd)).wait(), 0)
def TestInstanceImport(node, newinst, expnode, name):
"""gnt-backup import"""
master = qa_config.GetMasterNode()
......
......@@ -71,10 +71,14 @@ def ExportInstance(opts, args):
@return: the desired exit code
"""
ignore_remove_failures = opts.ignore_remove_failures
op = opcodes.OpExportInstance(instance_name=args[0],
target_node=opts.node,
shutdown=opts.shutdown,
shutdown_timeout=opts.shutdown_timeout)
shutdown_timeout=opts.shutdown_timeout,
remove_instance=opts.remove_instance,
ignore_remove_failures=ignore_remove_failures)
fin_resu, dlist = SubmitOpCode(op)
if not isinstance(dlist, list):
......@@ -97,6 +101,7 @@ def ExportInstance(opts, args):
rcode = 1
return rcode
def ImportInstance(opts, args):
"""Add an instance to the cluster.
......@@ -144,6 +149,7 @@ import_opts = [
SUBMIT_OPT,
]
commands = {
'list': (
PrintExportList, ARGS_NONE,
......@@ -151,7 +157,8 @@ commands = {
"", "Lists instance exports available in the ganeti cluster"),
'export': (
ExportInstance, ARGS_ONE_INSTANCE,
[FORCE_OPT, SINGLE_NODE_OPT, NOSHUTDOWN_OPT, SHUTDOWN_TIMEOUT_OPT],
[FORCE_OPT, SINGLE_NODE_OPT, NOSHUTDOWN_OPT, SHUTDOWN_TIMEOUT_OPT,
REMOVE_INSTANCE_OPT, IGNORE_REMOVE_FAILURES_OPT],
"-n <target_node> [opts...] <name>",
"Exports an instance to an image"),
'import': (
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment