Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-1959

"edit_line" interference across similar files

    XMLWordPrintable

    Details

      Description

      Imagine having a set of similar files, requiring similar maintenance. My particular case is RHEL/CentOS network config files "ifcfg-eth*" looking like:

      <pre>
      DEVICE="eth2"
      BOOTPROTO="..."
      HWADDR="..."
      IPADDR="..."
      NETMASK="..."
      ONBOOT="..."
      </pre>

      The library "set_line_based()" is designed to handle this, but has a problem with multiple similar files, because of the global scope of classes that are intended to be of local scope.

      The relevant part of the bundle looks like:

      <pre>
      bundle edit_line set_line_based(v, sep, bp, kp, cp)

      { ... replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^$(cp)($(i)$(bp).*|$(i))$" replace_with => value("$(i)$(sep)$($(v)[$(i)])"), ifvarclass => "!exists_$(ci[$(i)]).!replace_attempted_$(ci[$(i)]).!multiple_comments_$(ci[$(i)])", classes => always("uncommented_$(ci[$(i)])"); # If the line is there with the wrong value, replace with # the correct value "^\s*($(i)$(bp)(?!$(ev[$(i)])$).*|$(i))$" replace_with => value("$(i)$(sep)$($(v)[$(i)])"), classes => always("replace_attempted_$(ci[$(i)])"); insert_lines: # If the line doesn't exist, or there is more than one occurrence # of the LHS commented out, insert a new line and try to place it # after the commented LHS (keep new line with old comments) "$(i)$(sep)$($(v)[$(i)])" comment => "Insert the value, marker '$(i)' exists", location => after("^$(cp)($(i)$(bp).*|$(i))$"), ifvarclass => "replace_attempted_$(ci[$(i)]).multiple_comments_$(ci[$(i)])"; # If the line doesn't exist and there are no occurrences # of the LHS commented out, insert a new line at the eof "$(i)$(sep)$($(v)[$(i)])" comment => "Insert the value, marker '$(i)' doesn't exist", ifvarclass => "replace_attempted_$(ci[$(i)]).!multiple_comments_$(ci[$(i)]).!exists_$(ci[$(i)])"; ... }

      </pre>

      The intention is that the the "classes => ..." set inside the "replace_patterns" control the behaviour of other clauses. That's OK... on a single file.

      But now imagine calling this for multiple files. A call for one file may set those classes, supposedly locally for itself. But in fact those classes have global scope and will wrongly influence the behaviour of calls on other similar files, particularly any with similar keys.

      Those keys need better global uniqueness. For instance, I would suggest that lines such as:

      <pre>
      classes => always("replace_attempted_$(ci[$(i)])");

      ...

      ifvarclass => "replace_attempted_$(ci[$(i)]) ...";
      </pre>

      should instead be something like:

      <pre>
      classes => always("replace_attempted_$(ci[$(i)])in$(edit_filename)");

      ...

      ifvarclass => "replace_attempted_$(ci[$(i)])in$(edit_filename) ...";
      </pre>

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                a10042 Nick Anderson
                Reporter:
                davidlee David Lee
              • Votes:
                2 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Summary Panel