Fedora und das Packagekit Offline Update

Vor einigen Releases hat Fedora ein neues Updateverhalten via Packagekit eingeführt, das verdächtig nach „Windows macht das auch so“ stank. Wie grottig das wirklich laufen kann, kommt unten in Bild & Schrift.

Fedora und das Packagekit Offline Update

Um es gleich mal vorweg zu schicken: Ich bin pro Fedora und achte das, was die da auf die Beine stellen.

Aber nur weil man es mag, muß man nicht mit allem einverstanden sein und die Änderung des Updateverhaltens durch Packagekit’s „Offline Update“ ist eine der Sachen die ich nicht unterstützen kann. Damit Ihr Euch ein Bild von der Sache machen könnt, habe ich da mal was abgelichtet.

Ich bitte die schlechte Bildqualität zu entschuldigen, aber Screenshots sind an der Stelle im Bootvorgang nicht vorgesehen 😉

Gestern

Gestern war ich mit meinem Surface bei einem Kunden. Während ich da gearbeitet habe, hat sich Packagekit mit Updates versorgt, diese aber nicht eingespielt. ich hab es nur gemerkt, weil ich das Bandbreitenwidget im Gnome habe, das plötzlich hektisch aktiv wurde.

Heute morgen

schalte ich mein Tablet ein, weil ich für den nächsten Artikel was testen wollte. Es kommt die Kernel Auswahl, es kommt die Passwortabfrage für LUKS und dann passiert es:

Bitte fahren Sie den Computer nicht runter!

Größtenteils weiß man nicht mal, was da aktualisiert wird.

Es lief ein Offline-Update von Packagekit 🙁 Nicht 10 Sekunden, nicht 30 Sekunden, nicht eine Minute, nicht fünf Minuten, nein, für knappe acht Minuten war das Geräte vollständig blockiert. Weil ein neuer Kernel installiert worden war, mußten auch alle AKMOD Module für alle Kernels neu gebaut werden. Und dann … gingen die Lichter aus und blieben aus.

Achtet mal auf die Zeiten vom packagekit-offline-update.service

Anstatt das Update einzuspielen und durchzubooten, wurde das Tablet danach einfach abgeschaltet. Kommentarlos übrigens 🙁

Wie Ihr oben in den Bildern und hier sehen könnt:

wird einem nicht mal erzählt, was da aktualisiert wurde. Ab und zu blitzt mal ein Name durchs Display, aber das wars dann auch schon.

Per DNF aktualisiert, gibt es ein Logfile, in dem ganz genau drin steht, wann was von welcher Version auf welche neue Version aktualisiert wurde. Da DNF das Update nicht gemacht hat, ratet mal …

Natürlich gibt es von PackageKit auch einen Logeintrag. Den kann man sich aber so nicht ansehen, weil man dazu den GPK Logger aufrufen muß: gpk-log

Das ist ultimativ toll, wenn man von dem Tool noch nie etwas gehört hat, oder? Ein grep über /var/log bringt einem nämlich nur die Einträge von DNF, die zum Packagekit Paket gehören, wenn DNF das updated 😀

Die Krönung des Ganzen

war dann der Umstand, daß ich sowieso noch ein Update vorhatte, um den neuen Surfacekernel einzuspielen. Dazu mußten einige alte LUA Paket entfernt werden, damit das Update überhaupt stattfinden konnte. Als dann das Update endlich ging, war schon wieder ein neuer normaler Kernel verfügbar, der dann natürlich auch alle Kernel-Module neu bauen mußte.

Fazit

Das offline-update ist in diesem Fall lästig und überflüssig gewesen, weil beim nächsten Start schon neue Pakete zur Verfügung standen. Der Sinn und Zweck davon, es beim BOOTEN durchzuziehen, erschließt sich ohnehin nicht, weil für ein Kernelupdate die Kernelmods neugebaut werden müssen und damit die dann auch benutzt werden, muß man ohnehin rebooten, was „Packagekit Offline-Update“ dann ja auch, mit wenig Erfolg, gemacht hat.

Da kann man es doch auch gleich beim Runterfahren installieren, oder??? Dann kann man am nächsten Tag wenigstens sofort arbeiten.

