Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More extensive and expressive custom rules #464

Merged
merged 3 commits into from
Nov 16, 2021

Commits on Nov 12, 2021

  1. source/custom: implement generic feature matching

    Implement generic feature matchers that cover all feature sources (that
    implement the FeatureSource interface). The implementation relies on the
    unified data model provided by the FeatureSource interface as well as
    the generic expression-based rule processing framework that was added to
    the source/custom/expression package.
    
    With this patch any new features added will be automatically available
    for custom rules, without any additional work. Rule hierarchy follows
    the source/feature hierarchy by design.
    
    This patch introduces a new format for custom rule specifications,
    dropping the 'value' field and introducing new 'labels' field which
    makes it possible to specify multiple labels per rule. Also, in the new
    format the 'name' field is just for reference and no matching label is
    created. The new generic rules are available in this new rule format
    under a 'matchFeatures. MatchFeatures implements a logical AND over
    an array of per-feature matchers - i.e. a match for all of the matchers
    is required. The goal of the new rule format is to make it better follow
    K8s API design guidelines and make it extensible for future enhancements
    (e.g. addition of templating, taints, annotations, extended resources
    etc).
    
    The old rule format (with cpuID, kConfig, loadedKMod, nodename, pciID,
    usbID rules) is still supported. The rule format (new vs. old) is
    determined at config parsing time based on the existence of the
    'matchOn' field.
    
    The new rule format and the configuration format for the new
    matchFeatures field is
    
      - name: <rule-name>
        labels:
          <key>: <value>
          ...
        matchFeatures:
          - feature: <domain>.<feature>
            matchExpressions:
              <attribute>:
                op: <operator>
                value:
                  - <list-of-values>
          - feature: <domain>.<feature>
            ...
    
    Currently, "cpu", "kernel", "pci", "system", "usb" and "local" sources
    are covered by the matshers/feature selectors. Thus, the following
    features are available for matching with this patch:
    
      - cpu.cpuid:
          <cpuid-flag>: <exists/does-not-exist>
      - cpu.cstate:
          enabled: <bool>
      - cpu.pstate:
          status: <string>
          turbo: <bool>
          scaling_governor: <string>
      - cpu.rdt:
          <rdt-feature>: <exists/does-not-exist>
      - cpu.sst:
          bf.enabled: <bool>
      - cpu.topology:
          hardware_multithreading: <bool>
      - kernel.config:
          <flag-name>: <string>
      - kernel.loadedmodule:
          <module-name>: <exists/does-not-exist>
      - kernel.selinux:
          enabled: <bool>
      - kernel.version:
          major: <int>
          minor: <int>
          revision: <int>
          full: <string>
      - system.osrelease:
          <key-name>: <string>
          VERSION_ID.major: <int>
          VERSION_ID.minor: <int>
      - system.name:
          nodename: <string>
      - pci.device:
          <device-instance>:
            class: <string>
            vendor: <string>
            device: <string>
            subsystem_vendor: <string>
            susbystem_device: <string>
            sriov_totalvfs: <int>
      - usb.device:
          <device-instance>:
            class: <string>
            vendor: <string>
            device: <string>
            serial: <string>
      - local.label:
          <label-name>: <string>
    
    The configuration also supports some "shortforms" for convenience:
    
       matchExpressions: [<attr-1>, <attr-2>=<val-2>]
       ---
       matchExpressions:
         <attr-3>:
         <attr-4>: <val-4>
    
    is equal to:
    
       matchExpressions:
         <attr-1>: {op: Exists}
         <attr-2>: {op: In, value: [<val-2>]}
       ---
       matchExpressions:
         <attr-3>: {op: Exists}
         <attr-4>: {op: In, value: [<val-4>]}
    
    In other words:
    
      - feature: kernel.config
        matchExpressions: ["X86", "INIT_ENV_ARG_LIMIT=32"]
      - feature: pci.device
        matchExpressions:
          vendor: "8086"
    
    is the same as:
    
      - feature: kernel.config
        matchExpressions:
          X86: {op: Exists}
          INIT_ENV_ARG_LIMIT: {op: In, values: ["32"]}
      - feature: pci.device
        matchExpressions:
          vendor: {op: In, value: ["8086"]
    
    Some configuration examples below. In order to match a CPUID feature the
    following snippet can be used:
    
      - name: cpu-test-1
        labels:
          cpu-custom-feature: "true"
        matchFeatures:
          - feature: cpu.cpuid
            matchExpressions:
              AESNI: {op: Exists}
              AVX: {op: Exists}
    
    In order to match against a loaded kernel module and OS version:
    
      - name: kernel-test-1
        labels:
          kernel-custom-feature: "true"
        matchFeatures:
          - feature: kernel.loadedmodule
            matchExpressions:
              e1000: {op: Exists}
          - feature: system.osrelease
            matchExpressions:
              NAME: {op: InRegexp, values: ["^openSUSE"]}
              VERSION_ID.major: {op: Gt, values: ["14"]}
    
    In order to require a kernel module and both of two specific PCI devices:
    
      - name: multi-device-test
        labels:
          multi-device-feature: "true"
        matchFeatures:
          - feature: kernel.loadedmodule
            matchExpressions:
              driver-module: {op: Exists}
          - pci.device:
              vendor: "8086"
              device: "1234"
          - pci.device:
              vendor: "8086"
              device: "abcd"
    marquiz committed Nov 12, 2021
    Configuration menu
    Copy the full SHA
    e206f0b View commit details
    Browse the repository at this point in the history
  2. source/custom: implement matchAny directive

    Implement a new 'matchAny' directive in the new rule format, building on
    top of the previously implemented 'matchFeatures' matcher. MatchAny
    applies a logical OR over multiple matchFeatures directives. That is, it
    allows specifying multiple alternative matchers (at least one of which
    must match) in a single label rule.
    
    The configuration format for the new matchers is
    
      matchAny:
        - matchFeatures:
            - feature: <domain>.<feature>
              matchExpressions:
                <attribute>:
                  op: <operator>
                  value:
                    - <list-of-values>
        - matchFeatures:
          ...
    
    A configuration example. In order to require a cpu feature, kernel
    module and one of two specific PCI devices (taking use of the shortform
    notation):
    
      - name: multi-device-test
        labels:
          multi-device-feature: "true"
        matchFeatures:
          - feature: kernel.loadedmodule
            matchExpressions: [driver-module]
          - feature: cpu.cpuid
            matchExpressions: [AVX512F]
        matchAny:
          - matchFeatures:
              - feature; pci.device
                matchExpressions:
                  vendor: "8086"
                  device: "1234"
          - matchFeatures:
              - feature: pci.device
                matchExpressions:
                  vendor: "8086"
                  device: "abcd"
    marquiz committed Nov 12, 2021
    Configuration menu
    Copy the full SHA
    6cbed37 View commit details
    Browse the repository at this point in the history
  3. source/custom: improved logging of expression matching

    Print out the result of applying an expression. Also, truncate the
    output to max 10 elements (of items matched against) unless '-v 4'
    verbosity level is in use.
    marquiz committed Nov 12, 2021
    Configuration menu
    Copy the full SHA
    52d9aa2 View commit details
    Browse the repository at this point in the history