PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : xml vergleichen



Huhn Hur Tu
18.04.17, 10:41
Hi,

ich habe hier einige Jbosse, jboss7/ wildfly mit lebender xml Konfiguration, meint, cli Kommandos werden in eine XML geschrieben.

Ich will den Diff zur letzten Konfiguration lesen, am liebsten bis auf Properties Ebene.

Ich benoetige folgende Informationen

- ist eine Ressource hinzugekommen
- ist eine Ressource wegkonfiguriert worden
- sind Properties hinzugekommen
- sind Properties nicht mehr da
- haben sich Properties geaendert.

Da das XML nicht in allen Segmenten die gleiche Tiefe, auch nicht die gleiche Bedeutung hat, Frage ich einfach mal in die Runde wie ihr sowas umsetzen wuerdet, da die Properties in Ebene eins bis 4 Verschachtelt sind, je nach Ressource, mal unabhaengig der Sprache die am Schluss dann Python3 sein wird.

Mein erster Gedanke:
- Sichern aller "Ressourcen" innerhalb der Sektionen bis auf die Properties hinunter unabhangig der Verschachtelungsebene (XML auseinandernehmen)
- Ein sinnvoller Diff ueber das XML selbst (keine Ahnung wie)


Ein Beispiel habe ich hier

- https://pastebin.com/u3xS28f7

Gruss Stefan

nopes
18.04.17, 11:22
Hmm bin mir nicht ganz sicher, was das finale Ziel ist, klingt ein bisschen nach, stell gefälligst sicher, dass der Server nach einer Änderung noch läuft bzw prüfe, ob die Änderung ok ist. In diesem Falle wäre meine Heilewelt Lösung, XML-Schema-Validierung, die Konfiguration nur dann geschrieben werden, wenn die Validierung erfolgreich war.

Ok haben keine heile Welt.
Unerschiede bemerken:
Würde ich klassisch über Größe und Checksummen lösen:
Größe ungleich -> prüfen
Größe gleich, aber verschiedene Checksummen -> prüfen
Sonst keine Prüfung notwendig