Lösung

Wie bekommen wir das weg?

systemctl disable packagekit packagekit-offline-update
systemctl mask packagekit

„Wir sehen uns wieder, wenn Du wieder vernünftiger geworden bist.“ Denn natürlich gibt es einen Grund, wieso man nicht einfach so GB!weise Daten zieht, nur weil man eine Internetanbindung hat.

 

Linux am Dienstag – Programm für den 3.2.2023

Ich denke, Ihr seid alle gut durch den Jahreswechsel gekommen, da können wir uns bei Linux am Dienstag planmäßig treffen.

Linux am Dienstag – Programm für den 3.2.2023

Dienstag Abend ab 19 Uhr geht es u.a. um:

  • Sicherheit – Microsoft wird ProxyNotShell Schwachstelle einfach nicht los
  • Sicherheit – Passwortmanager LastPass mit Datenleck
    Linux – Sambatreiber im Kernel schwachstelle
  • Datenschutz – Microsoft zahlt 60M US$ Strafe
  • Datenschutz – Meta zahlt 750M US$ Strafe

und andere IT-Newsbeiträge aus aller Welt. Wie jede Woche per Videokonferenz auf https://meet.cloud-foo.de/Linux .

Hinweis: Die bisherigen Vorträge findet man unter https://linux-am-dienstag.de/archiv/ .

PVA: Pluginsystem für Carola

Goldene Zeiten für alle Voice Assistenten Fans unter Euch. Sofern Ihr Java könnt, seid Ihr nun in der Lage Carola um neue Funktionen zu erweitern.

PVA: Pluginsystem für Carola

Im GitHub Pluginsverzeichnis ist ein Beispiel, daß Euch die Möglichkeiten aufzeigt. Ihr könnt reine Kommandoausführung machen, also auf Sprachbefehle lauschen und ausführen, oder Ihr erstellt einen periodischen Dienst, der die ganze Zeit im Hintergrund arbeitet, oder beides 😉

Vor ein paar Tagen habe ich ja auf die neue Prozessüberwachung hingewiesen, die wurde jetzt umgeschrieben, so daß Sie als Plugin arbeitet. Das führte dazu, daß wir die „nervigen“ Audiowarnungen abschalten können, wenn die Ursache bekannt ist.

Was müssen wir machen um ein Plugin zu schrieben?

Nicht so viel wie man denken würde. Erstmal brauchen wir die nötigen Kommandos und Texte:

command:“schalte|warnung|aus“,“SILENCELOADWARNING“,““
command:“schalte|warnung|ein“,“UNSILENCELOADWARNING“,““

text:“de“,“HEALTHRESPONSETURNEDOFF“,“es erfolgen keine weiteren audiowarnungen mehr“
text:“de“,“HEALTHRESPONSETURNEDON“,“Sprachwarnungen eingeschaltet“

Und dann natürlich den Plugincode:

 



package plugins.files;

import plugins.Plugin;
import io.Dos;
import server.PVA;
import hash.StringHash;
import hash.TwoKeyHash;

public class LoadTask extends Plugin {

	private String getFilter = ":silence:";
	private String setFilter = ":silence:";
	private TwoKeyHash validValues = new TwoKeyHash(); // this way we get multiply options for an argument 
	
	public LoadTask() {
		System.out.println("Class LoadTask Constructor called");
	}
	
	public void init(PVA pva) {
		this.pva = pva;
		info.put("hasThread","yes"); // Das sagt dem Pluginloader, das wir einen Prozess laufen lassen wollen
		info.put("hasCodes","yes");  // Das sagt dem PVA Task, daß wir Kommandos verarbeiten
		info.put("name","LoadTask"); // Ein eindeutiger Name, könnte auch de.linux-am-dienstag.LoadTask sein.
		vars.put("silence","no");    // hier merken wir uns, ob wir Sprachwarnungen ausgeben wollen: JA!
		validValues.put("silence","yes","ok"); // Dieses Plugin prüft, ob die Variable "Silence" geändert werden darf und wenn ja wie
		validValues.put("silence","no","ok");
	}
	
