new structur for file and class layout features_editor
authorJens Kasten <jens@kasten-edv.de>
Tue, 22 Nov 2011 03:59:30 +0100
branchfeatures_editor
changeset 53 9eb8be6341f3
parent 52 cd1da09ac278
child 54 17b08e781dc6
new structur for file and class layout
COPYING
INSTALL
bin/kvm-admin
kvmtools/__init__.py
kvmtools/config/__init__.py
kvmtools/config/configparser.py
kvmtools/config/configtest.py
kvmtools/config/create_dialog.py
kvmtools/config/domain.py
kvmtools/config/modify_domain.py
kvmtools/config/set_config.py
kvmtools/configparser.py
kvmtools/configtest.py
kvmtools/header.py
kvmtools/kvm.py
kvmtools/kvm/__init__.py
kvmtools/kvm/action.py
kvmtools/kvm/build_command.py
kvmtools/kvm/build_config.py
kvmtools/kvm/monitor.py
kvmtools/kvm/validate_config.py
kvmtools/kvm_monitor.py
kvmtools/qemu_kvm_options.py
kvmtools/system_utils.py
--- a/COPYING	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
--- a/INSTALL	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-To install it execute as root user:
-python setup.py install
--- a/bin/kvm-admin	Tue Nov 22 03:58:43 2011 +0100
+++ b/bin/kvm-admin	Tue Nov 22 03:59:30 2011 +0100
@@ -6,6 +6,7 @@
 #
 # Depencies:
 #           python-argparse
+#           python-psutil == 0.1.3 (debian squeeze)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,372 +29,84 @@
 
 import os
 import sys
-import re
 import argparse
+import gettext
 
-from kvmtools.configparser import Parser
-from kvmtools.kvm import Kvm
+from kvmtools.kvm.action import KvmAction
+
+locale_app = sys.argv[0]
+if locale_app.endswith('.py'):
+    locale_app = locale_app[:len(locale_app)-3]
+else:
+    t = gettext.translation(locale_app, "/usr/share/locale", fallback=True)
+    _ = t.ugettext
 
 
 class KvmAdmin(object):
     """ Class for commandline usage for a qemu-kvm guest."""
 
     def __init__(self):
-        # absolute path to the configs, scripts and tools
-        self._base_dir = "/etc/kvm"
-        # path to store pidfile and if needed the socketfile
-        self._run_path = '/var/run/kvm'
-        # directory name to store the ifdown and ifup scripts
-        self._script_dir = 'scripts'
-        # directory name to store the guest configuration files
-        self._guest_config_dir = 'domains'
-        # directory name to store the global configuration file
-        self._global_config_dir = 'config'
-        # name for global configuration file
-        self._global_config = 'kvm.cfg'
-        # argument to show the string which should be execute
-        self._show_config_argument = "show"
-        # prefix for methodes which do some action for the guest
-        self._kvm_prefix = "kvm_"
-        # default telnet port 23, can only use once at time in one guest
-        # otherwise each guest have to set it explicit
-        self._telnet_port = 23
-        # store the pidfile 
-        self.pidfile = None
-        # contain the type for socket
-        # and if needed socket file or host and port
-        self.monitor_options = {}
-        # this exclude_options are using internal only
-        self.exclude_options = ['qemu-kvm', 'python-debug']
-        # contain all configuration variables
-        self.config = {}
-        # contain all bridges to export them
-        self.bridge = {}
-        # keep the status for debugging the python script while editing
-        # values can be True or False 
-        # but should set on global or guest configuration file
-        self.debug = False
-    
-    def _get_monitor(self):
-        """Return a dictionry with type and the path to the socket file or
-        the host and port.
-        """
-        if "monitor" in self.config:
-            
-            _monitor = self.config["monitor"]
-            # get the string befor the first comma 
-            # and then split this string by colon
-            _type = _monitor.split(',')[0].split(':')
-            if len(_type) == 3:
-                # this is usally for tcp
-                self.monitor_options['Type'] = _type[0] 
-                self.monitor_options['Host'] = _type[1]
-                self.monitor_options['Port'] = int(_type[2])
-            elif len(_type) == 2:
-                # this is for telnet, when no port is given
-                self.monitor_options['Type'] = _type[0]
-                if _type[0] == 'unix':
-                    self.monitor_options['SocketFile'] = _type[1]
-                self.monitor_options['Host'] = _type[1]
-                self.monitor_options['Port'] = self._telnet_port
-        else:
-            # set unix socket as default monitor access
-            self._set_socketfile()
-            _monitor = "unix:%s,server,nowait" % self.socketfile
-            self.monitor_options["Type"] = "unix"
-            self.monitor_options['SocketFile'] = self.socketfile
-        return _monitor 
-
-    def _set_pidfile(self):
-        """Set the absolute path for the pidfile."""
-        self.pidfile = "".join([self.guest, ".pid"])
-        self.pidfile = os.path.join(self._run_path, self.pidfile)
-    
-    def _set_socketfile(self):
-        """Set the absolute path for the socketfile."""
-        self.socketfile = "".join([self.guest, ".socket"])
-        self.socketfile = os.path.join(self._run_path, self.socketfile)
-
-    def _get_guest_config_dir(self):
-        """Return the absolute path for guest configuration directory."""
-        if os.path.isdir(os.path.join(self._base_dir, self._guest_config_dir)):
-            return os.path.join(self._base_dir, self._guest_config_dir)
-        else:
-            raise Exception("Guest config directory '%s' does not exists." %
-                self._guest_config_dir)
-
-    def _get_global_config_dir(self):
-        """Return the absolute path for global configuration directory."""
-        if os.path.isdir(os.path.join(self._base_dir, self._global_config_dir)):
-            return os.path.join(self._base_dir, self._global_config_dir)
-        else:
-            raise Exception("Global config directory '%s' does not exists." %
-                self._global_config_dir)
-
-    def available_guests(self):
-        """Return all available guests as an dictionary."""
-        guests = []
-        guest_config_dir = self._get_guest_config_dir()
-        for guest in os.listdir(guest_config_dir):
-            if os.path.isfile(os.path.join(guest_config_dir, guest)):
-                guests.append(guest)
-        if len(guests) >= 1:                
-            return guests
-        else:
-            raise Exception("Guest configuration directory is empty '%s'." 
-                % guest_config_dir)
-
-    def available_actions(self):
-        """Return all methods which start with _kvm_ from class Kvm."""
-        # add action to show the sting, there is no method for this
-        actions = [self._show_config_argument]
-        for action in dir(Kvm):
-            if action.startswith(self._kvm_prefix):
-                actions.append(action.replace(self._kvm_prefix, ""))
-        if len(actions) >= 2:
-            return actions
-        else:
-            raise Execption("No action available.")
-
-    def _get_guest_config(self):
-        """Return the absolute path to guest configuration file."""
-        guest_config = os.path.join(self._get_guest_config_dir(), self.guest)
-        return guest_config
-
-    def _get_global_config(self):
-        """Return the absolute path to global configuration file."""
-        global_config_dir = self._get_global_config_dir()
-        global_config = os.path.join(global_config_dir, self._global_config)
-        return global_config
-
-    def _qemu_kvm_script(self, script_option):
-        """Return the absoulute path for ifup or ifdown script."""
-        script_option = "".join(["kvm-", script_option])
-        script = os.path.join(self._base_dir, self._script_dir)
-        script = os.path.join(script, script_option)
-        return script
-
-    def _check_net_tap(self):
-        """Examine the -net tap option for ifname and additional scripts and 
-        bridge strings.
-        """
-        temp = {} 
-        counter = 0
-        for key, value in self.config["net"].iteritems():
-            if value.startswith("tap"):
-                # search for ifname otherwise set it from guest name
-                if re.search("ifname", value):
-                    temp_ifname = re.search(",ifname=([a-zA-Z0-9]+)", value)
-                    ifname = temp_ifname.group(1)
-                else:
-                    ifname = "".join([self.guest, str(counter)])
-                    temp_ifname = "=".join(["ifname", ifname])
-                    if re.match("tap,", value):
-                        value = re.sub("tap,", "tap,%s,", value) % temp_ifname
-                    else:
-                        value = re.sub("tap", "tap,%s", value) % temp_ifname
-                    counter += 1
-                # build the bridge key    
-                bridge_key = "_".join(["bridge", ifname])
-                # search for bridge otherwise raise an exception,
-                # because this value is needed
-                if re.search("bridge", value):
-                    temp_bridge = re.search(",bridge=([a-zA-Z0-9]+)", value)
-                    # get the bridge name from searched group
-                    bridge = temp_bridge.group(1)
-                    # remove the bridge from string
-                    value = value.replace(temp_bridge.group(0), "")
-                else:
-                    msg = "Missing second Value for bridge.\n"
-                    msg = "".join([msg, "Syntax example: bridge=br0"])
-                    raise Exception(msg)
-                # assign bridge for exporting the bridge name
-                self.bridge[bridge_key] = bridge
-                # search for script 
-                if not re.search("script", value):
-                    ifup = "=".join(["script", self._qemu_kvm_script('ifup')])
-                    value = ",".join([value, ifup])
-                # search for downscript
-                if not re.search("downscript", value):
-                    ifdown = "=".join(["downscript", 
-                                        self._qemu_kvm_script('ifdown')])
-                    value = ",".join([value, ifdown])
-                # add the cleaned value to temporary dictionary
-                temp[key] = value
-            else:                    
-                temp[key] = value
-        # add the cleand temp dictionary back to config        
-        self.config["net"] = temp
-
-    def _add_monitor_to_config(self):
-        """Append the monitor option to the config dictionary."""
-        self.config["monitor"] = self._get_monitor() 
-       
-    def _add_pidfile_to_config(self):
-        """Append the pidfile option to the config dictionary or reverse."""
-        if "pidfile" not in self.config:
-            pidfile = os.path.join(self._run_path, self.pidfile)
-            self.config["pidfile"] = pidfile
-        else:
-            self.pidfile = self.config["pidfile"]
-
-    def _add_uuid_to_config(self):
-        """Append an unique uuid to the config dictionary."""
-        import string
-        import random
-        random.seed(os.urandom(8))
-        charset = string.digits + "abcdef"
-        eight = "".join(random.sample(charset, 8))
-        four_first = "".join(random.sample(charset, 4))
-        four_second = "".join(random.sample(charset, 4))
-        four_third = "".join(random.sample(charset, 4))
-        twelve =  "".join(random.sample(charset, 12))
-        uuid = "-".join([eight, four_first, four_second, four_third, twelve])
-        self.config["uuid"] = uuid
-
-    def _add_name_to_config(self):
-        """Append a name for window title and process name (on linux only)."""
-        if "name" in self.config:
-            process_name = "=kvm_".join(["process", self.config["name"]])
-            self.config["name"] = ",".join([self.config["name"], process_name])
-        else:
-            process_name = "=".join(["process", self.guest])
-            self.config["name"] = ",".join([self.guest, process_name])
-
-    def _merge_configs(self, global_config, guest_config):
-        """Merge global and guest configfile.
-        Keep this method, maybe add some more configuration files later.
-        """
-        for key in global_config.keys():
-            if key in guest_config:
-                self.config[key] = guest_config[key]
-            else:
-                self.config[key] = global_config[key]
-    
-    def _load_config(self):
-        """Build user defined config."""
-        self._set_pidfile()
-        parser = Parser()
-        global_config = parser(self._get_global_config())
-        guest_config = parser(self._get_guest_config())
-        self._merge_configs(global_config, guest_config)
-        # add internal defaults and do some check
-        self._add_name_to_config()    
-        self._add_uuid_to_config()
-        self._add_monitor_to_config()
-        self._add_pidfile_to_config()
-        self._check_net_tap()    
-        if ("python-debug" in self.config 
-            and self.config["python-debug"] == "enabled"):
-            self.debug = True
-
-    def _build_command(self):
-        """Return a tuple. First entry is a list to execute via subprocess
-        and the second is a string to display it.
-        """
-        # import the auto generatet qemu-kvm options from kvm --help
-        from kvmtools.qemu_kvm_options import qemu_kvm_options
-        self._load_config()
-        cmd_execute = []
-        cmd_string = ""
-        # Start to build a list, firstly add the qemu-kvm binary
-        cmd_execute.append(self.config["qemu-kvm"])
-        # then remove internal option  
-        for key in self.exclude_options:
-            if key in self.config:
-                del self.config[key]
-        # iterate over the user config
-        for key, value in self.config.iteritems():
-            # check if key is in qemu_kvm_options
-            if key in qemu_kvm_options:
-                # this check search for more option like -drive -drive etc.
-                if isinstance(value, dict):
-                    for i in value.itervalues():
-                        cmd_execute.append(''.join(['-', key]))
-                        cmd_execute.append(i)
-                elif "enabled" != value:
-                    # this qemu-kvm option have an option, so add -key value
-                    cmd_execute.append(''.join(['-', key]))
-                    cmd_execute.append(value)
-                else:
-                    # this qemu-kvm option don't have any option 
-                    # so only add -key as argument
-                    cmd_execute.append(''.join(['-', key]))
-            else: 
-                msg = ("This option '%s' is not valid for qemu-kvm command." 
-                        % key)
-                raise Exception(msg)
-        # build a string for to display on terminal output
-        cmd_string = " ".join([value for value in cmd_execute])
-        return (cmd_execute, cmd_string)
+        self.kvm_action = KvmAction()
+        self.available_actions = self.kvm_action.available_actions()
 
     def run(self):
