Seite 1 von 1
auf allen Clients mit Software X Software Y auf setup setzen
Verfasst: 05 Feb 2015, 15:02
von holgerv
Code: Alles auswählen
opsi-admin -dS method productOnClient_getHashes '["clientId"]' '{"productId":"X","installationStatus":"installed"}'|grep "^clientId="| cut -d "=" -f 2- > /tmp/liste.txt
while read opsihostname; do echo opsi-admin -dS method setProductActionRequestWithDependencies \"Y\" \"${opsihostname}\" \"setup\"; done < /tmp/liste.txt > /tmp/opsi-admin-commands.sh
sh /tmp//tmp/opsi-admin-commands.sh
Geht das nicht eleganter? Das Abarbeiten der /tmp/opsi-admin-commands.sh braucht schon bei unter 100 Rechnern mehrere Minuten (auf ansonsten zufriedenstellender Hardware).
Vielen Dank!
Holger
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 05 Feb 2015, 17:48
von pandel
Na ja, ich denke, du hast, was Softwareinstallation anbelangt, eben generell zwei Möglichkeiten:
- configed, und damit grafisch
- oder via API
Bei letzterem finde ich deine Lösung schon ganz schön elegant. Es ist auf's Nötigste reduziert und macht exakt was du willst.
Hast du das MySQL Modul im Einsatz als Backend für alles, oder speicherst du deine Config im File Backend? MySQL soll ja auch ne ganze Ecke fixer sein. Wir haben bis dato auch leider nur das File Backend am Start und das schneckt eben vor sich hin...
Inoffizielle Backend-Alternative:
MongoDB:
https://github.com/dheid/opsi_mongodb/
PostgreSQL:
https://github.com/kochd/opsi-postgres
Lieber Gruß
Holger
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 06 Feb 2015, 11:26
von dkoch
wiki/userspace:webservice_corner:ruby-rpc
Code: Alles auswählen
opsirpc.productOnClient_getHashes(['clientId'], {productId: 'X', installationStatus: "installed"}).each do |match|
opsirpc.setProductActionRequestWithDependencies('Y', match['clientId'], 'setup')
end
Hier nochmal als Einzeiller dem Golffactor wegen:
Code: Alles auswählen
opsirpc.productOnClient_getHashes(['clientId'], {productId: 'X', installationStatus: "installed"}).each { |match| opsirpc.setProductActionRequestWithDependencies('Y', match['clientId'], 'setup') }
Das Problem beim Scripten mit Bash und nutzen von opsi-admin ist ganz einfach zu erklären:
Code: Alles auswählen
time opsi-admin -dS exit
real 0m0.694s
user 0m0.392s
sys 0m0.064s
Das bloße aufrufen und verlassen von opsi-admin dauert bereits 0.7 Sekunden.
Und das ist dein overhead pro Client ganz ohne den RPC weil Bash für jeden Client einen neuen Prozess von opsi-admin startet.
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 06 Feb 2015, 13:36
von pandel
dkoch hat geschrieben:
Das bloße aufrufen und verlassen von opsi-admin dauert bereits 0.7 Sekunden.
Und das ist dein overhead pro Client ganz ohne den RPC weil Bash für jeden Client einen neuen Prozess von opsi-admin startet.
Hast du eine Ahnung, wieso? Liegt das am Python Interpreter?
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 06 Feb 2015, 13:41
von holgerv
Das sieht gut aus. Wenn ich häufiger solche Aufgaben kriege, sollte ich mir mal ein Äquivalent in Python schreiben.
dkoch hat geschrieben:Das bloße aufrufen und verlassen von opsi-admin dauert bereits 0.7 Sekunden.
Und das ist dein overhead pro Client ganz ohne den RPC weil Bash für jeden Client einen neuen Prozess von opsi-admin startet.
Ja, das leuchtet ein. Danke!
Holger
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 06 Feb 2015, 14:19
von dkoch
pandel hat geschrieben:dkoch hat geschrieben:
Das bloße aufrufen und verlassen von opsi-admin dauert bereits 0.7 Sekunden.
Und das ist dein overhead pro Client ganz ohne den RPC weil Bash für jeden Client einen neuen Prozess von opsi-admin startet.
Hast du eine Ahnung, wieso? Liegt das am Python Interpreter?
Authentifizierung, Logo, Completion, etc. pp., unnötige libraries wie curses werden geladen.
opsi-admin ist eigentlich als Shell designend und nicht als Interpreter.
Also anstatt das die Methode ausgeführt wird wird erst mal jede menge Zeug gemacht, dass man gar nicht bräuchte.
Das ist so als würde man ein Bashscript schreiben in dem dann sowas steht :
Für eine interaktive Shell ist das alles wichtig und hilfreich. Für einen bloßen Interpreter aber unnötig
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 06 Feb 2015, 15:02
von pandel
Nachvollziehbar, danke! Wünschenswert wäre ja dann, wenn bspw. die Parameter -S, -s oder -r dafür sorgen würden, dass dieser ganze overhead nicht geladen wird. Das würds wahrscheinlich beschleunigen...
Re: auf allen Clients mit Software X Software Y auf setup se
Verfasst: 09 Feb 2015, 10:32
von n.wenselowski
Guten Morgen zusammen,
pandel hat geschrieben:Nachvollziehbar, danke! Wünschenswert wäre ja dann, wenn bspw. die Parameter -S, -s oder -r dafür sorgen würden, dass dieser ganze overhead nicht geladen wird. Das würds wahrscheinlich beschleunigen...
Hm, schwierig. Würde dann dazu führen dass irgendwo imports gemacht werden und sowas ist ziemlich schlechter Stil. Ein anderer Ansatz wäre der von wiederverwendbaren Interpretern, wie bspw. in
The Python I Would Like To See beschrieben.
Ich würde vorschlagen das ganze entweder über ein eigenes Python-Script, in welchem der Backend-Zugang wiederverwendet wird, oder eine Erweiterung.
Hier eine (ungetestete) Backend-Erweiterung, die genau das machen sollte, was dein Script macht. Die kann dann über
opsi-admin -d method installProductOnClientsWithProduct "foo" "bar" aufgerufen werden.
Code: Alles auswählen
def installProductOnClientsWithProduct(self, requiredProduct, productToInstall):
clients = set([poc.clientId for poc in self.productOnClient_getObjects(productId=requiredProduct, installationStatus="installed")])
for clientId in clients:
self.setProductActionRequestWithDependencies(productToInstall, clientId, "setup")
Für den
Golffactor 
kann man das auch in einen Einzeiler packen:
Code: Alles auswählen
def installProductOnClientsWithProduct(self, requiredProduct, productToInstall):
[self.setProductActionRequestWithDependencies(productToInstall, clientId, "setup") for clientId in set([poc.clientId for poc in self.productOnClient_getObjects(productId=requiredProduct, installationStatus="installed")])]
Viele Grüße
Niko