Skip to content

Commit

Permalink
Do not create placeholder status file for AKS extensions (#2298)
Browse files Browse the repository at this point in the history
  • Loading branch information
larohra committed Aug 13, 2021
1 parent 669105d commit b679128
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 1 deletion.
14 changes: 13 additions & 1 deletion azurelinuxagent/ga/exthandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ def handle_enable(self, ext_handler_i, extension):
# failures back to CRP. If a placeholder for an extension already exists with Transitioning status, we would
# not override it, hence we only create a placeholder for enable/disable commands but the extensions have the
# data to create their own if needed.
ext_handler_i.create_placeholder_status_file(extension)
if ext_handler_i.should_create_default_placeholder(extension):
ext_handler_i.create_placeholder_status_file(extension)
self.__handle_extension(ext_handler_i, extension, uninstall_exit_code)

@staticmethod
Expand Down Expand Up @@ -1389,6 +1390,17 @@ def initialize(self):
CGroupConfigurator.get_instance().setup_extension_slice(
extension_name=self.get_full_name())

def should_create_default_placeholder(self, extension=None):
"""
There's a bug in the AKS extension where they dont update the status file if it exists.
This violates the contract we have with extensions. Until they fix their extension,
we're going to skip creating a placeholder for them to ensure they dont have any downtime.
For all other extensions, we should create a
"""

ignore_extension_regex = r"Microsoft.AKS.Compute.AKS\S*"
return re.match(ignore_extension_regex, self.get_extension_full_name(extension)) is None

def create_placeholder_status_file(self, extension=None, status=ValidHandlerStatus.transitioning, code=0,
operation="Enabling Extension", message="Install/Enable is in progress."):
_, status_path = self.get_status_file_path(extension)
Expand Down
69 changes: 69 additions & 0 deletions tests/data/wire/ext_conf_aks_extension.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<Extensions version="1.0.0.0" goalStateIncarnation="9">
<GuestAgentExtension>
<GAFamilies>
<GAFamily>
<Name>Prod</Name>
<Uris>
<Uri>http://mock-goal-state/manifest_of_ga.xml</Uri>
</Uris>
</GAFamily>
<GAFamily>
<Name>Test</Name>
<Uris>
<Uri>http://mock-goal-state/manifest_of_ga.xml</Uri>
</Uris>
</GAFamily>
</GAFamilies>
</GuestAgentExtension>
<Plugins>
<Plugin name="OSTCExtensions.ExampleHandlerLinux" version="1.0.0" location="http://mock-goal-state/rdfepirv2hknprdstr03.blob.core.windows.net/b01058962be54ceca550a390fa5ff064/Microsoft.OSTCExtensions_ExampleHandlerLinux_asiaeast_manifest.xml" config="" state="enabled" autoUpgrade="false" failoverlocation="http://mock-goal-state/rdfepirv2hknprdstr04.blob.core.windows.net/b01058962be54ceca550a390fa5ff064/Microsoft.OSTCExtensions_ExampleHandlerLinux_asiaeast_manifest.xml" runAsStartupTask="false" isJson="true"/>
<Plugin name="Microsoft.AKS.Compute.AKS.Linux.AKSNode" version="1.0.0" location="https://mock-goal-state/zrdfepirv2sn3prdstr06.blob.core.windows.net/3055d769a0ed485d8c5ea8a7cd24073e/Microsoft.Powershell_ExampleExtension_ussouth_manifest.xml" state="enabled" autoUpgrade="true" failoverlocation="https://mock-goal-state/zrdfepirv2sn4prdstr02a.blob.core.windows.net/3055d769a0ed485d8c5ea8a7cd24073e/Microsoft.Powershell_ExampleExtension_ussouth_manifest.xml" runAsStartupTask="false" isJson="true" useExactVersion="false"/>
<Plugin name="Microsoft.AKS.Compute.AKS-Engine.Linux.Billing" version="1.0.0" location="https://mock-goal-state/rdfepirv2sn3prdstr01.blob.core.windows.net/8b23413e0ce64aa89889a295b6122112/Microsoft.EnterpriseCloud.Monitoring_ExampleHandlerLinux_ussouth_manifest.xml" state="enabled" autoUpgrade="true" failoverlocation="https://mock-goal-state/ardfepirv2sn3prdstr05.blob.core.windows.net/8b23413e0ce64aa89889a295b6122112/Microsoft.EnterpriseCloud.Monitoring_ExampleHandlerLinux_ussouth_manifest.xml" runAsStartupTask="false" isJson="true" useExactVersion="false"/>
<Plugin name="Microsoft.AKS.Compute.AKS.Linux.Billing" version="1.0.0" location="https://mock-goal-state/zrdfepirv2sn4prdstr09a.blob.core.windows.net/f72653efd9e349ed9842c8b99e4c1712/Microsoft.CPlat.Core_ExampleExtensionLinux_ussouth_manifest.xml" state="enabled" autoUpgrade="true" failoverlocation="https://mock-goal-state/ardfepirv2sn3prdstr05.blob.core.windows.net/f72653efd9e349ed9842c8b99e4c1712/Microsoft.CPlat.Core_ExampleExtensionLinux_ussouth_manifest.xml" runAsStartupTask="false" isJson="true" useExactVersion="false"/>
</Plugins>
<PluginSettings>
<Plugin name="OSTCExtensions.ExampleHandlerLinux" version="1.0.0">
<RuntimeSettings seqNo="0">
{
"runtimeSettings": [
{
"handlerSettings": {
"publicSettings": {"message": "Enabling non-AKS"}
}
}
]
}
</RuntimeSettings>
</Plugin>
<Plugin name="Microsoft.AKS.Compute.AKS.Linux.AKSNode" version="1.0.0">
<RuntimeSettings seqNo="0">
{
"runtimeSettings": [
{
"handlerSettings": {
"publicSettings": {"message": "Enabling AKSNode"}
}
}
]
}
</RuntimeSettings>
</Plugin>
<Plugin name="Microsoft.AKS.Compute.AKS-Engine.Linux.Billing" version="1.0.0">
<RuntimeSettings seqNo="0">
{
"runtimeSettings": [
{
"handlerSettings": {
"publicSettings": {"message": "Enabling AKSBilling"}
}
}
]
}
</RuntimeSettings>
</Plugin>
</PluginSettings>
<StatusUploadBlob statusBlobType="BlockBlob">
https://test.blob.core.windows.net/vhds/test-cs12.test-cs12.test-cs12.status?sr=b&amp;sp=rw&amp;se=9999-01-01&amp;sk=key1&amp;sv=2014-02-14&amp;sig=hfRh7gzUE7sUtYwke78IOlZOrTRCYvkec4hGZ9zZzXo
</StatusUploadBlob>
</Extensions>

50 changes: 50 additions & 0 deletions tests/ga/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,56 @@ def mock_popen(cmd, *args, **kwargs):
expected_msg="Dependent Extension OSTCExtensions.OtherExampleHandlerLinux did not reach a terminal state within the allowed timeout. Last status was {0}".format(
ValidHandlerStatus.warning))

