prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Apparmor denial for ntpd on Focal
  ## Description
  
  `ntpd` throws grsec denial message.
  
  ## Steps to Reproduce
  
  - [ ] Install focal on hardware (I hope the same will show up in vm too)
  - [ ] check `/var/log/syslog`
  
  ## Expected Behavior
  
  - no grsec error from ntpd
  
  ## Actual Behavior
  
  ```
  
  Feb 17 03:43:33 app systemd[1]: Starting Network Time Service... Feb 17 03:43:33 app kernel: [  202.428911] audit: type=1400 audit(1613533413.416:46): apparmor="DENIED" operation="open" profile="/usr/sbin/ntpd" name="/snap/bin/" pid=3303 comm="ntpd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 Feb 17 03:43:33 app ntpd[3303]: ntpd 4.2.8p12@1.3728-o (1): Starting Feb 17 03:43:33 app ntpd[3303]: Command line: /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 112:117 Feb 17 03:43:33 app ntpd[3306]: proto: precision = 0.175 usec (-22)
  --
  ```
  
  ## Comments
  
  Suggestions to fix, any other relevant information.
  
  
  </issue>
  <code>
  [start of molecule/testinfra/conftest.py]
  1 """
  2 Configuration for TestInfra test suite for SecureDrop.
  3 Handles importing host-specific test vars, so test functions
  4 can be reused across multiple hosts, with varied targets.
  5 
  6 Vars should be placed in `testinfra/vars/<hostname>.yml`.
  7 """
  8 
  9 import io
  10 import os
  11 import yaml
  12 import testutils
  13 
  14 # The config tests target staging by default. It's possible to override
  15 # for e.g. prod, but the associated vars files are not yet ported.
  16 target_host = os.environ.get('SECUREDROP_TESTINFRA_TARGET_HOST', 'staging')
  17 
  18 
  19 def securedrop_import_testinfra_vars(hostname, with_header=False):
  20     """
  21     Import vars from a YAML file to populate tests with host-specific
  22     values used in checks. For instance, the SecureDrop docroot will
  23     be under /vagrant in development, but /var/www/securedrop in staging.
  24 
  25     Vars must be stored in `testinfra/vars/<hostname>.yml`.
  26     """
  27     filepath = os.path.join(os.path.dirname(__file__), "vars", hostname+".yml")
  28     with io.open(filepath, 'r') as f:
  29         hostvars = yaml.safe_load(f)
  30 
  31     # Testing against both Focal and Xenial must be supported for now in both
  32     # staging scenarios, and in prod via `USE_FOCAL=1 ./securedrop-admin verify`
  33     testing_focal = False
  34     scenario_env = "MOLECULE_SCENARIO_NAME"
  35     if scenario_env in os.environ and os.environ.get(scenario_env).endswith("focal"):
  36         testing_focal = True
  37     if "USE_FOCAL" in os.environ:
  38         testing_focal = True
  39 
  40     if testing_focal:
  41         hostvars['securedrop_venv_site_packages'] = hostvars["securedrop_venv_site_packages"].format("3.8")  # noqa: E501
  42         hostvars['python_version'] = "3.8"
  43     else:
  44         hostvars['securedrop_venv_site_packages'] = hostvars["securedrop_venv_site_packages"].format("3.5")  # noqa: E501
  45         hostvars['python_version'] = "3.5"
  46 
  47     if with_header:
  48         hostvars = dict(securedrop_test_vars=hostvars)
  49 
  50     return hostvars
  51 
  52 
  53 def lookup_molecule_info():
  54     """
  55     Molecule automatically writes YAML files documenting dynamic host info
  56     such as remote IPs. Read that file and pass back the config dict.
  57     """
  58     molecule_instance_config_path = os.path.abspath(
  59             os.environ['MOLECULE_INSTANCE_CONFIG'])
  60     with open(molecule_instance_config_path, 'r') as f:
  61         molecule_instance_config = yaml.safe_load(f)
  62     return molecule_instance_config
  63 
  64 
  65 class Myvalues:
  66     def __init__(self):
  67         pass
  68 
  69 
  70 value = securedrop_import_testinfra_vars(target_host)
  71 res = Myvalues()
  72 for key, value in value.items():
  73     setattr(res, key, value)
  74 testutils.securedrop_test_vars = res
  75
  [end of molecule/testinfra/conftest.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/molecule/testinfra/conftest.py b/molecule/testinfra/conftest.py
  --- a/molecule/testinfra/conftest.py
  +++ b/molecule/testinfra/conftest.py
  @@ -9,8 +9,11 @@
   import io
   import os
   import yaml
  +from typing import Any, Dict
  +
   import testutils
   
  +
   # The config tests target staging by default. It's possible to override
   # for e.g. prod, but the associated vars files are not yet ported.
   target_host = os.environ.get('SECUREDROP_TESTINFRA_TARGET_HOST', 'staging')
  @@ -50,25 +53,30 @@
       return hostvars
   
   
  -def lookup_molecule_info():
  -    """
  -    Molecule automatically writes YAML files documenting dynamic host info
  -    such as remote IPs. Read that file and pass back the config dict.
  -    """
  -    molecule_instance_config_path = os.path.abspath(
  -            os.environ['MOLECULE_INSTANCE_CONFIG'])
  -    with open(molecule_instance_config_path, 'r') as f:
  -        molecule_instance_config = yaml.safe_load(f)
  -    return molecule_instance_config
  +class TestVars(dict):
  +    managed_attrs = {}  # type: Dict[str, Any]
  +
  +    def __init__(self, initial: Dict[str, Any]) -> None:
  +        self.securedrop_target_distribution = os.environ.get("SECUREDROP_TARGET_DISTRIBUTION")
  +        self.managed_attrs.update(initial)
   
  +    def __getattr__(self, name: str) -> Any:
  +        """
  +        If the requested attribute names a dict in managed_attrs and that
  +        contains a key with the name of the target distribution,
  +        e.g. "focal", return that. Otherwise return the entire item
  +        under the requested name.
  +        """
  +        try:
  +            attr = self.managed_attrs[name]
  +            if isinstance(attr, dict) and self.securedrop_target_distribution in attr:
  +                return attr[self.securedrop_target_distribution]
  +            return attr
  +        except KeyError:
  +            raise AttributeError(name)
   
  -class Myvalues:
  -    def __init__(self):
  -        pass
  +    def __str__(self) -> str:
  +        return str(self.managed_attrs)
   
   
  -value = securedrop_import_testinfra_vars(target_host)
  -res = Myvalues()
  -for key, value in value.items():
  -    setattr(res, key, value)
  -testutils.securedrop_test_vars = res
  +testutils.securedrop_test_vars = TestVars(securedrop_import_testinfra_vars(target_host))
  
verification_info: {"golden_diff": "diff --git a/molecule/testinfra/conftest.py b/molecule/testinfra/conftest.py\n--- a/molecule/testinfra/conftest.py\n+++ b/molecule/testinfra/conftest.py\n@@ -9,8 +9,11 @@\n import io\n import os\n import yaml\n+from typing import Any, Dict\n+\n import testutils\n \n+\n # The config tests target staging by default. It's possible to override\n # for e.g. prod, but the associated vars files are not yet ported.\n target_host = os.environ.get('SECUREDROP_TESTINFRA_TARGET_HOST', 'staging')\n@@ -50,25 +53,30 @@\n     return hostvars\n \n \n-def lookup_molecule_info():\n-    \"\"\"\n-    Molecule automatically writes YAML files documenting dynamic host info\n-    such as remote IPs. Read that file and pass back the config dict.\n-    \"\"\"\n-    molecule_instance_config_path = os.path.abspath(\n-            os.environ['MOLECULE_INSTANCE_CONFIG'])\n-    with open(molecule_instance_config_path, 'r') as f:\n-        molecule_instance_config = yaml.safe_load(f)\n-    return molecule_instance_config\n+class TestVars(dict):\n+    managed_attrs = {}  # type: Dict[str, Any]\n+\n+    def __init__(self, initial: Dict[str, Any]) -> None:\n+        self.securedrop_target_distribution = os.environ.get(\"SECUREDROP_TARGET_DISTRIBUTION\")\n+        self.managed_attrs.update(initial)\n \n+    def __getattr__(self, name: str) -> Any:\n+        \"\"\"\n+        If the requested attribute names a dict in managed_attrs and that\n+        contains a key with the name of the target distribution,\n+        e.g. \"focal\", return that. Otherwise return the entire item\n+        under the requested name.\n+        \"\"\"\n+        try:\n+            attr = self.managed_attrs[name]\n+            if isinstance(attr, dict) and self.securedrop_target_distribution in attr:\n+                return attr[self.securedrop_target_distribution]\n+            return attr\n+        except KeyError:\n+            raise AttributeError(name)\n \n-class Myvalues:\n-    def __init__(self):\n-        pass\n+    def __str__(self) -> str:\n+        return str(self.managed_attrs)\n \n \n-value = securedrop_import_testinfra_vars(target_host)\n-res = Myvalues()\n-for key, value in value.items():\n-    setattr(res, key, value)\n-testutils.securedrop_test_vars = res\n+testutils.securedrop_test_vars = TestVars(securedrop_import_testinfra_vars(target_host))\n", "issue": "Apparmor denial for ntpd on Focal\n## Description\r\n\r\n`ntpd` throws grsec denial message.\r\n\r\n## Steps to Reproduce\r\n\r\n- [ ] Install focal on hardware (I hope the same will show up in vm too)\r\n- [ ] check `/var/log/syslog`\r\n\r\n## Expected Behavior\r\n\r\n- no grsec error from ntpd\r\n\r\n## Actual Behavior\r\n\r\n```\r\n\r\nFeb 17 03:43:33 app systemd[1]: Starting Network Time Service... Feb 17 03:43:33 app kernel: [  202.428911] audit: type=1400 audit(1613533413.416:46): apparmor=\"DENIED\" operation=\"open\" profile=\"/usr/sbin/ntpd\" name=\"/snap/bin/\" pid=3303 comm=\"ntpd\" requested_mask=\"r\" denied_mask=\"r\" fsuid=0 ouid=0 Feb 17 03:43:33 app ntpd[3303]: ntpd 4.2.8p12@1.3728-o (1): Starting Feb 17 03:43:33 app ntpd[3303]: Command line: /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 112:117 Feb 17 03:43:33 app ntpd[3306]: proto: precision = 0.175 usec (-22)\r\n--\r\n```\r\n\r\n## Comments\r\n\r\nSuggestions to fix, any other relevant information.\r\n\n", "before_files": [{"content": "\"\"\"\nConfiguration for TestInfra test suite for SecureDrop.\nHandles importing host-specific test vars, so test functions\ncan be reused across multiple hosts, with varied targets.\n\nVars should be placed in `testinfra/vars/<hostname>.yml`.\n\"\"\"\n\nimport io\nimport os\nimport yaml\nimport testutils\n\n# The config tests target staging by default. It's possible to override\n# for e.g. prod, but the associated vars files are not yet ported.\ntarget_host = os.environ.get('SECUREDROP_TESTINFRA_TARGET_HOST', 'staging')\n\n\ndef securedrop_import_testinfra_vars(hostname, with_header=False):\n    \"\"\"\n    Import vars from a YAML file to populate tests with host-specific\n    values used in checks. For instance, the SecureDrop docroot will\n    be under /vagrant in development, but /var/www/securedrop in staging.\n\n    Vars must be stored in `testinfra/vars/<hostname>.yml`.\n    \"\"\"\n    filepath = os.path.join(os.path.dirname(__file__), \"vars\", hostname+\".yml\")\n    with io.open(filepath, 'r') as f:\n        hostvars = yaml.safe_load(f)\n\n    # Testing against both Focal and Xenial must be supported for now in both\n    # staging scenarios, and in prod via `USE_FOCAL=1 ./securedrop-admin verify`\n    testing_focal = False\n    scenario_env = \"MOLECULE_SCENARIO_NAME\"\n    if scenario_env in os.environ and os.environ.get(scenario_env).endswith(\"focal\"):\n        testing_focal = True\n    if \"USE_FOCAL\" in os.environ:\n        testing_focal = True\n\n    if testing_focal:\n        hostvars['securedrop_venv_site_packages'] = hostvars[\"securedrop_venv_site_packages\"].format(\"3.8\")  # noqa: E501\n        hostvars['python_version'] = \"3.8\"\n    else:\n        hostvars['securedrop_venv_site_packages'] = hostvars[\"securedrop_venv_site_packages\"].format(\"3.5\")  # noqa: E501\n        hostvars['python_version'] = \"3.5\"\n\n    if with_header:\n        hostvars = dict(securedrop_test_vars=hostvars)\n\n    return hostvars\n\n\ndef lookup_molecule_info():\n    \"\"\"\n    Molecule automatically writes YAML files documenting dynamic host info\n    such as remote IPs. Read that file and pass back the config dict.\n    \"\"\"\n    molecule_instance_config_path = os.path.abspath(\n            os.environ['MOLECULE_INSTANCE_CONFIG'])\n    with open(molecule_instance_config_path, 'r') as f:\n        molecule_instance_config = yaml.safe_load(f)\n    return molecule_instance_config\n\n\nclass Myvalues:\n    def __init__(self):\n        pass\n\n\nvalue = securedrop_import_testinfra_vars(target_host)\nres = Myvalues()\nfor key, value in value.items():\n    setattr(res, key, value)\ntestutils.securedrop_test_vars = res\n", "path": "molecule/testinfra/conftest.py"}]}