2010-11-02 6 views
0

J'ai écrit plusieurs petits scripts Python pour démarrer des clusters dans des infrastructures de cloud avec des systèmes de fichiers distribués. Maintenant, j'ai intégré le code dans une seule application de ligne de commande, mais la qualité du code est très mauvaise.Comment puis-je améliorer la qualité de ce code de service distant python?

http://code.google.com/p/diffuser/source/browse/trunk/diffuser.py

L'application doit envoyer beaucoup de commandes via SSH avec paramiko. Chaque commande qui est envoyée via SSH nécessite trois lignes de code:

stdin, stdout, stderr = client.exec_command("<command>") 
print stdout.readlines() 
print stderr.readlines() 

Comment puis-je améliorer la qualité du code?

+1

Pour commencer, vous pourriez apprendre à définir vos propres fonctions. Cela vous dirigera dans la direction générale nécessaire pour éliminer beaucoup de duplication. Voir http://docs.python.org/tutorial/controlflow.html#defining-functions. – FMc

Répondre

2

Les commandes sont exécutées dans un shell, vous pouvez donc utiliser une syntaxe shell régulière pour les combiner. Dans un premier temps, je lance un lot de commandes en une seule exec_command:

stdin, stdout, stderr = client.exec_command(
      "sudo hostname;" 
      "sudo apt-get update;" 
      "sudo apt-get -y install nfs-common nfs-kernel-server;" 
      "echo y | sudo mkfs.ext3 /dev/sdc;" 
      "sudo mkdir /mnt/export;" 
      "sudo mount /dev/sdc /mnt/export/;" 
      "sudo chmod o+wx /etc/exports;") 
    print stdout.readlines() 
    print stderr.readlines() 

En outre, je considère qu'il est inutile de commencer une nouvelle pour chacun d'sudo eux. Donc, je préfère écrire

stdin, stdout, stderr = client.exec_command(
      "sudo /bin/sh -c '" 
      "hostname;" 
      "apt-get update;" 
      "apt-get -y install nfs-common nfs-kernel-server;" 
      "echo y | mkfs.ext3 /dev/sdc;" 
      "mkdir /mnt/export;" 
      "mount /dev/sdc /mnt/export/;" 
      "chmod o+wx /etc/exports;" 
      "'") 
    print stdout.readlines() 
    print stderr.readlines() 
+0

Cela semble beaucoup mieux. Mais comment puis-je insérer des pièces comme ça? '' sudo echo '"+ réservation.instances [0] .public_dns_name +":/mnt/export/mnt/export nfs auto, rw, bg 0 0' >>/etc/fstab "' Le problème ici sont les citations '' 'nous utilisons déjà à' 'sudo/bin/sh -c '" ' – Neverland

+0

Utilisez la substitution% s (ou .format()). exec_command ("...% s ...", reservation.instances [0] .public_dns_name) –

+0

J'ai mal compris. Pour l'écho, je pense que l'utilisation de guillemets doubles (encore une fois) devrait faire l'affaire. –

1

La première chose que je voudrais faire est d'améliorer la lisibilité de ce qui se passe en ajoutant certaines fonctions, telle qu'elle est maintenant, il est un grand script avec trop de niveaux d'indentation et la redirection, ce qui le rend difficile à lire. Pour commencer, maintenant que vous avez une application de ligne de commande, vous devez d'abord vous assurer que c'est ainsi que cela fonctionne. Vous devriez également faire en sorte que la sélection du système de fichiers et tout ce qui doit être choisi à l'exécution soit un commutateur de ligne de commande. Si l'utilisateur entre quelque chose de mal, imprimez l'utilisation et quittez. Peut-être quelque chose comme ceci:

if __name__ == '__main__': 
    filesystem, other_thing = parse_args(sys.argv) 
    config = read_config() 
    if filesystem in valid_filesystems and valid_thing(other_thing): 
     start_client(config, filesystem) 
     start_server(whatever) 
    else: 
     print_usage() 
     sys.exit(0) 

puis ajoutez votre flux de contrôle de haut niveau pour start_client/démarrer le serveur. Vous pouvez également créer une classe GenericClient et une classe GenericServer, dont vous héritez et modifiez en fonction du système de fichiers sélectionné.

En général, je lisais un peu sur l'orientation de l'objet en python. J'ai trouvé un guide here mais il peut y avoir quelques meilleurs que d'autres peuvent suggérer.

Questions connexes