hat jemand von euch den Versionvergleich des Gluonautoupdaters verstanden?
Ich hatte zwischendurch mal ein paar Knoten von v2016.1.3 auf v2016.1.x aktualisiert. Also mit x meine ich den entsprechenden Git-Zweig.
Dazu musste ich damals das Manifest manipulieren. Jetzt wollte ich zurück auf v2016.1.5 und muss scheinbar wieder das Manifest manipulieren, weil die Knoten die neue Version nicht ziehen. Eigentlich müssten doch Buchstaben vor Zahlen kommen, dass heißt, wenn ich von v2016.1.x+1.1.3 auf v2016.1.5+1.1.4 aktualisieren will, müsste der Autoupdater das als neuer anerkennen? (Versionsnummerierung Schema Münsterland)
Hier mal der Code aus dem Gluon-Paket:
$ cat version.lua
module 'autoupdater.version'
-- version comparison is based on dpkg code
local function isdigit(s, i)
local c = s:sub(i, i)
return c and c:match('^%d$')
end
local function char_value(s, i)
return s:byte(i, i) or 0
end
local function char_order(s, i)
local c = s:sub(i, i)
if c == '' or c:match('^%d$') then
return 0
elseif c:match('^%a$') then
return c:byte()
elseif c == '~' then
return -1
else
return c:byte() + 256
end
end
-- returns true when a is a higher version number than b
function newer_than(a, b)
local apos = 1
local bpos = 1
while apos <= a:len() or bpos <= b:len() do
local first_diff = 0
while (apos <= a:len() and not isdigit(a, apos)) or (bpos <= b:len() and not isdigit(b, bpos)) do
local ac = char_order(a, apos)
local bc = char_order(b, bpos)
if ac ~= bc then
return ac > bc
end
apos = apos + 1
bpos = bpos + 1
end
while a:sub(apos, apos) == '0' do
apos = apos + 1
end
while b:sub(bpos, bpos) == '0' do
bpos = bpos + 1
end
while isdigit(a, apos) and isdigit(b, bpos) do
if first_diff == 0 then
first_diff = char_value(a, apos) - char_value(b, bpos)
end
apos = apos + 1
bpos = bpos + 1
end
if isdigit(a, apos) then
return true
end
if isdigit(b, bpos) then
return false
end
if first_diff ~= 0 then
return first_diff > 0
end
end
return false
end
Sieht jemand, warum es in beide Richtungen nicht geht?
Wenn die Version wirklich „v2016.1.x+1.1.3“ ist dann wirst du davon nur mit v2016.1.y+1.1.4 oder v2016.1.z+1.1.4 updaten können.
Die Zeichen werden wie Zahlen angesehen, y bzw z ist größer als x.
Ja, mit dem y funktioniert es. Das Problem an manipulierten Manifesten ist, dass die Geräte dann in eine Updateschleife geschickt werden, wenn man nicht daneben sitzt und die IPV6s einzeln sperrt.
Warum ist denn 5 nicht größer x? Ich dachte es wäre a-z0-9?
Okay, dann verstehe ich immer noch nicht, warum ich damals das Manifest manipulieren musste um von v2016.1.2+1.1.0 auf v2016.1.x+1.1.3 zu aktualisieren.
Ich halte es für durchaus überlegenswert, den Versionsnummernvergleich mit etwas mehr Intelligenz zu versehen.
Statt also zeichenweise nach numerischem char-Wert zu vergleichen zunächst einmal „numerische Blöcke“ zu bilden (Trennzeichen dabei z.B. eine Sammlung von „.,:\ /)(“) und der Übergang zwischen Ziffern und Buchstaben vice versa, ohne das Trennzeichen selbst aber als Sortierzeichen erster Ordnung einzubezieh, sondern eben nur als Trenner)
Und dann die diese Blöcke dann numerisch zu betrachten (also „123“>„13“. Und zudem Buchstaben davor. Also „0“ > „a“, so dass eine „0.11-a“ als älter eingeschätzt wird als eine „0.11.2“.
Ich kann was Versionierung angeht das hier als Leitfaden empfehlen:
Für Düsseldorf verwenden wir z.b. das folgende Schema:
v1.2.5-r2
Also [Versionsnummer]-r[Buildnummer], so können wir für die selbe Version mehrere Builds haben, normalerweise macht man nämlich nur neue Versionsnummern wenn sich was ändert :).
Ich weiss nicht, ob Du gelesen hast, was ich geschrieben habe.
Aber um aus dem von Dir refernzeierten Leitfaden zu zitieren:
A normal version number MUST take the form X.Y.Z where X, Y, and Z are
non-negative integers, and MUST NOT contain leading zeroes. X is the
major version, Y is the minor version, and Z is the patch version.
Each element MUST increase numerically. For instance: 1.9.0 → 1.10.0 → 1.11.0.
Und genau das leistet der Autoupdater derzeit leider nicht.
Denn für ihn ist „1.10.0“ < „1.9.0“
Denn es findet kein numerischer Vergleich (und damit notwendigerweise auch vorher eine syntaktische Analyse des Versionsstrings) statt. Sonder ein alfanumerischer Vergleich, Buchstabe für Buchstabe. (Was bei UTF8 passieren würde möchte ich gar nicht wissen…)
Ich möchte an dieser Stelle auf das Versionierungskonzept der Frankfurter verweisen:
Vieleicht mag @Jason dazu etwas aus der Praxis sagen.
First the initial part of each string consisting entirely of non-digit characters is determined. These two parts (one of which may be empty) are compared lexically. If a difference is found it is returned. The lexical comparison is a comparison of ASCII values modified so that all the letters sort earlier than all the non-letters and so that a tilde sorts before anything, even the end of a part. For example, the following parts are in sorted order from earliest to latest: ~~, ~~a, ~, the empty part, a.
Then the initial part of the remainder of each string which consists entirely of digit characters is determined. The numerical values of these two parts are compared, and any difference found is returned as the result of the comparison. For these purposes an empty string (which can only occur at the end of one or both version strings being compared) counts as zero.
These two steps (comparing and removing initial non-digit strings and initial digit strings) are repeated until a difference is found or both strings are exhausted.
So wie ich den Autoupdater kennengelernt habe, und das hat bei mir weh getan, so vergleicht er von links nach rechts die einzelnen Abschnitte, bis er einen Unterschied festgestellt hat.
Der Vergleich findet zeichenweise statt, solange es sich um keinen numerischen Ausdruck handelt.
Treffen bei einem Vergleich zwei numerische Ausdrücke aufeinander, so gewinnt der grössere. Bei Gleichheit wird dann der nächste Vergleich mit den auf die jeweiligen numerischen Ausdrücke folgenden Zeichen durchgeführt.
@adorfer Daher ist für den autoupdater „1.10.0“ > „1.9.0“ (er stellt fest, das 10 > 9 ist)
Treffen bei einem Vergleich ein Buchstabe bzw. ein Zeichen und die erste Ziffer eines numerischen Ausdruckes aufeinander, so wird die ASCII-Tabelle zur Hand genommen.
Alles was keine Ziffer ist wird als (Trenn-)Zeichen interpretiert und einzeln nach der ASCII-Tabelle ausgewertet.
EDIT: Edit gelöscht :o)
Da fehlt irgendwie eine Schlüssel-Information, hab aber keine Ahnung welche.
Kannst Du etwas Genaueres zur Behandlung und zur Manipulation der Manifestdatei in Münster sagen?
Mit Manipulation meine ich, dass ich, wie oben vorgeschlagen in der Manifestdatei die Version auf z. B. 2016.1.y ändere, obwohl es nur 2016.1.5 ist. Man spielt also eine neuere Version vor.
Das haben wir früher auch so gemacht, allerdings ist das sehr unpraktisch wenn mal jemand von Stable zu Beta oder andersherum wechseln möchte, daher läuft es nun so:
Vielleicht macht es auch Sinn, einfach die Anforderungen runterzuschrauben? Mit einem Schema 0.M.m~build und 0.M.m-rel kommt der bestehende Code doch klar, auf welcher Seite des Bildschirms existiert dann ein Problem? [M=Major, m=minor]
Ich habe vor Zeiten auf ein banales Timestamp (YYYYMMTThh) umgestellt mit einem suffix für sta/bet/exp.
Wer mehr wissen möchte, der soll gefälligst ins Git schauen. Außer den jeweiligen community-MaintainerInnen blickt in „1.0.51-rc3-stable“ sowieso niemand durch und alle anderen müssen (wer hätte es nicht anders vermutet) ins Git schauen.
Aber das ist doch totaler Mist, genau wie so etwas hier:
v1.10.3-test-83, das baut dann laut Daten in der Karte auf gluon-2016.1.4 auf.
Wenn dann mal, wie öfters, der Fall besteht bei Gluon Problemen zwischen den Communities zu vergleichen wird das selbst für an sich eingeweihte enorm schwierig.
Ist es wirklich zu viel verlangt dem Gluon Release Tag auf dem die Firmware basiert aufzunehmen?
Meine Frage ist beantwortet. Ihr könnt gerne noch über Versionsschemata diskutieren, ich wollte nur wissen, warum die Knoten bei uns nicht ziehen. Das ist gelöst.
Wir bauen nicht stumpf vanilla Gluon mit eigener site.conf, aktuell patchen wir auch das OpenWRT unter 2015.1.x. Insofern ist die Gluon-Basis nur ein Aspekt, und der wird in der minor number ausgewiesen. Unter anderem würde es die Nutzer zurecht verwirren, wenn wir Mitte 2016 eine Firmware aus 2015 rausbrächten … Suffixe für stable & Co. machen wir nicht, das würde einen neuen Build implizieren (oder andere Werte im Build und im Manifest) und damit etwas freigeben, was so nie getestet wurde. Aber das hat mit dem Versionsvergleich schon nichts mehr zu tun.