Prüfung:
Da finde ich die Anforderungen noch etwas ungenau (weil mir das Ziel unklar ist). Jedenfalls schreit eine Prüfung nach Listen bzw. Maps von erwarteten Ressourcen bzw. Properties, die man durchläuft und sicherstellt, dass das so in der Konfiguration zu finden sind. Diese Art von Prüfung würde ich erstmal ohne die alte Konfiguration erstellen, aber dabei drauf achten, dass diese Listen bzw. Maps am Ende aus der alten Konfiguration erstellt werden sollen.
Vielleicht liege ich aber auch falsch und es geht nicht um Prüfungen - xml_diff (https://github.com/JoshData/xml_diff) sieht finde ich viel versprechend aus und ist auch deutlich frischer, als das xmldiff bei pipy (https://pypi.python.org/pypi/xmldiff)

fork
18.04.17, 11:46
Hi,

in allen ausgereiften Programmiersprachen sind Bibliotheken für das parsen von
XML-Dateien mit dabei.

Mein Ansatz wäre, den XML-Baum der alten Datei rekursiv zu durchlaufen und dabei jedes
Element mit dem Element der neuen Datei zu vergleichen. Damit kann man Änderungen
und Löschungen ermitteln. Für die Prüfung auf hinzugefügte Elemente könnte man nochmal den XML-Baum
der neuen Datei durchlaufen und prüfen, ob die Elemente auch schon in der alten Datei schon
enthalten sind.

Ich würde vermuten, dass das insgesamt nicht so schwer sein dürfte.

Grüße,
fork();

Huhn Hur Tu
19.04.17, 12:13
Hmm bin mir nicht ganz sicher, was das finale Ziel ist, klingt ein bisschen nach, stell gefälligst sicher, dass der Server nach einer Änderung noch läuft bzw prüfe, ob die Änderung ok ist. In diesem Falle wäre meine Heilewelt Lösung, XML-Schema-Validierung, die Konfiguration nur dann geschrieben werden, wenn die Validierung erfolgreich war.


Mein Problem ist, dass ich einen Jboss Applikationsserver automatisiert ausrollen will, auch Aendernung.
Am besten und einfachsten geht dies ueber das interne CLI Interface.
Doch dieses ist nicht idempotent, bzw. es ist ein reisen Aufwand dort auf alle Properties zu pruefen.
Ich will vor Rollout testen ist der Server im Zustand des letzten Rollouts / Changes, wenn ja spiele deine Befehle ab (if ressource da, dann skip; else fire cli fi)
Damit habe ich wenige Zeilen CLI zu verwalten.
Im Fall einer manuellen Aenderung (ist im Problemfall manchmal Nachts noetig, bzw. auf Testservern auch gewuenscht )

Das Ziel ist:
Bei einem Diff zur urspruenglichen Konfiguration, die man nach dem ersten Rollout einmal anlegt, bzw. nach dem Rollout automatisch weggeschrieben wird (entweder ganzes XML oder Ressourcen bis zu den Properties ... whatever), dann einen Report ausspuckt was sich geaendert hat.
Ich habe ein wenig mit diff rumgespielt, da wird es gleich etwas haesslich. Am liebsten will ich einen lesbaren Diff Report, damit ich die Aenderung zuruecknehmen oder in den CLI Kommandos einpflegen kann.

xml_diff sieht gut aus, ich werde da mal testen


Gruss Stefan

marce
19.04.17, 17:41
Als Hinweis nebenbei: Wir haben Glassfish / Payarafish im Einsatz (ich weiß nicht, ob sich JBoss gleich verhält):
- die XML-Config-Datei wird beim PF nicht sofort nach einer Konfig-Änderung geschrieben sondern (spätestens) beim Runterfahren des Servers - sprich die Datei vergleichen / parsen kann zu falschen Ergebnissen führen (und damit sind auch Änderungen, die man an der Konfig an sich gemacht hat während der Server läuft, hinfällig)
- es gibt beim PF ein Cli-Kommando, welches einem die Konfgurations-Settings (Eigenschaft + Wert) als "Plaintext" ausgibt - also so, daß man sie direkt wieder in den Cli reinjagen kann. Schau mal die Doku durch, könnte mir vorstellen, daß JBoss das auch kann

Huhn Hur Tu
20.04.17, 09:39
@marce, danke fuer den Hinweis mit dem Schreibzeitpunkt, ich habe es getestet und es wird sofort mit bestaetigen der CLI geschrieben, was ja auch sinnvoll ist, da ein Applikationsserver ja auch hart beendet werden kann und dann nicht geschreiben wird.

@nopes, ich habe einiges ausprobiert und sobald die Aenderungen ein gewisses Mass ueberschreiten (ich habe die server.xml zweier verschiedener Cluster verglichen ) bekomme ich nur Skriptfehler bzw. wenn ich das unter Debian angebotene xml_diff verwende einen vollen SWAP und damit ein unbenutzbares System, bis zum kill des ganzen. Das von dir empfohlene xml_diff laeuft bei dem experiment auf Fehler, und es werden nur vorhandene, bzw. nicht vorhandene Zeilen, jedoch nicht die Properties beruecksichtigt.



Mir scheinen nun zwei Moeglichkeiten zu bleiben:
- Ich code mir einen xmldiff zusammen, durchiterieren
- oder ich mache es tumb mit diff, da kann ich hal;t weniger schoen Reports rauslassen

Odefr gibt es weitere Ideen ?

fork
20.04.17, 10:12
Ich frage mich immer noch, was Deine Ziele sind.

Vielleicht dieses hier?


Ein nachvollziehbares menschenlesbares Protokoll
Die Möglichkeit Änderungen wieder rückgängig machen zu können


Noch mehr?

Mit einer Versionsverwaltung(git/rcs/...) auf die Datei wäre der Sprung hin und her einfach machbar. Mit meinen obigen Ausführungen kann man die Änderungen strukturiert erfassen.

Huhn Hur Tu
20.04.17, 12:58
Ein nachvollziehbares menschenlesbares Protokoll
Die Möglichkeit Änderungen wieder rückgängig machen zu können


Zu 1, ja natuerlich, menschenlesbar sehr gerne
Zu 2, ich will Aenderungen erkennen, und die automation an diesem Punkt stoppen, bzw. im Anschluss per force Schalter ausrollen, dannach die Konfig wieder wegschreiben, als Letzter Stand gegen den geprueft wird.
Rollbacks sind nicht noetig.

Ich will manuelle Aenderungen sehen, diese auf den Sinn bewerten und entweder in meine Automagie einbauen oder verwerfen.
hier geht es mir einzig, ein XML mit einem anderen zu vergleichen um zu erfahren ob Aenderungen vorgenommen wurden, seit dem letzten Run der Automagie.

Um der Frage nach dem Sinn zuvorzukommen, mal ein klassisches Beispiel:
Samstag auf Sonntag kommt es zu Problemen, Logfiles lassen das SystemFS vollaufen, ich reduziere per Hand das Loglevel. Montag habe ich Urlaub, habe mitten in der Nacht vergessen eine Mail/Ticket zu schreiben, bzw. Montags hat das niemand gelesen. Irgendwer rollt per Automagie Montags einen Change aus und das Problem vom WE schlaegt wieder ein.

Da auch Entwicklungssysteme auf dieser Automagie basieren, will ich auch dass Entwickler nicht ihrer "Nicht Workflowkonformen" Aenderungen beraubt werden.

Es gibt eine Handvoll Moeglichkeiten sich automatisiert ins Knie zu schiessen, ich will mich vor einigen menschlichen Schuetzen.

fork
20.04.17, 13:50
Wie bereits geschrieben: Wenn die entsprechenden Dateien versioniert sind, dann kann man ja sehen, ob die Dateien bearbeitet wurden, oder ob der letzte Stand committet ist. Darüber bekommt man auch einen Diff. Zum bewerten der Änderung würde für mich ein einfacher diff reichen.

Der Automatismus liesse sich damit IMHO recht einfach steuern:


Dateien nicht mit dem letzten Stand in der Versionsverwaltung -> kein Überschreiben
Erzwungenes ausrollen: Den aktuellen Konfigurationsstand committen, durch automagie überschreiben und wieder comitten.

marce
20.04.17, 13:51
Auch - wenn auch nur Erfahrung aus GF / PF heraus - würde ich vor dem manuellen diff prüfen:
* Reihenfolge der Einträge

Beim GF hast Du von "Änderung" zu "Änderung" teilweise fast 100% Unterschiede, obwohl nur ein Eintrag geändert wurde, da sich die Reihenfolge der anderen Einträge ändert.

Evtl. wäre es also wirklich am einfachsten, wenn Du von einer Datei eine Version erzeugst (Versionsverwaltung über Server-Konfigs ist ja eh sinnvoll - muss ja nicht gleich ein SVN oder GIT sein, cp $datum tut's da ja auch - und dann über ein kleines Script in einer Sprache, die gut mit XML kann (also eine einigermaßen saubere Parser-Lib dafür bietet) das Ding Eintrag für Eintrag auseinandernimmst und vergleichst.

fork
20.04.17, 14:03
Einer unserer Kunden macht das so, dass er per Versionsverwaltung Änderungen den Diff als Ticket in sein OTRS eingeliefert bekommt, falls Änderungen festgestellt werden. Er nimmt dafür nicht etckeeper sondern etwas anderes älteres, weil man mit dem anderen beliebige Verzeichnisse beobachten kann. Wie diese Software jetzt heisst, weiss ich allerdings nicht mehr genau.

Nachtrag

Das verwendete Programm ist changetrack (http://changetrack.sourceforge.net/). Schon lange nicht mehr aktualisiert.

fork
20.04.17, 16:48
Das sieht doch hübsch aus:

https://github.com/joh/xmldiffs

Ich habe in einer Beispiel-XML-Datei einfach mal einen Block verschoben(also keine logische Änderung) und einen einfachen Wert geändert.

Normaler diff:




--- /etc/benno/benno.2.xml 2017-04-20 16:52:08.000000000 +0200
+++ /etc/benno/benno.3.xml 2017-04-20 16:55:21.000000000 +0200
@@ -75,16 +75,7 @@
</configuredcontainers>
<configuredcontainers>
<simplecontainer>
- <monthlyfsbox>
- <fshexbennobox>
- <monthlyfsjournal/>
- <directory>/srv/benno/archives/my.archiveserver.com/acmehealthandbeautygmbh/repo</directory>
- <subdirs>3</subdirs>
- <dirlength>2</dirlength>
- <compression>gzip</compression>
- </fshexbennobox>
- </monthlyfsbox>
- <identifier>ACME Beauty GmbH</identifier>
+ <identifier>ACME Nails and Beauty GmbH</identifier>
<conditions>
<or>
<domain sender="true" recipient="true" from="true" to="true" cc="true">acme.de</domain>
@@ -107,6 +98,15 @@
<luceneindex version="LUCENE_35">
<directory>/srv/benno/archives/my.archiveserver.com/acmehealthandbeautygmbh/index</directory>
</luceneindex>
+ <monthlyfsbox>
+ <fshexbennobox>
+ <monthlyfsjournal/>
+ <directory>/srv/benno/archives/my.archiveserver.com/acmehealthandbeautygmbh/repo</directory>
+ <subdirs>3</subdirs>
+ <dirlength>2</dirlength>
+ <compression>gzip</compression>
+ </fshexbennobox>
+ </monthlyfsbox>
</simplecontainer>
</configuredcontainers>
</containerarchive>


xmldiffs-Ausgabe:



./xmldiffs.py /etc/benno/benno.2.xml /etc/benno/benno.3.xml
--- /etc/benno/benno.2.xml
+++ /etc/benno/benno.3.xml
@@ -139,7 +139,7 @@
</or>
</conditions>
<identifier>
- ACME Beauty GmbH
+ ACME Nails and Beauty GmbH
</identifier>
<luceneindex version="LUCENE_35">
<directory>

nopes
21.04.17, 01:33
Jedenfalls gut gemacht, Laufzeit könnte ein Thema sein, die beiden Dateien werden nacheinander geladen, dabei werden sie zunächst sortiert und dann in eine Temp-Datei geschrieben, anschließend wird das Diff-Kommando auf die beiden Temp-Dateien angewandt - simpel :)
Falls Performance ein Thema wird, man könnte das relativ einfach auch ohne das schreiben der Temp-Dateien hinbekommen, braucht dann halt mehr RAM.

Problematisch wird es auch, wenn man nur einzelne Änderungen verwerfen will, aber auch da kann man bestimmt was machen - die Trees sollten ja möglichst gleich sein, wenn nicht kann man da dann fummeln (anschließend schreiben und den Review-Prozess von vorne anfangen)...

[edit]das mit dem Ident verfälscht auch, allerdings systematisch...
[edit2]die Temp-Dateien sind nicht als Ersatz geeignet, zum Prüfen nur bedingt, XML-Daten wo es auf die Reihenfolge ankommt, sollten jedenfalls nicht auf den Temp-Daten aufbauen:
<div><i>FOO</i><b>bar</b>is not<i>foo</i><b>BAR</b></div>
# vs
<div><i>foo</i><b>BAR</b>is not<i>FOO</i><b>bar</b></div>Das b-Element würde vor das i-Element geschrieben werden bzw der Sinn nur noch bedingt gegeben sein, für das Vorhaben vermutlich nicht relevant...

Huhn Hur Tu
25.04.17, 07:46
Danke fuer die vielen Antworten.

Ich habe mich jetzt fuer einen normalen Diff entschieden.
Dafuer vergleiche ich im ansible Lauf vor der Konfiguration die Live XML mit einer nach der Konfiguration weggeschriebenen, so sehe ich ob manuell geaendert wurde. Vom xmldiff nehme ich mal Abstand, da der voll durchdreht wenn der Unterschied zu gross wird

Gruss Stefan