Re: [PUG] python statt bash

2011-02-21 Diskussionsfäden Denny Schierz
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

2011-02-17 Diskussionsfäden Denny Schierz
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

2011-02-17 Diskussionsfäden Markus Wolf
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

2011-02-17 Diskussionsfäden Carsten Senger

--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

2011-02-15 Diskussionsfäden Rıdvan Ağar
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

2011-02-15 Diskussionsfäden Rıdvan Ağar
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

2011-02-15 Diskussionsfäden Carsten Senger



--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

2011-02-15 Diskussionsfäden Denny Schierz
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