Commit f226f085 authored by Guido Trotter's avatar Guido Trotter
Browse files

Merge branch 'master' into next


Signed-off-by: default avatarGuido Trotter <ultrotter@google.com>
parents 78f44650 b926bd98
Version 2.0 release candidate 5
- fix a couple of bugs (validation, argument checks)
- fix gnt-cluster getmaster on non-master nodes (regression)
- some small improvements to RAPI and IAllocator
- make watcher automatically start the master daemon if down
Version 2.0 release candidate 4
- change the OS list to not require locks; this helps with big
clusters
......
Ganeti 1.2
Ganeti 2.0
==========
For installation instructions, read the INSTALL and the doc/install.pdf
For installation instructions, read the INSTALL and the doc/install.html
files.
For a brief introduction, read the ganeti(7) manpage and the other pages
......
......@@ -2,7 +2,7 @@
m4_define([gnt_version_major], [2])
m4_define([gnt_version_minor], [0])
m4_define([gnt_version_revision], [0])
m4_define([gnt_version_suffix], [~rc4])
m4_define([gnt_version_suffix], [~rc5])
m4_define([gnt_version_full],
m4_format([%d.%d.%d%s],
gnt_version_major, gnt_version_minor,
......
......@@ -39,6 +39,7 @@ from ganeti import serializer
from ganeti import errors
from ganeti import opcodes
from ganeti import cli
from ganeti import luxi
MAXTRIES = 5
......@@ -69,6 +70,16 @@ def Indent(s, prefix='| '):
return "%s%s\n" % (prefix, ('\n' + prefix).join(s.splitlines()))
def StartMaster():
"""Try to start the master daemon.
"""
result = utils.RunCmd(['ganeti-masterd'])
if result.failed:
logging.error("Can't start the master daemon: output '%s'", result.output)
return not result.failed
class WatcherState(object):
"""Interface to a state file recording restart attempts.
......@@ -448,6 +459,7 @@ def main():
utils.SetupLogging(constants.LOG_WATCHER, debug=options.debug,
stderr_logging=options.debug)
update_file = True
try:
notepad = WatcherState()
try:
......@@ -455,7 +467,17 @@ def main():
client = cli.GetClient()
except errors.OpPrereqError:
# this is, from cli.GetClient, a not-master case
logging.debug("Not on master, exiting")
sys.exit(constants.EXIT_SUCCESS)
except luxi.NoMasterError, err:
logging.warning("Master seems to be down (%s), trying to restart",
str(err))
if not StartMaster():
logging.critical("Can't start the master, exiting")
update_file = False
sys.exit(constants.EXIT_FAILURE)
# else retry the connection
client = cli.GetClient()
try:
watcher = Watcher(options, notepad)
......@@ -465,7 +487,10 @@ def main():
watcher.Run()
finally:
notepad.Save()
if update_file:
notepad.Save()
else:
logging.debug("Not updating status file due to failure")
except SystemExit:
raise
except NotMasterError:
......
......@@ -49,7 +49,7 @@ Python
::
import urllib2
f = urllib2.urlopen('https://CLUSTERNAME:5080/info')
f = urllib2.urlopen('https://CLUSTERNAME:5080/2/info')
print f.read()
......@@ -63,7 +63,7 @@ JavaScript
::
var url = 'https://CLUSTERNAME:5080/info';
var url = 'https://CLUSTERNAME:5080/2/info';
var info;
var xmlreq = new XMLHttpRequest();
xmlreq.onreadystatechange = function () {
......
......@@ -1417,7 +1417,7 @@ class LUSetClusterParams(LogicalUnit):
_OP_REQP = []
REQ_BGL = False
def CheckParameters(self):
def CheckArguments(self):
"""Check parameters
"""
......@@ -1426,7 +1426,7 @@ class LUSetClusterParams(LogicalUnit):
if self.op.candidate_pool_size is not None:
try:
self.op.candidate_pool_size = int(self.op.candidate_pool_size)
except ValueError, err:
except (ValueError, TypeError), err:
raise errors.OpPrereqError("Invalid candidate_pool_size value: %s" %
str(err))
if self.op.candidate_pool_size < 1:
......@@ -5939,7 +5939,7 @@ class LUSetInstanceParams(LogicalUnit):
self.warn.append("Can't get info from primary node %s" % pnode)
else:
if not instance_info.failed and instance_info.data:
current_mem = instance_info.data['memory']
current_mem = int(instance_info.data['memory'])
else:
# Assume instance not running
# (there is a slight race condition here, but it's not very probable,
......@@ -6752,6 +6752,8 @@ class IAllocator(object):
"disk_template": iinfo.disk_template,
"hypervisor": iinfo.hypervisor,
}
pir["disk_space_total"] = _ComputeDiskSize(iinfo.disk_template,
pir["disks"])
instance_data[iinfo.name] = pir
data["instances"] = instance_data
......
......@@ -194,9 +194,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
while arg_list:
arg = arg_list.pop(0)
if arg == '-m':
memory = arg_list.pop(0)
memory = int(arg_list.pop(0))
elif arg == '-smp':
vcpus = arg_list.pop(0)
vcpus = int(arg_list.pop(0))
return (instance_name, pid, memory, vcpus, stat, times)
......
......@@ -34,6 +34,7 @@ I_FIELDS = ["name", "admin_state", "os",
"pnode", "snodes",
"disk_template",
"nic.ips", "nic.macs", "nic.bridges",
"network_port",
"disk.sizes", "disk_usage",
"beparams", "hvparams",
"oper_state", "oper_ram", "status",
......
......@@ -460,7 +460,10 @@
initrd to boot the instance with. Xen PVM instances
can use this always, while for KVM if this option is
only used if the <option>kernel_path</option> option
is also specified.
is also specified. You can pass here either an
absolute filename (the path to the initrd) if you
want to use an initrd, or use the format
<userinput>no_initrd_path</userinput> for no initrd.
</para>
</listitem>
</varlistentry>
......
......@@ -170,7 +170,7 @@ def TestInstanceModify(instance):
["-H", "%s=%s" % (constants.HV_KERNEL_PATH, test_kernel)],
["-H", "%s=%s" % (constants.HV_KERNEL_PATH, constants.VALUE_DEFAULT)],
["-H", "%s=%s" % (constants.HV_INITRD_PATH, test_initrd)],
["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_NONE)],
["-H", "no_%s" % (constants.HV_INITRD_PATH, )],
["-H", "%s=%s" % (constants.HV_INITRD_PATH, constants.VALUE_DEFAULT)],
# TODO: bridge tests
......
......@@ -154,29 +154,6 @@ def _ConfirmOperation(inames, text):
return choice
def _TransformPath(user_input):
"""Transform a user path into a canonical value.
This function transforms the a path passed as textual information
into the constants that the LU code expects.
"""
if user_input:
if user_input.lower() == "default":
result_path = constants.VALUE_DEFAULT
elif user_input.lower() == "none":
result_path = constants.VALUE_NONE
else:
if not os.path.isabs(user_input):
raise errors.OpPrereqError("Path '%s' is not an absolute filename" %
user_input)
result_path = user_input
else:
result_path = constants.VALUE_DEFAULT
return result_path
def _EnsureInstancesExist(client, names):
"""Check for and ensure the given instance names exist.
......
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