Exemplo n.º 1
0
    def test_findre_in_file(self):
        fp = tempfile.mktemp()
        with open(fp, 'w') as f:
            f.write(
'''
First line
Second line
Third line with more words
'''
            )

        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, ".*rst line$"))
        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, ".*ond line$"))
        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, ".*with more.*"))
        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, "^Third.*"))
        self.assertEquals(
            None,
            fileutil.findre_in_file(fp, "^Do not match.*"))
Exemplo n.º 2
0
    def test_findre_in_file(self):
        fp = tempfile.mktemp()
        with open(fp, 'w') as f:
            f.write(
'''
First line
Second line
Third line with more words
'''
            )

        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, ".*rst line$"))
        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, ".*ond line$"))
        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, ".*with more.*"))
        self.assertNotEquals(
            None,
            fileutil.findre_in_file(fp, "^Third.*"))
        self.assertEquals(
            None,
            fileutil.findre_in_file(fp, "^Do not match.*"))
Exemplo n.º 3
0
    def set_scsi_disks_timeout(self, timeout):
        pattern = r'^set sd:sd_io_time *= *(.*)$'

        #
        # Since changes to this setting require a reboot to take effect,
        # we're careful to only change the value and print the warning
        # message if the current value is different than the desired
        # value. Essentially, we only want to print the warning message
        # that suggest a reboot is required, if we actually modify the
        # value that's already set; otherwise, we could unnecessarily
        # suggest rebooting the system when that's not actually necessary.
        #

        for sf in ['/etc/system', '/etc/system.d/.self-assembly']:
            if not os.path.isfile(sf): continue
            match = fileutil.findre_in_file(sf, pattern)
            if match:
                try:
                    current = int(match.group(1))
                except ValueError:
                    raise OSUtilError(
                        'Unable to parse existing SCSI disk timeout: "{0}".'.
                        format(match.group(1)))

                if current == int(timeout):
                    return

        logger.warn(
            'Updating SCSI disk timeout to desired value of "{0}", reboot required to take effect.'
            .format(timeout))
        fileutil.write_file('/etc/system.d/system:virtualization:azure-agent',
                            'set sd:sd_io_time = {0}\n'.format(timeout))
    def test_disable_should_reset_cpu_quota_and_tracked_cgroups(self):
        with self._get_cgroup_configurator() as configurator:
            if len(CGroupsTelemetry._tracked) == 0:
                raise Exception(
                    "Test setup should have started tracking at least 1 cgroup (the agent's)"
                )
            if not CGroupsTelemetry._track_throttled_time:
                raise Exception(
                    "Test setup should have started tracking Throttle Time")

            configurator.disable("UNIT TEST")

            agent_drop_in_file_cpu_quota = configurator.mocks.get_mapped_path(
                UnitFilePaths.cpu_quota)
            self.assertTrue(
                os.path.exists(agent_drop_in_file_cpu_quota),
                "{0} was not created".format(agent_drop_in_file_cpu_quota))
            self.assertTrue(
                fileutil.findre_in_file(agent_drop_in_file_cpu_quota,
                                        "^CPUQuota=$"),
                "CPUQuota was not set correctly. Expected an empty value. Got:\n{0}"
                .format(fileutil.read_file(agent_drop_in_file_cpu_quota)))
            self.assertEqual(
                len(CGroupsTelemetry._tracked), 0,
                "No cgroups should be tracked after disable. Tracking: {0}".
                format(CGroupsTelemetry._tracked))
            self.assertFalse(
                CGroupsTelemetry._track_throttled_time,
                "Throttle Time should not be tracked after disable")
Exemplo n.º 5
0
 def set_dhcp_hostname(self, hostname):
     autosend = r'^[^#]*?send\s*host-name.*?(<hostname>|gethostname[(,)])'
     dhclient_files = ['/etc/dhcp/dhclient.conf', '/etc/dhcp3/dhclient.conf', '/etc/dhclient.conf']
     for conf_file in dhclient_files:
         if not os.path.isfile(conf_file):
             continue
         if fileutil.findre_in_file(conf_file, autosend):
             #Return if auto send host-name is configured
             return
         fileutil.update_conf_file(conf_file,
                                   'send host-name',
                                   'send host-name "{0}";'.format(hostname))
Exemplo n.º 6
0
 def set_dhcp_hostname(self, hostname):
     autosend = r'^[^#]*?send\s*host-name.*?(<hostname>|gethostname[(,)])'
     dhclient_files = ['/etc/dhcp/dhclient.conf', '/etc/dhcp3/dhclient.conf', '/etc/dhclient.conf']
     for conf_file in dhclient_files:
         if not os.path.isfile(conf_file):
             continue
         if fileutil.findre_in_file(conf_file, autosend):
             #Return if auto send host-name is configured
             return
         fileutil.update_conf_file(conf_file,
                                   'send host-name',
                                   'send host-name "{0}";'.format(hostname))
    def __get_unit_file_version(self):
        if not os.path.exists(self.get_service_file_path()):
            raise OSError("{0} not found".format(self.get_service_file_path()))

        match = fileutil.findre_in_file(
            self.get_service_file_path(),
            line_re=
            "This unit file \\(Version=([\\d.]+)\\) was created by the Azure VM Agent."
        )
        if match is None:
            raise ValueError("Version tag not found in the unit file")

        return match.group(1).strip()
    def test_enable_should_set_agent_cpu_quota_and_track_throttled_time(self):
        with self._get_cgroup_configurator(enable=False) as configurator:
            agent_drop_in_file_cpu_quota = configurator.mocks.get_mapped_path(
                UnitFilePaths.cpu_quota)
            if os.path.exists(agent_drop_in_file_cpu_quota):
                raise Exception(
                    "{0} should not have been created during test setup".
                    format(agent_drop_in_file_cpu_quota))

            configurator.enable()

            expected_quota = "CPUQuota={0}%".format(_AGENT_CPU_QUOTA)
            self.assertTrue(
                os.path.exists(agent_drop_in_file_cpu_quota),
                "{0} was not created".format(agent_drop_in_file_cpu_quota))
            self.assertTrue(
                fileutil.findre_in_file(agent_drop_in_file_cpu_quota,
                                        expected_quota),
                "CPUQuota was not set correctly. Expected: {0}. Got:\n{1}".
                format(expected_quota,
                       fileutil.read_file(agent_drop_in_file_cpu_quota)))
            self.assertTrue(CGroupsTelemetry.get_track_throttled_time(),
                            "Throttle time should be tracked")
Exemplo n.º 9
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))