def is_extension_resource_limits_setup_completed(self, extension_name):
     unit_file_install_path = systemd.get_unit_file_install_path()
     extension_slice_path = os.path.join(unit_file_install_path,
                                         SystemdCgroupsApi.get_extension_slice_name(extension_name))
     if os.path.exists(extension_slice_path):
         return True
     return False
 def remove_extension_slice(self, extension_name):
     """
     This method ensures that the extension slice gets removed from /lib/systemd/system if it exist
     Lastly stop the unit. This would ensure the cleanup the /sys/fs/cgroup controller paths
     """
     if self.enabled():
         unit_file_install_path = systemd.get_unit_file_install_path()
         extension_slice_name = SystemdCgroupsApi.get_extension_slice_name(extension_name)
         extension_slice_path = os.path.join(unit_file_install_path, extension_slice_name)
         if os.path.exists(extension_slice_path):
             self.stop_tracking_extension_cgroups(extension_name)
             CGroupConfigurator._Impl.__cleanup_unit_file(extension_slice_path)
         # stop the unit gracefully; the extensions slices will be removed from /sys/fs/cgroup path
         try:
             logger.info("Executing systemctl stop {0}".format(extension_slice_name))
             shellutil.run_command(["systemctl", "stop", extension_slice_name])
         except Exception as exception:
             _log_cgroup_warning("systemctl stop failed (remove slice): {0}", ustr(exception))
        def setup_extension_slice(self, extension_name):
            """
            Each extension runs under its own slice (Ex "Microsoft.CPlat.Extension.slice"). All the slices for
            extensions are grouped under "azure-vmextensions.slice.

            This method ensures that the extension slice is created. Setup should create
            under /lib/systemd/system if it is not exist.
            TODO: set cpu and memory quotas
            """
            if self.enabled():
                unit_file_install_path = systemd.get_unit_file_install_path()
                extension_slice_path = os.path.join(unit_file_install_path,
                                                     SystemdCgroupsApi.get_extension_slice_name(extension_name))
                try:
                    slice_contents = _EXTENSION_SLICE_CONTENTS.format(extension_name=extension_name)
                    CGroupConfigurator._Impl.__create_unit_file(extension_slice_path, slice_contents)
                except Exception as exception:
                    _log_cgroup_warning("Failed to create unit files for the extension slice: {0}", ustr(exception))
                    CGroupConfigurator._Impl.__cleanup_unit_file(extension_slice_path)
Example #4
0
        def __setup_azure_slice():
            """
            The agent creates "azure.slice" for use by extensions and the agent. The agent runs under "azure.slice" directly and each
            extension runs under its own slice ("Microsoft.CPlat.Extension.slice" in the example below). All the slices for
            extensions are grouped under "vmextensions.slice".

            Example:  -.slice
                      ├─user.slice
                      ├─system.slice
                      └─azure.slice
                        ├─walinuxagent.service
                        │ ├─5759 /usr/bin/python3 -u /usr/sbin/waagent -daemon
                        │ └─5764 python3 -u bin/WALinuxAgent-2.2.53-py2.7.egg -run-exthandlers
                        └─azure-vmextensions.slice
                          └─Microsoft.CPlat.Extension.slice
                              └─5894 /usr/bin/python3 /var/lib/waagent/Microsoft.CPlat.Extension-1.0.0.0/enable.py

            This method ensures that the "azure" and "vmextensions" slices are created. Setup should create those slices
            under /lib/systemd/system; but if they do not exist, __ensure_azure_slices_exist will create them.

            It also creates drop-in files to set the agent's Slice and CPUAccounting if they have not been
            set up in the agent's unit file.

            Lastly, the method also cleans up unit files left over from previous versions of the agent.
            """

            # Older agents used to create this slice, but it was never used. Cleanup the file.
            CGroupConfigurator._Impl.__cleanup_unit_file("/etc/systemd/system/system-walinuxagent.extensions.slice")

            unit_file_install_path = systemd.get_unit_file_install_path()
            azure_slice = os.path.join(unit_file_install_path, _AZURE_SLICE)
            vmextensions_slice = os.path.join(unit_file_install_path, _VMEXTENSIONS_SLICE)
            agent_unit_file = systemd.get_agent_unit_file()
            agent_drop_in_path = systemd.get_agent_drop_in_path()
            agent_drop_in_file_slice = os.path.join(agent_drop_in_path, _AGENT_DROP_IN_FILE_SLICE)
            agent_drop_in_file_cpu_accounting = os.path.join(agent_drop_in_path, _AGENT_DROP_IN_FILE_CPU_ACCOUNTING)

            files_to_create = []

            if not os.path.exists(azure_slice):
                files_to_create.append((azure_slice, _AZURE_SLICE_CONTENTS))

            if not os.path.exists(vmextensions_slice):
                files_to_create.append((vmextensions_slice, _VMEXTENSIONS_SLICE_CONTENTS))

            if fileutil.findre_in_file(agent_unit_file, r"Slice=") is not None:
                CGroupConfigurator._Impl.__cleanup_unit_file(agent_drop_in_file_slice)
            else:
                if not os.path.exists(agent_drop_in_file_slice):
                    files_to_create.append((agent_drop_in_file_slice, _AGENT_DROP_IN_FILE_SLICE_CONTENTS))

            if fileutil.findre_in_file(agent_unit_file, r"CPUAccounting=") is not None:
                CGroupConfigurator._Impl.__cleanup_unit_file(agent_drop_in_file_cpu_accounting)
            else:
                if not os.path.exists(agent_drop_in_file_cpu_accounting):
                    files_to_create.append((agent_drop_in_file_cpu_accounting, _AGENT_DROP_IN_FILE_CPU_ACCOUNTING_CONTENTS))

            if len(files_to_create) > 0:
                # create the unit files, but if 1 fails remove all and return
                try:
                    for path, contents in files_to_create:
                        CGroupConfigurator._Impl.__create_unit_file(path, contents)
                except Exception as exception:
                    _log_cgroup_warning("Failed to create unit files for the azure slice: {0}", ustr(exception))
                    for unit_file in files_to_create:
                        CGroupConfigurator._Impl.__cleanup_unit_file(unit_file)
                    return

                # reload the systemd configuration; the new slices will be used once the agent's service restarts
                try:
                    logger.info("Executing systemctl daemon-reload...")
                    shellutil.run_command(["systemctl", "daemon-reload"])
                except Exception as exception:
                    _log_cgroup_warning("daemon-reload failed (create azure slice): {0}", ustr(exception))