	public StringHash getPluginInfo() {
		return this.info;		// wir geben unsere Infos an den PluginManager damit der etwas über uns weiß.
	}

	public String  getVar(String name) {
		if ( getFilter.contains(":"+name+":") )   // Wir prüfen, ob die Variable "name" ausgelesen werden darf.
			return vars.get(name);            // Wenn JA, ann gibt Inhalt zurück
		return ""; // war wohl nichts.
	} 

        // Hier prüfen wir, ob eine bestimmte Variable von außen geändert werden darf. Das KANN man so machen, muß man aber nicht.

	public boolean setVar(String name,String value) {
		if ( getFilter.contains(":"+name+":") && validValues.get(name,value).equals("ok")  )  {
			vars.put(name,value);
			return true;
		}
		return false;
	}
	
	// getActionCodes() gibt alle Kommandos aus, die in der Config für dieses Plugin eingetragen sein sollten, ergo auf was es so hört:

	public String[] getActionCodes() {  return "SILENCELOADWARNING:UNSILENCELOADWARNING".split(":"); };

        // hier führen wir Kommandos aus. Dazu prüfen wir, ob wir das Kommando kennen. 
        // Optional gibt es noch den rohen text der Eingabe, so daß dort Infos ausgelesen werden können.
	public boolean execute(String actioncode, String rawtext) { 
		try {
			if ( actioncode.equals("SILENCELOADWARNING") ) {
				log("schalte warnung aus");
				setVar("silence","yes");
				pva.say( pva.texte.get( pva.config.get("conf","lang_short"), "HEALTHRESPONSETURNEDOFF") );
	
			} else if ( actioncode.equals("UNSILENCELOADWARNING") ) {
	
				log("schalte warnung ein");
				setVar("silence","no");
				pva.say( pva.texte.get( pva.config.get("conf","lang_short"), "HEALTHRESPONSETURNEDON") );
	
			} else return false;
	
			return true;
		}  catch (Exception localException) {
			localException.printStackTrace();
			return true;
		}
	};

	Float lastState = Float.parseFloat("0");
	
       // hier starten wir den eigentlich Überwachungsprozess und lesen die Load aus und berichten über unsere Funde via Sprachausgabe:
	public void run() {
		try {
			String load = "";
			int time = 0;
			boolean inform = false;

			while ( true ) {
				if (isInterrupted()) {
					return;
				}

				Float f = Float.parseFloat( dos.readPipe("cat /proc/loadavg").split(" ")[0].trim() );
				long  c = Long.parseLong( dos.readPipe("grep -c processor /proc/cpuinfo").trim() );
				
				if ( f > c && ( lastState < c || time > 60 ) ) {
						if ( vars.get("silence").equals("no") ) pva.say( pva.texte.get( pva.config.get("conf","lang_short"), "HEALTHRESPONSEHELPHELP") );
						time = 0;
						inform = true;
					
				} else if ( f > ( c*80/100) && ( lastState < ( c*80/100) || time > 60 ) ) {
						if ( vars.get("silence").equals("no") ) pva.say( pva.texte.get( pva.config.get("conf","lang_short"), "HEALTHRESPONSE80P") );
						time = 0;
						inform = true;
				} else if ( f < ( c/2 ) && lastState > (c/2) && inform ) {
						if ( vars.get("silence").equals("no") ) pva.say( pva.texte.get( pva.config.get("conf","lang_short"), "HEALTHRESPONSEOK") );
						inform = false;
				}	

				lastState = f;
				time++;
				sleep(1000L);

			}
		} catch (Exception localException) {
			localException.printStackTrace();
		}
	}
}

Die Load auslesen ist jetzt nicht so dramatisch schwer, so das das Plugin recht kurz ist. Da kann man natürlich auch viel umfangreichere Anwendungen schreiben.

Falls Euch der Javacode nichts sagt, wird es langsam Zeit mal Java zu lernen, daß ist recht einfach 😉

Ein cooles Plugin wäre eine Anbindugn an ChatGPT 😉 Vielleicht will ja mal wer oder fragt doch ChatGPT mal, der braucht doch auch Code 😉