summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorWilliam Wolf <throughnothing@gmail.com>2011-07-26 10:33:05 +0000
committerTarmac <>2011-07-26 10:33:05 +0000
commitcb631be09c36d29ddb6e89a647c5161bc43c4aa7 (patch)
tree5be2f5dfaeaee8dbc268f3c2f8cb26d56bd4b78d /plugins
parent85522bba82a4139a89915bba99865a50fd9b8f58 (diff)
parent5df221e970d8b060423034fa627735c5c24fce5d (diff)
downloadnova-cb631be09c36d29ddb6e89a647c5161bc43c4aa7.tar.gz
nova-cb631be09c36d29ddb6e89a647c5161bc43c4aa7.tar.xz
nova-cb631be09c36d29ddb6e89a647c5161bc43c4aa7.zip
Merge diablo-3 development from trunk (rev1322)
Diffstat (limited to 'plugins')
-rwxr-xr-xplugins/xenserver/xenapi/contrib/build-rpm.sh20
-rw-r--r--plugins/xenserver/xenapi/contrib/rpmbuild/SPECS/openstack-xen-plugins.spec37
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/agent55
-rwxr-xr-x[-rw-r--r--]plugins/xenserver/xenapi/etc/xapi.d/plugins/glance4
-rwxr-xr-x[-rw-r--r--]plugins/xenserver/xenapi/etc/xapi.d/plugins/migration0
-rwxr-xr-x[-rw-r--r--]plugins/xenserver/xenapi/etc/xapi.d/plugins/objectstore0
-rw-r--r--[-rwxr-xr-x]plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py0
-rwxr-xr-x[-rw-r--r--]plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost49
8 files changed, 127 insertions, 38 deletions
diff --git a/plugins/xenserver/xenapi/contrib/build-rpm.sh b/plugins/xenserver/xenapi/contrib/build-rpm.sh
new file mode 100755
index 000000000..f7bed4d84
--- /dev/null
+++ b/plugins/xenserver/xenapi/contrib/build-rpm.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+PACKAGE=openstack-xen-plugins
+RPMBUILD_DIR=$PWD/rpmbuild
+if [ ! -d $RPMBUILD_DIR ]; then
+ echo $RPMBUILD_DIR is missing
+ exit 1
+fi
+
+for dir in BUILD BUILDROOT SRPMS RPMS SOURCES; do
+ rm -rf $RPMBUILD_DIR/$dir
+ mkdir -p $RPMBUILD_DIR/$dir
+done
+
+rm -rf /tmp/$PACKAGE
+mkdir /tmp/$PACKAGE
+cp -r ../etc/xapi.d /tmp/$PACKAGE
+tar czf $RPMBUILD_DIR/SOURCES/$PACKAGE.tar.gz -C /tmp $PACKAGE
+
+rpmbuild -ba --nodeps --define "_topdir $RPMBUILD_DIR" \
+ $RPMBUILD_DIR/SPECS/$PACKAGE.spec
diff --git a/plugins/xenserver/xenapi/contrib/rpmbuild/SPECS/openstack-xen-plugins.spec b/plugins/xenserver/xenapi/contrib/rpmbuild/SPECS/openstack-xen-plugins.spec
new file mode 100644
index 000000000..cb2af2109
--- /dev/null
+++ b/plugins/xenserver/xenapi/contrib/rpmbuild/SPECS/openstack-xen-plugins.spec
@@ -0,0 +1,37 @@
+Name: openstack-xen-plugins
+Version: 2011.3
+Release: 1
+Summary: Files for XenAPI support.
+License: ASL 2.0
+Group: Applications/Utilities
+Source0: openstack-xen-plugins.tar.gz
+BuildArch: noarch
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Requires: parted
+
+%define debug_package %{nil}
+
+%description
+This package contains files that are required for XenAPI support for OpenStack.
+
+%prep
+%setup -q -n openstack-xen-plugins
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/etc
+cp -r xapi.d $RPM_BUILD_ROOT/etc
+chmod a+x $RPM_BUILD_ROOT/etc/xapi.d/plugins/*
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root,-)
+/etc/xapi.d/plugins/agent
+/etc/xapi.d/plugins/glance
+/etc/xapi.d/plugins/migration
+/etc/xapi.d/plugins/objectstore
+/etc/xapi.d/plugins/pluginlib_nova.py
+/etc/xapi.d/plugins/xenhost
+/etc/xapi.d/plugins/xenstore.py
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
index b8a1b936a..d609a88ab 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
@@ -37,7 +37,7 @@ import time
import XenAPIPlugin
from pluginlib_nova import *
-configure_logging("xenstore")
+configure_logging("agent")
import xenstore
AGENT_TIMEOUT = 30
@@ -72,7 +72,9 @@ def key_init(self, arg_dict):
info to be passed, such as passwords. Returns the shared
secret key value.
"""
- pub = int(arg_dict["pub"])
+ # WARNING: Some older Windows agents will crash if the public key isn't
+ # a string
+ pub = arg_dict["pub"]
arg_dict["value"] = json.dumps({"name": "keyinit", "value": pub})
request_id = arg_dict["id"]
arg_dict["path"] = "data/host/%s" % request_id
@@ -114,7 +116,6 @@ def resetnetwork(self, arg_dict):
xenstore.write_record(self, arg_dict)
-@jsonify
def inject_file(self, arg_dict):
"""Expects a file path and the contents of the file to be written. Both
should be base64-encoded in order to eliminate errors as they are passed
@@ -127,20 +128,21 @@ def inject_file(self, arg_dict):
been disabled, and raise a NotImplemented error if that is the case.
"""
b64_path = arg_dict["b64_path"]
- b64_file = arg_dict["b64_file"]
+ b64_file = arg_dict["b64_contents"]
request_id = arg_dict["id"]
- if self._agent_has_method("file_inject"):
+ agent_features = _get_agent_features(self, arg_dict)
+ if "file_inject" in agent_features:
# New version of the agent. Agent should receive a 'value'
# key whose value is a dictionary containing 'b64_path' and
# 'b64_file'. See old version below.
arg_dict["value"] = json.dumps({"name": "file_inject",
"value": {"b64_path": b64_path, "b64_file": b64_file}})
- elif self._agent_has_method("injectfile"):
+ elif "injectfile" in agent_features:
# Old agent requires file path and file contents to be
# combined into one base64 value.
raw_path = base64.b64decode(b64_path)
raw_file = base64.b64decode(b64_file)
- new_b64 = base64.b64encode("%s,%s") % (raw_path, raw_file)
+ new_b64 = base64.b64encode("%s,%s" % (raw_path, raw_file))
arg_dict["value"] = json.dumps({"name": "injectfile",
"value": new_b64})
else:
@@ -174,30 +176,23 @@ def agent_update(self, arg_dict):
return resp
-def _agent_has_method(self, method):
- """Check that the agent has a particular method by checking its
- features. Cache the features so we don't have to query the agent
- every time we need to check.
- """
+def _get_agent_features(self, arg_dict):
+ """Return an array of features that an agent supports."""
+ tmp_id = commands.getoutput("uuidgen")
+ dct = {}
+ dct.update(arg_dict)
+ dct["value"] = json.dumps({"name": "features", "value": ""})
+ dct["path"] = "data/host/%s" % tmp_id
+ xenstore.write_record(self, dct)
try:
- self._agent_methods
- except AttributeError:
- self._agent_methods = []
- if not self._agent_methods:
- # Haven't been defined
- tmp_id = commands.getoutput("uuidgen")
- dct = {}
- dct["value"] = json.dumps({"name": "features", "value": ""})
- dct["path"] = "data/host/%s" % tmp_id
- xenstore.write_record(self, dct)
- try:
- resp = _wait_for_agent(self, tmp_id, dct)
- except TimeoutError, e:
- raise PluginError(e)
- response = json.loads(resp)
- # The agent returns a comma-separated list of methods.
- self._agent_methods = response.split(",")
- return method in self._agent_methods
+ resp = _wait_for_agent(self, tmp_id, dct)
+ except TimeoutError, e:
+ raise PluginError(e)
+ response = json.loads(resp)
+ if response['returncode'] != 0:
+ return response["message"].split(",")
+ else:
+ return {}
def _wait_for_agent(self, request_id, arg_dict):
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance
index 46031ebe8..fbe080b22 100644..100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/glance
@@ -412,8 +412,8 @@ def copy_kernel_vdi(session, args):
def remove_kernel_ramdisk(session, args):
"""Removes kernel and/or ramdisk from dom0's file system"""
- kernel_file = exists(args, 'kernel-file')
- ramdisk_file = exists(args, 'ramdisk-file')
+ kernel_file = optional(args, 'kernel-file')
+ ramdisk_file = optional(args, 'ramdisk-file')
if kernel_file:
os.remove(kernel_file)
if ramdisk_file:
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration b/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration
index ac1c50ad9..ac1c50ad9 100644..100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/migration
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/objectstore b/plugins/xenserver/xenapi/etc/xapi.d/plugins/objectstore
index d0313b4ed..d0313b4ed 100644..100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/objectstore
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/objectstore
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py b/plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py
index f51f5fce4..f51f5fce4 100755..100644
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/pluginlib_nova.py
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
index a8428e841..292bbce12 100644..100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
@@ -33,9 +33,10 @@ import tempfile
import time
import XenAPIPlugin
+import pluginlib_nova as pluginlib
-from pluginlib_nova import *
-configure_logging("xenhost")
+
+pluginlib.configure_logging("xenhost")
host_data_pattern = re.compile(r"\s*(\S+) \([^\)]+\) *: ?(.*)")
@@ -65,14 +66,49 @@ def _run_command(cmd):
return proc.stdout.read()
+def _get_host_uuid():
+ cmd = "xe host-list | grep uuid"
+ resp = _run_command(cmd)
+ return resp.split(":")[-1].strip()
+
+
+@jsonify
+def set_host_enabled(self, arg_dict):
+ """Sets this host's ability to accept new instances.
+ It will otherwise continue to operate normally.
+ """
+ enabled = arg_dict.get("enabled")
+ if enabled is None:
+ raise pluginlib.PluginError(
+ _("Missing 'enabled' argument to set_host_enabled"))
+ if enabled == "true":
+ result = _run_command("xe host-enable")
+ elif enabled == "false":
+ result = _run_command("xe host-disable")
+ else:
+ raise pluginlib.PluginError(_("Illegal enabled status: %s") % enabled)
+ # Should be empty string
+ if result:
+ raise pluginlib.PluginError(result)
+ # Return the current enabled status
+ host_uuid = _get_host_uuid()
+ cmd = "xe host-param-list uuid=%s | grep enabled" % host_uuid
+ resp = _run_command(cmd)
+ # Response should be in the format: "enabled ( RO): true"
+ host_enabled = resp.strip().split()[-1]
+ if host_enabled == "true":
+ status = "enabled"
+ else:
+ status = "disabled"
+ return {"status": status}
+
+
@jsonify
def host_data(self, arg_dict):
"""Runs the commands on the xenstore host to return the current status
information.
"""
- cmd = "xe host-list | grep uuid"
- resp = _run_command(cmd)
- host_uuid = resp.split(":")[-1].strip()
+ host_uuid = _get_host_uuid()
cmd = "xe host-param-list uuid=%s" % host_uuid
resp = _run_command(cmd)
parsed_data = parse_response(resp)
@@ -180,4 +216,5 @@ def cleanup(dct):
if __name__ == "__main__":
XenAPIPlugin.dispatch(
- {"host_data": host_data})
+ {"host_data": host_data,
+ "set_host_enabled": set_host_enabled})