Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed a bug after refactoring.

Updated the documentation.
  • Loading branch information...
commit 2f4b261d5db550c62ad551c33e34190bd4c49f48 1 parent 93a52e9
@magiconair authored
Showing with 261 additions and 53 deletions.
  1. +98 −3 README.md
  2. +163 −50 ghettoUI
View
101 README.md
@@ -1,10 +1,10 @@
### GhettoUI
-*ghettoUI* is an interactive frontend for the *ghettoVCB.sh* and *ghettoVCB-restore.sh* scripts by William Lam.
+**ghettoUI** is an interactive frontend for the **ghettoVCB.sh** and **ghettoVCB-restore.sh** scripts by William Lam.
It is really easy to use. Just keep `ghettoUI`, `ghettoVCB.sh` and `ghettoVCB-restore.sh` in a directory accessible to your ESXi host and you're done. This can be a directory on the ESXi host or
-*ghettoUI* extracts the information of the available virtual machines from the current host and offers an interactive menu for performing a backup.
+**ghettoUI** extracts the information of the available virtual machines from the current host and offers an interactive menu for performing a backup.
To perform a restore *ghettoUI* checks the available datastores for valid backups and offers an interactive menu for a restore.
@@ -14,7 +14,102 @@ ghettoUI is a python script which uses just the available python interpreter and
To perform a backup ghettoUI lists the available virtual machines and datastores using vim-cmd, parses the output and displays the information as an interactive menu to the user. Once the user has chosen a machine to backup ghettoUI creates the necessary configuration files on the fly and runs the `ghettoVCB.sh` script to perform the actual backup.
-To perform a restore ghettoUI looks for `BACKUP` directories in all available datastores. It assumes the directory structure /path/to/datastore/BACKUP/vm-name/backup-name and presents the user with an interactive menu. After the user has made a choice ghettoUI again creates the necessary configuration files and runs the `ghettoVCB-restore.sh` script.
+To perform a restore ghettoUI looks for `BACKUP` directories in all available datastores. It assumes the directory structure `/path/to/datastore/BACKUP/vm-name/backup-name` and presents the user with an interactive menu. After the user has made a choice **ghettoUI** again creates the necessary configuration files and runs the `ghettoVCB-restore.sh` script.
+
+### Screenshot
+
+This is a screenshot of a backup procedure
+
+ /vmfs/volumes/23ed4bf3-6292d161 # ls
+ BACKUPS LOGS ghettoUI ghettoVCB-restore.sh ghettoVCB.sh
+ /vmfs/volumes/23ed4bf3-6292d161 # ./ghettoUI
+
+ ghettoUI Menu 0.5
+ -----------------
+
+ What do you want to do?
+
+ 1. Backup a virtual machine
+ 2. Restore a virtual machine
+
+ Q. Quit
+
+ > 1
+ ghettoUI Menu 0.5
+ -----------------
+
+ Select a virtual machine
+
+ 1. Ubuntu Server
+ 2. Windows XP
+ 3. Windows Vista
+ 4. Windows 2000
+ 5. Windows 7
+ 6. server-1
+ 7. server-template
+ 8. server-2
+ 9. server-3
+ 10. server-4
+ 11. server-5
+ 12. server-6
+ 13. server-7
+ 14. firewall
+
+ Q. Return
+
+ > 12
+ ghettoUI Menu 0.5
+ -----------------
+
+ Select a datastore
+
+ 1. datastore1 (VMFS)
+ 2. nfs1 (NFS)
+
+ Q. Return
+
+ > 2
+ ghettoUI Menu 0.5
+ -----------------
+
+ Do you want to backup 'server-6' onto 'nfs1'?
+
+ 1. info - Standard output
+ 2. debug - Debug output
+ 3. dryrun - Test only. No backup is performed
+
+ Q. Return
+
+ > 1
+ 2011-07-11 20:21:56 -- info: ============================== ghettoVCB LOG START ==============================
+
+ ...
+
+ 2011-07-11 20:21:58 -- info: Initiate backup for server-6
+ 2011-07-11 20:21:58 -- info: Creating Snapshot "ghettoVCB-snapshot-2011-07-11" for server-6
+ Destination disk format: VMFS thin-provisioned
+ Cloning disk '/vmfs/volumes/datastore1/server-6/server-6.vmdk'...
+ Clone: 94% done.
+ 2011-07-11 20:23:46 -- info: Removing snapshot from server-6 ...
+ 2011-07-11 20:23:46 -- info: Backup Duration: 1.80 Minutes
+ 2011-07-11 20:23:47 -- info: Successfully completed backup for server-6!
+ 2011-07-11 20:23:48 -- info: ###### Final status: All VMs backed up OK! ######
+
+ 2011-07-11 20:23:48 -- info: ============================== ghettoVCB LOG END ================================
+
+ ghettoUI Menu 0.5
+ -----------------
+
+ What do you want to do?
+
+ 1. Backup a virtual machine
+ 2. Restore a virtual machine
+
+ Q. Quit
+
+ > q
+ /vmfs/volumes/23ed4bf3-6292d161 #
+
### Known pitfalls
View
213 ghettoUI
@@ -6,7 +6,15 @@ ghettoUI.py
Interactive frontend for the ghettoVCB and
ghettoVCB-restore scripts.
-Copyright (C) 2011 by Frank Schroeder
+This script allows to perform interactive backups
+and restores of a single virtual machine using
+the ghettoVCB.sh and ghettoVCB-restore.sh scripts
+by William Lam (http://www.virtualghetto.com/).
+
+
+
+
+Copyright (C) 2011 of ghettoUI by Frank Schroeder (https://go-left.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -34,9 +42,12 @@ import time
from tempfile import mkstemp
from datetime import datetime
-version = "0.1"
+version = "0.5"
class Backup:
+ """
+ Entity class for a VM backup
+ """
def __init__(self):
self.name = ""
self.datastore = ""
@@ -52,6 +63,9 @@ class Backup:
return self.__str__()
class Datastore:
+ """
+ Entity class for a datastore
+ """
def __init__(self):
self.name = ""
self.url = ""
@@ -69,6 +83,9 @@ class Datastore:
class VM:
+ """
+ Entity class for a virtual machine
+ """
def __init__(self):
self.vmid = -1
self.name = ''
@@ -87,17 +104,27 @@ class VM:
class VimCmd:
+ """
+ Wrapper class for accessing status information of
+ the VMware ESXi host through the vim-cmd command
+ """
+
+
def vimcmd(self, arg):
+ """
+ Executes the /bin/vim-cmd with the given arguments
+ """
return os.popen("/bin/vim-cmd %s" % arg)
+
def getDatastores(self):
"""
Determines the list of configured datastores.
- Returns a list of Datastore instances.
+ Returns a list of Datastore entities.
"""
- f = self.vimcmd("hostsvc/datastore/listsummary")
datastores = []
+ f = self.vimcmd("hostsvc/datastore/listsummary")
for line in f:
m = re.search(r'name = "(.*)",', line)
if m:
@@ -127,15 +154,16 @@ class VimCmd:
return datastores
+
def getVMs(self):
"""
Determines the list of virtual machines in the
inventory of the host and returns a list of
- VM instances.
+ VM entities.
"""
vms = []
- s = self.vimcmd("vmsvc/getallvms")
- for line in s:
+ f = self.vimcmd("vmsvc/getallvms")
+ for line in f:
l = re.findall(r"(\d+)\s+(.+\w)\s+\[(\w+)\]\s+(.*\.vmx)\s+(\w+Guest)\s+(vmx-\d+)\s+(.*)\n", line)
if (len(l) == 0):
continue
@@ -153,21 +181,47 @@ class VimCmd:
return vms
+
+
class Menu:
- def header(self):
- # os.system("/bin/sh -c clear");
+ """
+ Interactive menu class.
+
+ Can display a numbered menu and a yes/no question.
+ """
+
+
+ def header(self, prompt, clearscreen):
+ """
+ Prints a header with a version number
+ """
+ if clearscreen:
+ os.system("/bin/sh -c clear");
+
print
- print "ghettoVCB Menu %s" % (version)
- print "------------------"
+ print "ghettoUI Menu %s" % (version)
+ print "-----------------"
print
+ print prompt
+ print
+
def show(self, prompt, returnPrompt, options):
+ """
+ Shows an interactive menu of the options.
+ The options are tuples of the form (value, text)
+ where 'value' is the value to return if that item
+ was selected and 'text' is the text to display.
+
+ 'prompt' is the prompt the user is shown.
+
+ When 'returnPrompt' is set an additional item
+ with the value 'q' is added to the menu which
+ allows to return or quit.
+ """
while True:
- # clear screen and show header
- self.header()
-
- print prompt
- print
+ # print header and prompt
+ self.header(prompt, False)
# print the menu
i = 0
@@ -192,21 +246,33 @@ class Menu:
pass
def yesno(self, prompt):
+ """
+ Shows a simple yes/no menu and returns either
+ 'yes' or 'no'
+ """
options = [("yes", "Yes"), ("no", "No")]
return self.show(prompt, None, options)
+
+
class GhettoVCB:
"""
Wrapper class for the ghettoVCB.sh and ghettoVCB-restore.sh
- scripts. Creates the temporary configuration files and
- run the scripts.
+ scripts. Creates temporary configuration files and
+ runs the scripts.
"""
- def __init__(self):
+
+ def __init__(self):
self.scriptdir = os.path.abspath(os.path.dirname(__file__))
def logfile(self, name, postfix):
+ """
+ Creates a filename for a logfile of the form
+ {name}-{postfix}-{date}. Checks if the log directory
+ exists and creates it if necessary.
+ """
now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
logdir = "%s/LOGS" % self.scriptdir
logfile = "%s/%s-%s-%s.log" % (logdir, name, postfix, now)
@@ -219,11 +285,26 @@ class GhettoVCB:
def backup(self, vm, datastore, debugLevel):
+ """
+ Performs a backup of a single VM to the given
+ datastore. The parameters of the backup are
+ currently hardcoded and the VM is not stopped
+ during the backup. Controller and VMDK type are
+ hard-coded.
+
+ This should probably use a conf directory
+ with VM specific configuration and only
+ default to a default configuration if
+ nothing was found.
+ """
+
+ # create the configuration file with the virtual machine name
(f, vmfile) = mkstemp(".tmp", "ghettoVCB-vm-")
os.write(f, vm.name)
os.write(f, "\n")
os.close(f)
+ # create the configuration file with the backup config parameters
(f, conffile) = mkstemp(".tmp", "ghettoVCB-conf-")
os.write(f, "VM_BACKUP_VOLUME=%s/BACKUPS\n" % datastore.url)
os.write(f, "DISK_BACKUP_FORMAT=thin\n")
@@ -251,53 +332,47 @@ class GhettoVCB:
os.write(f, "EMAIL_FROM=\n")
os.close(f)
+ # run the script
logfile = self.logfile(vm.name, "backup")
cmdline = "%s/ghettoVCB.sh -f '%s' -g '%s' -l '%s' -d '%s'" % \
(self.scriptdir, vmfile, conffile, logfile, debugLevel)
- print cmdline
- os.system(cmdline)
+ # print cmdline
+ os.system(cmdline)
+
+ # cleanup
os.unlink(vmfile)
os.unlink(conffile)
- pass
+
def restore(self, backup, datastore):
+ """
+ Restores the given backup to the datastore.
+ """
+ # create the config file for the restore script
(f, restorefile) = mkstemp(".tmp", "ghettoVCB-restore-")
os.write(f, "\"%s;%s;%d\"\n" % (backup.dir, datastore.url, 3))
os.close(f)
+ # run the script
logfile = self.logfile(backup.name, "restore")
cmdline = "%s/ghettoVCB-restore.sh -c '%s' -l '%s'" % \
(self.scriptdir, restorefile, logfile)
- print cmdline
+ # print cmdline
+
+ # cleanup
os.system(cmdline)
os.unlink(restorefile)
- pass
class GhettoUI:
+ """
+ Main class which contains the application logic.
+ """
- def selectAction(self):
- options = [
- ("backup", "Backup a virtual machine"),
- ("restore", "Restore a virtual machine")
- ];
- return Menu().show("What do you want to do?", "Quit", options)
-
- def selectDatastore(self):
- datastores = VimCmd().getDatastores()
- options = []
- for datastore in datastores:
- options.append((datastore, "%s (%s)" % (datastore.name, datastore.type)))
- return Menu().show("Select a datastore", "Return", options)
-
- def selectVm(self):
- vms = VimCmd().getVMs()
- options = []
- for vm in vms:
- options.append((vm, vm.name))
- return Menu().show("Select a virtual machine", "Return", options)
-
- def backup(self):
+ def actionBackup(self):
+ """
+ Logic for performing a backup.
+ """
while True:
vm = self.selectVm()
if vm == None:
@@ -318,7 +393,10 @@ class GhettoUI:
GhettoVCB().backup(vm, datastore, level)
return
- def restore(self):
+ def actionRestore(self):
+ """
+ Logic for performing a restore.
+ """
while True:
datastores = VimCmd().getDatastores()
backups = []
@@ -353,17 +431,52 @@ class GhettoUI:
GhettoVCB().restore(backup, datastore)
return
+ def selectAction(self):
+ """
+ Shows the menu for the available actions.
+ """
+ options = [
+ ("backup", "Backup a virtual machine"),
+ ("restore", "Restore a virtual machine")
+ ];
+ return Menu().show("What do you want to do?", "Quit", options)
+
+
+ def selectDatastore(self):
+ """
+ Shows the menu for selecting one of the available
+ datastores.
+ """
+ datastores = VimCmd().getDatastores()
+ options = []
+ for datastore in datastores:
+ options.append((datastore, "%s (%s)" % (datastore.name, datastore.type)))
+ return Menu().show("Select a datastore", "Return", options)
+
+
+ def selectVm(self):
+ """
+ Shows the menu for the available virtual machines.
+ """
+ vms = VimCmd().getVMs()
+ options = []
+ for vm in vms:
+ options.append((vm, vm.name))
+ return Menu().show("Select a virtual machine", "Return", options)
+
def run(self):
+ """
+ Main runloop.
+ """
while True:
action = self.selectAction()
if action == "backup":
- self.backup()
+ self.actionBackup()
elif action == "restore":
- self.restore()
+ self.actionRestore()
elif action == None:
return
if __name__ == '__main__':
GhettoUI().run()
-
Please sign in to comment.
Something went wrong with that request. Please try again.