summaryrefslogtreecommitdiff
path: root/azurelinuxagent/common/protocol/hostplugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/common/protocol/hostplugin.py')
-rw-r--r--azurelinuxagent/common/protocol/hostplugin.py96
1 files changed, 67 insertions, 29 deletions
diff --git a/azurelinuxagent/common/protocol/hostplugin.py b/azurelinuxagent/common/protocol/hostplugin.py
index 6569604..e83dd4b 100644
--- a/azurelinuxagent/common/protocol/hostplugin.py
+++ b/azurelinuxagent/common/protocol/hostplugin.py
@@ -22,19 +22,27 @@ from azurelinuxagent.common.utils import textutil
HOST_PLUGIN_PORT = 32526
URI_FORMAT_GET_API_VERSIONS = "http://{0}:{1}/versions"
+URI_FORMAT_GET_EXTENSION_ARTIFACT = "http://{0}:{1}/extensionArtifact"
URI_FORMAT_PUT_VM_STATUS = "http://{0}:{1}/status"
URI_FORMAT_PUT_LOG = "http://{0}:{1}/vmAgentLog"
API_VERSION = "2015-09-01"
-
+HEADER_CONTAINER_ID = "x-ms-containerid"
+HEADER_VERSION = "x-ms-version"
+HEADER_HOST_CONFIG_NAME = "x-ms-host-config-name"
+HEADER_ARTIFACT_LOCATION = "x-ms-artifact-location"
+HEADER_ARTIFACT_MANIFEST_LOCATION = "x-ms-artifact-manifest-location"
class HostPluginProtocol(object):
- def __init__(self, endpoint):
+ def __init__(self, endpoint, container_id, role_config_name):
if endpoint is None:
raise ProtocolError("Host plugin endpoint not provided")
self.is_initialized = False
self.is_available = False
self.api_versions = None
self.endpoint = endpoint
+ self.container_id = container_id
+ self.role_config_name = role_config_name
+ self.manifest_uri = None
def ensure_initialized(self):
if not self.is_initialized:
@@ -46,23 +54,48 @@ class HostPluginProtocol(object):
def get_api_versions(self):
url = URI_FORMAT_GET_API_VERSIONS.format(self.endpoint,
HOST_PLUGIN_PORT)
- logger.info("getting API versions at [{0}]".format(url))
+ logger.verbose("getting API versions at [{0}]".format(url))
+ return_val = []
try:
- response = restutil.http_get(url)
+ headers = {HEADER_CONTAINER_ID: self.container_id}
+ response = restutil.http_get(url, headers)
if response.status != httpclient.OK:
logger.error(
"get API versions returned status code [{0}]".format(
response.status))
- return []
- return response.read()
+ else:
+ return_val = ustr(remove_bom(response.read()), encoding='utf-8')
+
except HttpError as e:
logger.error("get API versions failed with [{0}]".format(e))
- return []
- def put_vm_status(self, status_blob, sas_url):
+ return return_val
+
+ def get_artifact_request(self, artifact_url, artifact_manifest_url=None):
+ if not self.ensure_initialized():
+ logger.error("host plugin channel is not available")
+ return
+ if textutil.is_str_none_or_whitespace(artifact_url):
+ logger.error("no extension artifact url was provided")
+ return
+
+ url = URI_FORMAT_GET_EXTENSION_ARTIFACT.format(self.endpoint,
+ HOST_PLUGIN_PORT)
+ headers = {HEADER_VERSION: API_VERSION,
+ HEADER_CONTAINER_ID: self.container_id,
+ HEADER_HOST_CONFIG_NAME: self.role_config_name,
+ HEADER_ARTIFACT_LOCATION: artifact_url}
+
+ if artifact_manifest_url is not None:
+ headers[HEADER_ARTIFACT_MANIFEST_LOCATION] = artifact_manifest_url
+
+ return url, headers
+
+ def put_vm_status(self, status_blob, sas_url, config_blob_type=None):
"""
Try to upload the VM status via the host plugin /status channel
:param sas_url: the blob SAS url to pass to the host plugin
+ :param config_blob_type: the blob type from the extension config
:type status_blob: StatusBlob
"""
if not self.ensure_initialized():
@@ -71,25 +104,30 @@ class HostPluginProtocol(object):
if status_blob is None or status_blob.vm_status is None:
logger.error("no status data was provided")
return
- url = URI_FORMAT_PUT_VM_STATUS.format(self.endpoint, HOST_PLUGIN_PORT)
- status = textutil.b64encode(status_blob.vm_status)
- headers = {"x-ms-version": API_VERSION}
- blob_headers = [{'headerName': 'x-ms-version',
- 'headerValue': status_blob.__storage_version__},
- {'headerName': 'x-ms-blob-type',
- 'headerValue': status_blob.type}]
- data = json.dumps({'requestUri': sas_url, 'headers': blob_headers,
- 'content': status}, sort_keys=True)
- logger.info("put VM status at [{0}]".format(url))
try:
- response = restutil.http_put(url, data, headers)
+ url = URI_FORMAT_PUT_VM_STATUS.format(self.endpoint, HOST_PLUGIN_PORT)
+ logger.verbose("Posting VM status to host plugin")
+ status = textutil.b64encode(status_blob.data)
+ blob_type = status_blob.type if status_blob.type else config_blob_type
+ headers = {HEADER_VERSION: API_VERSION,
+ "Content-type": "application/json",
+ HEADER_CONTAINER_ID: self.container_id,
+ HEADER_HOST_CONFIG_NAME: self.role_config_name}
+ blob_headers = [{'headerName': 'x-ms-version',
+ 'headerValue': status_blob.__storage_version__},
+ {'headerName': 'x-ms-blob-type',
+ 'headerValue': blob_type}]
+ data = json.dumps({'requestUri': sas_url, 'headers': blob_headers,
+ 'content': status}, sort_keys=True)
+ response = restutil.http_put(url, data=data, headers=headers)
if response.status != httpclient.OK:
- logger.error("put VM status returned status code [{0}]".format(
- response.status))
- except HttpError as e:
- logger.error("put VM status failed with [{0}]".format(e))
+ logger.error("PUT failed [{0}]", response.status)
+ else:
+ logger.verbose("Successfully uploaded status to host plugin")
+ except Exception as e:
+ logger.error("Put VM status failed [{0}]", e)
- def put_vm_log(self, content, container_id, deployment_id):
+ def put_vm_log(self, content):
"""
Try to upload the given content to the host plugin
:param deployment_id: the deployment id, which is obtained from the
@@ -102,18 +140,18 @@ class HostPluginProtocol(object):
if not self.ensure_initialized():
logger.error("host plugin channel is not available")
return
- if content is None or container_id is None or deployment_id is None:
+ if content is None or self.goal_state.container_id is None or self.goal_state.deployment_id is None:
logger.error(
"invalid arguments passed: "
"[{0}], [{1}], [{2}]".format(
content,
- container_id,
- deployment_id))
+ self.goal_state.container_id,
+ self.goal_state.deployment_id))
return
url = URI_FORMAT_PUT_LOG.format(self.endpoint, HOST_PLUGIN_PORT)
- headers = {"x-ms-vmagentlog-deploymentid": deployment_id,
- "x-ms-vmagentlog-containerid": container_id}
+ headers = {"x-ms-vmagentlog-deploymentid": self.goal_state.deployment_id,
+ "x-ms-vmagentlog-containerid": self.goal_state.container_id}
logger.info("put VM log at [{0}]".format(url))
try:
response = restutil.http_put(url, content, headers)