[Ovirt-devel] [PATCH node] Introduces the node-admin toolset.
Darryl L. Pierce
dpierce at redhat.com
Fri Jul 31 20:03:52 UTC 2009
Defines a primary entry point that displays a menu of options that user
can use to administer the managed node. It leverages the code from
virtinst-python to do the heavy lifting and just provides a front end
for collecting user data.
Created a new configuration class to be used for all configuration
screens.
The user can select to create a node. They are then walked through the
steps to create a VM similar to virt-manager.
The user can list all domains on the system.
Signed-off-by: Darryl L. Pierce <dpierce at redhat.com>
---
Makefile.am | 12 ++
node_admin/configscreen.py | 95 +++++++++++++++
node_admin/createuser.py | 22 ++++
node_admin/definevm.py | 284 ++++++++++++++++++++++++++++++++++++++++++++
node_admin/listvms.py | 67 +++++++++++
node_admin/mainmenu.py | 64 ++++++++++
node_admin/node-admin.py | 29 +++++
node_admin/node.py | 210 ++++++++++++++++++++++++++++++++
node_admin/nodeconfig.py | 123 +++++++++++++++++++
node_admin/startvm.py | 22 ++++
node_admin/stopvm.py | 22 ++++
node_admin/undefinevm.py | 22 ++++
ovirt-node.spec.in | 1 +
13 files changed, 973 insertions(+), 0 deletions(-)
create mode 100755 node_admin/__init__.py
create mode 100644 node_admin/configscreen.py
create mode 100755 node_admin/createuser.py
create mode 100755 node_admin/definevm.py
create mode 100755 node_admin/listvms.py
create mode 100755 node_admin/mainmenu.py
create mode 100755 node_admin/node-admin.py
create mode 100755 node_admin/node.py
create mode 100644 node_admin/nodeconfig.py
create mode 100755 node_admin/startvm.py
create mode 100755 node_admin/stopvm.py
create mode 100755 node_admin/undefinevm.py
diff --git a/Makefile.am b/Makefile.am
index 0374f07..5b758b7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,6 +26,18 @@ EXTRA_DIST = \
ovirt-node-selinux.fc \
images/grub-splash.xpm.gz \
images/syslinux-vesa-splash.jpg \
+ node_admin/configscreen.py \
+ node_admin/createuser.py \
+ node_admin/definevm.py \
+ node_admin/__init__.py \
+ node_admin/listvms.py \
+ node_admin/mainmenu.py \
+ node_admin/node-admin.py \
+ node_admin/node.py \
+ node_admin/startvm.py \
+ node_admin/stopvm.py \
+ node_admin/undefinevm.py \
+ node_admin/utils.py \
scripts/collectd \
scripts/collectd.conf.in \
scripts/ovirt \
diff --git a/node_admin/__init__.py b/node_admin/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/node_admin/configscreen.py b/node_admin/configscreen.py
new file mode 100644
index 0000000..48aacd1
--- /dev/null
+++ b/node_admin/configscreen.py
@@ -0,0 +1,95 @@
+# configscreen.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+
+class ConfigScreen:
+ '''Enables the creation of navigable, multi-paged configuration screens.'''
+
+ __BACK_BUTTON = "back"
+ __NEXT_BUTTON = "next"
+ __CANCEL_BUTTON = "cancel"
+ __FINISH_BUTTON = "finish"
+
+ def __init__(self, title):
+ self.__title = title
+ self.__current_page = 1
+ self.__finished = False
+
+ def set_finished(self):
+ self.__finished = True
+
+ def get_elements_for_page(self, screen, page):
+ return []
+
+ def page_has_next(self, page):
+ return False
+
+ def page_has_finish(self, page):
+ return False
+
+ def get_back_page(self, page):
+ if page > 1: return page - 1
+ return page
+
+ def go_back(self):
+ self.__current_page = self.get_back_page(self.__current_page)
+
+ def get_next_page(self, page):
+ return page + 1
+
+ def go_next(self):
+ self.__current_page = self.get_next_page(self.__current_page)
+
+ def validate_input(self, page):
+ return True
+
+ def process_input(self, page):
+ return
+
+ def start(self):
+ active = True
+ while active and (self.__finished == False):
+ screen = SnackScreen()
+ gridform = GridForm(screen, self.__title, 1, 4)
+ elements = self.get_elements_for_page(screen, self.__current_page)
+ current_element = 0
+ for element in elements:
+ gridform.add(element, 0, current_element)
+ current_element += 1
+ # create the navigation buttons
+ buttons = []
+ if self.__current_page > 1: buttons.append(["Back", self.__BACK_BUTTON])
+ if self.page_has_next(self.__current_page): buttons.append(["Next", self.__NEXT_BUTTON, "F12"])
+ if self.page_has_finish(self.__current_page): buttons.append(["Finish", self.__FINISH_BUTTON])
+ buttons.append(["Cancel", self.__CANCEL_BUTTON])
+ buttonbar = ButtonBar(screen, buttons)
+ gridform.add(buttonbar, 0, current_element, growx = 1)
+ current_element += 1
+ result = gridform.runOnce()
+ screen.popWindow()
+ screen.finish()
+ pressed = buttonbar.buttonPressed(result)
+ if pressed == self.__BACK_BUTTON:
+ self.go_back()
+ elif pressed == self.__NEXT_BUTTON or pressed == self.__FINISH_BUTTON:
+ if self.validate_input(self.__current_page):
+ self.process_input(self.__current_page)
+ self.go_next()
+ elif pressed == self.__CANCEL_BUTTON:
+ active = False
diff --git a/node_admin/createuser.py b/node_admin/createuser.py
new file mode 100755
index 0000000..e624570
--- /dev/null
+++ b/node_admin/createuser.py
@@ -0,0 +1,22 @@
+# definevm.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+
+def createUser():
+ print "Create user!"
diff --git a/node_admin/definevm.py b/node_admin/definevm.py
new file mode 100755
index 0000000..d79f4ce
--- /dev/null
+++ b/node_admin/definevm.py
@@ -0,0 +1,284 @@
+# definevm.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+from node import *
+from nodeutils import *
+import os
+from nodeconfig import NodeConfig
+from configscreen import ConfigScreen
+
+from virtinst import Guest, DistroInstaller, LiveCDInstaller, PXEInstaller
+
+VM_DETAILS_PAGE = 1
+LOCAL_INSTALL_PAGE = 2
+NETWORK_INSTALL_PAGE = 3
+OS_TYPE_PAGE = 10
+OS_VARIANT_PAGE = 11
+RAM_CPU_PAGE = 12
+LOCAL_STORAGE_PAGE = 13
+BRIDGE_PAGE = 14
+CONFIRM_PAGE = 15
+
+LOCATION="location"
+KICKSTART="kickstart"
+KERNELOPTS="kernel.options"
+OS_TYPE="os.type"
+OS_VARIANT="os.variant"
+MEMORY="memory"
+CPUS="cpus"
+
+class VirtualMachineConfigScreen(ConfigScreen):
+
+ def __init__(self):
+ ConfigScreen.__init__(self, "Create A New Virtual Machine")
+ self.__config = NodeConfig()
+
+ def get_elements_for_page(self, screen, page):
+ if page == VM_DETAILS_PAGE:
+ return self.get_vm_details_page(screen)
+ elif page == LOCAL_INSTALL_PAGE:
+ return self.get_local_install_page(screen)
+ elif page == NETWORK_INSTALL_PAGE:
+ return self.get_network_install_page(screen)
+ elif page == OS_TYPE_PAGE:
+ return self.get_os_type_page(screen)
+ elif page == OS_VARIANT_PAGE:
+ return self.get_os_variant_page(screen)
+ elif page == RAM_CPU_PAGE:
+ return self.get_ram_and_cpu_page(screen)
+ elif page == LOCAL_STORAGE_PAGE:
+ return self.get_local_storage_page(screen)
+ elif page == BRIDGE_PAGE:
+ return self.get_bridge_page(screen)
+ elif page == CONFIRM_PAGE:
+ return self.get_confirm_page(screen)
+ return []
+
+ def validate_input(self, page):
+ if page == VM_DETAILS_PAGE:
+ if len(self.__guest_name.value()) > 0:
+ return True
+ elif page == LOCAL_INSTALL_PAGE:
+ if len(self.__install_source.value()) > 0 and os.path.exists(self.__install_source.value()):
+ return True
+ elif page == NETWORK_INSTALL_PAGE:
+ if len(self.__install_url.value()) > 0: return True
+ elif page == OS_TYPE_PAGE: return True
+ elif page == OS_VARIANT_PAGE: return True
+ elif page == RAM_CPU_PAGE:
+ if (len(self.__memory.value()) > 0 and len(self.__cpus.value()) > 0) and (int(self.__memory.value()) > 0 and int(self.__cpus.value()) > 0):
+ return True
+ elif page == LOCAL_STORAGE_PAGE:
+ if self.__storage_type.getSelection() == Node.STORAGE_TYPE_NEW:
+ if len(self.__storage_size.value()) > 0:
+ if float(self.__storage_size.value()) > 0: return True
+ elif self.__storage_type.getSelection() == Node.STORAGE_TYPE_EXISTING:
+ if os.path.exists(self.__existing_storage.value()): return true
+ elif page == BRIDGE_PAGE: return True
+ elif page == CONFIRM_PAGE: return True
+ return False
+
+ def process_input(self, page):
+ if page == VM_DETAILS_PAGE:
+ self.__config.set_guest_name(self.__guest_name.value())
+ self.__config.set_install_type(self.__install_type.getSelection())
+ elif page == LOCAL_INSTALL_PAGE:
+ self.__config.set_install_location(self.__install_source.value())
+ elif page == NETWORK_INSTALL_PAGE:
+ self.__config[LOCATION] = self.__install_url.value()
+ self.__config[KICKSTART] = self.__kickstart_url.value()
+ self.__config[KERNELOPTS] = self.__kernel_options.value()
+ elif page == OS_TYPE_PAGE:
+ self.__config.set_os_type(self.__os_types.getSelection())
+ elif page == OS_VARIANT_PAGE:
+ self.__config.set_os_variant(self.__os_variants.getSelection())
+ elif page == RAM_CPU_PAGE:
+ self.__config.set_memory(int(self.__memory.value()))
+ self.__config.set_cpus(int(self.__cpus.value()))
+ elif page == LOCAL_STORAGE_PAGE:
+ self.__config.set_enable_storage(self.__enable_storage.value())
+ if self.__config.set_enable_storage:
+ if self.__storage_type.getSelection() == NodeConfig.NEW_STORAGE:
+ self.__config.set_use_local_storage(true)
+ self.__config.set_storage_size(float(self.__storage_size.value()))
+ self.__guest.set_allocate_storage(self.__allocate_storage.value())
+ elif self.__storage_type.getSelection() == Node.STORAGE_TYPE_EXISTING:
+ self.__config.set_use_local_storage(false)
+ self.__guest.set_existing_storage(self.__existing_storage.value())
+ elif page == CONFIRM_PAGE:
+ # save the VM
+ define_domain(self.__guest)
+ self.set_finished()
+
+ def get_back_page(self, page):
+ result = page
+ if page == OS_TYPE_PAGE:
+ install_type = self.__config.get_install_type()
+ if install_type == NodeConfig.LOCAL_INSTALL:
+ result = LOCAL_INSTALL_PAGE
+ elif install_type == NodeConfig.NETWORK_INSTALL:
+ result = NETWORK_INSTALL_PAGE
+ elif install_type == NodeConfig.PXE_INSTALL:
+ result = VM_DETAILS_PAGE
+ else:
+ if page > 1: result = page - 1
+ return result
+
+ def get_next_page(self, page):
+ result = page
+ if page == VM_DETAILS_PAGE:
+ install_type = self.__config.get_install_type()
+ if install_type == NodeConfig.LOCAL_INSTALL:
+ result = LOCAL_INSTALL_PAGE
+ elif install_type == NodeConfig.NETWORK_INSTALL:
+ result = NETWORK_INSTALL_PAGE
+ elif install_type == NodeConfig.PXE_INSTALL:
+ result = OS_TYPE_PAGE
+ elif page == LOCAL_INSTALL_PAGE or page == NETWORK_INSTALL_PAGE:
+ result = OS_TYPE_PAGE
+ else:
+ result = page + 1
+ return result
+
+ def page_has_finish(self, page):
+ if page == CONFIRM_PAGE: return True
+ return False
+
+ def page_has_next(self, page):
+ if page < CONFIRM_PAGE:
+ return True
+
+ def get_vm_details_page(self, screen):
+ self.__guest_name = Entry(50, self.__config.get_guest_name())
+ self.__install_type = RadioBar(screen, (("Local install media (ISO image or CDROM)",
+ NodeConfig.LOCAL_INSTALL,
+ self.__config.is_install_type(NodeConfig.LOCAL_INSTALL)),
+ ("Network Install (HTTP, FTP, or NFS)",
+ NodeConfig.NETWORK_INSTALL,
+ self.__config.is_install_type(NodeConfig.NETWORK_INSTALL)),
+ ("Network Boot (PXE)",
+ NodeConfig.PXE_INSTALL,
+ self.__config.is_install_type(NodeConfig.PXE_INSTALL))))
+ grid = Grid(2,4)
+ grid.setField(Label("Enter your machine details"), 0, 0, growx = 1)
+ grid.setField(Label("Name:"), 0, 1, anchorLeft = 1)
+ grid.setField(self.__guest_name, 1, 1)
+ grid.setField(Label("Choose how you would like to install the operating system"), 0, 2, growx = 1)
+ grid.setField(self.__install_type, 0, 3)
+ return [grid]
+
+ def get_local_install_page(self, screen):
+ self.__install_source = Entry(50, self.__config.get_install_location())
+ grid = Grid(2,1)
+ grid.setField(Label("Install source:"), 0, 0)
+ grid.setField(self.__install_source, 1, 0)
+ return [grid]
+
+ def get_network_install_page(self, screen):
+ self.__install_url = Entry(50, _get_field_str(self.__guest.get_location()))
+ self.__kickstart_url = Entry(50, self.__guest.get_kickstart_url())
+ self.__kernel_options = Entry(50, self.__guest.get_kernel_options())
+ grid = Grid(2,4)
+ grid.setField(Label("Provide the operating system URL"), 0, 0, growx = 1)
+ grid.setField(Label("URL:"), 0, 1)
+ grid.setField(self.__install_url, 1, 1)
+ grid.setField(Label("Kickstart URL:"), 0, 2)
+ grid.setField(self.__kickstart_url, 1, 2)
+ grid.setField(Label("Kernel Options:"), 0, 3)
+ grid.setField(self.__kernel_options, 1, 3)
+ return [grid]
+
+ def get_os_type_page(self, screen):
+ types = []
+ for type in Guest.list_os_types():
+ types.append([Guest.get_os_type_label(type), type, self.__config.is_os_type(type)])
+ self.__os_types = RadioBar(screen, types)
+ grid = Grid(2, 1)
+ grid.setField(Label("OS Type:"), 0, 0)
+ grid.setField(self.__os_types, 1, 0)
+ return [grid]
+
+ def get_os_variant_page(self, screen):
+ variants = []
+ type = self.__config.get_os_type()
+ for variant in Guest.list_os_variants(type):
+ variants.append([Guest.get_os_variant_label(type, variant), variant, self.__config.is_os_variant(variant)])
+ self.__os_variants = RadioBar(screen, variants)
+ grid = Grid(2, 1)
+ grid.setField(Label("OS Variant:"), 0, 0)
+ grid.setField(self.__os_variants, 1, 0)
+ return [grid]
+
+ def get_ram_and_cpu_page(self, screen):
+ self.__memory = Entry(4, str(self.__config.get_memory()))
+ self.__cpus = Entry(3, str(self.__config.get_cpus()))
+ grid = Grid(2,3)
+ grid.setField(Label("Choose memory and CPU settings"), 0, 0, growx = 1)
+ grid.setField(Label("Memory (RAM):"), 0, 1)
+ grid.setField(self.__memory, 1, 1)
+ grid.setField(Label("CPUs:"), 0, 2)
+ grid.setField(self.__cpus, 1, 2)
+ return [grid]
+
+ def get_local_storage_page(self, screen):
+ self.__enable_storage = Checkbox("Enable storage for this virtual machine", self.__config.get_enable_storage())
+ storage_types = []
+ for option in Node.STORAGE_TYPES.keys():
+ storage_types.append([Node.STORAGE_TYPES.get(option), option, self.__config.get_storage_type() == option])
+ self.__storage_type = RadioBar(screen,storage_types,
+ ((["Create a disk image on the computer's hard disk",
+ NodeConfig.NEW_STORAGE,
+ self.__config.get_use_local_storage()]),
+ (["Select managed or other existing storage",
+ NodeConfig.EXISTING_STORAGE,
+ self.__config.get_use_local_storage() is False])))
+ self.__storage_size = Entry(6, str(self.__config.get_storage_size()))
+ self.__allocate_storage = Checkbox("Allocate entire disk now", self.__config.get_allocate_storage())
+ self.__existing_storage = Entry(60, self.__config.get_existing_storage())
+ grid = Grid(2,5)
+ grid.setField(self.__enable_storage, 0, 0, growx = 1, anchorLeft = 1)
+ grid.setField(self.__storage_type, 1, 1, growx = 1)
+ grid.setField(self.__allocate_storage, 0, 2, growx = 1, anchorLeft = 1)
+ grid.setField(Label("Storage size (GB):"), 0, 3, anchorLeft = 1)
+ grid.setField(self.__storage_size, 1, 3)
+ grid.setField(Label("Existing storage:"), 0, 4)
+ grid.setField(self.__existing_storage, 1, 4)
+ return [grid]
+
+ def get_bridge_page(self, screen):
+ return []
+
+ def get_confirm_page(self, screen):
+ grid = Grid(2, 6)
+ grid.setField(Label("Ready to begin installation of %s" % self.__guest.get_name()), 0, 0, growx = 1)
+ grid.setField(Label("OS:"), 0, 1)
+ grid.setField(Label(self.__guest.get_os_type()), 1, 1)
+ grid.setField(Label("Install:"), 0, 2)
+ grid.setField(Label(self.__guest.get_boot_type_text()), 1, 2)
+ grid.setField(Label("Memory:"), 0, 3)
+ grid.setField(Label("%s MB" % self.__guest.get_memory()), 1, 3)
+ grid.setField(Label("CPUs:"), 0, 4)
+ grid.setField(Label("%d" % self.__guest.get_cpus()), 1, 4)
+ grid.setField(Label("Storage:"), 0, 5)
+ grid.setField(Label(self.__guest.get_existing_storage()), 1, 5)
+ return [grid]
+
+def defineVM():
+ vmconfig = VirtualMachineConfigScreen()
+ vmconfig.start()
diff --git a/node_admin/listvms.py b/node_admin/listvms.py
new file mode 100755
index 0000000..ff3e42e
--- /dev/null
+++ b/node_admin/listvms.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# definevm.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from configscreen import ConfigScreen
+from snack import *
+from nodeutils import *
+
+class ListDomainsConfigScreen(ConfigScreen):
+ __LIST_PAGE = 1
+ __DETAIL_PAGE = 2
+
+ def __init__(self):
+ ConfigScreen.__init__(self, 'List Domains')
+
+ def page_has_next(self, page):
+ return (page == self.__LIST_PAGE)
+
+ def page_has_back(self, page):
+ return (page == self.__DETAIL_PAGE)
+
+ def get_elements_for_page(self, screen, page):
+ if page == self.__LIST_PAGE:
+ return self.get_list_page_elements()
+ elif page == self.__DETAIL_PAGE:
+ return self.get_detail_page_elements()
+
+ def get_list_page_elements(self):
+ domains = get_domain_list()
+ self.__domain_list = Listbox(0)
+ for name in domains.keys():
+ self.__domain_list.append(name, name)
+ return [self.__domain_list]
+
+ def get_detail_page_elements(self):
+ domain = get_domain(self.__domain_list.current())
+ grid = Grid(2, 5)
+ grid.setField(Label("Name: "), 0, 0, anchorRight = 1)
+ grid.setField(Label(domain.name()), 1, 0, anchorLeft = 1)
+ grid.setField(Label("UUID: "), 0, 1, anchorRight = 1)
+ grid.setField(Label(domain.UUIDString()), 1, 1, anchorLeft = 1)
+ grid.setField(Label("OS Type: "), 0, 2, anchorRight = 1)
+ grid.setField(Label(domain.OSType()), 1, 2, anchorLeft = 1)
+ grid.setField(Label("Max. Memory: "), 0, 3, anchorRight = 1)
+ grid.setField(Label(str(domain.maxMemory())), 1, 3, anchorLeft = 1)
+ grid.setField(Label("Max. VCPUs: "), 0, 4, anchorRight = 1)
+ grid.setField(Label(str(domain.maxVcpus())), 1, 4, anchorLeft = 1)
+ return [grid]
+
+def listVMs():
+ screen = ListDomainsConfigScreen()
+ screen.start()
diff --git a/node_admin/mainmenu.py b/node_admin/mainmenu.py
new file mode 100755
index 0000000..6b3d27e
--- /dev/null
+++ b/node_admin/mainmenu.py
@@ -0,0 +1,64 @@
+# mainmenu.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+from definevm import defineVM
+from listvms import listVMs
+
+DEFINE_VM = 1
+START_VM = 2
+STOP_VM = 3
+UNDEFINE_VM = 4
+LIST_VMS = 5
+CREATE_USER = 6
+EXIT_CONSOLE = 99
+
+def mainMenu():
+ finished = False
+ while finished == False:
+ screen = SnackScreen()
+ menu = Listbox(height = 0, width = 0, returnExit = 1)
+ menu.append("Define a new VM", DEFINE_VM)
+ menu.append("Start a VM", START_VM)
+ menu.append("Stop a running VM", STOP_VM)
+ menu.append("Undefine a VM", UNDEFINE_VM)
+ menu.append("List all VMs", LIST_VMS)
+ menu.append("Create a user", CREATE_USER)
+ menu.append("Exit Node Administration", EXIT_CONSOLE)
+ gridform = GridForm(screen, "Node Administration Console", 1, 4)
+ gridform.add(menu, 0, 0)
+ result = gridform.run();
+ screen.popWindow()
+ screen.finish()
+
+ if result.current() == DEFINE_VM:
+ defineVM()
+ elif result.current() == START_VM:
+ startVM()
+ elif result.current() == STOP_VM:
+ stopVM()
+ elif result.current() == UNDEFINE_VM:
+ destroyVM()
+ elif result.current() == LIST_VMS:
+ listVMs()
+ elif result.current() == CREATE_USER:
+ createUser()
+ elif result.current() == EXIT_CONSOLE:
+ finished = True
+ else:
+ print "Nope.\n"
diff --git a/node_admin/node-admin.py b/node_admin/node-admin.py
new file mode 100755
index 0000000..5061362
--- /dev/null
+++ b/node_admin/node-admin.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+#
+# node-admin - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+import sys
+
+from mainmenu import *
+
+def main():
+ mainMenu()
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/node_admin/node.py b/node_admin/node.py
new file mode 100755
index 0000000..d566f87
--- /dev/null
+++ b/node_admin/node.py
@@ -0,0 +1,210 @@
+# node.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class Node:
+ BOOT_TYPE_LOCAL = "local"
+ BOOT_TYPE_NETWORK = "network"
+ BOOT_TYPE_PXE = "pxe"
+ BOOT_TYPES = {BOOT_TYPE_LOCAL : "Local install media (ISO image or CDROM)",
+ BOOT_TYPE_NETWORK : "Network Install (HTTP, FTP, or NFS)",
+ BOOT_TYPE_PXE : "Network Boot (PXE)"}
+ OS_TYPES = {"generic" : "Generic",
+ "linux" : "Linux",
+ "other" : "Other",
+ "solaris" : "Solaris",
+ "unix" : "UNIX",
+ "windows" : "Windows"}
+ OS_VERSIONS = ["Generic"]
+ STORAGE_TYPE_NEW = "new"
+ STORAGE_TYPE_EXISTING = "existing"
+ STORAGE_TYPES = {STORAGE_TYPE_NEW : "Create a disk image on the computer's hard disk",
+ STORAGE_TYPE_EXISTING : "Select managed or other existing storage"}
+
+ def __init__(self):
+ self.__name = ""
+ self.__boot_type = Node.BOOT_TYPE_PXE
+ self.__install_source = ""
+ self.__install_url = ""
+ self.__kickstart_url = ""
+ self.__kernel_options = ""
+ self.__os_type = "generic"
+ self.__os_version = "generic"
+ self.__memory = 512
+ self.__cpus = 1
+ self.__storage_size = 8.0
+ self.__allocate_storage = True
+ self.__storage_type = Node.STORAGE_TYPE_NEW
+ self.__existing_storage = ""
+
+ def set_name(self, name):
+ self.__name = name
+
+ def get_name(self):
+ return self.__name
+
+ def set_boot_type(self, boot_type):
+ if Node.BOOT_TYPES.has_key(boot_type):
+ self.__boot_type = boot_type
+ else:
+ raise ValueError("Invalid boot type: %s" % boot_type)
+
+ def get_boot_type(self):
+ return self.__boot_type
+
+ def get_boot_device(self):
+ if self.__boot_type == Node.BOOT_TYPE_PXE:
+ return "network"
+ else:
+ return "disk"
+
+ def get_boot_type_text(self):
+ return Node.BOOT_TYPES.get(self.__boot_type)
+
+ def set_install_source(self, install_source):
+ if os.path.exist(install_source):
+ self.__install_source = install_source
+ else:
+ raise Error("Non-existent install source: %s" % install_source)
+
+ def get_install_source(self):
+ return self.__install_source
+
+ def set_install_url(self, url):
+ self.__install_url = url
+
+ def get_install_url(self):
+ return self.__install_url
+
+ def set_kickstart_url(self, url):
+ self.__kickstart_url = url
+
+ def get_kickstart_url(self):
+ return self.__kickstart_url
+
+ def set_kernel_options(self, options):
+ self.__kernel_options = options
+
+ def get_kernel_options(self):
+ return self.__kernel_options
+
+ def set_os_type(self, os_type):
+ if Node.OS_TYPES.has_key(os_type):
+ self.__os_type = os_type
+ else:
+ raise ValueError("Invalid OS type: %s" % os_type)
+
+ def get_os_type(self):
+ return self.__os_type
+
+ def set_os_version(self, os_version):
+ try:
+ if Node.OS_VERSIONS.index(os_version) >= 0: self.__os_version = os_version
+ except ValueError, error:
+ raise error
+
+ def get_os_version(self):
+ return self.__os_version
+
+ def set_memory(self, memory):
+ if int(memory) > 0:
+ self.__memory = memory
+ else:
+ raise ValueError("Invalid memory value: %d" % int(memory))
+
+ def get_memory(self):
+ return self.__memory
+
+ def set_cpus(self, cpus):
+ if int(cpus):
+ self.__cpus = cpus
+ else:
+ raise ValueError("Invalid number of cpus: %d" % int(cpus))
+
+ def get_cpus(self):
+ return self.__cpus
+
+ def has_local_storage(self):
+ if self.__storage_size > 0: return True
+ return False
+
+ def get_local_storage(self):
+ return "/var/lib/libvirt/images/%s.img" % self.get_name()
+
+ def set_storage_size(self, storage_size):
+ if float(storage_size) > 0.0:
+ self.__storage_size = storage_size
+ else:
+ raise ValueError("Invalid storage size: %f" % float(storage_size))
+
+ def get_storage_size(self):
+ return self.__storage_size
+
+ def set_allocate_storage(self, allocate_storage):
+ self.__allocate_storage = allocate_storage
+
+ def get_allocate_storage(self):
+ return self.__allocate_storage
+
+ def set_storage_type(self, storage_type):
+ if Node.STORAGE_TYPES.has_key(storage_type):
+ self.__storage_type = storage_type
+ else:
+ raise ValueError("Invalid storage type: %s" % storage_type)
+
+ def get_storage_type(self):
+ return self.__storage_type
+
+ def set_existing_storage(self, existing_storage):
+ if os.path.exist(existing_storage):
+ self.__existing_storage = existing_storage
+ else:
+ raise ValueError("No such file: %s" % existing_storage)
+
+ def get_existing_storage(self):
+ return self.__existing_storage
+
+ def get_xml(self):
+ result = "<domain type='kvm'>\n"
+ result += "<name>%s</name>\n" % self.get_name()
+ result += "<memory>%d</memory>\n" % (self.get_memory() * 1024 * 1024)
+ result += "<vcpu>%d</vcpu>\n" % self.get_cpus()
+ result += "<os>\n"
+ result += "<type arch='%s' machine='%s'>%s</type>\n" % ('x86_64', 'pc', 'hvm')
+ result += "<boot dev='%s' />\n" % self.get_boot_device()
+ result += "</os>\n"
+ result += "<features>\n"
+ result += "<acpi />\n"
+ result += "<pae />\n"
+ result += "</features>\n"
+ result += "<clock offset='utc' />\n"
+ result += "<on_poweroff>destroy</on_poweroff>\n"
+ result += "<on_reboot>restart</on_reboot>\n"
+ result += "<on_crash>restart</on_crash>\n"
+ result += "<devices>\n"
+ if self.has_local_storage():
+ result += "<disk type='file' device='disk'>\n"
+ result += "<source file='%s' />\n" % self.get_local_storage()
+ result += "<target dev='vda' bus='virtio' />\n"
+ result += "</disk>\n"
+ result += "<serial type='pty' />\n"
+ result += "<console type='pty' />\n"
+ result += "<graphics type='vnc' port='-1' autoport='yes' keyman='en-us' />\n"
+ result += "</devices>\n"
+ result += "</domain>\n"
+
+ return result
diff --git a/node_admin/nodeconfig.py b/node_admin/nodeconfig.py
new file mode 100644
index 0000000..1e1106d
--- /dev/null
+++ b/node_admin/nodeconfig.py
@@ -0,0 +1,123 @@
+# nodeconfig.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from virtinst import Guest
+
+class NodeConfig:
+ LOCAL_INSTALL = "local"
+ NETWORK_INSTALL = "network"
+ PXE_INSTALL = "pxe"
+
+ NEW_STORAGE = "new"
+ EXISTING_STORAGE = "existing"
+
+ def __init__(self):
+ self.__guest_name = ""
+ self.__install_type = NodeConfig.LOCAL_INSTALL
+ self.__install_location = ""
+ self.__os_type = Guest.list_os_types()[0]
+ self.__os_variant = Guest.list_os_variants(self.__os_type)[0]
+ self.__memory = 512
+ self.__cpus = 1
+ self.__enable_storage = True
+ self.__use_local_storage = True
+ self.__storage_size = 8.0
+ self.__allocate_storage = True
+ self.__existing_storage = ""
+
+ def set_guest_name(self, name):
+ self.__guest_name = name
+
+ def get_guest_name(self):
+ return self.__guest_name
+
+ def set_install_type(self, type):
+ self.__install_type = type
+
+ def get_install_type(self):
+ return self.__install_type
+
+ def is_install_type(self, type):
+ return self.__install_type == type
+
+ def set_install_location(self, location):
+ self.__install_location = location
+
+ def get_install_location(self):
+ return self.__install_location
+
+ def set_os_type(self, type):
+ self.__os_type = type
+ self.__os_variant = Guest.list_os_variants(type)[0]
+
+ def get_os_type(self):
+ return self.__os_type
+
+ def is_os_type(self, type):
+ return self.__os_type == type
+
+ def set_os_variant(self, variant):
+ self.__os_variant = variant
+
+ def get_os_variant(self):
+ return self.__os_variant
+
+ def is_os_variant(self, variant):
+ return self.__os_variant == variant
+
+ def set_memory(self, memory):
+ self.__memory = int(memory)
+
+ def get_memory(self):
+ return self.__memory
+
+ def set_cpus(self, cpus):
+ self.__cpus = cpus
+
+ def get_cpus(self):
+ return self.__cpus
+
+ def set_enable_storage(self, enable):
+ self.__enable_storage = enable
+
+ def get_enable_storage(self):
+ return self.__enable_storage
+
+ def set_use_local_storage(self, use):
+ self.__use_local_storage = use
+
+ def get_use_local_storage(self):
+ return self.__use_local_storage
+
+ def set_storage_size(self, size):
+ self.__storage_size = size
+
+ def get_storage_size(self):
+ return self.__storage_size
+
+ def set_allocate_storage(self, allocate):
+ self.__allocate_storage = allocate
+
+ def get_allocate_storage(self):
+ return self.__allocate_storage
+
+ def set_existing_storage(self, storage):
+ self.__existing_storage = storage
+
+ def get_existing_storage(self):
+ return self.__existing_storage
diff --git a/node_admin/startvm.py b/node_admin/startvm.py
new file mode 100755
index 0000000..00b4cd2
--- /dev/null
+++ b/node_admin/startvm.py
@@ -0,0 +1,22 @@
+# definevm.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+
+def startVM():
+ print "Start VM!"
diff --git a/node_admin/stopvm.py b/node_admin/stopvm.py
new file mode 100755
index 0000000..656dfdc
--- /dev/null
+++ b/node_admin/stopvm.py
@@ -0,0 +1,22 @@
+# definevm.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+
+def stopVM():
+ print "Stop VM!"
diff --git a/node_admin/undefinevm.py b/node_admin/undefinevm.py
new file mode 100755
index 0000000..7217985
--- /dev/null
+++ b/node_admin/undefinevm.py
@@ -0,0 +1,22 @@
+# definevm.py - Copyright (C) 2009 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# 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; version 2 of the License.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from snack import *
+
+def defineVM():
+ print "Undefine VM!"
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index 3138011..4fded95 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -43,6 +43,7 @@ Requires: nc
Requires: grub
Requires: /usr/sbin/crond
Requires: anyterm
+Requires: newt-python
ExclusiveArch: %{ix86} x86_64
%define app_root %{_datadir}/%{name}
--
1.6.2.5
More information about the ovirt-devel
mailing list