-        """Do an action for a guest domain.
-        Call a method based on commandline option two.
+        """Do an action for a domain.
+        Call a method based on commandline option.
         """
-        cmd = self._build_command()
-        kvm_method = "".join([self._kvm_prefix, self.action])
-        kvm = Kvm(self.guest, self.config['uuid'], self.pidfile, 
-            self.monitor_options)
-        if self._show_config_argument == self.action:
-            print "This string would executed:\n%s" % cmd[1]
-        elif "boot" == self.action:
-            getattr(kvm, kvm_method)(cmd[0], self.bridge)
-        elif "monitor" in self.action or "migrate" in self.action:
+        self.kvm_action.kvm_domain_name = self.domain
+        self.kvm_action.load_command()
+        kvm_method = "".join(["kvm_", self.action, "_action"])
+        if "monitor" in self.action or "migrate" in self.action:
             if len(sys.argv) >= 4:
                 # build string from third option till end
                 cmd_monitor = " ".join(str(i) for i in self.monitor)
-                getattr(kvm, kvm_method)(cmd_monitor)
+                getattr(self.kvm_action, kvm_method)(cmd_monitor)
             else:
                 raise Exception("Missing monitor argument. Type 'help'.")
         else:
-            getattr(kvm, kvm_method)()
+            getattr(self.kvm_action, kvm_method)()
 
 def main():
-    kvm = KvmAdmin()
-    guests = kvm.available_guests()
-    actions = kvm.available_actions()
+    kvm_admin = KvmAdmin()
+    actions = kvm_admin.available_actions
         
     # manage the arguments
     parser = argparse.ArgumentParser(
         epilog="Available action: %s" % ", ".join(actions))
 
-    group1 = parser.add_argument_group("KVM guest name")
-    group1.add_argument("guest", choices=guests,  
-        metavar=("kvm_guest_name"),
-        help="Choose a KVM guest name, "
-             "its the same like the configuration file")
-
-    group2 = parser.add_argument_group("Action for a guest")
-    group2.add_argument("action", choices=actions,  
-        metavar=("action"),
-        help="Choose an action for the KVM guest")
-
-    group3 = parser.add_argument_group("Monitor command.")
+    group1 = parser.add_argument_group(_("QEMU-KVM domain"))
+    group1.add_argument("domain", default=False,
+        metavar=(_("domain_name")),
+        help=_("Choose a KVM domain name, "
+             "its the same like the configuration file name"))
+    group2 = parser.add_argument_group("Action for a domain")
+    group2.add_argument("action", choices=actions, default=False, 
+        help=_("Choose an action for the KVM guest"))
+    group3 = parser.add_argument_group("Monitor command")
     group3.add_argument("monitor", nargs="*", default=False,
         metavar="option",
-        help="One ore more arguments can pass to the monitor.")
-   
-    group4 = parser.add_argument_group("Qemu options")
-    group4.add_argument("--generate-options", default=False, 
-        action="store_true", 
-        help="Generate new qemu-kvm options. From time to time its "
-             "should execute, because they can change.")
+        help=_("One ore more arguments can pass to the monitor."))
+    group4 = parser.add_argument_group("Domain")
+    group4.add_argument("create", default=False, action="store_true",
+        help=_("Create a domain config file."))
+    group4.add_argument("modify", default=False, action="store_true",
+        help=_("Modify a domain config file."))
+    args = parser.parse_args(namespace=kvm_admin)
 
-      
-    args = parser.parse_args(namespace=kvm)
+    if not kvm_admin.create:
+        if not kvm_adin.domain in domains:
+            parser.error(_("Available domains: %s") % domains)
     # run the action
-    try:
-        if kvm.generate_options:
-            os.system("generate-kvm-options doit")                
-        else:
-            kvm.run()
-    except Exception, error_msg:
-        print error_msg
+    #try:
+    kvm_admin.run()
+#    except Exception, error_msg:
+ #       print error_msg
+  #      sys.exit(1)
 
 
 if __name__ == "__main__":
     try:
         main()
     except KeyboardInterrupt:
-        print "\rUser break."
+        print _("\rUser break.")
+        sys.exit(0)
--- a/kvmtools/__init__.py	Tue Nov 22 03:58:43 2011 +0100
+++ b/kvmtools/__init__.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,14 @@
+try:
+    from kvmtools.qemu_kvm_options import qemu_kvm_options
+except ImportError:
+    import os
+    os.system("generate-kvm-options --generate")
+    try:
+        from kvmtools.qemu_kvm_options import qemu_kvm_options
+    except ImportError, error_msg:
+        import sys
+        print error_msg
+        sys.extit(1)
+        
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/config/configparser.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+#
+# Parser to get content from a configfile.
+#
+# config file syntax:
+#       key = value
+#       #key = value    <- commented 
+#       key = value  # comment
+#
+
+"""
+(c) 2007-2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+import sys
+import re
+
+
+class Parser(object):
+    """Simple config parser for kvm guest config file."""
+
+    def __init__(self):
+        # list thats contain all lines from configurations file
+        self.config_lines = []
+        # dictionary thats contain the configuration parameters 
+        self.config = {}
+
+    def read_config(self, config_name):
+        """
+        Read the file content from a guest configuration.
+        Full list self.config_lines with all lines.
+        @param string config_name
+        """
+        if not os.path.isfile(config_name):
+            print "Configuration file '%s' does not exists." % config_name
+            sys.exit()
+        else:
+            try:
+                # set a line counter
+                counter = 1 
+                _fd = open(config_name)
+                lines = _fd.readlines()
+                # remove withespace but not and arguments 
+                # and add them to a list
+                for line in lines:
+                    if len(line) > 1 and not line.startswith('#'):
+                        # split only the first equal sign
+                        temp = line.strip().split("=", 1)
+                        # check for sign '=' 
+                        if len(temp) == 1:
+                            msg = "Missing sign '=' in %s on line %s" % \
+                                (config_name, counter)
+                            raise Exception(msg)
+                        # remove all withespace from string
+                        temp_first = re.sub(r'\s', '', temp[0])
+                        # remove only the withspace on the beginning and the end
+                        temp_second = temp[1].lstrip(' ')
+                        temp_second = temp_second.split("#")[0].rstrip(" ")
+                        # put the cleaned string together again
+                        temp_result = "=".join([temp_first, temp_second])
+                        self.config_lines.append(temp_result)
+                        counter += 1
+                _fd.close()
+            except OSError, error_msg:
+                print str(error_msg)
+                sys.exit(1)
+
+    def __call__(self, config_name):
+        """Return a dictionary"""
+        self.read_config(config_name)
+        # counter for printing exact position if a error occur
+        try:
+            drive = {}
+            drive_counter = 0
+            net = {}
+            net_counter = 0
+            chardev = {}
+            chardev_counter = 0
+            for line in self.config_lines:
+                if len(line) > 0:
+                    line = line.split("=", 1)
+                    # check for drive, net and char keys and 
+                    # add them im a separate dict to avoid overriding
+                    if line[0] == "drive":
+                        drive[drive_counter] = line[1]
+                        self.config['drive'] = drive
+                        drive_counter += 1
+                    elif line[0] == "net":
+                        net[net_counter] = line[1]
+                        self.config['net'] = net
+                        net_counter += 1
+                    elif line[0] == "chardev":
+                        chardev[chardev_counter] = line[1]
+                        self.config['chardev'] = chardev
+                        chardev_counter += 1
+                    else:
+                        self.config[line[0]] = line[1]
+                    if len(line[1]) == 0:
+                        raise IndexError
+            return self.config
+        except IndexError:
+            msg = "Missing value for key '%s' in %s" % (line[0], config_name)
+            print msg               
+            print "Use syntax: key = value"
+            sys.exit()                
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/config/configtest.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Test for kvm guest config file
+#
+
+"""
+(c) 2007-2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+import argparse
+
+from kvmtools.configparser import Parser
+
+
+class TestConfig(object):
+    """kvm guest test config parser"""
+    
+    def show_result(self, config_file):
+        """Print the parsed config file."""
+        if not os.path.isfile(config_file):
+            print "Configfile does not exists: ", config_file
+            return
+        parser = Parser()
+        result = parser(config_file)
+        for key, value in result.iteritems():
+            print "%s=%s" % (key, value)
+
+
+def main():
+    """commandline usage"""
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-c", "--config", metavar="kvm guest config file",
+        help="Absolute path for kvm guest config file.")
+    args = parser.parse_args()
+
+    if not args.config:
+        parser.print_usage()
+        return
+    config = TestConfig()
+    config.show_result(args.config)
+
+
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/config/create_dialog.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,177 @@
+#
+# Module to create an initial kvm-admin domain configuration file
+#
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+from kvmtools.system_utils import System
+
+
+class CreateDialogConsole(object):
+    """Console dialog to create inital config file."""
+    
+    def __init__(self):
+        self.system = System()
+
+    def create_dialog(self, open_type="r"):
+        """Methode to create a dialog for creating a domain config"""
+        with open(self.kvm_domain_file, open_type) as _fd:
+            name = raw_input("Name [%s]: " % self.kvm_domain_name)
+            if len(name) == 0:
+                _fd.write("name = %s\n" % self.kvm_domain_name)
+            else:
+                _fd.write("name = %s\n" % name)
+            # set memory 
+            print ("Total memory of the machine: %d" % \
+            self.system.total_memory())
+            while True:
+                memory = raw_input("Memory in MB [%d]: " % 128)
+                if len(memory) == 0:
+                    _fd.write("m = 128\t\t\t# system memory in megabyte\n")
+                    break
+                if memory == "q":
+                    break
+                try:
+                    memory = int(memory)
+                    if memory > self.system.total_memory():
+                        print ("Machine has not enough total memory %d." % \
+                            self.system.avail_memory())
+                        accept = raw_input("Should this value used? [Y/n]:").lower()
+                        if len(accept) == 0 or accept == "y":
+                            _fd.write("m = %d\t\t\t# system memory in megabyte\n" % \
+                                memory)
+                            break
+                   
+                    elif memory > self.system.avail_memory():
+                        print ("Machine has not enough available memory %d." % \
+                            self.system.avail_memory())
+                        accept = raw_input("Should this value used? [Y/n]:").lower()
+                        if len(accept) == 0 or accept == "y":
+                            _fd.write("m = %d\t# system memory in megabyte\n" % \
+                                memory)
+                            break
+                    else:
+                        _fd.write("m = %d\t# system memory in megabyte\n" % \
+                            memory)
+                        break
+                except ValueError:
+                    print ("Memory must give as a positive digit or type q to contiue.")
+            # set cdrom
+            is_cdrom = False
+            cdrom = raw_input("Would you like use a cdrom [Y/n]: ").lower()
+            if len(cdrom) == 0 or cdrom == "y":
+                if self.system.get_cdrom():
+                    cdrom_path = raw_input("Path to cdrom device [%s] press just enter or path to image: " \
+                        % self.system.get_cdrom())
+                else:
+                    print ("Could not found cdrom device.")
+                    while True:
+                        cdrom_path = raw_input("Path to iso image: ")
+                        if len(cdrom_path) == 0:
+                            print "Type q to continue."
+                        elif cdrom_path == "q" or len(cdrom_path) > 0:
+                            break
+                while True:
+                    if cdrom_path == "q":
+                        break
+                    if len(cdrom_path) == 0:
+                        is_cdrom = True
+                        cdrom_device = self.system.get_cdrom()
+                        if self.system.get_cdrom():
+                            _fd.write("cdrom = %s\t# path to cdrom or iso image\n" % \
+                                self.system.get_cdrom())
+                            break
+                        else:
+                            break
+                    else:
+                        is_cdrom = True
+                        _fd.write("cdrom = %s\t# path to cdrom or iso image\n" % cdrom_path)
+                        break
+                if is_cdrom:
+                    boot = raw_input("Would you like to boot the qemu-kvm guest from cdrom? [Y/n]")
+                    while True:
+                        if boot.lower() == "y" or len(boot) == 0:
+                            _fd.write("boot = cd\t# boot order harddrive and if not bootable then cdrom.\n")
+                            break
+                        else:
+                            _fd.write("boot = c\t# boot order harddrive and if not bootable then cdrom.\n")
+                            break
+            # set drive
+            drives = {}
+            while True:
+                print ("Available qemu-kvm device driver [ide,scsi,virtio].")
+                print ("Type q to continue without harddrive.")
+                driver = raw_input("default qemu-kvm device driver [virtio]: ")
+                if driver == "q":
+                    break
+                if driver in ["ide", "scsi", "virtio"]:
+                    break
+                elif len(driver) == 0:
+                    driver = "virtio"
+                    break
+            while True:
+                if driver == "q":
+                    break
+                drive_amount = raw_input("How many harddrives you are like to use [1]: ")
+                try:
+                    if drive_amount == "q":
+                        break
+                    elif len(drive_amount) == 0:
+                        drive_amount = 1
+                        break
+                    else:
+                        drive_amount = int(drive_amount)
+                        if drive_amount > 4:
+                            print "Its initial configuration. Max 4 devices cat set."
+                        else:
+                            break
+                except ValueError:
+                    print ("Amount of drive must a positive digit greater the null.")
+                    print ("Type q to continue without harddrive.")
+            while True:
+                if driver == "q":
+                    break
+                for i in range(1, drive_amount + 1):
+                    while True:
+                        drive = raw_input("Path to hardrive %d: " % i)
+                        if len(drive) > 0:
+                            drives[i] = {
+                                "file": drive, 
+                                "if": driver, 
+                                "index": i-1,
+                                "boot": "off",
+                                "cache": "none",
+                                "media": "disk",
+                            }
+                            break
+                break
+            if len(drives) > 1:
+                print ("From which device should boot: ")
+            while True:
+                if driver == "q":
+                    break
+                if len(drives) == 1:
+                    drives[1]["boot"] = "on"
+                    break
+                else:
+                    for key in drives.iterkeys():
+                        print "[%d] %s" % (key, drives[key]["file"])
+                    boot = raw_input("Index: ")
+                    if boot == "q":
+                        break
+                try:
+                    boot = int(boot)
+                    drives[boot]["boot"] = "on"
+                    break
+                except ValueError:
+                    print "Index have to a digit from list above."
+                    print "Type q to continue without set boot on for a harddrive."
+                except KeyError:
+                    print "Index not in list."
+            for key, value in drives.iteritems():
+                to_write = "drive = file=%s,index=%d,media=%s,cache=%s,boot=%s" % \
+                    (value["file"], value["index"], value["media"], 
+                     value["cache"], value["boot"])
+                _fd.write(to_write + "\n")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/config/domain.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,46 @@
+# 
+# Module which handle the domain config
+#
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+
+from kvmtools.header import Header
+from kvmtools.config.create_dialog import CreateDialogConsole
+from kvmtools.config.set_config import SetConfig
+
+
+class Domain(Header, CreateDialogConsole, SetConfig):
+    """Class domain handle the domain(guest) configuration."""
+
+    def __init__(self):
+        Header.__init__(self)
+        SetConfig.__init__(self)
+        CreateDialogConsole.__init__(self)
+
+    def create(self):
+        """Create a minimalistic guest config file."""
+        print ("Creating the domain config file: %s" % self.kvm_domain_file)
+        self.create_dialog("w")
+        self.modify()
+
+    def modify(self):
+        """Edit a guest config file."""
+        if os.path.isfile(self.kvm_domain_file):
+            if os.access(self.kvm_domain_file, os.W_OK):
+                os.execl("/usr/bin/editor", "", self.kvm_domain_file)
+            else:
+                print ("Permission denied to write to %s" % \
+                    self.kvm_domain_file)
+        else:
+            self.create()
+
+    def read(self):
+        with open(self.kvm_domain_file) as _fd:
+            lines = _fd.readlines()
+            for line in lines:
+                print lines
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/config/modify_domain.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,64 @@
+#
+# Module to edit or create a guest configfile for kvm-admin
+#
+
+"""
+(c) Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+
+from kvmtools.config.config import Domain
+from kvmtools.system_utils import System
+from kvmtools.config.create_dialog import CreateDialogConsole
+
+
+class ModifyDomain(CreateDialogConsole):
+    """Class for manipulating a guest config."""
+
+    def __init__(self):
+        # instance the parent class for create dialog
+        CreateDialogConsole.__init__(self)
+        # make system information available
+        self.system = System()
+
+    def create(self):
+        """Create a minimalistic guest config file."""
+        print ("Creating the domain config file: %s" % self.domain_conf_file)
+        self._create_dialog_config("w")
+        self.modify()
+
+    def modify(self):
+        """Edit a guest config file."""
+        if os.path.isfile(self.domain_conf_file):
+            if os.access(self.domain_conf_file, os.W_OK):
+                os.execl("/usr/bin/editor", "", self.domain_conf_file)
+            else:
+                print ("Permission denied to write to %s" % \
+                    self.domain_conf_file)
+        else:
+            self.create()
+
+    def read(self):
+        with open(self.domain_conf_file) as _fd:
+            lines = _fd.readlines()
+            for line in lines:
+                print lines
+                        
+   
+
+def main():
+    domain = Domain()
+    domain_name = "testme"
+    domain.domain_conf_name = domain_name
+    m = ModifyDomain()
+    m.domain_conf_name = domain.domain_conf_name
+    m.domain_conf_file = domain.domain_conf_file
+    m.uuid = "1-1-1-1"
+    m.create()
+    #m.modify()
+    m.read()
+
+if __name__ == "__main__":
+    main()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/config/set_config.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,109 @@
+#
+# Module to set the basics paths and files
+#
+#       The values come from header.py
+#       This value surrounded by {}
+#       self.kvm_base_config_dir = {/etc/kvm}
+#       self.kvm_conf_dir = self.kvm_base_config_dir/{conf}
+#       self.kvm_domain_dir = self.kvm_base_config_dir/{domains}
+#       self.kvm_domain_name = sys.argv[1]
+#       self.kvm_domain_file = self.kvm_domain_dir/self.kvm_domain_name
+#       self.kvm_script_dir = self.kvm_base_config_dir/{scripts}
+#       self.kvm_conf_file = self.kvm_conf_dir/{kvm.cfg}
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+
+
+class SetConfig(object):
+
+    def __init__(self):
+        # initialize attribute
+        self.kvm_domain_dir = None
+        self.kvm_domain_name_all = []
+        self.kvm_domain_name = None
+        self.kvm_domain_file = None
+        self.kvm_script_dir = None
+        self.kvm_pidfile = None
+        self.kvm_socketfile = None
+        self.kvm_conf_file = None
+        self._value = None
+        self.config()
+
+    def config(self):
+        """Methode to call from other modules. 
+        Set all nesessary attribute."""
+        self._set_kvm_script_dir()
+        self._set_kvm_conf_dir()
+        self._set_kvm_conf_file()
+        self._set_kvm_domain_dir()
+        self._set_kvm_domain_name_all()
+
+    def _set_kvm_pid_file(self):
+        """Set the absolute path for the pidfile."""
+        kvm_pidfile = "".join([self.kvm_domain_name, ".pid"])
+        self.kvm_pidfile = os.path.join(self.kvm_run_path, kvm_pidfile)
+        assert type(self.kvm_pidfile) is str, "pidfile is None"
+    
+    def _set_kvm_socket_file(self):
+        """Set the absolute path for the socketfile."""
+        kvm_socketfile = "".join([self.kvm_domain_name, ".socket"])
+        self.kvm_socketfile = os.path.join(self.kvm_run_path, kvm_socketfile)
+        assert type(self.kvm_socketfile) is str, "socketfile is None"
+
+    def _set_kvm_script_dir(self):
+        """Set the absolute path for global configuration directory."""
+        kvm_script_dir = os.path.join(self.kvm_base_config_dir,
+            self._kvm_script_dir)
+        if os.path.isdir(kvm_script_dir):
+            self.kvm_script_dir = kvm_script_dir
+        assert type(self.kvm_script_dir) is str, "kvm_script_dir is None"
+
+    def _set_kvm_conf_dir(self):
+        """Set the absolute path for global configuration directory."""
+        kvm_conf_dir = os.path.join(self.kvm_base_config_dir,
+            self._kvm_conf_dir)
+        if os.path.isdir(kvm_conf_dir):
+            self.kvm_conf_dir = kvm_conf_dir
+        assert type(self.kvm_conf_dir) is str, "kvm_conf_dir is None"
+
+    def _set_kvm_conf_file(self):
+        """Set the global config file."""
+        kvm_conf_file = os.path.join(self.kvm_conf_dir, self._kvm_conf_name)
+        if os.path.isfile(kvm_conf_file):
+            self.kvm_conf_file = kvm_conf_file
+        assert type(self.kvm_conf_file) is str, "kvm_conf_file is None"
+
+    def _set_kvm_domain_dir(self):
+        """Set the absolute path for domain configuration directory."""
+        kvm_domain_dir = os.path.join(self.kvm_base_config_dir,
+            self._kvm_domain_dir)
+        if os.path.isdir(kvm_domain_dir):
+            self.kvm_domain_dir = kvm_domain_dir
+        assert type(self.kvm_domain_dir) is str, "kvm_domain_dir is None"
+
+    def _set_kvm_domain_name_all(self):
+        """Set all available guests as an dictionary."""
+        for domain_name in os.listdir(self.kvm_domain_dir):
+            if os.path.isfile(os.path.join(self.kvm_domain_dir, domain_name)):
+                self.kvm_domain_name_all.append(domain_name)
+
+    # property to set, get, and delte the domain_conf_file
+    def _set(self, value):
+        """Set property."""
+        if value:
+            self._value = value
+            self.kvm_domain_file = os.path.join(self.kvm_domain_dir, value)
+            assert type(self.kvm_domain_file) is str, \
+                "kvm_domain_file is None"
+            self._set_kvm_pid_file()
+            self._set_kvm_socket_file()
+
+    def _get(self):
+        """Get property."""
+        return self._value
+
+    kvm_domain_name = property(_get, _set)
--- a/kvmtools/configparser.py	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-
-""" 
-Parser to get content from a configfile.
-(c) 2007-2010 Jens Kasten <jens@kasten-edv.de>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-"""
-
-import os
-import sys
-import re
-
-
-class Parser:
-
-    def __init__(self):
-        # list thats contain all lines from configurations file
-        self.config_lines = []
-        # dictionary thats contain the configuration parameters 
-        self.config = {}
-
-    def read_config(self, config_name):
-        """
-        Read the file content from a guest configuration.
-        Full list self.config_lines with all lines.
-        @param string config_name
-        """
-        if not os.path.isfile(config_name):
-            print "Configuration file '%s' does not exists." % config_name
-            sys.exit()
-        else:
-            try:
-                fd = open(config_name)
-                lines = fd.readlines()
-                # remove withespace but not and arguments 
-                # and add them to a list
-                for line in lines:
-                    if len(line) > 1 and not line.startswith('#'):
-                        # split only the first equal sign
-                        temp = line.strip().split("=", 1)
-                        # remove all withespace from string
-                        temp_first = re.sub(r'\s', '', temp[0])
-                        # remove only the withspace on the beginning and the end
-                        temp_second = temp[1].lstrip(' ')#.rstrip(' ')
-                        # put the cleaned string together again
-                        # FIX: configparser have to revisit 
-                        temp_result = "=".join([temp_first, temp_second])
-                        self.config_lines.append(temp_result)
-                fd.close()
-            except OSError, e:
-                print str(e)
-                sys.exit()
-
-
-    def __call__(self, config_name):
-        """  
-        Return a dictionary
-        """
-        self.read_config(config_name)
-        # counter for printing exact position if a error occur
-        try:
-            counter = 1
-            drive = {}
-            drive_counter = 0
-            net = {}
-            net_counter = 0
-            chardev = {}
-            chardev_counter = 0
-            for line in self.config_lines:
-                # remove empty lines and coments at line begin
-                if len(line) > 0 and not re.search("^#", line):
-                    line = line.split("=", 1)
-                    # remove coments after values
-                    value = line[1].split('#', 1)
-                    # check for drive, net and char keys and add them im a separate dict 
-                    # to avoid overriding
-                    if line[0] == "drive":
-                        drive[drive_counter] = value[0]
-                        self.config['drive'] = drive
-                        drive_counter += 1
-                    elif line[0] == "net":
-                        net[net_counter] = value[0]
-                        self.config['net'] = net
-                        net_counter += 1
-                    elif line[0] == "chardev":
-                        chardev[chardev_counter] = value[0]
-                        self.config['chardev'] = chardev
-                        chardev_counter += 1
-                    else:
-                        self.config[line[0]] = value[0]
-                    if len(value[0]) == 0:
-                        raise IndexError
-                counter += 1                        
-            return self.config
-        except IndexError, e:
-            msg = "Missing value for key '%s' on line %d in '%s'" % \
-                (line[0], counter, config_name)
-            print msg               
-            print "Use syntax: key = value"
-            sys.exit()                
-                    
-# vim: tabstop=4 expandtab shiftwidth=4
--- a/kvmtools/configtest.py	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-Testcase for configparser.
-(c) 2007-20010 Jens Kasten <igraltist@rsbac.org>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-"""
-
-import os
-import sys
-import getopt
-
-from configparser import Parser
-
-
-class TestParser(object):
-
-    def help(self):
-        print """ 
--c | --config  # its need the absolut path to the config wich should testet.
--h | --help    # print this help
-        """
-        sys.exit()
-
-    def usage(self):
-        print "usage: %s -c 'configfile' or [--help|-h]" % sys.argv[0]
-        sys.exit()
-
-    def arguments(self):
-        """
-        It take a configfile and print the output 'key = value' from configparser.
-        """
-        try:
-            opts, args = getopt.getopt(sys.argv[1:], "hc:", ["help", "config"])
-        except getopt.GetoptError:
-            self.usage()
-
-        if len(opts) == 1:
-            if opts[0][0] in ("-c", "--config"):
-                config_to_parse = opts[0][1]
-                if not os.path.isfile(config_to_parse):
-                    print "Error, '%s' not exists" % config_to_parse
-                    sys.exit()
-                else:
-                    return config_to_parse
-            else:
-                if opts[0][0] in ("-h, --help"):
-                    self.help()
-                else:
-                    self.usage()
-        else:
-            self.usage()
-
-
-def main():
-    tester = TestParser()
-    config = tester.arguments()
-    parser = Parser()
-    result = parser(config)
-    for key,value in result.iteritems():
-        print "%s=%s" % (key, value)
-
-if __name__ == "__main__":
-    main()
-
-# vim: tabstop=4 expandtab shiftwidth=4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/header.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,35 @@
+#
+# header file 
+#
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+
+
+class Header(object):
+    """Contain all attribute to store filename or paths."""
+    
+    def __init__(self):
+        # base direcotry configs, and scripts 
+        self.kvm_base_config_dir = "/etc/kvm"
+        # subdirecotories from self.base_dir
+        # directory name to store the ifdown and ifup scripts
+        self._kvm_script_dir = 'scripts'
+        # directory name to store the guest configuration files
+        self._kvm_domain_dir = 'domains'
+        # directory name to store the global configuration file
+        self._kvm_conf_dir = 'config'
+        # name for global configuration file
+        self._kvm_conf_name = 'kvm.cfg'
+        # default telnet port 23, can only use once at time in one guest
+        # otherwise each guest have to set expliciet a different port
+        self.telnet_port = 23
+        # default directory for pidfile,and socketfile
+        self.kvm_run_path = '/var/run/kvm'
+        # this exclude_options are using internal only
+        self.exclude_options = ['qemu-kvm', 'python-debug']
+
+
--- a/kvmtools/kvm.py	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-#!/usr/bin/env python
-#
-# Module provide the action methodes for a guest.
-#
-
-"""
-(c) 2007-2011 Jens Kasten <jens@kasten-edv.de> 
-"""
-
-import os
-import sys
-from subprocess import Popen, PIPE
-from time import sleep
-
-from kvm_monitor import KvmMonitor
-
-
-class Kvm(KvmMonitor):
-    """
-    Class Kvm provide methodes for start, stop and all stuff around this.
-    """
-
-    def __init__(self, guest, uuid, pidfile, monitor):
-        self._environ_path = "/bin:/usr/bin/:/sbin:/usr/sbin"
-        self._pid = None
-        self._guest_status = None
-        self.guest = guest
-        self.uuid = uuid
-        self.pidfile = pidfile
-        self.socketfile = None
-        if "SocketFile" in monitor:
-            self.socketfile = monitor['SocketFile']
-        # call the parent constructor 
-        KvmMonitor.__init__(self, monitor)
-
-    def __del__(self):
-        KvmMonitor.__del__(self)
-    
-    def kvm_monitor(self, command_monitor):
-        """Monitor to the qemu-kvm guest on commandline."""
-        if self._is_running():
-            self.monitor_send(command_monitor)
-            data = self.monitor_recieve()
-            data = "\n".join([i for i in data])
-            print data
-        else:
-            print "Guest is not running."
-
-    def kvm_boot(self, cmd, bridge):
-        """Boot the qemu-kvm guest."""
-        if not self._is_running():
-            env = {} 
-            #env['PATH'] = self._environ_path
-            # Fix: add only nessesary path options
-            env = os.environ.copy()
-            # add the bridge(s) to the enviroment,
-            # so the kvm-if[up|down] can use them
-            if len(bridge) > 0:
-                for key, value in bridge.iteritems():
-                    env[key] = value
-            try:        
-                result = Popen(cmd, env=env, stdin=PIPE, stdout=PIPE)
-                result.wait()
-            except OSError, e:
-                print "Starting guest. [FAIL]"
-                return False
-            except IOError, e:
-                print "Starting guest. [FAIL]"
-                return False
-            else:
-                if self._is_running():
-                    print "Starting guest. [OK]" 
-                else:
-                    print "Starting guest. [FAIL]"
-        else:
-            print "Guest is already running."
-
-    def kvm_reboot(self):
-        """Reboot the guest."""
-        if self._is_running():
-            if self.monitor_send(self.qemu_monitor["reboot"]):
-                print "Rebooting ..."
-            else:
-                print "Could not send signal reboot to guest."
-        else:
-            print "Guest is not running."
-
-    def kvm_shutdown(self):
-        """Shutdown the guest.
-        Its work for windows and linux guests, 
-        but not on linux when the Xserver is looked.
-        """
-        flag = 0
-        if self._is_running():
-            if self.monitor_send(self.qemu_monitor["shutdown"]):
-                self.monitor_send(self.qemu_monitor["enter"])
-                print "Shutdown ..."
-                while True:
-                    # some fancy ticker
-                    if flag == 0:
-                        sign = "\\"; flag = 1
-                    elif flag == 1:    
-                        sign = "|"; flag = 2
-                    elif flag == 2:
-                        sign = "/"; flag = 3
-                    elif flag == 3:
-                        sign = "-"; flag = 0
-                    sys.stdout.write("waiting ... %s\r" % sign)
-                    sys.stdout.flush()
-                    sleep(0.05)
-                    #if self._check_is_running():
-                    if not os.path.isfile(self.pidfile):
-                        sys.stdout.write("Done.         \n")
-                        sys.stdout.flush()
-                        sys.exit(0) 
-                    else:
-                        self._is_running()
-            else:
-                print "Could not send signal shutdown."
-        else:
-            print "Guest is not running."
-
-    def kvm_kill(self):
-        """Kill the guest.
-        Dangerous option, its simply like pull the power cable out.
-        """
-        if self._is_running():
-            try:    
-                os.kill(self._pid, 9)
-                sleep(0.8)
-                if not self._is_running():
-                    print "Killed guest. [OK]"
-            except OSError, e:
-                 print e
-        else:
-            print "Guest is not running."
-
-    def kvm_status(self):
-        """Show information about the guest."""
-        if self._is_running():
-            process = self._get_process_information()
-            print "Name: %s" % process['Name'].split("[")[0]
-            print "%s" % process["Status"]
-            print "Guest uuid: %s" % process['Uuid']
-            print "State: %s" % process['State']
-            print "UID: %s" % process['Uid']
-            print "GID: %s" % process['Gid']
-            print "Groups: %s" % process['Groups']
-            print "PID: %s :: PPID: %s" % (process['Pid'], process['PPid'])
-            print "VNC: %s" % process["VNC"]
-        else:
-            print "Guest is not running."
-
-    def _check_is_running(self):
-        """Check if the process is running by a given pidfile."""
-        if os.path.isfile(self.pidfile):
-            with open(self.pidfile) as fd:
-                self._pid = int(fd.readline().strip())
-                fd.close()
-            # check if process alive
-            try:
-                signal = os.kill(self._pid, 0)
-                return True
-            except OSError, e:
-                return False
-            except IOError, e:
-                return False
-        else:
-            p1 = Popen(['ps', 'aux'], stdout=PIPE, stderr=PIPE)
-            search = "kvm_" + self.guest
-            p2 = Popen(['grep', search], stdin=p1.stdout, stdout=PIPE,
-                stderr=PIPE)
-            result = p2.communicate()
-            status = result[0].split("\n")
-            # search for pid
-            if len(status) > 1:
-                # iterate over the ps aux output per line
-                for i in status:
-                    if not "grep" in i:
-                        pid = i.split(" ")
-                        # remove first element, its the user name
-                        del pid[0]
-                        for j in pid:
-                            if j == "":
-                                continue
-                            else:
-                                # found pid 
-                                self._pid = int(j)
-                                return True
-                return False
-            else:
-                return False
-
-    def _is_running(self):
-        """Avoid killing the socket connection, 
-        if call boot twice or more on a running guest.
-        """
-        if self._check_is_running():
-            return True
-        else:
-            if os.path.isfile(self.pidfile):
-                os.remove(self.pidfile)
-            try:
-                os.remove(self.socketfile)
-            except OSError, e:
-                pass
-            return False
-
-    def _get_vnc(self):
-        self.monitor_send("info vnc")
-        vnc = self.monitor_recieve()
-        vnc = "\n".join(vnc)
-        return vnc
-
-    def _get_uuid(self):
-        """Return the guest uuid."""
-        self.monitor_send(self.qemu_monitor["uuid"])
-        uuid = self.monitor_recieve()[0]
-        return uuid
-
-    def _get_status(self):
-        """Return the status from guest."""
-        self.monitor_send(self.qemu_monitor["status"])
-        status = self.monitor_recieve()[0]
-        return status
-
-    def _get_process_information(self):
-        """Collect process information from different sources."""
-        from subprocess import Popen, PIPE
-        process = {}
-        process['Uuid'] = self._get_uuid()
-        process['Status'] = self._get_status()
-        process["VNC"] = self._get_vnc()
-        try:
-            fd = open(os.path.join("/proc", "%d/status" % self._pid))
-            lines = [line.strip().split(':') for line in fd.readlines()]
-            fd.close()
-            for i in lines:
-                process[i[0]] = i[1]
-        except OSError, e:
-            raise Exception(e)
-        except IOError, e:
-            raise Exception(e)
-        else:
-            return process
-
-def main():
-    if len(sys.argv) == 3:
-        guest = sys.argv[1]
-        action = sys.argv[2]
-        pid = "/var/run/kvm/%s.pid" % guest
-        socket = "/var/run/kvm/%s.socket" % guest
-        monitor = {}
-        monitor['Type'] = "unix"
-        monitor['SocketFile'] = socket
-        kvm = Kvm(guest, pid, socket)
-        kvm.guest = guest
-        if action == "shutdown":
-            kvm.kvm_shutdown()
-        if action == "status":
-            kvm.kvm_status()
-        if action == "boot":
-            kvm.kvm_boot("no", "no")
-        if action == "reboot":
-            kvm.kvm_reboot()
-        if action == "kill":
-            kvm.kvm_kill()
-    else:
-        print "Usage: %s guest_name action" % (sys.argv[0])
-
-if __name__ == "__main__":
-    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/kvm/action.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,217 @@
+#
+# Modulde which contain the methodes which can call from commandline
+#
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+import sys
+from subprocess import Popen, PIPE
+from time import sleep
+
+from kvmtools.kvm.monitor import KvmMonitor
+from kvmtools.config.domain import Domain
+from kvmtools.kvm.build_config import BuildConfig
+from kvmtools.kvm.build_command import BuildCommand
+from kvmtools.system_utils import System
+
+class KvmAction(Domain, BuildConfig, BuildCommand, KvmMonitor, System):
+    
+    def __init__(self):
+        Domain.__init__(self)
+        BuildConfig.__init__(self)
+        BuildCommand.__init__(self)
+        System.__init__(self)
+        self.command = ()
+        self.socket = None
+
+    def load_command(self):
+        """Load config"""
+        try:
+            self.build_config()
+        except Exception:
+            self.kvm_modify_action()
+        self.command = self.build_command()
+        KvmMonitor.__init__(self)
+
+    def available_actions(self):
+        """Return all methods which start with kvm_ and end with _action."""
+        actions = []
+        for action in dir(self):
+            if action.startswith("kvm_") and action.endswith("_action"):
+                methode = action.replace("kvm_", "").replace("_action", "")
+                actions.append(methode)
+        return actions
+   
+    def kvm_show_action(self):
+        """show the command as string"""
+        print self.command[1]
+
+    def kvm_modify_action(self):
+        """Modify a domain configuration file."""
+        self.modify()
+
+    def kvm_create_action(self):
+        """Create a domain configuration file."""
+        if os.path.isfile(self.kvm_domain_file):
+            self.modify()
+        else:
+            self.create()
+
+    def kvm_migrate_action(self, command_monitor):
+        self.kvm_monitor_action(command_monitor)
+
+    def kvm_monitor_action(self, command_monitor):
+        """Monitor to the qemu-kvm guest on commandline."""
+        if not self.is_running(self.kvm_pid):
+            print ("Guest is not running.")
+            return
+        self.monitor_send(command_monitor)
+        data = self.monitor_recieve()
+        data = "\n".join([i for i in data])
+        print data
+
+    def kvm_boot_action(self):
+        """Boot the qemu-kvm guest."""
+        if self.is_running(self.kvm_pid):
+            print ("Guest already running.")
+            return True
+        env = os.environ.copy()
+        # add the bridge(s) to the enviroment
+        if len(self.bridge) > 0:
+            for key, value in self.bridge.iteritems():
+                env[key] = value
+        try:
+            result = Popen(self.command[0], env=env, stdin=PIPE, stdout=PIPE)
+            result.wait()
+            return (True, "")
+        except OSError, error_msg:
+            return (False, error_msg)
+        except IOError, error_msg:
+            return (False, error_msg)
+
+    def kvm_reboot_action(self):
+        """Reboot the guest."""
+        if not self.is_running(self.kvm_pid):
+            print ("Guest is not running.")
+            return False
+        if self.monitor_send(self.qemu_monitor["reboot"]):
+            print ("Rebooting ...")
+        else:
+            print ("Could not send signal reboot to guest.")
+
+    def kvm_shutdown_action(self):
+        """Shutdown the guest.
+        Its work for windows and linux guests, 
+        but not on linux when the Xserver is looked.
+        """
+        if not self.system.is_running(self.kvm_pid):
+            print ("Guest is not running.")
+        flag = 0
+        if self.monitor_send(self.qemu_monitor["shutdown"]):
+            self.monitor_send(self.qemu_monitor["enter"])
+            print ("Shutdown ...")
+            while True:
+                # some fancy ticker
+                if flag == 0:
+                    sign = "\\" 
+                    flag = 1
+                elif flag == 1:    
+                    sign = "|"
+                    flag = 2
+                elif flag == 2:
+                    sign = "/"
+                    flag = 3
+                elif flag == 3:
+                    sign = "-"
+                    flag = 0
+                sys.stdout.write("waiting ... %s\r" % sign)
+                sys.stdout.flush()
+                sleep(0.05)
+                # if self._check_is_running():
+                if not os.path.isfile(self.kvm_pidfile):
+                    sys.stdout.write("Done.         \n")
+                    sys.stdout.flush()
+                    sys.exit(0) 
+                if not self.is_running(self.kvm_pid):
+                    if os.path.isfile(self.kvm_pidfile):
+                        os.remove(self.kvm_pidfile)
+            else:
+                print ("Could not send signal shutdown.")
+
+    def kvm_kill_action(self):
+        """Kill the guest.
+        Dangerous option, its simply like pull the power cable out.
+        """
+        if not self.is_running(self.kvm_pid):
+            print ("Guest is not running.")
+            return False
+        try:    
+            os.kill(self.kvm_pid, 9)
+            sleep(0.8)
+            sys.exit(0)
+        except OSError, error_msg:
+            print error_msg
+            sys.exit(1)
+
+    def kvm_status_action(self):
+        """Show information about the guest."""
+        if not self.is_running(self.kvm_pid):
+            print ("Guest is not running.")
+            return False
+        process = self.get_process_information()
+        info = self.get_process_info(self.kvm_pid)
+        print "Name: %s" % process['Name'].split("[")[0]
+        print "Cmdline: %s" % info["cmdline"]
+        print "rss in %d KB" % info["rss"]
+        print "vms in %d KB" % info["vms"]
+        print "%s" % process["Status"]
+        print "Guest uuid: %s" % process['Uuid']
+        print "State: %s" % process['State']
+        print "UID: %s" % process['Uid']
+        print "GID: %s" % process['Gid']
+        print "Groups: %s" % process['Groups']
+        print "PID: %s :: PPID: %s" % (process['Pid'], process['PPid'])
+        print "VNC: %s" % process["VNC"]
+
+    def _check_is_running(self):
+        """Check if the process is running by a given pidfile."""
+        if os.path.isfile(self.pidfile):
+            with open(self.pidfile) as file_descriptor:
+                self._pid = int(file_descriptor.readline().strip())
+                file_descriptor.close()
+            # check if process alive
+            try:
+                os.kill(self._pid, 0)
+                return True
+            except OSError:
+                return False
+            except IOError:
+                return False
+        else:
+            process1 = Popen(['ps', 'aux'], stdout=PIPE, stderr=PIPE)
+            search = "kvm_" + self.guest
+            process2 = Popen(['grep', search], stdin=process1.stdout, 
+                stdout=PIPE, stderr=PIPE)
+            result = process2.communicate()
+            status = result[0].split("\n")
+            # search for pid
+            if len(status) > 1:
+                # iterate over the ps aux output per line
+                for i in status:
+                    if not "grep" in i:
+                        pid = i.split(" ")
+                        # remove first element, its the user name
+                        del pid[0]
+                        for j in pid:
+                            if j == "":
+                                continue
+                            else:
+                                # found pid 
+                                self._pid = int(j)
+                                return True
+                return False
+            else:
+                return False
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/kvm/build_command.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,51 @@
+#
+# build command to executing
+#
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+
+class BuildCommand(object):
+    """Build command"""
+    
+    def __init__(self):
+        pass
+
+    def build_command(self):
+        """Return a tuple. First entry is a list to execute via subprocess
+        and the second is a string to display it.
+        """
+        self.build_config()
+        cmd_execute = []
+        cmd_string = ""
+        # Start to build a list, firstly add the qemu-kvm binary
+        if "qemu-kvm" not in self.config:
+            return (False, "Need qemu-kvm = /path/to/kvm option in config.")
+        cmd_execute.append(self.config["qemu-kvm"])
+        for key in self.exclude_options:
+            if key in self.config:
+                del self.config[key]
+        # iterate over the user config and build a list
+        for key, value in self.config.iteritems():
+            # this check search for more option like -drive -drive etc.
+            if "disabled" == value:
+                continue
+            elif isinstance(value, dict):
+                for i in value.itervalues():
+                    cmd_execute.append(''.join(['-', key]))
+                    cmd_execute.append(i)
+            elif "enabled" != value:
+                # this qemu-kvm option have an option, so add -key value
+                cmd_execute.append(''.join(['-', key]))
+                cmd_execute.append(value)
+            else:
+                # this qemu-kvm option don't have any option 
+                # so only add -key as argument
+                cmd_execute.append(''.join(['-', key]))
+        # build a string for to display on terminal output
+        cmd_string = " ".join([value for value in cmd_execute])
+        return (cmd_execute, cmd_string)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/kvm/build_config.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,106 @@
+#
+# Module BuildConfig collect all data to create a command qemu-kvm command.
+# 
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+import random
+import string
+
+from kvmtools.config.configparser import Parser
+from kvmtools.kvm.validate_config import ValidateConfig
+
+
+class BuildConfig(ValidateConfig):
+    
+    def __init__(self):
+        ValidateConfig.__init__(self)
+        self.config = {}
+        self.monitor_options = {}
+               
+    def build_config(self):
+        """Load domain and global config and then merge them."""
+        parser = Parser()
+        kvm_conf_file = parser(self.kvm_conf_file)
+        self.check_config(kvm_conf_file)
+        kvm_domain_file = parser(self.kvm_domain_file)
+        self.check_config(kvm_domain_file)
+        self._merge_configs(kvm_conf_file, kvm_domain_file)
+        self._add_name()
+        self._add_uuid()
+        self._add_pidfile()
+        self._add_monitor()
+        self._check_net_tap()
+        self._get_pid()
+
+    def _merge_configs(self, kvm_conf_file, kvm_domain_file):
+        """Merge global and guest configfile.
+        Keep this method, maybe add some more configuration files later.
+        """
+        for key, value in kvm_conf_file.iteritems():
+            self.config[key] = value
+        for key in kvm_conf_file.keys():
+            if key not in kvm_conf_file:
+                self.config[key] = kvm_conf_file[key]
+
+    def _add_pidfile(self):
+        """Append the pidfile option to the config dictionary or reverse."""
+        if "pidfile" not in self.config:
+            pidfile = os.path.join(self.kvm_run_path, self.kvm_pidfile)
+            self.config["pidfile"] = pidfile
+        else:
+            self.kvm_pidfile = self.config["pidfile"]
+
+    def _add_uuid(self):
+        """Append an unique uuid to the config dictionary."""
+        random.seed(os.urandom(8))
+        charset = string.digits + "abcdef"
+        eight = "".join(random.sample(charset, 8))
+        four_first = "".join(random.sample(charset, 4))
+        four_second = "".join(random.sample(charset, 4))
+        four_third = "".join(random.sample(charset, 4))
+        twelve =  "".join(random.sample(charset, 12))
+        uuid = "-".join([eight, four_first, four_second, four_third, twelve])
+        self.config["uuid"] = uuid
+
+    def _add_name(self):
+        """Append a name for window title and process name (on linux only)."""
+        if "name" in self.config:
+            process_name = "=kvm_".join(["process", self.config["name"]])
+            self.config["name"] = ",".join([self.config["name"], process_name])
+        else:
+            process_name = "=".join(["process", self.guest])
+            self.config["name"] = ",".join([self.guest, process_name])
+
+    def _add_monitor(self):
+        """Add a dictionry with type and the path to the socket file or
+        the host and port.
+        """
+        if "monitor" in self.config:
+            monitor = self.config["monitor"]
+            # get the string befor the first comma 
+            # and then split this string by colon
+            monitor_type = monitor.split(',')[0].split(':')
+            if len(monitor_type) == 3:
+                # this is usally for tcp
+                self.monitor_options['Type'] = monitor_type[0] 
+                self.monitor_options['Host'] = monitor_type[1]
+                self.monitor_options['Port'] = int(monitor_type[2])
+            elif len(monitor_type) == 2:
+                # this is for telnet, when no port is given
+                self.monitor_options['Type'] = monitor_type[0]
+                if monitor_type[0] == 'unix':
+                    self.monitor_options['SocketFile'] = monitor_type[1]
+                self.monitor_options['Host'] = monitor_type[1]
+                self.monitor_options['Port'] = self.telnet_port
+        else:
+            # set unix socket as default monitor access
+            monitor = "unix:%s,server,nowait" % self.kvm_socketfile
+            self.monitor_options["Type"] = "unix"
+            self.monitor_options['SocketFile'] = self.kvm_socketfile
+        self.config["monitor"] = monitor 
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/kvm/monitor.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+#
+# Module to handle the monitor stuff.
+#
+
+"""
+(c) 2009-2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import socket
+import time
+
+
+class KvmMonitor(object):
+    """
+    Class for connect and disconnect to a qemu monitor socket.
+    Additional send data to and recieve data from monitor.
+    """
+
+    def __init__(self):
+        # keep the socket
+        self.socket = None
+        # flag if socket can acces
+        self.socket_status = False
+        # data for method socket_recieve
+        self.recieve_data = {
+            "data_offset_first_call": 2, 
+            "data_offset_second_call": 1,
+        } 
+        # predefined qemu monitor options
+        self.qemu_monitor = {
+            "shutdown": "system_powerdown",
+            "reboot": "sendkey ctrl-alt-delete 200",
+            "enter": "sendkey ret",
+            "status": "info status",
+            "uuid": "info uuid",
+            "network": "info network",
+        }
+        self._monitor_open()
+
+    def __del__(self):
+        """Close to socket when exit the program."""
+        self._monitor_close()
+
+    #########################################
+    # monitor via unix socket or tcp socket #
+    #########################################
+    def _monitor_open(self):        
+        """Open a socket to connect to the qemu-kvm monitor."""
+        if self.monitor_options['Type'] == 'unix': 
+            self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            try:
+                self.socket.connect(self.kvm_socketfile)
+                self.socket_status = True
+            except socket.error:
+                return False      
+        else:
+            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            try:
+                self.socket.connect((self.monitor_options['Host'], 
+                    self.monitor_options['Port']))
+                self.socket_status = True
+            except socket.error:
+                return False
+
+    def _monitor_close(self):
+        """Close the opened socket connection."""    
+        if self.socket is not None:
+            self.socket.close()
+
+    def monitor_send(self, command, raw=True):
+        """Send data to socket."""
+        if raw:
+            command = '%s\n' % command
+        if self.socket_status:
+            try:
+                self.socket.send(command)
+                time.sleep(0.2)
+                return True
+            except socket.error, error_msg:
+                if error_msg[0] == 32:
+                    print "Could not send data to socket."
+                print error_msg[1]
+                return False
+        else:
+            return False
+
+    def monitor_recieve(self, socket_buffer=4098):
+        """Recieve data from socket and return it as a list."""
+        result = []
+        no_result = ['No data available']
+        if self.socket_status:
+            data = self.socket.recv(socket_buffer)
+            if len(data) == 0:
+                return no_result
+            data = data.split("\r\n")
+            # have to do this check because second call does not send
+            # the qemu info string
+            if data[0].startswith("QEMU"):
+                counter = self.recieve_data['data_offset_first_call']
+                if len(data) > self.recieve_data['data_offset_first_call']:
+                    while counter < len(data) - 1:
+                        result.append(data[counter])
+                        counter += 1
+                    if len(result) == 0:
+                        result = ["Done"]
+                    return result
+            else:                    
+                counter = self.recieve_data['data_offset_second_call']
+                if len(data) > self.recieve_data['data_offset_second_call']:
+                    while counter < len(data)-1:
+                        result.append(data[counter])
+                        counter += 1
+                    return result
+        return no_result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/kvm/validate_config.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,138 @@
+#
+# validate config
+#
+
+"""
+(c) 2011 Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+import sys
+import re
+try:
+    from kvmtools.qemu_kvm_options import qemu_kvm_options
+except ImportError, error_msg:
+    print error_msg
+    sys.exit(1)
+
+
+class ValidateConfig(object):
+    """Validate the domain config file against qemu-kvm options."""
+
+    def __init__(self):
+        self.bridge = {}
+
+    def check_config(self, config):
+        """check the config files if the have valid qemu-kvm options."""
+        for key in config.iterkeys():
+            # ignore the exclude options form check
+            if key in self.exclude_options:
+                continue
+            if key not in qemu_kvm_options:
+                return False
+        else:
+            return True
+
+    def _qemu_kvm_script(self, script_option):
+        """Return the absoulute path for ifup or ifdown script."""
+        script_option = "".join(["kvm-", script_option])
+        script = os.path.join(self.kvm_script_dir, script_option)
+        return script
+
+    def _check_net_tap(self):
+        """Examine the -net tap option for ifname and additional scripts and 
+        bridge strings.
+        """
+        temp = {} 
+        counter = 0
+        for key, value in self.config["net"].iteritems():
+            if value.startswith("tap"):
+                # search for ifname otherwise set it from guest name
+                if re.search("ifname", value):
+                    temp_ifname = re.search(",ifname=([a-zA-Z0-9]+)", value)
+                    ifname = temp_ifname.group(1)
+                else:
+                    ifname = "".join([self.kvm_domain_name, str(counter)])
+                    temp_ifname = "=".join(["ifname", ifname])
+                    if re.match("tap,", value):
+                        value = re.sub("tap,", "tap,%s,", value) % temp_ifname
+                    else:
+                        value = re.sub("tap", "tap,%s", value) % temp_ifname
+                    counter += 1
+                # build the bridge key    
+                bridge_key = "_".join(["bridge", ifname])
+                # search for bridge otherwise raise an exception,
+                # because this value is needed
+                if re.search("bridge", value):
+                    temp_bridge = re.search(",bridge=([a-zA-Z0-9]+)", value)
+                    # get the bridge name from searched group
+                    bridge = temp_bridge.group(1)
+                    # remove the bridge from string
+                    value = value.replace(temp_bridge.group(0), "")
+                else:
+                    msg = "Missing second Value for bridge.\n"
+                    msg = "".join([msg, "Syntax example: bridge=br0"])
+                    raise Exception(msg)
+                # assign bridge for exporting the bridge name
+                self.bridge[bridge_key] = bridge
+                # search for script 
+                if not re.search("script", value):
+                    ifup = "=".join(["script", self._qemu_kvm_script('ifup')])
+                    value = ",".join([value, ifup])
+                # search for downscript
+                if not re.search("downscript", value):
+                    ifdown = "=".join(["downscript", 
+                                        self._qemu_kvm_script('ifdown')])
+                    value = ",".join([value, ifdown])
+                # add the cleaned value to temporary dictionary
+                temp[key] = value
+            else:                    
+                temp[key] = value
+        # add the cleand temp dictionary back to config        
+        self.config["net"] = temp
+        return True
+    
+    def _get_pid(self):
+        """Set pif if pidfile is available"""
+        if os.path.isfile(self.kvm_pidfile):
+            with open(self.kvm_pidfile) as fd:
+                self.kvm_pid = int(fd.readline().strip())
+
+   
+    def _get_vnc(self):
+        """Return vnc info."""
+        self.monitor_send("info vnc")
+        vnc = self.monitor_recieve()
+        vnc = "\n".join(vnc)
+        return vnc
+
+    def _get_uuid(self):
+        """Return the guest uuid."""
+        self.monitor_send(self.qemu_monitor["uuid"])
+        uuid = self.monitor_recieve()[0]
+        return uuid
+
+    def _get_status(self):
+        """Return the status from guest."""
+        self.monitor_send(self.qemu_monitor["status"])
+        status = self.monitor_recieve()[0]
+        return status
+
+    def get_process_information(self):
+        """Collect process information from different sources."""
+        process = {}
+        process['Uuid'] = self._get_uuid()
+        process['Status'] = self._get_status()
+        process["VNC"] = self._get_vnc()
+        try:
+            _fd = open(os.path.join("/proc", "%d/status" % self.kvm_pid))
+            lines = [line.strip().split(':') for line in _fd.readlines()]
+            _fd.close()
+            for i in lines:
+                process[i[0]] = i[1]
+        except OSError, error_msg:
+            raise Exception(error_msg)
+        except IOError, error_msg:
+            raise Exception(error_msg)
+        else:
+            return process 
--- a/kvmtools/kvm_monitor.py	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-#!/usr/bin/env python
-#
-# Module to handle the monitor stuff.
-#
-
-"""
-(c) 2009-2011 Jens Kasten <jens@kasten-edv.de>
-"""
-
-from os import path
-from sys import exit
-import socket
-import time
-
-
-class KvmMonitor(object):
-    """
-    Class for connect and disconnect to a qemu monitor socket.
-    Additional send data to and recieve data from monitor.
-    """
-
-    def __init__(self, monitor):
-        self._monitor = monitor
-        # flag if socket can acces
-        self.socket_status = False
-        # data for method socket_recieve
-        self.recieve_data = {
-            "data_offset_first_call": 2, 
-            "data_offset_second_call": 1,
-        } 
-        # predefined qemu monitor options
-        self.qemu_monitor = {
-            "shutdown": "system_powerdown",
-            "reboot": "sendkey ctrl-alt-delete 200",
-            "enter": "sendkey ret",
-            "status": "info status",
-            "uuid": "info uuid",
-            "network": "info network",
-        }
-        try:
-            self._monitor_open()
-        except:
-            pass
-
-    def __del__(self):
-        try:
-            self.monitor_close()
-        except:
-            pass
-
-    #########################################
-    # monitor via unix socket or tcp socket #
-    #########################################
-    def _monitor_open(self):        
-        """Open a socket to connect to the qemu-kvm monitor."""
-        if self._monitor['Type'] == 'unix': 
-            self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-            try:
-                self.socket.connect(self.socketfile)
-                self.socket_status = True
-            except socket.error:
-                return False      
-        else:
-            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            try:
-                self.socket.connect((self._monitor['Host'], self._monitor['Port']))
-                self.socket_status = True
-            except socket.error:
-                return False
-
-    def _monitor_close(self):
-        """Close the opened socket connection."""    
-        self.socket.close()
-
-    def monitor_send(self, command, raw=True):
-        """Send data to socket."""
-        if raw:
-            command = '%s\n' % command
-        if self.socket_status:
-            try:
-                self.socket.send(command)
-                time.sleep(0.2)
-                return True
-            except socket.error, e:
-                from sys import exit
-                if e[0] == 32:
-                    print "Could not send data to socket."
-                print e[1]
-                return False
-        else:
-            return False
-
-    def monitor_recieve(self, buffer=4098):
-        """Recieve data from socket and return it as a list."""
-        result = []
-        no_result = ['No data available']
-        if self.socket_status:
-            data = self.socket.recv(buffer)
-            if len(data) == 0:
-                 return no_result
-            data = data.split("\r\n")
-            # have to do this check because second call does not send
-            # the qemu info string
-            if data[0].startswith("QEMU"):
-                counter = self.recieve_data['data_offset_first_call']
-                if len(data) > self.recieve_data['data_offset_first_call']:
-                    while counter < len(data) - 1:
-                        result.append(data[counter])
-                        counter += 1
-                    if len(result) == 0:
-                        result = ["Done"]
-                    return result
-            else:                    
-                counter = self.recieve_data['data_offset_second_call']
-                if len(data) > self.recieve_data['data_offset_second_call']:
-                    while counter < len(data)-1:
-                        result.append(data[counter])
-                        counter += 1
-                    return result
-        return no_result        
-            
-
-def main():
-    pass
-
-
-if __name__ == "__main__":
-    main()
-            
--- a/kvmtools/qemu_kvm_options.py	Tue Nov 22 03:58:43 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-#!/usr/bin/env python
-"""
-    Autogenerated dictionary. Don't edit this file!
-"""
-
-qemu_kvm_options = {
-	"M": "disabled",
-	"cpu": "disabled",
-	"smp": "disabled",
-	"numa": "disabled",
-	"fda": "disabled",
-	"fdb": "disabled",
-	"hda": "disabled",
-	"hdb": "disabled",
-	"hdc": "disabled",
-	"hdd": "disabled",
-	"cdrom": "disabled",
-	"drive": "disabled",
-	"set": "disabled",
-	"global": "disabled",
-	"mtdblock": "disabled",
-	"sd": "disabled",
-	"pflash": "disabled",
-	"boot": "disabled",
-	"snapshot": "disabled",
-	"m": "disabled",
-	"k": "disabled",
-	"audio-help": "disabled",
-	"soundhw": "disabled",
-	"usb": "disabled",
-	"usbdevice": "disabled",
-	"device": "disabled",
-	"name": "disabled",
-	"uuid": "disabled",
-	"nographic": "disabled",
-	"curses": "disabled",
-	"no-frame": "disabled",
-	"alt-grab": "disabled",
-	"ctrl-grab": "disabled",
-	"no-quit": "disabled",
-	"sdl": "disabled",
-	"portrait": "disabled",
-	"vga": "disabled",
-	"full-screen": "disabled",
-	"vnc": "disabled",
-	"win2k-hack": "disabled",
-	"no-fd-bootchk": "disabled",
-	"no-acpi": "disabled",
-	"no-hpet": "disabled",
-	"balloon": "disabled",
-	"acpitable": "disabled",
-	"smbios": "disabled",
-	"net": "disabled",
-	"netdev": "disabled",
-	"chardev": "disabled",
-	"bt": "disabled",
-	"kernel": "disabled",
-	"append": "disabled",
-	"initrd": "disabled",
-	"serial": "disabled",
-	"parallel": "disabled",
-	"monitor": "disabled",
-	"qmp": "disabled",
-	"mon": "disabled",
-	"pidfile": "disabled",
-	"singlestep": "disabled",
-	"S": "disabled",
-	"gdb": "disabled",
-	"s": "disabled",
-	"d": "disabled",
-	"hdachs": "disabled",
-	"L": "disabled",
-	"bios": "disabled",
-	"enable-kvm": "disabled",
-	"no-reboot": "disabled",
-	"no-shutdown": "disabled",
-	"loadvm": "disabled",
-	"daemonize": "disabled",
-	"option-rom": "disabled",
-	"clock": "disabled",
-	"rtc": "disabled",
-	"icount": "disabled",
-	"watchdog": "disabled",
-	"watchdog-action": "disabled",
-	"echr": "disabled",
-	"virtioconsole": "disabled",
-	"show-cursor": "disabled",
-	"tb-size": "disabled",
-	"incoming": "disabled",
-	"nodefaults": "disabled",
-	"chroot": "disabled",
-	"runas": "disabled",
-	"readconfig": "disabled",
-	"writeconfig": "disabled",
-	"no-kvm": "disabled",
-	"no-kvm-irqchip": "disabled",
-	"no-kvm-pit": "disabled",
-	"no-kvm-pit-reinjection": "disabled",
-	"pcidevice": "disabled",
-	"enable-nesting": "disabled",
-	"nvram": "disabled",
-	"tdf": "disabled",
-	"kvm-shadow-memory": "disabled",
-	"mem-path": "disabled",
-	"mem-prealloc": "disabled",
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmtools/system_utils.py	Tue Nov 22 03:59:30 2011 +0100
@@ -0,0 +1,69 @@
+#
+# Module provide system information through the python-psutil
+#
+
+"""
+(c) Jens Kasten <jens@kasten-edv.de>
+"""
+
+import os
+import sys
+try:
+    import psutil
+    required_version = [0, 1, 3]
+    version = [int(i) for i in psutil.__version__.split(".")]
+    for i in range(len(required_version)):
+        if version[i] > required_version[i]:
+            print "psutil in version %s is required" % required_version
+            print "Installed version %s" % version
+            sys.exit(1)
+except ImportError, error_msg:
+    print error_msg
+    sys.exit(1)
+
+
+class System(object):
+
+    def avail_memory(self):
+        """Return available system memory in megabyte."""
+        memory = psutil.avail_phymem()
+        return memory / (1024 * 1024)
+
+    def total_memory(self):
+        """Return total amount of system memory in megabyte."""
+        memory = psutil.TOTAL_PHYMEM
+        return memory / (1024 * 1024)
+
+    def get_cdrom(self):
+        """Check if machine has a cdrom. Return the path to cdrom device."""
+        if os.path.exists("/dev/cdrom"):
+            return "/dev/cdrom"
+        elif os.path.exists("/dev/dvd"):
+            return "/dev/dvd"
+        else:
+            for i in range(0, 11):
+                if os.path.exists("/dev/sr%d" % i):
+                    return "/dev/sr%d" % i
+        return None
+
+    def get_process_info(self, pid):
+        """Return a disctionary about the process on given pid."""
+        if not  self.is_running(pid):
+            return False
+        info = {}
+        process = psutil.Process(pid)
+        info["name"] = process.name
+        info["uid"] = process.uid
+        info["gid"] = process.gid
+        rss, vms = process.get_memory_info()
+        info["rss"] = rss / 1024
+        info["vms"] = vms / 1024
+        info["cmdline"] = process.cmdline
+        #info["cpu_times"] = 
+        return info
+
+    def is_running(self, pid):
+        if not type(pid) is int and psutil.pid_exits(pid):
+            return False
+        else:
+            return True