def inject_file(self, context, instance_id, path, file_contents): """Write a file to the specified path on an instance on this server""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) instance_id = instance_ref["id"] instance_state = instance_ref["state"] expected_state = power_state.RUNNING if instance_state != expected_state: LOG.warn( _( "trying to inject a file into a non-running " "instance: %(instance_id)s (state: %(instance_state)s " "expected: %(expected_state)s)" ) % locals() ) # Files/paths *should* be base64-encoded at this point, but # double-check to make sure. b64_path = utils.ensure_b64_encoding(path) b64_contents = utils.ensure_b64_encoding(file_contents) plain_path = base64.b64decode(b64_path) nm = instance_ref["name"] msg = _("instance %(nm)s: injecting file to %(plain_path)s") % locals() LOG.audit(msg) self.driver.inject_file(instance_ref, b64_path, b64_contents)
def inject_file(self, instance, b64_path, b64_contents): """Write a file to the VM instance. The path to which it is to be written and the contents of the file need to be supplied; both should be base64-encoded to prevent errors with non-ASCII characters being transmitted. If the agent does not support file injection, or the user has disabled it, a NotImplementedError will be raised. """ # Files/paths *should* be base64-encoded at this point, but # double-check to make sure. b64_path = utils.ensure_b64_encoding(b64_path) b64_contents = utils.ensure_b64_encoding(b64_contents) # Need to uniquely identify this request. transaction_id = str(uuid.uuid4()) args = {'id': transaction_id, 'b64_path': b64_path, 'b64_contents': b64_contents} # If the agent doesn't support file injection, a NotImplementedError # will be raised with the appropriate message. resp = self._make_agent_call('inject_file', instance, '', args) resp_dict = json.loads(resp) if resp_dict['returncode'] != '0': # There was some other sort of error; the message will contain # a description of the error. raise RuntimeError(resp_dict['message']) return resp_dict['message']