114
114
xenstore.write_record(self, arg_dict)
118
117
def inject_file(self, arg_dict):
119
118
"""Expects a file path and the contents of the file to be written. Both
120
119
should be base64-encoded in order to eliminate errors as they are passed
129
128
b64_path = arg_dict["b64_path"]
130
129
b64_file = arg_dict["b64_contents"]
131
130
request_id = arg_dict["id"]
132
if self._agent_has_method("file_inject"):
131
agent_features = _get_agent_features(self, arg_dict)
132
if "file_inject" in agent_features:
133
133
# New version of the agent. Agent should receive a 'value'
134
134
# key whose value is a dictionary containing 'b64_path' and
135
135
# 'b64_file'. See old version below.
136
136
arg_dict["value"] = json.dumps({"name": "file_inject",
137
137
"value": {"b64_path": b64_path, "b64_file": b64_file}})
138
elif self._agent_has_method("injectfile"):
138
elif "injectfile" in agent_features:
139
139
# Old agent requires file path and file contents to be
140
140
# combined into one base64 value.
141
141
raw_path = base64.b64decode(b64_path)
142
142
raw_file = base64.b64decode(b64_file)
143
new_b64 = base64.b64encode("%s,%s") % (raw_path, raw_file)
143
new_b64 = base64.b64encode("%s,%s" % (raw_path, raw_file))
144
144
arg_dict["value"] = json.dumps({"name": "injectfile",
145
145
"value": new_b64})
177
def _agent_has_method(self, method):
178
"""Check that the agent has a particular method by checking its
179
features. Cache the features so we don't have to query the agent
180
every time we need to check.
177
def _get_agent_features(self, arg_dict):
178
"""Return an array of features that an agent supports."""
179
tmp_id = commands.getoutput("uuidgen")
182
dct["value"] = json.dumps({"name": "features", "value": ""})
183
dct["path"] = "data/host/%s" % tmp_id
184
xenstore.write_record(self, dct)
184
except AttributeError:
185
self._agent_methods = []
186
if not self._agent_methods:
187
# Haven't been defined
188
tmp_id = commands.getoutput("uuidgen")
190
dct["value"] = json.dumps({"name": "features", "value": ""})
191
dct["path"] = "data/host/%s" % tmp_id
192
xenstore.write_record(self, dct)
194
resp = _wait_for_agent(self, tmp_id, dct)
195
except TimeoutError, e:
197
response = json.loads(resp)
198
# The agent returns a comma-separated list of methods.
199
self._agent_methods = response.split(",")
200
return method in self._agent_methods
186
resp = _wait_for_agent(self, tmp_id, dct)
187
except TimeoutError, e:
189
response = json.loads(resp)
190
if response['returncode'] != 0:
191
return response["message"].split(",")
203
196
def _wait_for_agent(self, request_id, arg_dict):