def test_it_should_not_create_placeholder_for_aks_extension(self, mock_http_get, mock_crypt_util, *args):
original_popen = subprocess.Popen

def mock_popen(cmd, *_, **kwargs):
if 'env' in kwargs:
if ExtensionCommandNames.ENABLE not in cmd:
# To force the test extension to not create a status file on Install, changing command
return original_popen(["echo", "not-enable"], *_, **kwargs)

seq_no = kwargs['env'][ExtCommandEnvVariable.ExtensionSeqNumber]
ext_path = kwargs['env'][ExtCommandEnvVariable.ExtensionPath]
status_file_name = "{0}.status".format(seq_no)
status_file = os.path.join(ext_path, "status", status_file_name)
if "AKS" in cmd:
self.assertFalse(os.path.exists(status_file), "Placeholder file should not be created for AKS")
else:
self.assertTrue(os.path.exists(status_file), "Placeholder file should be created for all extensions")

return original_popen(cmd, *_, **kwargs)

aks_test_mock = DATA_FILE.copy()
aks_test_mock["ext_conf"] = "wire/ext_conf_aks_extension.xml"

exthandlers_handler, protocol = self._create_mock(mockwiredata.WireProtocolData(aks_test_mock),
mock_http_get, mock_crypt_util, *args)

with patch('azurelinuxagent.common.cgroupapi.subprocess.Popen', side_effect=mock_popen):
exthandlers_handler.run()
exthandlers_handler.report_ext_handlers_status()

self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0",
expected_handler_name="OSTCExtensions.ExampleHandlerLinux")
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0",
expected_handler_name="Microsoft.AKS.Compute.AKS.Linux.AKSNode")
self._assert_handler_status(protocol.report_vm_status, "Ready", 1, "1.0.0",
expected_handler_name="Microsoft.AKS.Compute.AKS-Engine.Linux.Billing")
# Extension without settings
self._assert_handler_status(protocol.report_vm_status, "Ready", 0, "1.0.0",
expected_handler_name="Microsoft.AKS.Compute.AKS.Linux.Billing")

self._assert_ext_status(protocol.report_vm_status, ValidHandlerStatus.success, 0,
expected_handler_name="OSTCExtensions.ExampleHandlerLinux",
expected_msg="Enabling non-AKS")
self._assert_ext_status(protocol.report_vm_status, ValidHandlerStatus.success, 0,
expected_handler_name="Microsoft.AKS.Compute.AKS.Linux.AKSNode",
expected_msg="Enabling AKSNode")
self._assert_ext_status(protocol.report_vm_status, ValidHandlerStatus.success, 0,
expected_handler_name="Microsoft.AKS.Compute.AKS-Engine.Linux.Billing",
expected_msg="Enabling AKSBilling")

def test_it_should_include_part_of_status_in_ext_handler_message(self, mock_http_get, mock_crypt_util, *args):
"""
Testing scenario when the status file is invalid,
Expand Down

0 comments on commit b679128

Please sign in to comment.