summaryrefslogtreecommitdiff
path: root/azurelinuxagent/common/protocol
diff options
context:
space:
mode:
authorƁukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com>2017-03-15 10:19:34 +0100
committerusd-importer <ubuntu-server@lists.ubuntu.com>2017-03-17 13:08:24 +0000
commitc6339c307f36f77a4198d6faf1275acdf371200b (patch)
treec774046e1e30617514c09e5a2b896568706a25a8 /azurelinuxagent/common/protocol
parentdd73af563850762aad64e7ed2a9897377830af10 (diff)
parent2bc77af05fe602a2ba92569428c6006d1aebd19f (diff)
downloadvyos-walinuxagent-c6339c307f36f77a4198d6faf1275acdf371200b.tar.gz
vyos-walinuxagent-c6339c307f36f77a4198d6faf1275acdf371200b.zip
Import patches-applied version 2.2.6-0ubuntu1 to applied/ubuntu/zesty-proposed
Imported using git-ubuntu import. Changelog parent: dd73af563850762aad64e7ed2a9897377830af10 Unapplied parent: 2bc77af05fe602a2ba92569428c6006d1aebd19f New changelog entries: * New upstream release (LP: #1661750). * debian/control: - Change the maintainer to Ubuntu Developers (LP: #1657528). - Add the dependency of isc-dhcp-client as our maintainer scripts assume it's installed. - Add trailing commas to dependencies, add whitespaces. * Rename ephemeral-disk-warning.sh to ephemeral-disk-warning (lintian error). * debian/docs: - Remove LICENSE.txt as it's redundant. * debian/postinst: - Stop checking for update-initramfs existence using the absolute path, use the 'command' command instead to make lintian happy. * Remove debian/patches/disable-auto-update.patch: - We now ship with auto-updates enabled (LP: #1650522). * debian/maintscript: - Add a maintscript to rename the old logrotate file on upgrade from an ancient version of walinuxagent (LP: #1673152).
Diffstat (limited to 'azurelinuxagent/common/protocol')
-rw-r--r--azurelinuxagent/common/protocol/hostplugin.py29
-rw-r--r--azurelinuxagent/common/protocol/restapi.py56
-rw-r--r--azurelinuxagent/common/protocol/wire.py36
3 files changed, 85 insertions, 36 deletions
diff --git a/azurelinuxagent/common/protocol/hostplugin.py b/azurelinuxagent/common/protocol/hostplugin.py
index e83dd4b..bdae56e 100644
--- a/azurelinuxagent/common/protocol/hostplugin.py
+++ b/azurelinuxagent/common/protocol/hostplugin.py
@@ -16,7 +16,6 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
-
from azurelinuxagent.common.protocol.wire import *
from azurelinuxagent.common.utils import textutil
@@ -32,6 +31,7 @@ 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, container_id, role_config_name):
if endpoint is None:
@@ -41,6 +41,7 @@ class HostPluginProtocol(object):
self.api_versions = None
self.endpoint = endpoint
self.container_id = container_id
+ self.deployment_id = None
self.role_config_name = role_config_name
self.manifest_uri = None
@@ -49,6 +50,11 @@ class HostPluginProtocol(object):
self.api_versions = self.get_api_versions()
self.is_available = API_VERSION in self.api_versions
self.is_initialized = True
+
+ from azurelinuxagent.common.event import add_event, WALAEventOperation
+ add_event(name="WALA",
+ op=WALAEventOperation.InitializeHostPlugin,
+ is_success=self.is_available)
return self.is_available
def get_api_versions(self):
@@ -74,10 +80,10 @@ class HostPluginProtocol(object):
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
+ return None, None
if textutil.is_str_none_or_whitespace(artifact_url):
logger.error("no extension artifact url was provided")
- return
+ return None, None
url = URI_FORMAT_GET_EXTENSION_ARTIFACT.format(self.endpoint,
HOST_PLUGIN_PORT)
@@ -121,7 +127,10 @@ class HostPluginProtocol(object):
'content': status}, sort_keys=True)
response = restutil.http_put(url, data=data, headers=headers)
if response.status != httpclient.OK:
- logger.error("PUT failed [{0}]", response.status)
+ logger.warn("PUT {0} [{1}: {2}]",
+ url,
+ response.status,
+ response.reason)
else:
logger.verbose("Successfully uploaded status to host plugin")
except Exception as e:
@@ -140,18 +149,20 @@ class HostPluginProtocol(object):
if not self.ensure_initialized():
logger.error("host plugin channel is not available")
return
- if content is None or self.goal_state.container_id is None or self.goal_state.deployment_id is None:
+ if content is None \
+ or self.container_id is None \
+ or self.deployment_id is None:
logger.error(
"invalid arguments passed: "
"[{0}], [{1}], [{2}]".format(
content,
- self.goal_state.container_id,
- self.goal_state.deployment_id))
+ self.container_id,
+ self.deployment_id))
return
url = URI_FORMAT_PUT_LOG.format(self.endpoint, HOST_PLUGIN_PORT)
- headers = {"x-ms-vmagentlog-deploymentid": self.goal_state.deployment_id,
- "x-ms-vmagentlog-containerid": self.goal_state.container_id}
+ headers = {"x-ms-vmagentlog-deploymentid": self.deployment_id,
+ "x-ms-vmagentlog-containerid": self.container_id}
logger.info("put VM log at [{0}]".format(url))
try:
response = restutil.http_put(url, content, headers)
diff --git a/azurelinuxagent/common/protocol/restapi.py b/azurelinuxagent/common/protocol/restapi.py
index 5f71cf2..a42db37 100644
--- a/azurelinuxagent/common/protocol/restapi.py
+++ b/azurelinuxagent/common/protocol/restapi.py
@@ -16,11 +16,12 @@
#
# Requires Python 2.4+ and Openssl 1.0+
#
-
+import socket
import azurelinuxagent.common.logger as logger
import azurelinuxagent.common.utils.restutil as restutil
from azurelinuxagent.common.exception import ProtocolError, HttpError
from azurelinuxagent.common.future import ustr
+from azurelinuxagent.common.version import DISTRO_VERSION, DISTRO_NAME, CURRENT_VERSION
def validate_param(name, val, expected_type):
@@ -87,8 +88,13 @@ Data contract between guest and host
class VMInfo(DataContract):
- def __init__(self, subscriptionId=None, vmName=None, containerId=None,
- roleName=None, roleInstanceName=None, tenantName=None):
+ def __init__(self,
+ subscriptionId=None,
+ vmName=None,
+ containerId=None,
+ roleName=None,
+ roleInstanceName=None,
+ tenantName=None):
self.subscriptionId = subscriptionId
self.vmName = vmName
self.containerId = containerId
@@ -96,18 +102,26 @@ class VMInfo(DataContract):
self.roleInstanceName = roleInstanceName
self.tenantName = tenantName
+
class CertificateData(DataContract):
def __init__(self, certificateData=None):
self.certificateData = certificateData
+
class Cert(DataContract):
- def __init__(self, name=None, thumbprint=None, certificateDataUri=None, storeName=None, storeLocation=None):
+ def __init__(self,
+ name=None,
+ thumbprint=None,
+ certificateDataUri=None,
+ storeName=None,
+ storeLocation=None):
self.name = name
self.thumbprint = thumbprint
self.certificateDataUri = certificateDataUri
self.storeLocation = storeLocation
self.storeName = storeName
+
class CertList(DataContract):
def __init__(self):
self.certificates = DataContractList(Cert)
@@ -131,8 +145,12 @@ class VMAgentManifestList(DataContract):
class Extension(DataContract):
- def __init__(self, name=None, sequenceNumber=None, publicSettings=None,
- protectedSettings=None, certificateThumbprint=None):
+ def __init__(self,
+ name=None,
+ sequenceNumber=None,
+ publicSettings=None,
+ protectedSettings=None,
+ certificateThumbprint=None):
self.name = name
self.sequenceNumber = sequenceNumber
self.publicSettings = publicSettings
@@ -207,8 +225,13 @@ class ExtensionSubStatus(DataContract):
class ExtensionStatus(DataContract):
- def __init__(self, configurationAppliedTime=None, operation=None,
- status=None, seq_no=None, code=None, message=None):
+ def __init__(self,
+ configurationAppliedTime=None,
+ operation=None,
+ status=None,
+ seq_no=None,
+ code=None,
+ message=None):
self.configurationAppliedTime = configurationAppliedTime
self.operation = operation
self.status = status
@@ -219,7 +242,11 @@ class ExtensionStatus(DataContract):
class ExtHandlerStatus(DataContract):
- def __init__(self, name=None, version=None, status=None, code=0,
+ def __init__(self,
+ name=None,
+ version=None,
+ status=None,
+ code=0,
message=None):
self.name = name
self.version = version
@@ -230,16 +257,19 @@ class ExtHandlerStatus(DataContract):
class VMAgentStatus(DataContract):
- def __init__(self, version=None, status=None, message=None):
- self.version = version
+ def __init__(self, status=None, message=None):
self.status = status
self.message = message
+ self.hostname = socket.gethostname()
+ self.version = str(CURRENT_VERSION)
+ self.osname = DISTRO_NAME
+ self.osversion = DISTRO_VERSION
self.extensionHandlers = DataContractList(ExtHandlerStatus)
class VMStatus(DataContract):
- def __init__(self):
- self.vmAgent = VMAgentStatus()
+ def __init__(self, status, message):
+ self.vmAgent = VMAgentStatus(status=status, message=message)
class TelemetryEventParam(DataContract):
diff --git a/azurelinuxagent/common/protocol/wire.py b/azurelinuxagent/common/protocol/wire.py
index 9f634e9..71c3e37 100644
--- a/azurelinuxagent/common/protocol/wire.py
+++ b/azurelinuxagent/common/protocol/wire.py
@@ -250,6 +250,9 @@ def ga_status_to_v1(ga_status):
v1_ga_status = {
'version': ga_status.version,
'status': ga_status.status,
+ 'osversion': ga_status.osversion,
+ 'osname': ga_status.osname,
+ 'hostname': ga_status.hostname,
'formattedMessage': formatted_msg
}
return v1_ga_status
@@ -338,7 +341,7 @@ def vm_status_to_v1(vm_status, ext_statuses):
'handlerAggregateStatus': v1_handler_status_list
}
v1_vm_status = {
- 'version': '1.0',
+ 'version': '1.1',
'timestampUTC': timestamp,
'aggregateStatus': v1_agg_status
}
@@ -638,9 +641,10 @@ class WireClient(object):
uri, headers = host.get_artifact_request(version.uri)
response = self.fetch(uri, headers)
if not response:
+ host = self.get_host_plugin(force_update=True)
logger.info("Retry fetch in {0} seconds",
- LONG_WAITING_INTERVAL)
- time.sleep(LONG_WAITING_INTERVAL)
+ SHORT_WAITING_INTERVAL)
+ time.sleep(SHORT_WAITING_INTERVAL)
else:
host.manifest_uri = version.uri
logger.verbose("Manifest downloaded successfully from host plugin")
@@ -659,9 +663,10 @@ class WireClient(object):
if resp.status == httpclient.OK:
return_value = self.decode_config(resp.read())
else:
- logger.warn("Could not fetch {0} [{1}]",
+ logger.warn("Could not fetch {0} [{1}: {2}]",
uri,
- resp.status)
+ resp.status,
+ resp.reason)
except (HttpError, ProtocolError) as e:
logger.verbose("Fetch failed from [{0}]", uri)
return return_value
@@ -716,7 +721,7 @@ class WireClient(object):
if not forced:
last_incarnation = None
- if (os.path.isfile(incarnation_file)):
+ if os.path.isfile(incarnation_file):
last_incarnation = fileutil.read_file(incarnation_file)
new_incarnation = goal_state.incarnation
if last_incarnation is not None and \
@@ -731,11 +736,11 @@ class WireClient(object):
file_name = GOAL_STATE_FILE_NAME.format(goal_state.incarnation)
goal_state_file = os.path.join(conf.get_lib_dir(), file_name)
self.save_cache(goal_state_file, xml_text)
- self.save_cache(incarnation_file, goal_state.incarnation)
self.update_hosting_env(goal_state)
self.update_shared_conf(goal_state)
self.update_certs(goal_state)
self.update_ext_conf(goal_state)
+ self.save_cache(incarnation_file, goal_state.incarnation)
if self.host_plugin is not None:
self.host_plugin.container_id = goal_state.container_id
self.host_plugin.role_config_name = goal_state.role_config_name
@@ -760,7 +765,7 @@ class WireClient(object):
return self.goal_state
def get_hosting_env(self):
- if (self.hosting_env is None):
+ if self.hosting_env is None:
local_file = os.path.join(conf.get_lib_dir(),
HOSTING_ENV_FILE_NAME)
xml_text = self.fetch_cache(local_file)
@@ -768,7 +773,7 @@ class WireClient(object):
return self.hosting_env
def get_shared_conf(self):
- if (self.shared_conf is None):
+ if self.shared_conf is None:
local_file = os.path.join(conf.get_lib_dir(),
SHARED_CONF_FILE_NAME)
xml_text = self.fetch_cache(local_file)
@@ -776,7 +781,7 @@ class WireClient(object):
return self.shared_conf
def get_certs(self):
- if (self.certs is None):
+ if self.certs is None:
local_file = os.path.join(conf.get_lib_dir(), CERTS_FILE_NAME)
xml_text = self.fetch_cache(local_file)
self.certs = Certificates(self, xml_text)
@@ -823,7 +828,7 @@ class WireClient(object):
logger.info("Wire protocol version:{0}", PROTOCOL_VERSION)
elif PROTOCOL_VERSION in version_info.get_supported():
logger.info("Wire protocol version:{0}", PROTOCOL_VERSION)
- logger.warn("Server prefered version:{0}", preferred)
+ logger.warn("Server preferred version:{0}", preferred)
else:
error = ("Agent supported wire protocol version: {0} was not "
"advised by Fabric.").format(PROTOCOL_VERSION)
@@ -982,8 +987,12 @@ class WireClient(object):
"x-ms-guest-agent-public-x509-cert": cert
}
- def get_host_plugin(self):
- if self.host_plugin is None:
+ def get_host_plugin(self, force_update=False):
+ if self.host_plugin is None or force_update:
+ if force_update:
+ logger.warn("Forcing update of goal state")
+ self.goal_state = None
+ self.update_goal_state(forced=True)
goal_state = self.get_goal_state()
self.host_plugin = HostPluginProtocol(self.endpoint,
goal_state.container_id,
@@ -1402,7 +1411,6 @@ class InVMArtifactsProfile(object):
* encryptedHealthChecks (optional)
* encryptedApplicationProfile (optional)
"""
-
def __init__(self, artifacts_profile):
if not textutil.is_str_none_or_whitespace(artifacts_profile):
self.__dict__.update(parse_json(artifacts_profile))