Re: [PUG] python statt bash
hi Carsten, ich antworte mal nur, um dich nicht im Dunklen zu lassen. Ich werde mir deine Mail ausdrucken(!) und Ruhe zu Gemüte führen. Danke für die ausführliche Mail!. cu denny signature.asc Description: This is a digitally signed message part -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
hi, ich habe mal die Anmerkungen übernommen und versuche nun die Funktion get_state zu basteln. Dazu muss zuerst wieder die Liste der verfügbaren VMs erzeugt werden, um diese dann zu durchsuchen. Der Benutzer soll tippen können: ./vmx -g cluster1 Als Ausgabe soll ein schlichtes: off/on erscheinen. Ruft man das vmware-cmd Tool auf, sieht das so aus: vmware-cmd /vmfs/volumes/4c52874b-65503560-05f0-0021288ea4ad/cluster_1/cluster_1.vmx getstate Ausgabe: getstate() = off Od. auch: vmware-cmd /vmfs/volumes/4c52874b-65503560-05f0-0021288ea4ad/cacti/cacti.vmx getstate getstate() = on Mittels find und dann split müssten man das so zerlegen, dass der User nur cacti od. cluster_1 angeben kann, wobei auch Leerzeichen OK sein müssen: /vmfs/volumes/4c52874b-65503560-05f0-0021288ea4ad/vmwarevm/Windows XP Professional.vmx Ich wäre wieder für Tipps aufgeschlossen :-) Hier mal mein derzeitiger Code, wobei ich anmerken muss, dass mir das if/else am Ende nicht gefällt. Da gibt es sicher etwas eleganteres. cu denny #!/usr/bin/python2.5 #Dient der verwaltung von VMs imports import sys from optparse import OptionParser from subprocess import Popen, PIPE, STDOUT ### Definitionen Liste der registrierten VMs vom ESX erhalten def reg_vm(regvm): vm = Popen(['vmware-cmd','-s', 'listvms'], stdout=PIPE, stdin=PIPE, stderr=STDOUT).communicate()[0].split('\n') vm = [line.strip() for line in vm if line.strip()] if regvm == str(all): for entry in vm: print vm.index(entry), entry else: try: print vm[regvm] except IndexError: print(Kein Eintrag vorhanden) sys.exit(3) def get_state(getstate): vm = Popen(['vmware-cmd','-s', 'listvms'], stdout=PIPE, stdin=PIPE, stderr=STDOUT).communicate()[0].split('\n') vm = [line.strip() for line in vm if line.strip()] vm = vm.split(.) vm = vm.find(getstate) print vm ### Arg parser ### parser = OptionParser() parser.add_option(-r, --registerd-vm, action=store, type=string, dest=regvm, help=Get list of registerd VM, use 'all' to get all VMs) parser.add_option(-s, --set-state, action=store, type=string, dest=setstate, #choices=['off', 'on', 'reset'], help=Set powerstate from VM) parser.add_option(-g, --get-state, action=store, type=string, dest=getstate, help=Get powerstate from VM) (options, args) = parser.parse_args() Werte zuweisen regvm = options.regvm print(regvm, regvm) setstate = options.setstate print(setstate,setstate) getstate = options.getstate print(getstate, getstate) ## main # if regvm == None and getstate == None and setstate == None: print(Keine Paramter angegeben, siehe --help) if regvm == None and (getstate == None and setstate == None) or (getstate != None and setstate != None): print(-g und -s schliessen sich aus) else: if regvm != None: if regvm == str(all): reg_vm(regvm) else: regvm = int(regvm) reg_vm(regvm) else: if getstate != None: get_state(getstate) signature.asc Description: This is a digitally signed message part -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
Hallo Denny, if regvm == None and getstate == None and setstate == None: print(Keine Paramter angegeben, siehe --help) if regvm == None and (getstate == None and setstate == None) or (getstate != None and setstate != None): print(-g und -s schliessen sich aus) else: müssten die Zeilen if regvm == None and (getstate == None and setstate == None) or (getstate != None and setstate != None): print(-g und -s schliessen sich aus) nicht einfacher heissen: if getstate != None and setstate != None: print(-g und -s schliessen sich aus) ? 'regvm == None and (getstate == None and setstate == None)' ist doch die Wiederholung der zweiten Zeile davor? Kann aber auch völlig daneben liegen.. Viel Spass weiterhin, Markus -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
--On Donnerstag, Februar 17, 2011 11:21:12 +0100 Denny Schierz linuxm...@4lin.net wrote: hi, Kurze Frage vorweg: hat vmware keine Python api? [...] ./vmx -g cluster1 Als Ausgabe soll ein schlichtes: off/on erscheinen. Ruft man das vmware-cmd Tool auf, sieht das so aus: vmware-cmd /vmfs/volumes/4c52874b-65503560-05f0-0021288ea4ad/cluster_1/cluster_1.vmx getstate Ausgabe: getstate() = off splitte stdout nicht an den Zeileinenden und suche in der kompletten Zeichenkette: if output.find('getstate() = off') = 0: print 'off' exit() elif output.find('getstate() = on') = 0: print 'on' exit() else: # Irgendwas anderes print output string.find(sub) hat eine blöde api. Es gibt die Position des ersten Treffer für sub im string zurückgibt. Das kann also 0..n sein. Wenn er nicht gefunden wird bekommt man -1. Das läßt sich aber nicht auf True/False testen, denn bool(0) ist False (der Substring wurde am Anfang der Zeichenkette gefunden, bool(1) ist True und bool(-1) ist auch True. Also musst Du mit = 0 (gefunden) oder 0 (nicht gefunden) testen. Die den Pfad der Virtuellen Maschine hast Du ja in einer Liste. Wenn Du vm-namen benutzen willst sortiere die VMs in eine andere Datenstrukture ein, z.B. ein dict: machines_by_name = {} for vm in liste der vms: vm_name = vm.split('/')[-2] # letzter verzeichnisname # oder from os.path import splitext vm_name = splitext(vm)[0] # splitext gibt ein (dateiname, erweiterung) tuple zurück machines[vm_name] = vm dann kannst statt mit nummern mit namen arbeiten. vm = machines_by_name['cluster_1'] [...] if regvm == None and getstate == None and setstate == None: print(Keine Paramter angegeben, siehe --help) if regvm == None and (getstate == None and setstate == None) or (getstate != None and setstate != None): Die untere Bedingung ist im vorderen Teil Identisch mit der oberen. if var == None kannst Du durch if var ersetzen, weil None hier zu False evaluiert wird und damit wird das ein Vergleiche auf True oder False. Wenn Du explizit auf None testen musst, weil Deine Variable z.B. False, 0, '' (leerer string) oder ein leeres objekt sein kann, nimm is: if var is None: # Testet, ob es sich um identische Objekte handelt. Denn: False == None True 0 == None True False is None False Also z.B. if not (regvm or getstate or setstate): ... Ich hab dir den unteren Teil Deines Skriptes mal geordnet, wie man es häufig findet. ..Carsten def get_opts(): '''Kommandozeilenargumente sammeln''' parser = OptionParser() parser.add_option(-r, --registerd-vm, action=store, type=string, dest=regvm, help=Get list of registerd VM, use 'all' to get all VMs) parser.add_option(-s, --set-state, action=store, type=string, dest=setstate, #choices=['off', 'on', 'reset'], help=Set powerstate from VM) # willst Du das nicht mit type=int speichern? parser.add_option(-g, --get-state, action=store, type=string, dest=getstate, help=Get powerstate from VM) (options, args) = parser.parse_args() # Werte zuweisen regvm = options.regvm print(regvm, regvm) setstate = options.setstate print(setstate, setstate) getstate = options.getstate print(getstate, getstate) if regvm and regvm != 'all': try: regvm = int(regvm) except ValueError: parser.error('regvm kann nur all oder eine Zahl sein') if not (regvm or getstate or setstate): # will exit with errorcode 2 and prints usage message parser.error(Keine Paramter angegeben) if getstate and setstate: parser.error(-g und -s schliessen sich aus) return (regvm, getstate, setstate) def main(): (regvm, getstate, setstate) = get_opts() if regvm: reg_vm(reg_vm) elif getstate: get_state(getstate) if __name__ == '__main__': main() -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
Versuche mal mit del list[-2] Am 15. Februar 2011 08:56 schrieb Denny Schierz linuxm...@4lin.net: hi, da aus Perl nichts geworden ist, versuche ich es mal mit Python und habe gleich die erste Aufgabe gefunden: Ich will mir (unter anderem für Nagios) einen Wrapper schreiben, mit dem ich bestimmte Zustände von ESX VMs abfragen od. auch initiieren kann. »Also Ist VM X eingeschaltet, wenn nicht, schalte sie ein etc.« Dafür rufe ich im Prinzip immer nur vmware-cmd paramter auf. Die Ausgabe von z.B. vmware-cmd -s listvms (Listet alle registrierten VMs auf) lasse ich in eine Liste schreiben. Nun hatte ich das Problem, dass am Ende der Liste immer noch zwei Einträge mit Leerzeilen vorhanden waren (.split('\n')). Diese wollte ich löschen, habe es nicht so richtig hinbekommen, im Sinne von: lösche mit del list[:2] die letzten beiden Einträge. Allerdings wirkt das genau verkehrt rum ... es werden nur noch die Einträge 0 und 1 angezeigt. Also habe ich vorher ein list.reverse() angeworfen und siehe da, mein del list[:2] löscht die überflüssigen Einträge raus. Doch mich würde interessieren, wie ich die Leerzeilen bereits beim befüllen der Liste vermeiden kann. Da mir das schon wieder wie ein Hack vorkommt: ./test2.py [..] ('VM :', 18, '/vmfs/volumes/4c52874b-05f0/vm5/vm5.vmx') ('VM :', 19, '/vmfs/volumes/4c52874b-05f0/cluster_1/cluster_1.vmx') ('VM :', 20, '/vmfs/volumes/4c52874b-05f0/cluster_2/cl_2.vmx') ('VM :', 21, '') ('VM :', 22, '') da man nicht weiß, wie lang die Liste wird, kann man diese nicht explizit mit del 21,22 angehen. Die beiden Newlines kommen schon vom vmware-cmd Kommando: # vmware-vmd -s listvms | od -taz [...] 0002620 a d / c l u s t e r _ 2 / c l u ad/cluster_2/clu 0002640 s t e r _ 2 . v m x nl nl ster_2.vmx.. 0002654 Meine ersten Anfänge sehen so aus (2 Bücher + Google) = #!/usr/bin/python2.5 #imports from optparse import OptionParser from subprocess import Popen, PIPE, STDOUT # Definitionen def list_vm(choice): list = Popen(['vmware-cmd','-s', 'listvms'], stdout=PIPE, stdin=PIPE, stderr=STDOUT).communicate()[0].split('\n') #list.reverse() #del list[:2] if choice == 0: for index in range(len(list)): print(VM :,index, list[index]) else: print(VM:, list[choice]) choice = 0 list_vm(0) == Wie bekomme ich die überflüssigen \nl da nun raus? cu denny -- PUG - Penguin User Group Wiesbaden - http://www.pug.org -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
Korrektur: probiere es mit del list[-2:] Am 15. Februar 2011 08:56 schrieb Denny Schierz linuxm...@4lin.net: hi, da aus Perl nichts geworden ist, versuche ich es mal mit Python und habe gleich die erste Aufgabe gefunden: Ich will mir (unter anderem für Nagios) einen Wrapper schreiben, mit dem ich bestimmte Zustände von ESX VMs abfragen od. auch initiieren kann. »Also Ist VM X eingeschaltet, wenn nicht, schalte sie ein etc.« Dafür rufe ich im Prinzip immer nur vmware-cmd paramter auf. Die Ausgabe von z.B. vmware-cmd -s listvms (Listet alle registrierten VMs auf) lasse ich in eine Liste schreiben. Nun hatte ich das Problem, dass am Ende der Liste immer noch zwei Einträge mit Leerzeilen vorhanden waren (.split('\n')). Diese wollte ich löschen, habe es nicht so richtig hinbekommen, im Sinne von: lösche mit del list[:2] die letzten beiden Einträge. Allerdings wirkt das genau verkehrt rum ... es werden nur noch die Einträge 0 und 1 angezeigt. Also habe ich vorher ein list.reverse() angeworfen und siehe da, mein del list[:2] löscht die überflüssigen Einträge raus. Doch mich würde interessieren, wie ich die Leerzeilen bereits beim befüllen der Liste vermeiden kann. Da mir das schon wieder wie ein Hack vorkommt: ./test2.py [..] ('VM :', 18, '/vmfs/volumes/4c52874b-05f0/vm5/vm5.vmx') ('VM :', 19, '/vmfs/volumes/4c52874b-05f0/cluster_1/cluster_1.vmx') ('VM :', 20, '/vmfs/volumes/4c52874b-05f0/cluster_2/cl_2.vmx') ('VM :', 21, '') ('VM :', 22, '') da man nicht weiß, wie lang die Liste wird, kann man diese nicht explizit mit del 21,22 angehen. Die beiden Newlines kommen schon vom vmware-cmd Kommando: # vmware-vmd -s listvms | od -taz [...] 0002620 a d / c l u s t e r _ 2 / c l u ad/cluster_2/clu 0002640 s t e r _ 2 . v m x nl nl ster_2.vmx.. 0002654 Meine ersten Anfänge sehen so aus (2 Bücher + Google) = #!/usr/bin/python2.5 #imports from optparse import OptionParser from subprocess import Popen, PIPE, STDOUT # Definitionen def list_vm(choice): list = Popen(['vmware-cmd','-s', 'listvms'], stdout=PIPE, stdin=PIPE, stderr=STDOUT).communicate()[0].split('\n') #list.reverse() #del list[:2] if choice == 0: for index in range(len(list)): print(VM :,index, list[index]) else: print(VM:, list[choice]) choice = 0 list_vm(0) == Wie bekomme ich die überflüssigen \nl da nun raus? cu denny -- PUG - Penguin User Group Wiesbaden - http://www.pug.org -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
--On Dienstag, Februar 15, 2011 08:56:50 +0100 Denny Schierz linuxm...@4lin.net wrote: [...] Einträge raus. Doch mich würde interessieren, wie ich die Leerzeilen bereits beim befüllen der Liste vermeiden kann. Da mir das schon wieder wie ein Hack vorkommt: ./test2.py [..] ('VM :', 18, '/vmfs/volumes/4c52874b-05f0/vm5/vm5.vmx') ('VM :', 19, '/vmfs/volumes/4c52874b-05f0/cluster_1/cluster_1.vmx') ('VM :', 20, '/vmfs/volumes/4c52874b-05f0/cluster_2/cl_2.vmx') ('VM :', 21, '') ('VM :', 22, '') da man nicht weiß, wie lang die Liste wird, kann man diese nicht explizit mit del 21,22 angehen. Die beiden Newlines kommen schon vom vmware-cmd Kommando: # vmware-vmd -s listvms | od -taz [...] 0002620 a d / c l u s t e r _ 2 / c l u ad/cluster_2/clu 0002640 s t e r _ 2 . v m x nl nl ster_2.vmx.. 0002654 Meine ersten Anfänge sehen so aus (2 Bücher + Google) = # !/usr/bin/python2.5 # imports from optparse import OptionParser from subprocess import Popen, PIPE, STDOUT # Definitionen def list_vm(choice): list = Popen(['vmware-cmd','-s', 'listvms'], stdout=PIPE, stdin=PIPE, stderr=STDOUT).communicate()[0].split('\n') Du solltest 'list' nicht überschreiben, da es eine eingebaute Funktion list() gibt. #list.reverse() #del list[:2] if choice == 0: for index in range(len(list)): In python iteriert man eher so über listen: for entry in mylist: print mylist.index(entry), entry wobei list.index() immer den ersten Eintrag in einer Liste findet, es also nicht funktioneiert, wenn die Liste Duplikate enthält. Dann würde ich eher for (index, line) in enumerate(mylist): ... nehmen. print(VM :,index, list[index]) else: print(VM:, list[choice]) choice = 0 list_vm(0) == Wie bekomme ich die überflüssigen \nl da nun raus? Du kannst den Leerzeichen, Tabs und \n and den Enden des Strings entfernen: output = ... output.strip() oder besser mit einer list comprehension [1] alle leeren Eintrage entfernen und Leerzeichen an den Enden entfernen: filtered = [line.strip() for line in mylist if line.strip()] Wenn Du sicher bist, dass die einzelnen Zeilen wie in Deinem Beispiel kein Leerzeichen enthalten geht auch filtered = [line for line in mylist if line] ..Carsten ps: in python ist es üblich, mit 4 Leerzeichen einzurücken. [1] http://docs.python.org/tutorial/datastructures.html#list-comprehensions -- PUG - Penguin User Group Wiesbaden - http://www.pug.org
Re: [PUG] python statt bash
hi, Am Dienstag, den 15.02.2011, 10:19 +0100 schrieb Carsten Senger: output = ... output.strip() oder besser mit einer list comprehension [1] alle leeren Eintrage entfernen und Leerzeichen an den Enden entfernen: filtered = [line.strip() for line in mylist if line.strip()] das klingt doch schonmal gut. Das werde ich testen :-) Wenn Du sicher bist, dass die einzelnen Zeilen wie in Deinem Beispiel kein Leerzeichen enthalten geht auch filtered = [line for line in mylist if line] ..Carsten ps: in python ist es üblich, mit 4 Leerzeichen einzurücken. sind 4 Zeichen, nur für Mail anders aufbereitet ;-) cu denny signature.asc Description: This is a digitally signed message part -- PUG - Penguin User Group Wiesbaden - http://www.pug.org