Add code for virt-manager TUI from OVirt node project
This code is taken from the ovirt node project. Overtime the plan is to share lots of code between the GUI and TUI. This is step 1 though. Code can be invoked with: cd src/virtManagerTui python nodeadmin.py Additional requirements beyond plain virt-manager are a system installed IPy and newt-python (or whatever package provides the 'snack' module)
This commit is contained in:
parent
d5a1262ee6
commit
b000c87302
|
@ -0,0 +1,19 @@
|
|||
# __init__.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 nodeadmin import NodeAdmin
|
|
@ -0,0 +1,512 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# adddomain.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import os
|
||||
from createmeter import CreateMeter
|
||||
from domainconfig import DomainConfig
|
||||
from configscreen import ConfigScreen
|
||||
import utils
|
||||
|
||||
from virtinst import *
|
||||
|
||||
VM_DETAILS_PAGE = 1
|
||||
LOCAL_INSTALL_PAGE = 2
|
||||
SELECT_CDROM_PAGE = 3
|
||||
SELECT_ISO_PAGE = 4
|
||||
NETWORK_INSTALL_PAGE = 5
|
||||
OS_TYPE_PAGE = 6
|
||||
OS_VARIANT_PAGE = 7
|
||||
RAM_CPU_PAGE = 8
|
||||
ENABLE_STORAGE_PAGE = 9
|
||||
LOCAL_STORAGE_PAGE = 10
|
||||
SELECT_POOL_PAGE = 11
|
||||
SELECT_VOLUME_PAGE = 12
|
||||
BRIDGE_PAGE = 13
|
||||
VIRT_DETAILS_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 DomainConfigScreen(ConfigScreen):
|
||||
def __init__(self):
|
||||
ConfigScreen.__init__(self, "Create A New Virtual Machine")
|
||||
self.__config = DomainConfig()
|
||||
self.__config.set_architecture(self.get_libvirt().get_default_architecture())
|
||||
self.__config.set_virt_type(self.get_libvirt().get_default_virt_type())
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is VM_DETAILS_PAGE: return self.get_vm_details_page(screen)
|
||||
elif page is LOCAL_INSTALL_PAGE: return self.get_local_install_page(screen)
|
||||
elif page is SELECT_CDROM_PAGE: return self.get_select_cdrom_page(screen)
|
||||
elif page is SELECT_ISO_PAGE: return self.get_select_iso_page(screen)
|
||||
elif page is NETWORK_INSTALL_PAGE: return self.get_network_install_page(screen)
|
||||
elif page is OS_TYPE_PAGE: return self.get_os_type_page(screen)
|
||||
elif page is OS_VARIANT_PAGE: return self.get_os_variant_page(screen)
|
||||
elif page is RAM_CPU_PAGE: return self.get_ram_and_cpu_page(screen)
|
||||
elif page is ENABLE_STORAGE_PAGE: return self.get_enable_storage_page(screen)
|
||||
elif page is LOCAL_STORAGE_PAGE: return self.get_local_storage_page(screen)
|
||||
elif page is SELECT_POOL_PAGE: return self.get_select_pool_page(screen)
|
||||
elif page is SELECT_VOLUME_PAGE: return self.get_select_volume_page(screen)
|
||||
elif page is BRIDGE_PAGE: return self.get_bridge_page(screen)
|
||||
elif page is VIRT_DETAILS_PAGE: return self.get_virt_details_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
return []
|
||||
|
||||
def get_page_list(self):
|
||||
return ["Virtual Machine Details",
|
||||
"Local Installation Details",
|
||||
"Setup CD-ROM Device",
|
||||
"Setup ISO File",
|
||||
"Setup Network Installation",
|
||||
"Select Operating System Type",
|
||||
"Select Operating System Variant",
|
||||
"Set Memory Size",
|
||||
"Enable Storage",
|
||||
"Setup Local Storage",
|
||||
"Select Storage Pool",
|
||||
"Select Storage Volume",
|
||||
"Setup Bridge",
|
||||
"Review Virtual Machine Details",
|
||||
"Confirm Virtual Machine"]
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is VM_DETAILS_PAGE:
|
||||
if len(self.__guest_name.value()) > 0:
|
||||
if self.get_libvirt().domain_exists(self.__guest_name.value()):
|
||||
errors.append("Guest name '%s' is already in use." % self.__guest_name.value())
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
errors.append("Guest name must be a string between 0 and 50 characters.")
|
||||
elif page is LOCAL_INSTALL_PAGE:
|
||||
if self.__install_source.getSelection() == DomainConfig.INSTALL_SOURCE_CDROM:
|
||||
return True
|
||||
elif self.__install_source.getSelection() == DomainConfig.INSTALL_SOURCE_ISO:
|
||||
return True
|
||||
elif page is SELECT_CDROM_PAGE:
|
||||
if self.__install_media.getSelection() != None:
|
||||
if len(self.get_hal().list_installable_volumes()) == 0:
|
||||
errors.append("No installable media is available.")
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
errors.append("You must select an install media.")
|
||||
elif page is SELECT_ISO_PAGE:
|
||||
if len(self.__iso_path.value()) > 0:
|
||||
if os.path.exists(self.__iso_path.value()):
|
||||
if os.path.isfile(self.__iso_path.value()):
|
||||
return True
|
||||
else:
|
||||
errors.append("%s is not a file." % self.__iso_path.value())
|
||||
else:
|
||||
errors.append("No such install media exists:")
|
||||
errors.append(self.__iso_path.value())
|
||||
else:
|
||||
errors.append("An install media selection is required.")
|
||||
elif page is NETWORK_INSTALL_PAGE:
|
||||
if len(self.__install_url.value()) > 0:
|
||||
return True
|
||||
else:
|
||||
errors.append("An install tree is required.")
|
||||
elif page is OS_TYPE_PAGE: return True
|
||||
elif page is OS_VARIANT_PAGE: return True
|
||||
elif page is 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
|
||||
else:
|
||||
if len(self.__memory.value()) == 0:
|
||||
errors.append("A value must be entered for memory.")
|
||||
elif int(self.__memory.value()) <= 0:
|
||||
errors.append("A positive integer value must be entered for memory.")
|
||||
if len(self.__cpus.value()) == 0:
|
||||
errors.append("A value must be entered for CPUs.")
|
||||
elif int(self.__cpus.value()) <= 0:
|
||||
errors.append("A positive integer value must be entered for memory.")
|
||||
elif page is ENABLE_STORAGE_PAGE: return True
|
||||
elif page is LOCAL_STORAGE_PAGE:
|
||||
if len(self.__storage_size.value()) > 0:
|
||||
if float(self.__storage_size.value()) > 0:
|
||||
return True
|
||||
else:
|
||||
errors.append("A positive value must be entered for the storage size.")
|
||||
else:
|
||||
errors.append("A value must be entered for the storage size.")
|
||||
elif page is SELECT_POOL_PAGE:
|
||||
if self.__storage_pool.getSelection() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("Please select a storage pool.")
|
||||
elif page is SELECT_VOLUME_PAGE:
|
||||
if self.__storage_volume.getSelection() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("Please select a storage volume.")
|
||||
elif page is BRIDGE_PAGE:
|
||||
if self.__network_bridges.getSelection() != None:
|
||||
if len(self.__mac_address.value()) > 0:
|
||||
# TODO: regex check the format
|
||||
return True
|
||||
else:
|
||||
errors.append("MAC address must be supplied.")
|
||||
else:
|
||||
errors.append("A network bridge must be selected.")
|
||||
elif page is VIRT_DETAILS_PAGE:
|
||||
if self.__virt_types.getSelection() != None and self.__architectures.getSelection() != None:
|
||||
return True
|
||||
if self.__virt_types.getSelection() is None:
|
||||
errors.append("Please select a virtualization type.")
|
||||
if self.__architectures.getSelection() is None:
|
||||
errors.append("Please selection an architecture.")
|
||||
elif page is CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is VM_DETAILS_PAGE:
|
||||
self.__config.set_guest_name(self.__guest_name.value())
|
||||
self.__config.set_install_type(self.__install_type.getSelection())
|
||||
elif page is LOCAL_INSTALL_PAGE:
|
||||
self.__config.set_use_cdrom_source(self.__install_source.getSelection() == DomainConfig.INSTALL_SOURCE_CDROM)
|
||||
elif page is SELECT_CDROM_PAGE:
|
||||
self.__config.set_install_media(self.__install_media.getSelection())
|
||||
elif page is SELECT_ISO_PAGE:
|
||||
self.__config.set_iso_path(self.__iso_path.value())
|
||||
elif page is NETWORK_INSTALL_PAGE:
|
||||
self.__config.set_install_url(self.__install_url.value())
|
||||
self.__config.set_kickstart_url(self.__kickstart_url.value())
|
||||
self.__config.set_kernel_options(self.__kernel_options.value())
|
||||
elif page is OS_TYPE_PAGE:
|
||||
self.__config.set_os_type(self.__os_types.getSelection())
|
||||
elif page is OS_VARIANT_PAGE:
|
||||
self.__config.set_os_variant(self.__os_variants.getSelection())
|
||||
elif page is RAM_CPU_PAGE:
|
||||
self.__config.set_memory(int(self.__memory.value()))
|
||||
self.__config.set_cpus(int(self.__cpus.value()))
|
||||
elif page is ENABLE_STORAGE_PAGE:
|
||||
self.__config.set_enable_storage(self.__enable_storage.value())
|
||||
if self.__storage_type.getSelection() == DomainConfig.NEW_STORAGE:
|
||||
self.__config.set_use_local_storage(True)
|
||||
elif self.__storage_type.getSelection() == DomainConfig.EXISTING_STORAGE:
|
||||
self.__config.set_use_local_storage(False)
|
||||
elif page is LOCAL_STORAGE_PAGE:
|
||||
self.__config.set_storage_size(float(self.__storage_size.value()))
|
||||
self.__config.set_allocate_storage(self.__allocate_storage.value())
|
||||
elif page is SELECT_POOL_PAGE:
|
||||
self.__config.set_use_local_storage(False)
|
||||
self.__config.set_storage_pool(self.__storage_pool.getSelection())
|
||||
elif page is SELECT_VOLUME_PAGE:
|
||||
self.__config.set_storage_volume(self.__storage_volume.getSelection())
|
||||
volume = self.get_libvirt().get_storage_volume(self.__config.get_storage_pool(),
|
||||
self.__config.get_storage_volume())
|
||||
self.__config.set_storage_size(volume.info()[1] / 1024.0 ** 3)
|
||||
elif page is BRIDGE_PAGE:
|
||||
self.__config.set_network_bridge(self.__network_bridges.getSelection())
|
||||
elif page is VIRT_DETAILS_PAGE:
|
||||
self.__config.set_virt_type(self.__virt_types.getSelection())
|
||||
self.__config.set_architecture(self.__architectures.getSelection())
|
||||
elif page is CONFIRM_PAGE:
|
||||
self.get_libvirt().define_domain(self.__config, CreateMeter())
|
||||
self.set_finished()
|
||||
|
||||
def get_back_page(self, page):
|
||||
result = page
|
||||
if page is OS_TYPE_PAGE:
|
||||
install_type = self.__config.get_install_type()
|
||||
if install_type == DomainConfig.LOCAL_INSTALL:
|
||||
if self.__config.get_use_cdrom_source():
|
||||
result = SELECT_CDROM_PAGE
|
||||
else:
|
||||
result = SELECT_ISO_PAGE
|
||||
elif install_type == DomainConfig.NETWORK_INSTALL:
|
||||
result = NETWORK_INSTALL_PAGE
|
||||
elif install_type == DomainConfig.PXE_INSTALL:
|
||||
result = VM_DETAILS_PAGE
|
||||
elif page is LOCAL_STORAGE_PAGE or page is SELECT_VOLUME_PAGE:
|
||||
result = ENABLE_STORAGE_PAGE
|
||||
elif page is SELECT_POOL_PAGE:
|
||||
result = ENABLE_STORAGE_PAGE
|
||||
elif page is NETWORK_INSTALL_PAGE:
|
||||
result = VM_DETAILS_PAGE
|
||||
elif page is SELECT_CDROM_PAGE or page == SELECT_ISO_PAGE:
|
||||
result = LOCAL_INSTALL_PAGE
|
||||
elif page is BRIDGE_PAGE:
|
||||
if self.__config.get_use_local_storage():
|
||||
result = LOCAL_STORAGE_PAGE
|
||||
else:
|
||||
result = SELECT_VOLUME_PAGE
|
||||
else:
|
||||
if page > 1: result = page - 1
|
||||
return result
|
||||
|
||||
def get_next_page(self, page):
|
||||
result = page
|
||||
if page is VM_DETAILS_PAGE:
|
||||
install_type = self.__config.get_install_type()
|
||||
if install_type == DomainConfig.LOCAL_INSTALL:
|
||||
result = LOCAL_INSTALL_PAGE
|
||||
elif install_type == DomainConfig.NETWORK_INSTALL:
|
||||
result = NETWORK_INSTALL_PAGE
|
||||
elif install_type == DomainConfig.PXE_INSTALL:
|
||||
result = OS_TYPE_PAGE
|
||||
elif page is LOCAL_INSTALL_PAGE:
|
||||
if self.__config.get_use_cdrom_source():
|
||||
result = SELECT_CDROM_PAGE
|
||||
else:
|
||||
result = SELECT_ISO_PAGE
|
||||
elif page is SELECT_CDROM_PAGE or page == SELECT_ISO_PAGE:
|
||||
result = OS_TYPE_PAGE
|
||||
elif page is NETWORK_INSTALL_PAGE:
|
||||
result = OS_TYPE_PAGE
|
||||
elif page is ENABLE_STORAGE_PAGE:
|
||||
result = BRIDGE_PAGE
|
||||
if self.__config.get_enable_storage():
|
||||
if self.__config.get_use_local_storage():
|
||||
result = LOCAL_STORAGE_PAGE
|
||||
else:
|
||||
result = SELECT_POOL_PAGE
|
||||
elif page is LOCAL_STORAGE_PAGE:
|
||||
result = BRIDGE_PAGE
|
||||
else:
|
||||
result = page + 1
|
||||
return result
|
||||
|
||||
def page_has_finish(self, page):
|
||||
if page is CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is SELECT_POOL_PAGE: return self.__has_pools
|
||||
elif page is SELECT_VOLUME_PAGE: return self.__has_volumes
|
||||
elif 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)",
|
||||
DomainConfig.LOCAL_INSTALL,
|
||||
self.__config.is_install_type(DomainConfig.LOCAL_INSTALL)),
|
||||
("Network Install (HTTP, FTP, or NFS)",
|
||||
DomainConfig.NETWORK_INSTALL,
|
||||
self.__config.is_install_type(DomainConfig.NETWORK_INSTALL)),
|
||||
("Network Boot (PXE)",
|
||||
DomainConfig.PXE_INSTALL,
|
||||
self.__config.is_install_type(DomainConfig.PXE_INSTALL))))
|
||||
grid = Grid(2,3)
|
||||
grid.setField(Label("Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__guest_name, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Choose how you would like to install the operating system"), 1, 1,
|
||||
anchorLeft = 1, anchorTop = 1)
|
||||
grid.setField(self.__install_type, 1, 2, anchorLeft = 1)
|
||||
return [Label("Enter your machine details"),
|
||||
grid]
|
||||
|
||||
def get_local_install_page(self, screen):
|
||||
self.__install_source = RadioBar(screen, (("Use CDROM or DVD",
|
||||
DomainConfig.INSTALL_SOURCE_CDROM,
|
||||
self.__config.get_use_cdrom_source()),
|
||||
("Use ISO image",
|
||||
DomainConfig.INSTALL_SOURCE_ISO,
|
||||
self.__config.get_use_cdrom_source() is False)))
|
||||
grid = Grid(1,1)
|
||||
grid.setField(self.__install_source, 0, 0, anchorLeft = 1)
|
||||
return [Label("Locate your install media"),
|
||||
grid]
|
||||
|
||||
def get_select_cdrom_page(self, screen):
|
||||
drives = []
|
||||
media = self.get_hal().list_installable_volumes()
|
||||
for drive in media.keys():
|
||||
drives.append([media[drive], drive, self.__config.is_install_media(drive)])
|
||||
self.__install_media = RadioBar(screen, (drives))
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__install_media, 0, 0)
|
||||
return [Label("Select the install media"),
|
||||
grid]
|
||||
|
||||
def get_select_iso_page(self, screen):
|
||||
self.__iso_path = Entry(50, self.__config.get_iso_path())
|
||||
grid = Grid(1, 2)
|
||||
grid.setField(Label("Enter ISO path:"), 0, 0, anchorLeft = 1)
|
||||
grid.setField(self.__iso_path, 0, 1, anchorLeft = 1)
|
||||
return [Label("Enter the full path to an install ISO"),
|
||||
grid]
|
||||
|
||||
def get_network_install_page(self, screen):
|
||||
self.__install_url = Entry(50, self.__config.get_install_url())
|
||||
self.__kickstart_url = Entry(50, self.__config.get_kickstart_url())
|
||||
self.__kernel_options = Entry(50, self.__config.get_kernel_options())
|
||||
grid = Grid(2,3)
|
||||
grid.setField(Label("URL:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__install_url, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Kickstart URL:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(self.__kickstart_url, 1, 1, anchorLeft = 1)
|
||||
grid.setField(Label("Kernel Options:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(self.__kernel_options, 1, 2, anchorLeft = 1)
|
||||
return [Label("Provide the operating system URL"),
|
||||
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(1, 1)
|
||||
grid.setField(self.__os_types, 0, 0, anchorLeft = 1)
|
||||
return [Label("Choose the operating system type"),
|
||||
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(1, 1)
|
||||
grid.setField(self.__os_variants, 0, 0, anchorLeft = 1)
|
||||
return [Label("Choose the operating system version"),
|
||||
grid]
|
||||
|
||||
def get_ram_and_cpu_page(self, screen):
|
||||
self.__memory = Entry(10, str(self.__config.get_memory()))
|
||||
self.__cpus = Entry(10, str(self.__config.get_cpus()))
|
||||
grid = Grid(2,2)
|
||||
grid.setField(Label("Memory (RAM):"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__memory, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("CPUs:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(self.__cpus, 1, 1, anchorLeft = 1)
|
||||
return [Label("Choose memory and CPU settings"),
|
||||
grid]
|
||||
|
||||
def get_enable_storage_page(self, screen):
|
||||
self.__enable_storage = Checkbox("Enable storage for this virtual machine", self.__config.get_enable_storage())
|
||||
self.__storage_type = RadioBar(screen,((["Create a disk image on the computer's hard disk",
|
||||
DomainConfig.NEW_STORAGE,
|
||||
self.__config.get_use_local_storage()]),
|
||||
(["Select managed or other existing storage",
|
||||
DomainConfig.EXISTING_STORAGE,
|
||||
self.__config.get_use_local_storage() is False])))
|
||||
grid = Grid(1,2)
|
||||
grid.setField(self.__enable_storage, 0, 0, anchorLeft = 1)
|
||||
grid.setField(self.__storage_type, 0, 1, anchorLeft = 1)
|
||||
return [Label("Configure storage"),
|
||||
grid]
|
||||
|
||||
def get_local_storage_page(self, screen):
|
||||
self.__storage_size = Entry(6, str(self.__config.get_storage_size()))
|
||||
self.__allocate_storage = Checkbox("Allocate entire disk now", self.__config.get_allocate_storage())
|
||||
grid = Grid(2, 2)
|
||||
grid.setField(self.__allocate_storage, 0, 0, growx = 1, anchorLeft = 1)
|
||||
grid.setField(Label("Storage size (GB):"), 0, 1, anchorLeft = 1)
|
||||
grid.setField(self.__storage_size, 1, 1)
|
||||
return [Label("Configure local storage"),
|
||||
grid]
|
||||
|
||||
def get_select_pool_page(self, screen):
|
||||
pools = []
|
||||
for pool in self.get_libvirt().list_storage_pools():
|
||||
pools.append([pool, pool, pool == self.__config.get_storage_pool()])
|
||||
if len(pools) > 0:
|
||||
self.__storage_pool = RadioBar(screen, (pools))
|
||||
grid = Grid(2, 1)
|
||||
grid.setField(Label("Storage pool:"), 0, 0, anchorTop = 1)
|
||||
grid.setField(self.__storage_pool, 1, 0)
|
||||
self.__has_pools = True
|
||||
else:
|
||||
grid = Label("There are no storage pools available.")
|
||||
self.__has_pools = False
|
||||
return [Label("Configure Managed Storage: Select A Pool"),
|
||||
grid]
|
||||
|
||||
def get_select_volume_page(self, screen):
|
||||
volumes = []
|
||||
for volume in self.get_libvirt().list_storage_volumes(self.__config.get_storage_pool()):
|
||||
volumes.append([volume, volume, volume == self.__config.get_storage_volume()])
|
||||
if len(volumes) > 0:
|
||||
self.__storage_volume = RadioBar(screen, (volumes))
|
||||
grid = Grid(2, 1)
|
||||
grid.setField(Label("Storage volumes:"), 0, 0, anchorTop = 1)
|
||||
grid.setField(self.__storage_volume, 1, 0)
|
||||
self.__has_volumes = True
|
||||
else:
|
||||
grid = Label("This storage pool has no defined volumes.")
|
||||
self.__has_volumes = False
|
||||
return [Label("Configure Managed Storage: Select A Volume"),
|
||||
grid]
|
||||
|
||||
def get_bridge_page(self, screen):
|
||||
bridges = []
|
||||
for bridge in self.get_libvirt().list_bridges():
|
||||
bridges.append(["Virtual network '%s'" % bridge.name(), bridge.name(), self.__config.get_network_bridge() is bridge.name()])
|
||||
self.__network_bridges = RadioBar(screen, (bridges))
|
||||
if self.__config.get_mac_address() is None:
|
||||
self.__config.set_mac_address(self.get_libvirt().generate_mac_address())
|
||||
self.__mac_address = Entry(20, self.__config.get_mac_address())
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__network_bridges, 0, 0)
|
||||
return [Label("Select an existing bridge"),
|
||||
grid]
|
||||
|
||||
def get_virt_details_page(self, screen):
|
||||
virt_types = []
|
||||
for type in self.get_libvirt().list_virt_types():
|
||||
virt_types.append([type, type, self.__config.is_virt_type(type)])
|
||||
self.__virt_types = RadioBar(screen, (virt_types))
|
||||
archs = []
|
||||
for arch in self.get_libvirt().list_architectures():
|
||||
archs.append([arch, arch, self.__config.is_architecture(arch)])
|
||||
self.__architectures = RadioBar(screen, (archs))
|
||||
grid = Grid(2, 2)
|
||||
grid.setField(Label("Virt Type:"), 0, 0, anchorRight = 1, anchorTop = 1)
|
||||
grid.setField(self.__virt_types, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Architecture:"), 0, 1, anchorRight = 1, anchorTop = 1)
|
||||
grid.setField(self.__architectures, 1, 1, anchorLeft = 1)
|
||||
return [Label("Configure virtualization details"),
|
||||
grid]
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
grid = Grid(2, 6)
|
||||
grid.setField(Label("OS:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label(Guest.get_os_variant_label(self.__config.get_os_type(),
|
||||
self.__config.get_os_variant())), 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Install:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_install_type_text()), 1, 1, anchorLeft = 1)
|
||||
grid.setField(Label("Memory:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(Label("%s MB" % self.__config.get_memory()), 1, 2, anchorLeft = 1)
|
||||
grid.setField(Label("CPUs:"), 0, 3, anchorRight = 1)
|
||||
grid.setField(Label("%d" % self.__config.get_cpus()), 1, 3, anchorLeft = 1)
|
||||
grid.setField(Label("Storage:"), 0, 4, anchorRight = 1)
|
||||
grid.setField(Label("%s (on %s)" % (self.__config.get_storage_volume(),
|
||||
self.__config.get_storage_pool())),
|
||||
1, 4, anchorLeft = 1)
|
||||
grid.setField(Label("Network:"), 0, 5, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_network_bridge()), 1, 5, anchorLeft = 1)
|
||||
return [Label("Ready to begin installation of %s" % self.__config.get_guest_name()),
|
||||
grid]
|
||||
|
||||
def AddDomain():
|
||||
screen = DomainConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,135 @@
|
|||
# addhost.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
DETAILS_PAGE = 1
|
||||
CONFIRM_PAGE = 2
|
||||
|
||||
HYPERVISOR_XEN = "xen"
|
||||
HYPERVISOR_KVM = "kvm"
|
||||
|
||||
HYPERVISORS = {HYPERVISOR_XEN : "Xen",
|
||||
HYPERVISOR_KVM : "QEMU/KVM"}
|
||||
|
||||
CONNECTION_LOCAL = "local"
|
||||
CONNECTION_KERBEROS = "kerberos"
|
||||
CONNECTION_SSL = "ssl"
|
||||
CONNECTION_SSH = "ssh"
|
||||
|
||||
CONNECTIONS = {CONNECTION_LOCAL : "Local",
|
||||
CONNECTION_KERBEROS : "Remote Password or Kerberos",
|
||||
CONNECTION_SSL : "Remote SSL/TLS with x509 certificate",
|
||||
CONNECTION_SSH : "Remote tunnel over SSH"}
|
||||
|
||||
class AddHostConfigScreen(ConfigScreen):
|
||||
def __init__(self):
|
||||
ConfigScreen.__init__(self, "Add A Remote Host")
|
||||
self.__configured = False
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is DETAILS_PAGE: return self.get_details_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
return page < CONFIRM_PAGE
|
||||
|
||||
def page_has_back(self, page):
|
||||
return page > DETAILS_PAGE
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is DETAILS_PAGE:
|
||||
if self.__connection.getSelection() is CONNECTION_LOCAL:
|
||||
return True
|
||||
elif len(self.__hostname.value()) > 0:
|
||||
return True
|
||||
else:
|
||||
errors.append("You must enter a remote hostname.")
|
||||
elif page is CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONFIRM_PAGE:
|
||||
hv = self.__hypervisor.getSelection()
|
||||
conn = self.__connection.getSelection()
|
||||
hostname = self.__hostname.value()
|
||||
|
||||
if hv is HYPERVISOR_XEN:
|
||||
if conn is CONNECTION_LOCAL: url = "xen:///"
|
||||
elif conn is CONNECTION_KERBEROS: url = "xen+tcp:///" + hostname + "/"
|
||||
elif conn is CONNECTION_SSL: url = "xen+tls:///" + hostname + "/"
|
||||
elif conn is CONNECTION_SSH: url = "xen+ssh:///" + hostname + "/"
|
||||
elif hv is HYPERVISOR_KVM:
|
||||
if conn is CONNECTION_LOCAL: url = "qemu:///system"
|
||||
elif conn is CONNECTION_KERBEROS: url = "qemu+tcp://" + hostname + "/system"
|
||||
elif conn is CONNECTION_SSL: url = "qemu+tls://" + hostname + "/system"
|
||||
elif conn is CONNECTION_SSH: url = "qemu+ssh://" + hostname + "/system"
|
||||
|
||||
self.get_virt_manager_config().add_connection(url)
|
||||
self.set_finished()
|
||||
|
||||
def get_details_page(self, screen):
|
||||
if not self.__configured:
|
||||
self.__hypervisor = RadioBar(screen, ((HYPERVISORS[HYPERVISOR_XEN], HYPERVISOR_XEN, True),
|
||||
(HYPERVISORS[HYPERVISOR_KVM], HYPERVISOR_KVM, False)))
|
||||
self.__connection = RadioBar(screen, ((CONNECTIONS[CONNECTION_LOCAL], CONNECTION_LOCAL, True),
|
||||
(CONNECTIONS[CONNECTION_KERBEROS], CONNECTION_KERBEROS, False),
|
||||
(CONNECTIONS[CONNECTION_SSL], CONNECTION_SSL, False),
|
||||
(CONNECTIONS[CONNECTION_SSH], CONNECTION_SSH, False)))
|
||||
self.__hostname = Entry(50, "")
|
||||
self.__autoconnect = Checkbox("Autoconnect on Startup")
|
||||
self.__configured = True
|
||||
grid = Grid(2, 4)
|
||||
grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1, anchorTop = 1)
|
||||
grid.setField(self.__hypervisor, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Connection:"), 0, 1, anchorRight = 1, anchorTop = 1)
|
||||
grid.setField(self.__connection, 1, 1, anchorLeft = 1)
|
||||
grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(self.__hostname, 1, 2, anchorLeft = 1)
|
||||
grid.setField(Label(""), 0, 3, anchorRight = 1)
|
||||
grid.setField(self.__autoconnect, 1, 3, anchorLeft = 1)
|
||||
return [Label("Add Connection"),
|
||||
grid]
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
grid = Grid(2, 4)
|
||||
grid.setField(Label("Hypervisor:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label(HYPERVISORS[self.__hypervisor.getSelection()]), 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Connection:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(Label(CONNECTIONS[self.__connection.getSelection()]), 1, 1, anchorLeft = 1)
|
||||
if self.__connection.getSelection() is not CONNECTION_LOCAL:
|
||||
hostname = self.__hostname.value()
|
||||
else:
|
||||
hostname = "local"
|
||||
grid.setField(Label("Hostname:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(Label(hostname), 1, 2, anchorLeft = 1)
|
||||
grid.setField(Label("Autoconnect on Startup:"), 0, 3, anchorRight = 1)
|
||||
label = "Yes"
|
||||
if not self.__autoconnect.value(): label = "No"
|
||||
grid.setField(Label(label), 1, 3, anchorLeft = 1)
|
||||
return [Label("Confirm Connection"),
|
||||
grid]
|
||||
|
||||
def AddHost():
|
||||
screen = AddHostConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,187 @@
|
|||
# addstorage.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
import utils
|
||||
|
||||
from configscreen import *
|
||||
from poolconfig import PoolConfig
|
||||
from virtinst import Storage
|
||||
|
||||
POOL_NAME_PAGE = 1
|
||||
POOL_DETAILS_PAGE = 2
|
||||
CONFIRM_PAGE = 3
|
||||
|
||||
class AddStoragePoolConfigScreen(ConfigScreen):
|
||||
def __init__(self):
|
||||
ConfigScreen.__init__(self, "Add A Storage Pool")
|
||||
self.__config = PoolConfig(self.get_libvirt())
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is POOL_NAME_PAGE: return self.get_pool_name_page(screen)
|
||||
elif page is POOL_DETAILS_PAGE: return self.get_pool_details_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
return page < CONFIRM_PAGE
|
||||
|
||||
def page_has_back(self, page):
|
||||
return page > POOL_NAME_PAGE
|
||||
|
||||
return page > POOL_NAME_PAGE
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is POOL_NAME_PAGE:
|
||||
if utils.string_is_not_blank(self.__name.value()):
|
||||
if self.get_libvirt().storage_pool_exists(self.__name.value()):
|
||||
errors.append("Name '%s' already in use by another pool." % self.__name.value())
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
errors.append("Storage object name must be a string between 0 and 50 characters.")
|
||||
elif page is POOL_DETAILS_PAGE:
|
||||
result = True
|
||||
if self.__config.needs_target_path():
|
||||
if utils.string_is_not_blank(self.__target_path.value()):
|
||||
if self.__target_path.value()[0:1] is not '/':
|
||||
errors.append("'%s' is not an absolute path." % self.__target_path.value())
|
||||
result = False
|
||||
else:
|
||||
errors.append("You must enter a target path.")
|
||||
result = False
|
||||
if self.__config.needs_format():
|
||||
if self.__formats.getSelection() is None:
|
||||
errors.append("You must select a pool format.")
|
||||
result = False
|
||||
if self.__config.needs_hostname():
|
||||
if not utils.string_is_not_blank(self.__hostname.value()):
|
||||
errors.append("You must enter a hostname.")
|
||||
result = False
|
||||
if self.__config.needs_source_path():
|
||||
if utils.string_is_not_blank(self.__source_path.value()):
|
||||
if self.__config.source_must_be_absolute():
|
||||
if self.__source_path.value()[0:1] is not '/':
|
||||
errors.append("'%s' is not an absolute path." % self.__source_path.value())
|
||||
result = False
|
||||
else:
|
||||
errors.append("you must enter a source path.")
|
||||
result = False
|
||||
return result
|
||||
elif page is CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is POOL_NAME_PAGE:
|
||||
self.__config.set_name(self.__name.value())
|
||||
self.__config.set_type(self.__type.getSelection())
|
||||
#self._reset_flags(self.__type.current())
|
||||
elif page is POOL_DETAILS_PAGE:
|
||||
if self.__config.needs_target_path():
|
||||
self.__config.set_target_path(self.__target_path.value())
|
||||
if self.__config.needs_format():
|
||||
self.__config.set_format(self.__formats.getSelection())
|
||||
if self.__config.needs_hostname():
|
||||
self.__config.set_hostname(self.__hostname.value())
|
||||
if self.__config.needs_source_path():
|
||||
self.__config.set_source_path(self.__source_path.value())
|
||||
if self.__config.needs_build_pool():
|
||||
self.__config.set_build_pool(self.__build_pool.value())
|
||||
elif page is CONFIRM_PAGE:
|
||||
self.get_libvirt().define_storage_pool(self.__config.get_name(), config = self.__config)
|
||||
self.get_libvirt().create_storage_pool(self.__config.get_name())
|
||||
self.set_finished()
|
||||
|
||||
def get_pool_name_page(self, screen):
|
||||
self.__name = Entry(50, self.__config.get_name())
|
||||
pooltypes = []
|
||||
for pooltype in Storage.StoragePool.get_pool_types():
|
||||
pooltypes.append(["%s: %s" % (pooltype, Storage.StoragePool.get_pool_type_desc(pooltype)),
|
||||
pooltype,
|
||||
self.__config.get_type() is pooltype])
|
||||
self.__type = RadioBar(screen, pooltypes)
|
||||
grid = Grid(2, 2)
|
||||
grid.setField(Label("Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__name, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Type:"), 0, 1, anchorRight = 1, anchorTop = 1)
|
||||
grid.setField(self.__type, 1, 1, anchorLeft = 1)
|
||||
return [Label("Add Storage Pool"),
|
||||
grid]
|
||||
|
||||
def get_pool_details_page(self, screen):
|
||||
rows = 0
|
||||
if self.__config.needs_target_path():
|
||||
self.__target_path = Entry(50, self.__config.get_target_path())
|
||||
rows += 1
|
||||
if self.__config.needs_format():
|
||||
formats = []
|
||||
for format in self.__config.get_formats():
|
||||
formats.append([format, format, format is self.__config.get_format()])
|
||||
self.__formats = RadioBar(screen, formats)
|
||||
rows += 1
|
||||
if self.__config.needs_hostname():
|
||||
self.__hostname = Entry(50, self.__config.get_hostname())
|
||||
rows += 1
|
||||
if self.__config.needs_source_path():
|
||||
self.__source_path = Entry(50, self.__config.get_source_path())
|
||||
rows += 1
|
||||
if self.__config.needs_build_pool():
|
||||
self.__build_pool = Checkbox("Build Pool", self.__config.get_build_pool())
|
||||
rows += 1
|
||||
self.__build_pool = Checkbox("Build Pool", self.__config.get_build_pool())
|
||||
rows += 1
|
||||
grid = Grid(2, rows)
|
||||
currentrow = 0
|
||||
if self.__config.needs_target_path():
|
||||
grid.setField(Label("Target Path:"), 0, currentrow, anchorRight = 1)
|
||||
grid.setField(self.__target_path, 1, currentrow, anchorLeft = 1)
|
||||
currentrow += 1
|
||||
if self.__config.needs_format():
|
||||
grid.setField(Label("Format:"), 0, currentrow, anchorRight = 1, anchorTop = 1)
|
||||
grid.setField(self.__formats, 1, currentrow, anchorLeft = 1)
|
||||
currentrow += 1
|
||||
if self.__config.needs_hostname():
|
||||
grid.setField(Label("Host Name:"), 0, currentrow, anchorRight = 1)
|
||||
grid.setField(self.__hostname, 1, currentrow, anchorRight = 1)
|
||||
currentrow += 1
|
||||
if self.__config.needs_source_path():
|
||||
grid.setField(Label("Source Path:"), 0, currentrow, anchorRight = 1)
|
||||
grid.setField(self.__source_path, 1, currentrow, anchorLeft = 1)
|
||||
currentrow += 1
|
||||
if self.__config.needs_build_pool():
|
||||
grid.setField(Label(" "), 0, currentrow, anchorRight = 1)
|
||||
grid.setField(self.__build_pool, 1, currentrow, anchorLeft = 1)
|
||||
currentrow += 1
|
||||
return [Label("Specify a storage location to be later split into virtual machine storage"),
|
||||
grid]
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
grid = Grid(2, 2)
|
||||
grid.setField(Label("Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_name()), 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Target Path:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_target_path()), 1, 1, anchorLeft = 1)
|
||||
return [Label("Confirm Pool Details"),
|
||||
grid]
|
||||
|
||||
def AddStoragePool():
|
||||
screen = AddStoragePoolConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,178 @@
|
|||
# addvolume.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
from createmeter import CreateMeter
|
||||
from configscreen import *
|
||||
from volumeconfig import StorageVolumeConfig
|
||||
from utils import *
|
||||
|
||||
SELECT_POOL_PAGE = 1
|
||||
VOLUME_NAME_PAGE = 2
|
||||
VOLUME_FORMAT_PAGE = 3
|
||||
MAX_CAPACITY_PAGE = 4
|
||||
CONFIRM_PAGE = 5
|
||||
|
||||
class AddVolumeConfigScreen(StorageListConfigScreen):
|
||||
def __init__(self):
|
||||
StorageListConfigScreen.__init__(self, "Add A New Storage Volume")
|
||||
self.__config = StorageVolumeConfig()
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is SELECT_POOL_PAGE: return self.get_storage_pool_list_page(screen)
|
||||
elif page is VOLUME_NAME_PAGE: return self.get_volume_name_page(screen)
|
||||
elif page is VOLUME_FORMAT_PAGE: return self.get_volume_format_page(screen)
|
||||
elif page is MAX_CAPACITY_PAGE: return self.get_max_capacity_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is SELECT_POOL_PAGE:
|
||||
return self.has_selectable_pools()
|
||||
else:
|
||||
if page < CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page > SELECT_POOL_PAGE: return True
|
||||
return False
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_PAGE
|
||||
|
||||
def get_next_page(self, page):
|
||||
if page is VOLUME_NAME_PAGE:
|
||||
if self.__config.needs_format():
|
||||
return VOLUME_FORMAT_PAGE
|
||||
else:
|
||||
return MAX_CAPACITY_PAGE
|
||||
return StorageListConfigScreen.get_next_page(self, page)
|
||||
|
||||
def get_back_page(self, page):
|
||||
if page is MAX_CAPACITY_PAGE:
|
||||
if self.__config.needs_format():
|
||||
return VOLUME_FORMAT_PATH
|
||||
else:
|
||||
return VOLUME_NAME_PAGE
|
||||
return StorageListConfigScreen.get_back_page(self, page)
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is SELECT_POOL_PAGE:
|
||||
if self.get_selected_pool() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("You must select a storage pool.")
|
||||
elif page is VOLUME_NAME_PAGE:
|
||||
if string_is_not_blank(self.__name.value()):
|
||||
return True
|
||||
else:
|
||||
errors.append("Storage object name can only contain alphanumeric, '_', '.', or '-' characters.")
|
||||
elif page is VOLUME_FORMAT_PAGE:
|
||||
if self.__formats.current() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("You must select a volume format.")
|
||||
elif page is MAX_CAPACITY_PAGE:
|
||||
if string_is_not_blank(self.__capacity.value()):
|
||||
if string_is_not_blank(self.__allocation.value()):
|
||||
capacity = int(self.__capacity.value())
|
||||
allocation = int(self.__allocation.value())
|
||||
if capacity > 0:
|
||||
if capacity <= self.__config.get_pool().info()[3] / 1024**2:
|
||||
if allocation >= 0:
|
||||
if allocation <= capacity:
|
||||
return True
|
||||
else:
|
||||
errors.append("Allocation cannot exceed the maximum capacity.")
|
||||
else:
|
||||
errors.append("The allocation must be greater than or equal to 0.")
|
||||
else:
|
||||
errors.append("The maximum capacity cannot exceed the storage pool size.")
|
||||
else:
|
||||
errors.append("The capacity must be greater than zero.")
|
||||
else:
|
||||
errors.append("An allocation value must be entered.")
|
||||
else:
|
||||
errors.append("A maximum volume capacity must be entered.")
|
||||
elif page is CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is SELECT_POOL_PAGE:
|
||||
self.__config.set_pool(self.get_libvirt().get_storage_pool(self.get_selected_pool()))
|
||||
elif page is VOLUME_NAME_PAGE:
|
||||
self.__config.set_name(self.__name.value())
|
||||
elif page is VOLUME_FORMAT_PAGE:
|
||||
self.__config.set_format(self.__formats.current())
|
||||
elif page is MAX_CAPACITY_PAGE:
|
||||
self.__config.set_max_capacity(int(self.__capacity.value()))
|
||||
self.__config.set_allocation(int(self.__allocation.value()))
|
||||
elif page is CONFIRM_PAGE:
|
||||
self.get_libvirt().define_storage_volume(self.__config, CreateMeter())
|
||||
self.set_finished()
|
||||
|
||||
def get_volume_name_page(self, screen):
|
||||
self.__name = Entry(50, self.__config.get_name())
|
||||
grid = Grid(2, 1)
|
||||
grid.setField(Label("Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__name, 1, 0, anchorLeft = 1)
|
||||
return [Label("New Storage Volume"),
|
||||
grid,
|
||||
Label("Name of the volume to create. File extension may be appended.")]
|
||||
|
||||
def get_volume_format_page(self, screen):
|
||||
self.__formats = Listbox(0)
|
||||
for format in self.__config.get_formats_for_pool():
|
||||
self.__formats.append(format, format)
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__formats, 0, 0)
|
||||
return [Label("Select The Volume Format"),
|
||||
grid]
|
||||
|
||||
def get_max_capacity_page(self, screen):
|
||||
self.__capacity = Entry(6, str(self.__config.get_max_capacity()))
|
||||
self.__allocation = Entry(6, str(self.__config.get_allocation()))
|
||||
grid = Grid(2, 2)
|
||||
grid.setField(Label("Max. Capacity (MB):"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__capacity, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Allocation (MB):"), 0, 1, anchorRight = 1)
|
||||
grid.setField(self.__allocation, 1, 1, anchorLeft = 1)
|
||||
return [Label("Storage Volume Quota"),
|
||||
Label("%s's available space: %s" % (self.__config.get_pool().name(),
|
||||
size_as_mb_or_gb(self.__config.get_pool().info()[3]))),
|
||||
grid]
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
grid = Grid(2, 5)
|
||||
grid.setField(Label("Volume Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label("%s (%s)" % (self.__config.get_name(), self.__config.get_pool().name())), 1, 0, anchorLeft = 1)
|
||||
if self.__config.needs_format():
|
||||
grid.setField(Label("Format:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_format()), 1, 1, anchorLeft = 1)
|
||||
# NOTE: here we multiply the sizes by 1024^2 since the size_as_mb_or_gb is expect bytes
|
||||
grid.setField(Label("Max. Capacity:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(Label("%s" % (size_as_mb_or_gb(self.__config.get_max_capacity() * 1024**2))), 1, 2, anchorLeft = 1)
|
||||
grid.setField(Label("Allocation:"), 0, 3, anchorRight = 1)
|
||||
grid.setField(Label("%s" % (size_as_mb_or_gb(self.__config.get_allocation() * 1024**2))), 1, 3, anchorLeft = 1)
|
||||
return [Label("Ready To Allocation New Storage Volume"),
|
||||
grid]
|
||||
|
||||
def AddStorageVolume():
|
||||
screen = AddVolumeConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,60 @@
|
|||
# changehost.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
|
||||
import logging
|
||||
import libvirtworker
|
||||
from configscreen import *
|
||||
|
||||
CONNECTION_LIST_PAGE = 1
|
||||
CONNECTED_PAGE = 2
|
||||
|
||||
class ChangeHostConfigScreen(HostListConfigScreen):
|
||||
def __init__(self):
|
||||
HostListConfigScreen.__init__(self, "")
|
||||
|
||||
def get_title(self):
|
||||
return "Currently: %s" % self.get_libvirt().get_url()
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is CONNECTION_LIST_PAGE: return self.get_connection_list_page(screen)
|
||||
elif page is CONNECTED_PAGE: return self.get_connected_page(screen)
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONNECTION_LIST_PAGE:
|
||||
logging.info("Changing libvirt connection to %s" % self.get_selected_connection())
|
||||
self.get_libvirt().open_connection(self.get_selected_connection())
|
||||
elif page is CONNECTED_PAGE: self.set_finished()
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is CONNECTION_LIST_PAGE: return self.has_selectable_connections()
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
return page > CONNECTION_LIST_PAGE
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONNECTED_PAGE
|
||||
|
||||
def get_connected_page(self, screen):
|
||||
return [Label("Connected to %s" % self.get_selected_connection())]
|
||||
|
||||
def ChangeHost():
|
||||
screen = ChangeHostConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,295 @@
|
|||
# configscreen.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 halworker import HALWorker
|
||||
from libvirtworker import *
|
||||
import traceback
|
||||
|
||||
BACK_BUTTON = "back"
|
||||
NEXT_BUTTON = "next"
|
||||
CANCEL_BUTTON = "cancel"
|
||||
FINISH_BUTTON = "finish"
|
||||
|
||||
class ConfigScreen:
|
||||
'''Enables the creation of navigable, multi-paged configuration screens.'''
|
||||
|
||||
def __init__(self, title):
|
||||
self.__title = title
|
||||
self.__current_page = 1
|
||||
self.__finished = False
|
||||
self.__hal = HALWorker()
|
||||
self.__libvirt = LibvirtWorker()
|
||||
self.__vm_config = VirtManagerConfig()
|
||||
|
||||
def get_title(self):
|
||||
return self.__title
|
||||
|
||||
def get_hal(self):
|
||||
return self.__hal
|
||||
|
||||
def get_libvirt(self):
|
||||
return self.__libvirt
|
||||
|
||||
def get_virt_manager_config(self):
|
||||
return self.__vm_config
|
||||
|
||||
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, errors):
|
||||
return True
|
||||
|
||||
def process_input(self, page):
|
||||
return
|
||||
|
||||
def get_page_list(self):
|
||||
return []
|
||||
|
||||
def get_current_page(self):
|
||||
0
|
||||
|
||||
def start(self):
|
||||
active = True
|
||||
while active and (self.__finished == False):
|
||||
screen = SnackScreen()
|
||||
elements = self.get_elements_for_page(screen, self.__current_page)
|
||||
# TODO: need to set the form height to the number of elements on the page
|
||||
gridform = GridForm(screen, self.get_title(), 2, 2)
|
||||
|
||||
# Here you would put the list of elements
|
||||
# and programmatically set the indicator as
|
||||
# they're rendered
|
||||
pages = self.get_page_list()
|
||||
if len(pages) > 0:
|
||||
leftmenu = Grid(2, len(pages))
|
||||
current_element = 0
|
||||
for page in pages:
|
||||
leftmenu.setField(Label(page), 0, current_element, anchorLeft = 1)
|
||||
indicator = " "
|
||||
if current_element == self.__current_page - 1:
|
||||
indicator = "<-"
|
||||
leftmenu.setField(Label(indicator), 1, current_element)
|
||||
current_element += 1
|
||||
gridform.add(leftmenu, 0, 0, anchorTop = 1, padding = (3, 0, 3, 0))
|
||||
|
||||
content = Grid(1, len(elements) + 1)
|
||||
current_element = 0
|
||||
for element in elements:
|
||||
content.setField(element, 0, current_element)
|
||||
current_element += 1
|
||||
# create the navigation buttons
|
||||
buttons = []
|
||||
if self.__current_page > 1: buttons.append(["Back", BACK_BUTTON, "F11"])
|
||||
if self.page_has_next(self.__current_page): buttons.append(["Next", NEXT_BUTTON, "F12"])
|
||||
if self.page_has_finish(self.__current_page): buttons.append(["Finish", FINISH_BUTTON, "F10"])
|
||||
buttons.append(["Cancel", CANCEL_BUTTON, "ESC"])
|
||||
buttonbar = ButtonBar(screen, buttons)
|
||||
content.setField(buttonbar, 0, current_element, growx = 1)
|
||||
gridform.add(content, 1, 0, anchorTop = 1)
|
||||
current_element += 1
|
||||
try:
|
||||
result = gridform.runOnce()
|
||||
pressed = buttonbar.buttonPressed(result)
|
||||
if pressed == BACK_BUTTON:
|
||||
self.go_back()
|
||||
elif pressed == NEXT_BUTTON or pressed == FINISH_BUTTON:
|
||||
errors = []
|
||||
if self.validate_input(self.__current_page, errors):
|
||||
self.process_input(self.__current_page)
|
||||
self.go_next()
|
||||
else:
|
||||
error_text = ""
|
||||
for error in errors:
|
||||
error_text += "%s\n" % error
|
||||
ButtonChoiceWindow(screen,
|
||||
"There Were Errors",
|
||||
error_text,
|
||||
buttons = ["OK"])
|
||||
elif pressed == CANCEL_BUTTON:
|
||||
active = False
|
||||
except Exception, error:
|
||||
ButtonChoiceWindow(screen,
|
||||
"An Exception Has Occurred",
|
||||
str(error) + "\n" + traceback.format_exc(),
|
||||
buttons = ["OK"])
|
||||
screen.popWindow()
|
||||
screen.finish()
|
||||
|
||||
class DomainListConfigScreen(ConfigScreen):
|
||||
'''Provides a base class for all config screens that require a domain list.'''
|
||||
|
||||
def __init__(self, title):
|
||||
ConfigScreen.__init__(self, title)
|
||||
|
||||
def get_domain_list_page(self, screen, defined=True, created=True):
|
||||
domains = self.get_libvirt().list_domains(defined, created)
|
||||
result = None
|
||||
|
||||
if len(domains) > 0:
|
||||
self.__has_domains = True
|
||||
self.__domain_list = Listbox(0)
|
||||
for name in domains:
|
||||
self.__domain_list.append(name, name)
|
||||
result = [self.__domain_list]
|
||||
else:
|
||||
self.__has_domains = False
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(Label("There are no domains available."), 0, 0)
|
||||
result = [grid]
|
||||
return result
|
||||
|
||||
def get_selected_domain(self):
|
||||
return self.__domain_list.current()
|
||||
|
||||
def has_selectable_domains(self):
|
||||
return self.__has_domains
|
||||
|
||||
class NetworkListConfigScreen(ConfigScreen):
|
||||
'''Provides a base class for all config screens that require a network list.'''
|
||||
|
||||
def __init__(self, title):
|
||||
ConfigScreen.__init__(self, title)
|
||||
|
||||
def get_network_list_page(self, screen, defined=True, created=True):
|
||||
networks = self.get_libvirt().list_networks(defined, created)
|
||||
result = None
|
||||
|
||||
if len(networks) > 0:
|
||||
self.__has_networks = True
|
||||
self.__network_list = Listbox(0)
|
||||
for name in networks:
|
||||
self.__network_list.append(name, name)
|
||||
result = self.__network_list
|
||||
else:
|
||||
self.__has_networks = False
|
||||
result = Label("There are no networks available.")
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(result, 0, 0)
|
||||
return [Label("Network List"),
|
||||
grid]
|
||||
|
||||
def get_selected_network(self):
|
||||
return self.__network_list.current()
|
||||
|
||||
def has_selectable_networks(self):
|
||||
return self.__has_networks
|
||||
|
||||
class StorageListConfigScreen(ConfigScreen):
|
||||
'''Provides a base class for any configuration screen that deals with storage pool lists.'''
|
||||
|
||||
def __init__(self, title):
|
||||
ConfigScreen.__init__(self, title)
|
||||
|
||||
def get_storage_pool_list_page(self, screen, defined=True, created=True):
|
||||
pools = self.get_libvirt().list_storage_pools(defined=defined, created=created)
|
||||
if len(pools) > 0:
|
||||
self.__has_pools = True
|
||||
self.__pools_list = Listbox(0)
|
||||
for pool in pools:
|
||||
self.__pools_list.append(pool, pool)
|
||||
result = self.__pools_list
|
||||
else:
|
||||
self.__has_pools = False
|
||||
result = Label("There are no storage pools available.")
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(result, 0, 0)
|
||||
return [Label("Storage Pool List"),
|
||||
grid]
|
||||
|
||||
def get_selected_pool(self):
|
||||
return self.__pools_list.current()
|
||||
|
||||
def has_selectable_pools(self):
|
||||
return self.__has_pools
|
||||
|
||||
def get_storage_volume_list_page(self, screen):
|
||||
'''Requires that self.__pools_list have a selected element.'''
|
||||
pool = self.get_libvirt().get_storage_pool(self.get_selected_pool())
|
||||
if len(pool.listVolumes()) > 0:
|
||||
self.__has_volumes = True
|
||||
self.__volumes_list = Listbox(0)
|
||||
for volname in pool.listVolumes():
|
||||
volume = pool.storageVolLookupByName(volname)
|
||||
self.__volumes_list.append("%s (%0.2f GB)" % (volume.name(), volume.info()[2] / 1024**3), volume.name())
|
||||
result = self.__volumes_list
|
||||
else:
|
||||
self.__has_volumes = False
|
||||
result = Label("There are no storage volumes available.")
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(result, 0, 0)
|
||||
return [Label("Storage Volume List"),
|
||||
grid]
|
||||
|
||||
def get_selected_volume(self):
|
||||
return self.__volumes_list.current()
|
||||
|
||||
def has_selectable_volumes(self):
|
||||
return self.__has_volumes
|
||||
|
||||
class HostListConfigScreen(ConfigScreen):
|
||||
'''Provides a base class for working with lists of libvirt hosts.'''
|
||||
|
||||
def __init__(self, title):
|
||||
ConfigScreen.__init__(self, title)
|
||||
|
||||
def get_connection_list_page(self, screen):
|
||||
connections = self.get_virt_manager_config().get_connection_list()
|
||||
result = None
|
||||
|
||||
if len(connections) > 0:
|
||||
self.__has_connections = True
|
||||
self.__connection_list = Listbox(0)
|
||||
for connection in connections:
|
||||
self.__connection_list.append(connection, connection)
|
||||
result = self.__connection_list
|
||||
else:
|
||||
self.__has_connections = False
|
||||
result = Label("There are no defined connections.")
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(result, 0, 0)
|
||||
return [Label("Host List"),
|
||||
grid]
|
||||
|
||||
def get_selected_connection(self):
|
||||
return self.__connection_list.current()
|
||||
|
||||
def has_selectable_connections(self):
|
||||
return self.__has_connections
|
|
@ -0,0 +1,30 @@
|
|||
# createmeter.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 urlgrabber.progress as progress
|
||||
import logging
|
||||
|
||||
class CreateMeter(progress.BaseMeter):
|
||||
def _do_start(self, now = None):
|
||||
logging.info("Starting...")
|
||||
|
||||
def _do_end(self, amount_read, now = None):
|
||||
logging.info("Ending: read=%d" % amount_read)
|
||||
|
||||
def _do_update(self, amount_read, now = None):
|
||||
logging.info("Update: read=%d" % amount_read)
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# createnetwork.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
LIST_PAGE = 1
|
||||
CREATE_PAGE = 2
|
||||
|
||||
class CreateNetworkConfigScreen(NetworkListConfigScreen):
|
||||
def __init__(self):
|
||||
NetworkListConfigScreen.__init__(self, "Create A Network")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_PAGE: return self.get_network_list_page(screen, created = False)
|
||||
elif page is CREATE_PAGE: return self.get_create_network_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is LIST_PAGE: return self.has_selectable_networks()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return (page is CREATE_PAGE)
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_PAGE:
|
||||
self.get_libvirt().create_network(self.get_selected_network())
|
||||
return True
|
||||
|
||||
def get_create_network_page(self, screen):
|
||||
return [Label("Network Started"),
|
||||
Label("%s was successfully started." % self.get_selected_network())]
|
||||
|
||||
def CreateNetwork():
|
||||
screen = CreateNetworkConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# createuser.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import ConfigScreen
|
||||
from userworker import UserWorker
|
||||
|
||||
import libuser
|
||||
|
||||
DETAILS_PAGE = 1
|
||||
CONFIRM_PAGE = 2
|
||||
|
||||
class CreateUserConfigScreen(ConfigScreen):
|
||||
def __init__(self):
|
||||
ConfigScreen.__init__(self, "Create A User Account")
|
||||
self.__username = None
|
||||
self.__useradmin = libuser.admin()
|
||||
self.__user_worker = UserWorker()
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is DETAILS_PAGE: return self.get_details_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is DETAILS_PAGE:
|
||||
if len(self.__username.value()) > 0:
|
||||
name = self.__username.value()
|
||||
if self.__useradmin.lookupUserByName(name) is None:
|
||||
if len(self.__password.value()) > 0:
|
||||
if self.__password.value() == self.__confirm.value():
|
||||
return True
|
||||
else:
|
||||
errors.append("Passwords do not match.")
|
||||
else:
|
||||
errors.append("You must enter a password.")
|
||||
else:
|
||||
errors.append("User %s already exists." % name)
|
||||
else:
|
||||
errors.append("You must enter a username.")
|
||||
self.__confirm.value()
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONFIRM_PAGE:
|
||||
self.__user_worker.create_user(self.__username.value(),
|
||||
self.__password.value(),
|
||||
"wheel" if self.__adminuser.value() else None)
|
||||
self.set_finished()
|
||||
|
||||
def page_has_next(self, page):
|
||||
return (page is DETAILS_PAGE)
|
||||
|
||||
def page_has_back(self, page):
|
||||
return (page is CONFIRM_PAGE)
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return (page is CONFIRM_PAGE)
|
||||
|
||||
def get_details_page(self, screen):
|
||||
if self.__username is None:
|
||||
self.__username = Entry(50, "")
|
||||
self.__password = Entry(50, "", password = 1)
|
||||
self.__confirm = Entry(50, "", password = 1)
|
||||
self.__adminuser = Checkbox("This user is an administrator", False)
|
||||
grid = Grid(2, 4)
|
||||
grid.setField(Label("Username:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__username, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Password:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(self.__password, 1, 1, anchorLeft = 1)
|
||||
grid.setField(Label("Confirm password:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(self.__confirm, 1, 2, anchorLeft = 1)
|
||||
grid.setField(Label(" "), 0, 3)
|
||||
grid.setField(self.__adminuser, 1, 3, anchorLeft = 1)
|
||||
return [Label("Enter The User Details"),
|
||||
grid]
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
grid = Grid(1, 2)
|
||||
grid.setField(Label("Username: %s" % self.__username.value()), 0, 0)
|
||||
admin_label = "is not"
|
||||
if self.__adminuser.value():
|
||||
admin_label = "is"
|
||||
grid.setField(Label("This user %s an administrator." % admin_label), 0, 1)
|
||||
return [Label("Create this user account?"),
|
||||
grid]
|
||||
|
||||
def CreateUser():
|
||||
screen = CreateUserConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,257 @@
|
|||
# definenet.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 IPy import IP
|
||||
import traceback
|
||||
import logging
|
||||
import re
|
||||
|
||||
from configscreen import ConfigScreen
|
||||
from networkconfig import NetworkConfig
|
||||
from utils import *
|
||||
|
||||
NETWORK_NAME_PAGE = 1
|
||||
IPV4_ADDRESS_PAGE = 2
|
||||
PUBLIC_NETWORK_ALERT_PAGE = 3
|
||||
NETWORK_DETAILS_PAGE = 4
|
||||
DHCP_RANGE_PAGE = 5
|
||||
NETWORK_TYPE_PAGE = 6
|
||||
SELECT_PHYSICAL_NETWORK_PAGE = 7
|
||||
SUMMARY_PAGE = 8
|
||||
|
||||
class DefineNetworkConfigScreen(ConfigScreen):
|
||||
def __init__(self):
|
||||
ConfigScreen.__init__(self, "Create A Virtual Network Interface")
|
||||
self.__config = NetworkConfig()
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is NETWORK_NAME_PAGE: return self.get_network_name_page(screen)
|
||||
elif page is IPV4_ADDRESS_PAGE: return self.get_ipv4_address_page(screen)
|
||||
elif page is PUBLIC_NETWORK_ALERT_PAGE: return self.get_public_network_alert_page(screen)
|
||||
elif page is NETWORK_DETAILS_PAGE: return self.get_network_details_page(screen)
|
||||
elif page is DHCP_RANGE_PAGE: return self.get_dhcp_range_page(screen)
|
||||
elif page is NETWORK_TYPE_PAGE: return self.get_network_type_page(screen)
|
||||
elif page is SELECT_PHYSICAL_NETWORK_PAGE: return self.get_select_physical_network_page(screen)
|
||||
elif page is SUMMARY_PAGE: return self.get_summary_page(screen)
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is NETWORK_NAME_PAGE:
|
||||
if len(self.__name.value()) > 0:
|
||||
if re.match("^[a-zA-Z0-9_]*$", self.__name.value()):
|
||||
return True
|
||||
else:
|
||||
errors.append("The network name can only contain letters, numbers and the underscore, and no spaces.")
|
||||
else:
|
||||
errors.append("Network name must be non-blank and less than 50 characters")
|
||||
elif page is IPV4_ADDRESS_PAGE:
|
||||
if len(self.__ipv4_address.value()) > 0:
|
||||
try:
|
||||
self.__config.set_ipv4_address(self.__ipv4_address.value())
|
||||
return True
|
||||
except Exception, error:
|
||||
errors.append("The network address could not be understood: %s" % str(error))
|
||||
else:
|
||||
errors.append("Network must be entered in the format 1.2.3.4/8")
|
||||
elif page is PUBLIC_NETWORK_ALERT_PAGE: return True
|
||||
elif page is NETWORK_DETAILS_PAGE: return True
|
||||
elif page is DHCP_RANGE_PAGE:
|
||||
try:
|
||||
if len(self.__start_address.value()) > 0 and len(self.__end_address.value()) > 0:
|
||||
start = IP(self.__start_address.value(), )
|
||||
end = IP(self.__end_address.value())
|
||||
if not self.__config.is_bad_address(start) and not self.__config.is_bad_address(end):
|
||||
return True
|
||||
else:
|
||||
errors.append("Start and/or end address are outside of the choosen network.")
|
||||
else:
|
||||
errors.append("Start and end address must be non-blank.")
|
||||
except Exception, error:
|
||||
logging.error(str(error))
|
||||
errors.append("The start and/or end addresses could not be understood.")
|
||||
elif page is NETWORK_TYPE_PAGE: return True
|
||||
elif page is SELECT_PHYSICAL_NETWORK_PAGE: return True
|
||||
elif page is SUMMARY_PAGE: return True
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is NETWORK_NAME_PAGE:
|
||||
self.__config.set_name(self.__name.value())
|
||||
elif page is DHCP_RANGE_PAGE:
|
||||
self.__config.set_ipv4_start_address(self.__start_address.value())
|
||||
self.__config.set_ipv4_end_address(self.__end_address.value())
|
||||
elif page is NETWORK_TYPE_PAGE:
|
||||
self.__config.set_isolated_network(self.__isolated_network.value())
|
||||
elif page is SELECT_PHYSICAL_NETWORK_PAGE:
|
||||
self.__config.set_physical_device(self.__physical_devices.getSelection())
|
||||
elif page is SUMMARY_PAGE:
|
||||
self.get_libvirt().define_network(self.__config)
|
||||
self.set_finished()
|
||||
|
||||
def get_next_page(self, page):
|
||||
if page is IPV4_ADDRESS_PAGE:
|
||||
if self.__config.is_public_ipv4_network():
|
||||
return PUBLIC_NETWORK_ALERT_PAGE
|
||||
else:
|
||||
return NETWORK_DETAILS_PAGE
|
||||
if page is NETWORK_TYPE_PAGE:
|
||||
if self.__config.is_isolated_network():
|
||||
return SUMMARY_PAGE
|
||||
else:
|
||||
return SELECT_PHYSICAL_NETWORK_PAGE
|
||||
return ConfigScreen.get_next_page(self, page)
|
||||
|
||||
def get_back_page(self, page):
|
||||
if page is NETWORK_DETAILS_PAGE:
|
||||
return IPV4_ADDRESS_PAGE
|
||||
if page is SUMMARY_PAGE:
|
||||
if self.__config.is_isolated_network():
|
||||
return NETWORK_TYPE_PAGE
|
||||
else:
|
||||
return SELECT_PHYSICAL_NETWORK_PAGE
|
||||
return ConfigScreen.get_back_page(self, page)
|
||||
|
||||
def page_has_finish(self, page):
|
||||
if page is SUMMARY_PAGE: return True
|
||||
return False
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page < SUMMARY_PAGE: return True
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page > NETWORK_NAME_PAGE: return True
|
||||
return False
|
||||
|
||||
def get_network_name_page(self, screen):
|
||||
self.__name = Entry(50, self.__config.get_name())
|
||||
grid = Grid(2, 1)
|
||||
grid.setField(Label("Network Name:"), 0, 0)
|
||||
grid.setField(self.__name, 1, 0)
|
||||
return [Label("Please choose a name for your virtual network"),
|
||||
grid]
|
||||
|
||||
def get_ipv4_address_page(self, screen):
|
||||
self.__ipv4_address = Entry(18, self.__config.get_ipv4_address())
|
||||
grid = Grid(2, 1)
|
||||
grid.setField(Label("Network:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__ipv4_address, 1, 0, anchorLeft = 1)
|
||||
return [Label("You will need to choose an IPv4 address space for the virtual network:"),
|
||||
grid,
|
||||
Label("HINT: The network should be chosen from"),
|
||||
Label("one of the IPv4 private address ranges;"),
|
||||
Label("e.g., 10.0.0.0/8, 172.168.0.0/12, 192.168.0.0/16")]
|
||||
|
||||
def get_network_details_page(self, screen):
|
||||
grid = Grid(2, 6)
|
||||
grid.setField(Label("Network:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_ipv4_address()), 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Netmask:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_ipv4_netmask()), 1, 1, anchorLeft = 1)
|
||||
grid.setField(Label("Broadcast:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_ipv4_broadcast()), 1, 2, anchorLeft = 1)
|
||||
grid.setField(Label("Gateway:"), 0, 3, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_ipv4_gateway()), 1, 3, anchorLeft = 1)
|
||||
grid.setField(Label("Size:"), 0, 4, anchorRight = 1)
|
||||
grid.setField(Label("%d addresses" % self.__config.get_ipv4_max_addresses()), 1, 4, anchorLeft = 1)
|
||||
grid.setField(Label("Type:"), 0, 5, anchorRight = 1)
|
||||
grid.setField(Label(self.__config.get_ipv4_network_type()), 1, 5, anchorLeft = 1)
|
||||
return [Label("Network Details"),
|
||||
grid]
|
||||
|
||||
def get_public_network_alert_page(self, screen):
|
||||
grid = Grid(1, 2)
|
||||
grid.setField(Label("The network should normally use a private IPv4 address."), 0, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Use this non-private address anyway?"), 0, 1, anchorLeft = 1)
|
||||
return [Label("Check Network Address"),
|
||||
grid]
|
||||
|
||||
def get_dhcp_range_page(self, screen):
|
||||
self.__start_address = Entry(15, self.__config.get_ipv4_start_address())
|
||||
self.__end_address = Entry(15, self.__config.get_ipv4_end_address())
|
||||
grid = Grid(2,2)
|
||||
grid.setField(Label("Start:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(self.__start_address, 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("End:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(self.__end_address, 1, 1, anchorLeft = 1)
|
||||
return [Label("Selecting The DHCP Range"),
|
||||
grid,
|
||||
Label("TIP: Unless you wish to reserve some addresses to allow static network"),
|
||||
Label("configuration in virtual machines, these paraemters can be left with"),
|
||||
Label("their default values.")]
|
||||
|
||||
def get_network_type_page(self, screen):
|
||||
self.__isolated_network = Checkbox("Isolated virtual network",
|
||||
self.__config.is_isolated_network())
|
||||
grid = Grid(1, 3)
|
||||
grid.setField(Label("Please indicate whether this virtual network should be"), 0, 0, anchorLeft = 1)
|
||||
grid.setField(Label("connected to the physical network."), 0, 1, anchorLeft = 1)
|
||||
grid.setField(self.__isolated_network, 0, 2)
|
||||
return [Label("Connecting To Physical Network"),
|
||||
grid]
|
||||
|
||||
def get_select_physical_network_page(self, screen):
|
||||
devices = []
|
||||
devices.append(["NAT to any physical device", "", self.__config.get_physical_device() == ""])
|
||||
for device in self.get_hal().list_network_devices():
|
||||
devices.append(["NAT to physical device %s" % device, device, self.__config.get_physical_device() == device])
|
||||
self.__physical_devices = RadioBar(screen, (devices))
|
||||
grid = Grid(1, 2)
|
||||
grid.setField(Label("Forward to physical network:"), 0, 0)
|
||||
grid.setField(self.__physical_devices, 0, 1)
|
||||
return [Label("Connecting To Physical Network"),
|
||||
grid]
|
||||
|
||||
def get_summary_page(self, screen):
|
||||
grid1 = Grid(2, 1)
|
||||
grid1.setField(Label("Network name:"), 0, 0, anchorRight = 1)
|
||||
grid1.setField(Label(self.__config.get_name()), 1, 0, anchorLeft = 1)
|
||||
|
||||
grid2 = Grid(2, 3)
|
||||
grid2.setField(Label("Network:"), 0, 0, anchorRight = 1)
|
||||
grid2.setField(Label(self.__config.get_ipv4_address()), 1, 0, anchorLeft = 1)
|
||||
grid2.setField(Label("Gateway:"), 0, 1, anchorRight = 1)
|
||||
grid2.setField(Label(self.__config.get_ipv4_gateway()), 1, 1, anchorLeft = 1)
|
||||
grid2.setField(Label("Netmask:"), 0, 2, anchorRight = 1)
|
||||
grid2.setField(Label(self.__config.get_ipv4_netmask()), 1, 2, anchorLeft = 1)
|
||||
|
||||
grid3 = Grid(2, 2)
|
||||
grid3.setField(Label("Start address:"), 0, 0, anchorRight = 1)
|
||||
grid3.setField(Label(self.__config.get_ipv4_start_address()), 1, 0, anchorLeft = 1)
|
||||
grid3.setField(Label("End address:"), 0, 1, anchorRight = 1)
|
||||
grid3.setField(Label(self.__config.get_ipv4_end_address()), 1, 1, anchorLeft = 1)
|
||||
|
||||
grid4 = Grid(2, 1)
|
||||
grid4.setField(Label("Connectivity:"), 0, 0, anchorRight = 1)
|
||||
if self.__config.is_isolated_network():
|
||||
grid4.setField(Label("Isolated virtual network"), 1, 0, anchorLeft = 1)
|
||||
else:
|
||||
grid4.setField(Label("NAT to %s" % self.__config.get_physical_device_text()), 1, 0, anchorLeft = 1)
|
||||
|
||||
return [Label("Ready To Create Network"),
|
||||
Label("Summary"),
|
||||
grid1,
|
||||
Label("IPv4 Network"),
|
||||
grid2,
|
||||
Label("DHCP"),
|
||||
grid3,
|
||||
Label("Forwarding"),
|
||||
grid4]
|
||||
|
||||
def DefineNetwork():
|
||||
screen = DefineNetworkConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# destroynetwork.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
LIST_PAGE = 1
|
||||
DESTROY_PAGE = 2
|
||||
|
||||
class DestroyNetworkConfigScreen(NetworkListConfigScreen):
|
||||
def __init__(self):
|
||||
NetworkListConfigScreen.__init__(self, "Destroy A Network")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_PAGE: return self.get_network_list_page(screen, defined = False)
|
||||
elif page is DESTROY_PAGE: return self.get_destroy_network_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is LIST_PAGE: return self.has_selectable_networks()
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page is DESTROY_PAGE: return True
|
||||
return False
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_PAGE:
|
||||
network = self.get_selected_network()
|
||||
self.get_libvirt().destroy_network(network)
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_destroy_network_page(self, screen):
|
||||
return [Label("Network Destroyed"),
|
||||
Label("%s has been destroyed." % self.get_selected_network())]
|
||||
|
||||
def DestroyNetwork():
|
||||
screen = DestroyNetworkConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,224 @@
|
|||
# domainconfig.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 DomainConfig:
|
||||
LOCAL_INSTALL = "local"
|
||||
NETWORK_INSTALL = "network"
|
||||
PXE_INSTALL = "pxe"
|
||||
INSTALL_TYPE_TEXT = {LOCAL_INSTALL : "Local CDROM/ISO",
|
||||
NETWORK_INSTALL : "URL INstall Tree",
|
||||
PXE_INSTALL : "PXE Install"}
|
||||
|
||||
INSTALL_SOURCE_CDROM = "cdrom"
|
||||
INSTALL_SOURCE_ISO = "iso"
|
||||
|
||||
NEW_STORAGE = "new"
|
||||
EXISTING_STORAGE = "existing"
|
||||
|
||||
def __init__(self):
|
||||
self.__guest_name = ""
|
||||
self.__install_type = DomainConfig.LOCAL_INSTALL
|
||||
self.__use_cdrom_source = True
|
||||
self.__install_location = ""
|
||||
self.__install_media = ""
|
||||
self.__iso_path = ""
|
||||
self.__install_url = ""
|
||||
self.__kickstart_url = ""
|
||||
self.__kernel_options = ""
|
||||
self.__os_type = "other"
|
||||
self.__os_variant = None
|
||||
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.__storage_pool = ""
|
||||
self.__storage_volume = ""
|
||||
self.__network_bridge = None
|
||||
self.__mac_address = None
|
||||
self.__virt_type = None
|
||||
self.__architecture = None
|
||||
|
||||
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 get_install_type_text(self):
|
||||
return DomainConfig.INSTALL_TYPE_TEXT[self.get_install_type()]
|
||||
|
||||
def is_install_type(self, type):
|
||||
return self.__install_type == type
|
||||
|
||||
def set_install_location(self, location):
|
||||
self.__install_location = location
|
||||
|
||||
def set_use_cdrom_source(self, use):
|
||||
self.__use_cdrom_source = use
|
||||
|
||||
def get_use_cdrom_source(self):
|
||||
return self.__use_cdrom_source
|
||||
|
||||
def get_install_location(self):
|
||||
return self.__install_location
|
||||
|
||||
def is_install_location(self, location):
|
||||
return self.__install_location == location
|
||||
|
||||
def set_install_media(self, media):
|
||||
self.__install_media = media
|
||||
|
||||
def get_install_media(self):
|
||||
return self.__install_media
|
||||
|
||||
def is_install_media(self, media):
|
||||
return self.__install_media == media
|
||||
|
||||
def set_iso_path(self, path):
|
||||
self.__iso_path = path
|
||||
|
||||
def get_iso_path(self):
|
||||
return self.__iso_path
|
||||
|
||||
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, 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_storage_pool(self, pool):
|
||||
self.__storage_pool = pool
|
||||
|
||||
def get_storage_pool(self):
|
||||
return self.__storage_pool
|
||||
|
||||
def set_storage_volume(self, volume):
|
||||
self.__storage_volume = volume
|
||||
|
||||
def get_storage_volume(self):
|
||||
return self.__storage_volume
|
||||
|
||||
def is_existing_storage(self, storage):
|
||||
return self.__existing_storage == storage
|
||||
|
||||
def set_network_bridge(self, bridge):
|
||||
self.__network_bridge = bridge
|
||||
|
||||
def get_network_bridge(self):
|
||||
return self.__network_bridge
|
||||
|
||||
def set_mac_address(self, address):
|
||||
self.__mac_address = address
|
||||
|
||||
def get_mac_address(self):
|
||||
return self.__mac_address
|
||||
|
||||
def set_virt_type(self, type):
|
||||
self.__virt_type = type
|
||||
|
||||
def get_virt_type(self):
|
||||
return self.__virt_type
|
||||
|
||||
def is_virt_type(self, type):
|
||||
return self.__virt_type == type
|
||||
|
||||
def set_architecture(self, architecture):
|
||||
self.__architecture = architecture
|
||||
|
||||
def get_architecture(self):
|
||||
return self.__architecture
|
||||
|
||||
def is_architecture(self, architecture):
|
||||
return self.__architecture == architecture
|
|
@ -0,0 +1,45 @@
|
|||
# halworker.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 dbus
|
||||
import virtinst
|
||||
|
||||
class HALWorker:
|
||||
'''Provides utilities for working with HAL to get hardware information.'''
|
||||
def __init__(self):
|
||||
self.__bus = dbus.SystemBus()
|
||||
hobj = self.__bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager")
|
||||
self.__conn = dbus.Interface(hobj, "org.freedesktop.Hal.Manager")
|
||||
|
||||
def list_installable_volumes(self):
|
||||
result = {}
|
||||
for udi in self.__conn.FindDeviceByCapability("volume"):
|
||||
device = self.__bus.get_object("org.freedesktop.Hal", udi)
|
||||
info = dbus.Interface(device, "org.freedesktop.Hal.Device")
|
||||
if info.GetProperty("volume.is_disc"):
|
||||
if info.GetProperty("volume.disc.has_data"):
|
||||
result[str(info.GetProperty("block.device"))] = info.GetProperty("volume.label")
|
||||
return result
|
||||
|
||||
def list_network_devices(self):
|
||||
result = []
|
||||
for udi in self.__conn.FindDeviceByCapability("net"):
|
||||
device = self.__bus.get_object("org.freedesktop.Hal", udi)
|
||||
info = dbus.Interface(device, "org.freedesktop.Hal.Device")
|
||||
result.append(info.GetProperty("net.interface"))
|
||||
return result
|
|
@ -0,0 +1,29 @@
|
|||
# hostconnect.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
class HostConnectConfigScreen(ConfigScreen):
|
||||
def __init__(self):
|
||||
ConfigScree
|
||||
|
||||
def HostConnect():
|
||||
screen = HostConnectConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,46 @@
|
|||
# hostmenu.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 menuscreen import MenuScreen
|
||||
from changehost import ChangeHost
|
||||
from addhost import AddHost
|
||||
from removehost import RemoveHost
|
||||
|
||||
SELECT_HOST = 1
|
||||
ADD_HOST = 2
|
||||
REMOVE_HOST = 3
|
||||
|
||||
class HostMenuScreen(MenuScreen):
|
||||
def __init__(self):
|
||||
MenuScreen.__init__(self, "Host Menu Screen")
|
||||
|
||||
def get_menu_items(self):
|
||||
return (("Select A Host", SELECT_HOST),
|
||||
("Add A Host", ADD_HOST),
|
||||
("Remove A Host", REMOVE_HOST))
|
||||
|
||||
def handle_selection(self, item):
|
||||
if item is SELECT_HOST: ChangeHost()
|
||||
elif item is ADD_HOST: AddHost()
|
||||
elif item is REMOVE_HOST: RemoveHost()
|
||||
|
||||
def HostMenu():
|
||||
screen = HostMenuScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,461 @@
|
|||
# libvirtworker.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 dbus
|
||||
import libvirt
|
||||
import os
|
||||
import virtinst
|
||||
import utils
|
||||
import logging
|
||||
|
||||
from domainconfig import DomainConfig
|
||||
|
||||
DEFAULT_POOL_TARGET_PATH="/var/lib/libvirt/images"
|
||||
DEFAULT_URL="qemu:///system"
|
||||
|
||||
default_url = DEFAULT_URL
|
||||
|
||||
def set_default_url(url):
|
||||
logging.info("Changing DEFAULT_URL to %s" % url)
|
||||
global default_url
|
||||
|
||||
default_url = url
|
||||
|
||||
def get_default_url():
|
||||
logging.info("Returning default URL of %s" % default_url)
|
||||
return default_url
|
||||
|
||||
class VirtManagerConfig:
|
||||
def __init__(self, filename = "/etc/remote-libvirt.conf"):
|
||||
self.__filename = filename
|
||||
|
||||
def get_connection_list(self):
|
||||
result = []
|
||||
if os.path.exists(self.__filename):
|
||||
input = file(self.__filename, "r")
|
||||
for entry in input: result.append(entry[0:-1])
|
||||
return result
|
||||
|
||||
def add_connection(self, connection):
|
||||
connections = self.get_connection_list()
|
||||
if connections.count(connection) is 0:
|
||||
connections.append(connection)
|
||||
self._save_connections(connections)
|
||||
|
||||
def remove_connection(self, connection):
|
||||
connections = self.get_connection_list()
|
||||
if connections.count(connection) > 0:
|
||||
connections.remove(connection)
|
||||
self._save_connections(connections)
|
||||
|
||||
def _save_connections(self, connections):
|
||||
output = file(self.__filename, "w")
|
||||
for entry in connections:
|
||||
print >> output, entry
|
||||
output.close
|
||||
|
||||
class LibvirtWorker:
|
||||
'''Provides utilities for interfacing with libvirt.'''
|
||||
def __init__(self, url = None):
|
||||
if url is None: url = get_default_url()
|
||||
logging.info("Connecting to libvirt: %s" % url)
|
||||
self.__url = None
|
||||
self.__conn = None
|
||||
self.open_connection(url)
|
||||
self.__capabilities = virtinst.CapabilitiesParser.parse(self.__conn.getCapabilities())
|
||||
self.__net = virtinst.VirtualNetworkInterface(conn = self.__conn)
|
||||
self.__net.setup(self.__conn)
|
||||
(self.__new_guest, self.__new_domain) = virtinst.CapabilitiesParser.guest_lookup(conn = self.__conn)
|
||||
|
||||
def get_connection(self):
|
||||
'''Returns the underlying connection.'''
|
||||
return self.__conn
|
||||
|
||||
def get_url(self):
|
||||
return self.__url
|
||||
|
||||
def open_connection(self, url):
|
||||
'''Lets the user change the url for the connection.'''
|
||||
old_conn = self.__conn
|
||||
old_url = self.__url
|
||||
try:
|
||||
self.__conn = libvirt.open(url)
|
||||
self.__url = url
|
||||
set_default_url(url)
|
||||
except Exception, error:
|
||||
self.__conn = old_conn
|
||||
self.__url = old_url
|
||||
raise error
|
||||
|
||||
def list_domains(self, defined = True, started = True):
|
||||
'''Lists all domains.'''
|
||||
result = []
|
||||
if defined:
|
||||
result.extend(self.__conn.listDefinedDomains())
|
||||
if started:
|
||||
for id in self.__conn.listDomainsID():
|
||||
result.append(self.__conn.lookupByID(id).name())
|
||||
return result
|
||||
|
||||
def get_domain(self, name):
|
||||
'''Returns the specified domain.'''
|
||||
result = self.__conn.lookupByName(name)
|
||||
if result is None: raise Exception("No such domain exists: %s" % name)
|
||||
|
||||
return result
|
||||
|
||||
def domain_exists(self, name):
|
||||
'''Returns whether a domain with the specified node exists.'''
|
||||
domains = self.list_domains()
|
||||
if name in domains: return True
|
||||
return False
|
||||
|
||||
def create_domain(self, name):
|
||||
'''Creates the specified domain.'''
|
||||
domain = self.get_domain(name)
|
||||
domain.create()
|
||||
|
||||
def destroy_domain(self, name):
|
||||
'''Destroys the specified domain.'''
|
||||
domain = self.get_domain(name)
|
||||
domain.destroy()
|
||||
|
||||
def undefine_domain(self, name):
|
||||
'''Undefines the specified domain.'''
|
||||
domain = self.get_domain(name)
|
||||
domain.undefine()
|
||||
|
||||
def migrate_domain(self, name, target):
|
||||
'''Migrates the specified domain to the target machine.'''
|
||||
target_conn = libvirt.open(target)
|
||||
virtmachine = self.get_domain(name)
|
||||
virtmachine.migrate(target_conn, libvirt.VIR_MIGRATE_LIVE, None, None, 0)
|
||||
|
||||
def list_networks(self, defined = True, started = True):
|
||||
'''Lists all networks.'''
|
||||
result = []
|
||||
if defined: result.extend(self.__conn.listDefinedNetworks())
|
||||
if started: result.extend(self.__conn.listNetworks())
|
||||
return result
|
||||
|
||||
def get_network(self, name):
|
||||
'''Returns the specified network.'''
|
||||
result = self.__conn.networkLookupByName(name)
|
||||
if result is None: raise Exception("No such network exists: %s" % name)
|
||||
|
||||
return result
|
||||
|
||||
def network_exists(self, name):
|
||||
'''Returns if a network with the given name already exists.'''
|
||||
networks = self.list_networks()
|
||||
if name in networks: return True
|
||||
return False
|
||||
|
||||
def define_network(self, config):
|
||||
'''Defines a new network.'''
|
||||
# since there's no other way currently, we'll have to use XML
|
||||
name = config.get_name()
|
||||
ip = config.get_ipv4_address_raw()
|
||||
start = config.get_ipv4_start_address()
|
||||
end = config.get_ipv4_end_address()
|
||||
fw = config.get_physical_device()
|
||||
|
||||
xml = "<network>" + \
|
||||
" <name>%s</name>\n" % name
|
||||
if not config.is_public_ipv4_network():
|
||||
if fw is not "":
|
||||
xml += " <forward dev='%s'/>\n" % fw[1]
|
||||
else:
|
||||
xml += " <forward/>\n"
|
||||
|
||||
xml += " <ip address='%s' netmask='%s'>\n" % (str(ip[1]), str(ip.netmask()))
|
||||
xml += " <dhcp>\n"
|
||||
xml += " <range start='%s' end='%s'/>\n" % (str(start), str(end))
|
||||
xml += " </dhcp>\n"
|
||||
xml += " </ip>\n"
|
||||
xml += "</network>\n"
|
||||
|
||||
self.__conn.networkDefineXML(xml)
|
||||
|
||||
def create_network(self, name):
|
||||
'''Creates a defined network.'''
|
||||
network = self.get_network(name)
|
||||
network.create()
|
||||
|
||||
def destroy_network(self, name):
|
||||
'''Destroys the specified network.'''
|
||||
network = self.get_network(name)
|
||||
network.destroy()
|
||||
|
||||
def undefine_network(self, name):
|
||||
'''Undefines the specified network.'''
|
||||
network = self.get_network(name)
|
||||
network.undefine()
|
||||
|
||||
def list_storage_pools(self, defined=True, created=True):
|
||||
'''Returns the list of all defined storage pools.'''
|
||||
pools = []
|
||||
if defined: pools.extend(self.__conn.listDefinedStoragePools())
|
||||
if created: pools.extend(self.__conn.listStoragePools())
|
||||
return pools
|
||||
|
||||
def storage_pool_exists(self, name):
|
||||
'''Returns whether a storage pool exists.'''
|
||||
pools = self.list_storage_pools()
|
||||
if name in pools: return True
|
||||
return False
|
||||
|
||||
def create_storage_pool(self, name):
|
||||
'''Starts the named storage pool if it is not currently started.'''
|
||||
if name not in self.list_storage_pools(defined = False):
|
||||
pool = self.get_storage_pool(name)
|
||||
pool.create(0)
|
||||
|
||||
def destroy_storage_pool(self, name):
|
||||
'''Stops the specified storage pool.'''
|
||||
if name in self.list_storage_pools(defined = False):
|
||||
pool = self.get_storage_pool(name)
|
||||
pool.destroy()
|
||||
|
||||
def define_storage_pool(self, name, config = None, meter = None):
|
||||
'''Defines a storage pool with the given name.'''
|
||||
if config is None:
|
||||
pool = virtinst.Storage.DirectoryPool(conn=self.__conn,
|
||||
name=name,
|
||||
target_path=DEFAULT_POOL_TARGET_PATH)
|
||||
newpool = pool.install(build=True, create=True, meter=meter)
|
||||
newpool.setAutostart(True)
|
||||
else:
|
||||
pool = config.get_pool()
|
||||
pool.target_path = config.get_target_path()
|
||||
if config.needs_hostname():
|
||||
pool.host = config.get_hostname()
|
||||
if config.needs_source_path():
|
||||
pool.source_path = config.get_source_path()
|
||||
if config.needs_format():
|
||||
pool.format = config.get_format()
|
||||
pool.conn = self.__conn
|
||||
pool.get_xml_config()
|
||||
newpool = pool.install(meter=meter,
|
||||
build=True, # config.get_build_pool(),
|
||||
create=True)
|
||||
newpool.setAutostart(True)
|
||||
|
||||
def undefine_storage_pool(self, name):
|
||||
'''Undefines the specified storage pool.'''
|
||||
pool = self.get_storage_pool(name)
|
||||
pool.undefine()
|
||||
|
||||
def get_storage_pool(self, name):
|
||||
'''Returns the storage pool with the specified name.'''
|
||||
return self.__conn.storagePoolLookupByName(name)
|
||||
|
||||
def list_storage_volumes(self, poolname):
|
||||
'''Returns the list of all defined storage volumes for a given pool.'''
|
||||
pool = self.get_storage_pool(poolname)
|
||||
return pool.listVolumes()
|
||||
|
||||
def define_storage_volume(self, config, meter):
|
||||
'''Defines a new storage volume.'''
|
||||
self.create_storage_pool(config.get_pool().name())
|
||||
volume = config.create_volume()
|
||||
volume.install(meter = meter)
|
||||
|
||||
def remove_storage_volume(self, poolname, volumename):
|
||||
'''Removes the specified storage volume.'''
|
||||
volume = self.get_storage_volume(poolname, volumename)
|
||||
volume.delete(0)
|
||||
|
||||
def get_storage_volume(self, poolname, volumename):
|
||||
'''Returns a reference to the specified storage volume.'''
|
||||
pool =self.get_storage_pool(poolname)
|
||||
volume = pool.storageVolLookupByName(volumename)
|
||||
return volume
|
||||
|
||||
def list_bridges(self):
|
||||
'''Lists all defined and active bridges.'''
|
||||
bridges = self.__conn.listNetworks()
|
||||
bridges.extend(self.__conn.listDefinedNetworks())
|
||||
result = []
|
||||
for name in bridges:
|
||||
bridge = self.__conn.networkLookupByName(name)
|
||||
result.append(bridge)
|
||||
return result
|
||||
|
||||
def generate_mac_address(self):
|
||||
return self.__net.macaddr
|
||||
|
||||
def get_storage_size(self, poolname, volumename):
|
||||
'''Returns the size of the specified storage volume.'''
|
||||
volume = self.get_storage_volume(poolname, volumename)
|
||||
return volume.info()[1] / (1024.0 ** 3)
|
||||
|
||||
def get_virt_types(self):
|
||||
result = []
|
||||
for guest in self.__capabilities.guests:
|
||||
guest_type = guest.os_type
|
||||
for domain in guest.domains:
|
||||
domain_type = domain.hypervisor_type
|
||||
label = domain_type
|
||||
|
||||
if domain_type is "kvm" and guest_type is "xen": label = "xenner"
|
||||
elif domain_type is "xen":
|
||||
if guest_type is "xen":
|
||||
label = "xen (paravirt)"
|
||||
elif guest_type is "kvm":
|
||||
label = "xen (fullvirt)"
|
||||
elif domain_type is "test":
|
||||
if guest_type is "xen":
|
||||
label = "test (xen)"
|
||||
elif guest_type is "hvm":
|
||||
label = "test (hvm)"
|
||||
|
||||
for row in result:
|
||||
if row[0] == label:
|
||||
label = None
|
||||
break
|
||||
if label is None: continue
|
||||
|
||||
result.append([label, domain_type, guest_type])
|
||||
return result
|
||||
|
||||
def list_virt_types(self):
|
||||
virt_types = self.get_virt_types()
|
||||
result = []
|
||||
for type in virt_types:
|
||||
result.append(type[0])
|
||||
return result
|
||||
|
||||
def get_default_architecture(self):
|
||||
'''Returns a default hypervisor type for new domains.'''
|
||||
return self.__new_guest.arch
|
||||
|
||||
def get_hypervisor(self, virt_type):
|
||||
virt_types = self.get_virt_types()
|
||||
for type in virt_types:
|
||||
if type[0] is virt_type: return type[1]
|
||||
return None
|
||||
|
||||
def get_default_virt_type(self):
|
||||
'''Returns the default virtualization type for new domains.'''
|
||||
return self.__new_domain.hypervisor_type
|
||||
|
||||
def get_os_type(self, virt_type):
|
||||
virt_types = self.get_virt_types()
|
||||
for type in virt_types:
|
||||
if type[0] is virt_type: return type[2]
|
||||
return None
|
||||
|
||||
def list_architectures(self):
|
||||
result = []
|
||||
for guest in self.__capabilities.guests:
|
||||
for domain in guest.domains:
|
||||
label = guest.arch
|
||||
for row in result:
|
||||
if row == label:
|
||||
label = None
|
||||
break
|
||||
if label is None: continue
|
||||
|
||||
result.append(label)
|
||||
return result
|
||||
|
||||
def define_domain(self, config, meter):
|
||||
location = extra = kickstart = None
|
||||
|
||||
if config.get_install_type() == DomainConfig.LOCAL_INSTALL:
|
||||
if config.get_use_cdrom_source():
|
||||
iclass = virtinst.DistroInstaller
|
||||
location = config.get_install_media()
|
||||
else:
|
||||
iclass = virtinst.LiveCDInstaller
|
||||
location = config.get_iso_path()
|
||||
elif config.get_install_type() == DomainConfig.NETWORK_INSTALL:
|
||||
iclass = virtinst.DistroInstaller
|
||||
location = config.get_install_url()
|
||||
extra = config.get_kernel_options()
|
||||
kickstart = config.get_kickstart_url()
|
||||
elif config.get_install_type() == DomainConfig.PXE_INSTALL:
|
||||
iclass = virtinst.PXEInstaller
|
||||
|
||||
installer = iclass(conn = self.__conn,
|
||||
type = self.get_hypervisor(config.get_virt_type()),
|
||||
os_type = self.get_os_type(config.get_virt_type()))
|
||||
self.__guest = installer.guest_from_installer()
|
||||
self.__guest.name = config.get_guest_name()
|
||||
self.__guest.vcpus = config.get_cpus()
|
||||
self.__guest.memory = config.get_memory()
|
||||
self.__guest.maxmemory = config.get_memory()
|
||||
|
||||
self.__guest.installer.location = location
|
||||
if config.get_use_cdrom_source(): self.__guest.installer.cdrom = True
|
||||
extraargs = ""
|
||||
if extra: extraargs += extra
|
||||
if kickstart: extraargs += " ks=%s" % kickstart
|
||||
if extraargs: self.__guest.installer.extraarags = extraargs
|
||||
|
||||
self.__guest.uuid = virtinst.util.uuidToString(virtinst.util.randomUUID())
|
||||
|
||||
if config.get_os_type() != "generic": self.__guest.os_type = config.get_os_type()
|
||||
if config.get_os_variant() != "generic": self.__guest.os_variant = config.get_os_variant()
|
||||
|
||||
self.__guest._graphics_dev = virtinst.VirtualGraphics(type = virtinst.VirtualGraphics.TYPE_VNC)
|
||||
self.__guest.sound_devs = []
|
||||
self.__guest.sound_devs.append(virtinst.VirtualAudio(model = "es1370"))
|
||||
|
||||
self._setup_nics(config)
|
||||
self._setup_disks(config)
|
||||
|
||||
self.__guest.conn = self.__conn
|
||||
self.__domain = self.__guest.start_install(False, meter = meter)
|
||||
|
||||
def _setup_nics(self, config):
|
||||
self.__guest.nics = []
|
||||
nic = virtinst.VirtualNetworkInterface(type = virtinst.VirtualNetworkInterface.TYPE_VIRTUAL,
|
||||
bridge = config.get_network_bridge(),
|
||||
network = config.get_network_bridge(),
|
||||
macaddr = config.get_mac_address())
|
||||
self.__guest.nics.append(nic)
|
||||
# ensure the network is running
|
||||
if config.get_network_bridge() not in self.__conn.listNetworks():
|
||||
network = self.__conn.networkLookupByName(config.get_network_bridge())
|
||||
network.create()
|
||||
|
||||
def _setup_disks(self, config):
|
||||
self.__guest.disks = []
|
||||
if config.get_enable_storage():
|
||||
path = None
|
||||
if config.get_use_local_storage():
|
||||
if self.storage_pool_exists("default") is False:
|
||||
self.define_storage_pool("default")
|
||||
pool = self.__conn.storagePoolLookupByName("default")
|
||||
path = virtinst.Storage.StorageVolume.find_free_name(config.get_guest_name(),
|
||||
pool_object = pool,
|
||||
suffix = ".img")
|
||||
path = os.path.join(DEFAULT_POOL_TARGET_PATH, path)
|
||||
else:
|
||||
volume = self.get_storage_volume(config.get_storage_pool(),
|
||||
config.get_storage_volume())
|
||||
path = volume.path()
|
||||
|
||||
if path is not None:
|
||||
storage= virtinst.VirtualDisk(conn = self.__conn,
|
||||
path = path,
|
||||
size = config.get_storage_size())
|
||||
self.__guest.disks.append(storage)
|
||||
self.__guest.conn = self.__conn
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# listdomains.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 libvirtworker import LibvirtWorker
|
||||
from configscreen import *
|
||||
|
||||
class ListDomainsConfigScreen(DomainListConfigScreen):
|
||||
LIST_PAGE = 1
|
||||
DETAIL_PAGE = 2
|
||||
|
||||
def __init__(self):
|
||||
DomainListConfigScreen.__init__(self, 'List Virtual Machines')
|
||||
|
||||
def page_has_next(self, page):
|
||||
return (page == self.LIST_PAGE)
|
||||
|
||||
def page_has_back(self, page):
|
||||
return (page == self.DETAIL_PAGE)
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page == self.LIST_PAGE:
|
||||
if self.get_selected_domain() is None:
|
||||
errors.append("Please select a virtual machine to view.")
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page == self.LIST_PAGE:
|
||||
return self.get_domain_list_page(screen)
|
||||
elif page == self.DETAIL_PAGE:
|
||||
return self.get_detail_page_elements(screen)
|
||||
|
||||
def get_detail_page_elements(self, screen):
|
||||
domain = self.get_libvirt().get_domain(self.get_selected_domain())
|
||||
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 ListDomains():
|
||||
screen = ListDomainsConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,55 @@
|
|||
# listnetworks.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
|
||||
LIST_PAGE = 1
|
||||
DETAILS_PAGE = 2
|
||||
|
||||
class ListNetworksConfigScreen(NetworkListConfigScreen):
|
||||
def __init__(self):
|
||||
NetworkListConfigScreen.__init__(self, "List Networks")
|
||||
|
||||
def page_has_next(self, page):
|
||||
return (page is LIST_PAGE) and self.has_selectable_networks()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return (page is DETAILS_PAGE)
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_PAGE: return self.get_network_list_page(screen)
|
||||
elif page is DETAILS_PAGE: return self.get_network_details_page(screen)
|
||||
|
||||
def get_network_details_page(self, screen):
|
||||
network = self.get_libvirt().get_network(self.get_selected_network())
|
||||
grid = Grid(2, 3)
|
||||
grid.setField(Label("Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label(network.name()), 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Autostart:"), 0, 1, anchorRight = 1)
|
||||
label = "No"
|
||||
if network.autostart(): label = "Yes"
|
||||
grid.setField(Label(label), 1, 1, anchorLeft = 1)
|
||||
if network.bridgeName() is not "":
|
||||
grid.setField(Label("Bridge:"), 0, 2, anchorRight = 1)
|
||||
grid.setField(Label(network.bridgeName()), 1, 2, anchorLeft = 1)
|
||||
return [Label("Network Interface Details"),
|
||||
grid]
|
||||
|
||||
def ListNetworks():
|
||||
screen = ListNetworksConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,64 @@
|
|||
# listpools.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
from utils import *
|
||||
|
||||
LIST_PAGE = 1
|
||||
DETAILS_PAGE = 2
|
||||
|
||||
class ListStoragePoolsConfigScreen(StorageListConfigScreen):
|
||||
def __init__(self):
|
||||
StorageListConfigScreen.__init__(self, "List Storage Pools")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_PAGE: return self.get_storage_pool_list_page(screen)
|
||||
elif page is DETAILS_PAGE: return self.get_pool_details_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is LIST_PAGE and self.has_selectable_pools():
|
||||
return True
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page is DETAILS_PAGE: return True
|
||||
return False
|
||||
|
||||
def get_pool_details_page(self, screen):
|
||||
pool = self.get_libvirt().get_storage_pool(self.get_selected_pool())
|
||||
volumes = Listbox(0);
|
||||
for name in pool.listVolumes():
|
||||
volume = pool.storageVolLookupByName(name)
|
||||
volumes.append("%s (%s)" % (name, size_as_mb_or_gb(volume.info()[1])), name)
|
||||
grid = Grid(2, 3)
|
||||
grid.setField(Label("Name:"), 0, 0, anchorRight = 1)
|
||||
grid.setField(Label(pool.name()), 1, 0, anchorLeft = 1)
|
||||
grid.setField(Label("Volumes:"), 0, 1, anchorRight = 1)
|
||||
grid.setField(volumes, 1, 1, anchorLeft = 1)
|
||||
grid.setField(Label("Autostart:"), 0, 2, anchorRight = 1)
|
||||
label = "No"
|
||||
if pool.autostart(): label = "Yes"
|
||||
grid.setField(Label(label), 1, 2, anchorLeft = 1)
|
||||
return [Label("Details For Storage Pool: %s" % self.get_selected_pool()),
|
||||
grid]
|
||||
|
||||
def ListStoragePools():
|
||||
screen = ListStoragePoolsConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,55 @@
|
|||
# mainmenu.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
from menuscreen import MenuScreen
|
||||
from nodemenu import NodeMenu
|
||||
from netmenu import NetworkMenu
|
||||
from storagemenu import StoragePoolMenu
|
||||
from hostmenu import HostMenu
|
||||
|
||||
import utils
|
||||
import logging
|
||||
|
||||
NODE_MENU = 1
|
||||
NETWORK_MENU = 2
|
||||
STORAGE_MENU = 3
|
||||
HOST_MENU = 4
|
||||
EXIT_CONSOLE = 99
|
||||
|
||||
class MainMenuScreen(MenuScreen):
|
||||
def __init__(self):
|
||||
MenuScreen.__init__(self, "Main Menu")
|
||||
|
||||
def get_menu_items(self):
|
||||
return (("Node Administration", NODE_MENU),
|
||||
("Network Administration", NETWORK_MENU),
|
||||
("Storage Pool Administration", STORAGE_MENU),
|
||||
("Host Administration", HOST_MENU))
|
||||
|
||||
def handle_selection(self, page):
|
||||
if page is NODE_MENU: NodeMenu()
|
||||
elif page is NETWORK_MENU: NetworkMenu()
|
||||
elif page is STORAGE_MENU: StoragePoolMenu()
|
||||
elif page is HOST_MENU: HostMenu()
|
||||
|
||||
def MainMenu():
|
||||
screen = MainMenuScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,57 @@
|
|||
# mainmenu.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
import utils
|
||||
import logging
|
||||
|
||||
EXIT_MENU = 99
|
||||
|
||||
class MenuScreen:
|
||||
def __init__(self, title):
|
||||
self.__title = title
|
||||
|
||||
def start(self):
|
||||
finished = False
|
||||
while finished == False:
|
||||
screen = SnackScreen()
|
||||
menu = Listbox(height = 0, width = 0, returnExit = 1)
|
||||
for menu_item in self.get_menu_items():
|
||||
menu.append(menu_item[0], menu_item[1])
|
||||
menu.append("Exit Menu", EXIT_MENU)
|
||||
gridform = GridForm(screen, self.__title, 1, 4)
|
||||
gridform.add(menu, 0, 0)
|
||||
result = gridform.run();
|
||||
screen.popWindow()
|
||||
screen.finish()
|
||||
|
||||
try:
|
||||
if result.current() == EXIT_MENU: finished = True
|
||||
else: self.handle_selection(result.current())
|
||||
except Exception, error:
|
||||
screen = SnackScreen()
|
||||
logging.info("An exception occurred: %s" % str(error))
|
||||
ButtonChoiceWindow(screen,
|
||||
"An Exception Has Occurred",
|
||||
str(error) + "\n" + traceback.format_exc(),
|
||||
buttons = ["OK"])
|
||||
screen.popWindow()
|
||||
screen.finish()
|
||||
finished = True
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# migratedomain.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 libvirtworker import LibvirtWorker
|
||||
from configscreen import *
|
||||
|
||||
LIST_DOMAINS = 1
|
||||
SELECT_TARGET = 2
|
||||
CONFIRM_PAGE = 3
|
||||
|
||||
class MigrateDomainConfigScreen(DomainListConfigScreen):
|
||||
def __init__(self):
|
||||
DomainListConfigScreen.__init__(self, "Migrate Virtual Machine")
|
||||
self.__configured = False
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_DOMAINS: return self.get_domain_list_page(screen)
|
||||
elif page is SELECT_TARGET: return self.get_target_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is LIST_DOMAINS: return self.has_selectable_domains()
|
||||
else: return page < CONFIRM_PAGE
|
||||
|
||||
def page_has_back(self, page):
|
||||
return page < CONFIRM_PAGE
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_DOMAINS: return self.get_selected_domain() is not None
|
||||
elif page is SELECT_TARGET:
|
||||
if self.__targets.current() is None:
|
||||
errors.append("Please enter a target hostname or IP address.")
|
||||
return False
|
||||
elif page is CONFIRM_PAGE:
|
||||
if not self.__confirm.value():
|
||||
errors.append("You must confirm migrating this virtual machine to proceed.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONFIRM_PAGE:
|
||||
self.get_libvirt().migrate_domain(self.get_selected_domain(), self.__targets.current())
|
||||
self.set_finished()
|
||||
|
||||
def get_target_page(self, screen):
|
||||
self.__targets = Listbox(0)
|
||||
for connection in self.get_virt_manager_config().get_connection_list():
|
||||
self.__targets.append(connection, connection)
|
||||
return [Label("Select A Target Host"),
|
||||
self.__targets]
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
self.__confirm = Checkbox("Confirm migrating this virtual machine.")
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__confirm, 0, 0)
|
||||
return [grid]
|
||||
|
||||
def MigrateDomain():
|
||||
screen = MigrateDomainConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,58 @@
|
|||
# mainmenu.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
from menuscreen import MenuScreen
|
||||
from definenet import DefineNetwork
|
||||
from createnetwork import CreateNetwork
|
||||
from destroynetwork import DestroyNetwork
|
||||
from undefinenetwork import UndefineNetwork
|
||||
from listnetworks import ListNetworks
|
||||
|
||||
import utils
|
||||
import logging
|
||||
|
||||
DEFINE_NETWORK = 1
|
||||
CREATE_NETWORK = 2
|
||||
DESTROY_NETWORK = 3
|
||||
UNDEFINE_NETWORK = 4
|
||||
LIST_NETWORKS = 5
|
||||
|
||||
class NetworkMenuScreen(MenuScreen):
|
||||
def __init__(self):
|
||||
MenuScreen.__init__(self, "Network Administration")
|
||||
|
||||
def get_menu_items(self):
|
||||
return (("Define A Network", DEFINE_NETWORK),
|
||||
("Create A Network", CREATE_NETWORK),
|
||||
("Destroy A Network", DESTROY_NETWORK),
|
||||
("Undefine A Network", UNDEFINE_NETWORK),
|
||||
("List Networks", LIST_NETWORKS))
|
||||
|
||||
def handle_selection(self, item):
|
||||
if item is DEFINE_NETWORK: DefineNetwork()
|
||||
elif item is CREATE_NETWORK: CreateNetwork()
|
||||
elif item is DESTROY_NETWORK: DestroyNetwork()
|
||||
elif item is UNDEFINE_NETWORK: UndefineNetwork()
|
||||
elif item is LIST_NETWORKS: ListNetworks()
|
||||
|
||||
def NetworkMenu():
|
||||
screen = NetworkMenuScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,99 @@
|
|||
# networkconfig.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 IPy import IP
|
||||
import logging
|
||||
|
||||
class NetworkConfig:
|
||||
def __init__(self):
|
||||
self.__name = ""
|
||||
self.set_ipv4_address("192.168.100.0/24")
|
||||
self.__isolated_network = True
|
||||
self.__physical_device = ""
|
||||
|
||||
def set_name(self, name):
|
||||
self.__name = name
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def set_ipv4_address(self, address):
|
||||
self.__ipv4_address = IP(address)
|
||||
start = int(self.__ipv4_address.len() / 2)
|
||||
end = self.__ipv4_address.len() - 2
|
||||
self.__ipv4_start = str(self.__ipv4_address[start])
|
||||
self.__ipv4_end = str(self.__ipv4_address[end])
|
||||
|
||||
def get_ipv4_address(self):
|
||||
return self.__ipv4_address.strNormal()
|
||||
|
||||
def get_ipv4_address_raw(self):
|
||||
return self.__ipv4_address
|
||||
|
||||
def get_ipv4_netmask(self):
|
||||
return self.__ipv4_address.netmask().strNormal()
|
||||
|
||||
def get_ipv4_broadcast(self):
|
||||
return self.__ipv4_address.broadcast().strNormal()
|
||||
|
||||
def get_ipv4_gateway(self):
|
||||
return str(self.__ipv4_address[1])
|
||||
|
||||
def get_ipv4_max_addresses(self):
|
||||
return self.__ipv4_address.len()
|
||||
|
||||
def get_ipv4_network_type(self):
|
||||
return self.__ipv4_address.iptype()
|
||||
|
||||
def is_public_ipv4_network(self):
|
||||
if self.__ipv4_address.iptype() is "PUBLIC":
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_ipv4_start_address(self, address):
|
||||
self.__ipv4_start = address
|
||||
|
||||
def get_ipv4_start_address(self):
|
||||
return self.__ipv4_start
|
||||
|
||||
def set_ipv4_end_address(self, address):
|
||||
self.__ipv4_end = address
|
||||
|
||||
def get_ipv4_end_address(self):
|
||||
return self.__ipv4_end
|
||||
|
||||
def is_bad_address(self, address):
|
||||
return not self.__ipv4_address.overlaps(address)
|
||||
|
||||
def set_isolated_network(self, isolated):
|
||||
self.__isolated_network = isolated
|
||||
|
||||
def is_isolated_network(self):
|
||||
return self.__isolated_network
|
||||
|
||||
def set_physical_device(self, device):
|
||||
self.__physical_device = device
|
||||
|
||||
def get_physical_device(self):
|
||||
return self.__physical_device
|
||||
|
||||
def get_physical_device_text(self):
|
||||
if self.__physical_device == "":
|
||||
return "any physical device"
|
||||
else:
|
||||
return "physical device %s" % self.__physical_device
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# node-admin - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 MainMenu
|
||||
|
||||
def NodeAdmin():
|
||||
MainMenu()
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(NodeAdmin())
|
|
@ -0,0 +1,67 @@
|
|||
# mainmenu.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
from menuscreen import MenuScreen
|
||||
from configscreen import ConfigScreen
|
||||
from adddomain import AddDomain
|
||||
from startdomain import StartDomain
|
||||
from stopdomain import StopDomain
|
||||
from removedomain import RemoveDomain
|
||||
from listdomains import ListDomains
|
||||
from migratedomain import MigrateDomain
|
||||
from createuser import CreateUser
|
||||
|
||||
import utils
|
||||
import logging
|
||||
|
||||
ADD_DOMAIN = 1
|
||||
START_DOMAIN = 2
|
||||
STOP_DOMAIN = 3
|
||||
REMOVE_DOMAIN = 4
|
||||
LIST_DOMAINS = 5
|
||||
MIGRATE_DOMAIN = 6
|
||||
CREATE_USER = 7
|
||||
|
||||
class NodeMenuScreen(MenuScreen):
|
||||
def __init__(self):
|
||||
MenuScreen.__init__(self, "Node Administration")
|
||||
|
||||
def get_menu_items(self):
|
||||
return (("Add A Virtual Machine", ADD_DOMAIN),
|
||||
("Start A Virtual Machine", START_DOMAIN),
|
||||
("Stop A Virtual Machine", STOP_DOMAIN),
|
||||
("Remove A Virtual Machine", REMOVE_DOMAIN),
|
||||
("List All Virtual Machines", LIST_DOMAINS),
|
||||
("Migrate Virtual Machine", MIGRATE_DOMAIN),
|
||||
("Create A User", CREATE_USER))
|
||||
|
||||
def handle_selection(self, item):
|
||||
if item is ADD_DOMAIN: AddDomain()
|
||||
elif item is START_DOMAIN: StartDomain()
|
||||
elif item is STOP_DOMAIN: StopDomain()
|
||||
elif item is REMOVE_DOMAIN: RemoveDomain()
|
||||
elif item is LIST_DOMAINS: ListDomains()
|
||||
elif item is MIGRATE_DOMAIN: MigrateDomain()
|
||||
elif item is CREATE_USER: CreateUser()
|
||||
|
||||
def NodeMenu():
|
||||
screen = NodeMenuScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,145 @@
|
|||
# poolconfig.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 Storage
|
||||
|
||||
ROOT_TARGET_PATH="/var/lib/libvirt/images/%s"
|
||||
|
||||
class PoolConfig:
|
||||
def __init__(self, libvirt):
|
||||
self.__libvirt = libvirt
|
||||
self.__name = ""
|
||||
self.set_type(None)
|
||||
self.__format = None
|
||||
self.__hostname = ""
|
||||
self.__target_path = ""
|
||||
self.__source_path = ""
|
||||
self.__build_pool = False
|
||||
|
||||
def get_pool(self):
|
||||
return self.__pool
|
||||
|
||||
def set_name(self, name):
|
||||
self.__name = name
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def set_type(self, pooltype):
|
||||
self.__type = pooltype
|
||||
self.__needs_target_path = False
|
||||
self.__needs_format = False
|
||||
self.__needs_target_path = False
|
||||
self.__needs_format = False
|
||||
self.__needs_hostname = False
|
||||
self.__needs_source_path = False
|
||||
self.__needs_build_pool = False
|
||||
if pooltype is not None:
|
||||
if pooltype is Storage.StoragePool.TYPE_DIR:
|
||||
self.__needs_target_path = True
|
||||
self.__target_path = ROOT_TARGET_PATH % self.__name
|
||||
self.__build_pool = True
|
||||
elif pooltype is Storage.StoragePool.TYPE_DISK:
|
||||
self.__needs_target_path = True
|
||||
self.__needs_format = True
|
||||
self.__needs_source_path = True
|
||||
self.__needs_build_pool = True
|
||||
elif pooltype is Storage.StoragePool.TYPE_FS:
|
||||
self.__needs_target_path = True
|
||||
self.__needs_format = True
|
||||
self.__needs_source_path = True
|
||||
self.__build_pool = True
|
||||
elif pooltype is Storage.StoragePool.TYPE_ISCSI:
|
||||
self.__needs_target_path = True
|
||||
self.__needs_hostname = True
|
||||
self.__needs_source_path = True
|
||||
self.__build_pool = False
|
||||
elif pooltype is Storage.StoragePool.TYPE_LOGICAL:
|
||||
self.__needs_target_path = True
|
||||
self.__needs_source_path = True
|
||||
self.__needs_build_pool = True
|
||||
elif pooltype is Storage.StoragePool.TYPE_NETFS:
|
||||
self.__needs_target_path = True
|
||||
self.__needs_format = True
|
||||
self.__needs_hostname = True
|
||||
self.__needs_source_path = True
|
||||
self.__build_pool = True
|
||||
# create pool
|
||||
pool_class = Storage.StoragePool.get_pool_class(self.__type)
|
||||
self.__pool = pool_class(name = self.__name,
|
||||
conn = self.__libvirt.get_connection())
|
||||
if self.__needs_format:
|
||||
self.__format = self.__pool.formats[0]
|
||||
else:
|
||||
self.__type = Storage.StoragePool.get_pool_types()[0]
|
||||
|
||||
def get_type(self):
|
||||
return self.__type
|
||||
|
||||
def needs_target_path(self):
|
||||
return self.__needs_target_path
|
||||
|
||||
def needs_format(self):
|
||||
return self.__needs_format
|
||||
|
||||
def needs_hostname(self):
|
||||
return self.__needs_hostname
|
||||
|
||||
def source_must_be_absolute(self):
|
||||
if self.__type is Storage.StoragePool.TYPE_ISCSI:
|
||||
return False
|
||||
return True
|
||||
|
||||
def needs_source_path(self):
|
||||
return self.__needs_source_path
|
||||
|
||||
def needs_build_pool(self):
|
||||
return self.__needs_build_pool
|
||||
|
||||
def set_target_path(self, path):
|
||||
self.__target_path = path
|
||||
|
||||
def get_target_path(self):
|
||||
return self.__target_path
|
||||
|
||||
def get_formats(self):
|
||||
return self.__pool.formats
|
||||
|
||||
def set_format(self, format):
|
||||
self.__format = format
|
||||
|
||||
def get_format(self):
|
||||
return self.__format
|
||||
|
||||
def set_hostname(self, hostname):
|
||||
self.__hostname = hostname
|
||||
|
||||
def get_hostname(self):
|
||||
return self.__hostname
|
||||
|
||||
def set_source_path(self, source_path):
|
||||
self.__source_path = source_path
|
||||
|
||||
def get_source_path(self):
|
||||
return self.__source_path
|
||||
|
||||
def set_build_pool(self, build_pool):
|
||||
self.__build_pool = build_pool
|
||||
|
||||
def get_build_pool(self):
|
||||
return self.__build_pool
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# removedomain.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
class RemoveDomainConfigScreen(DomainListConfigScreen):
|
||||
LIST_PAGE = 1
|
||||
CONFIRM_PAGE = 2
|
||||
REMOVE_PAGE = 3
|
||||
|
||||
def __init__(self):
|
||||
DomainListConfigScreen.__init__(self, "Remove A Domain")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is self.LIST_PAGE: return self.get_domain_list_page(screen)
|
||||
elif page is self.CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
elif page is self.REMOVE_PAGE: return self.get_remove_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is self.LIST_PAGE: return self.has_selectable_domains()
|
||||
elif page is self.CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page is self.CONFIRM_PAGE: return True
|
||||
elif page is self.REMOVE_PAGE: return True
|
||||
return False
|
||||
|
||||
def get_back_page(self, page):
|
||||
if page is self.CONFIRM_PAGE: return self.LIST_PAGE
|
||||
elif page is self.REMOVE_PAGE: return self.LIST_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is self.LIST_PAGE:
|
||||
if self.get_selected_domain() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("You must first select a domain.")
|
||||
elif page is self.CONFIRM_PAGE:
|
||||
if self.__confirm_remove.value():
|
||||
domain = self.get_selected_domain()
|
||||
try:
|
||||
self.get_libvirt().undefine_domain(domain)
|
||||
return True
|
||||
except Exception, error:
|
||||
errors.append("Failed to remove %s." % domain)
|
||||
errors.append(str(error))
|
||||
else:
|
||||
errors.append("You must confirm undefining the domain to proceed.")
|
||||
return False
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
self.__confirm_remove = Checkbox("Check here to confirm undefining %s." % self.get_selected_domain(), 0)
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__confirm_remove, 0, 0)
|
||||
return [grid]
|
||||
|
||||
def get_remove_page(self, screen):
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(Label("%s has been removed." % self.get_selected_domain()), 0, 0)
|
||||
return [grid]
|
||||
|
||||
def RemoveDomain():
|
||||
screen = RemoveDomainConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,66 @@
|
|||
# removehost.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
SELECT_HOST_PAGE = 1
|
||||
CONFIRM_REMOVE_PAGE = 2
|
||||
|
||||
class RemoveHostConfigScreen(HostListConfigScreen):
|
||||
def __init__(self):
|
||||
HostListConfigScreen.__init__(self, "Remove Host Connection")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is SELECT_HOST_PAGE: return self.get_connection_list_page(screen)
|
||||
elif page is CONFIRM_REMOVE_PAGE: return self.get_confirm_remove_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
return page is SELECT_HOST_PAGE and self.has_selectable_connections()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return page is CONFIRM_REMOVE_PAGE
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_REMOVE_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is SELECT_HOST_PAGE: return True
|
||||
elif page is CONFIRM_REMOVE_PAGE:
|
||||
if self.__confirm.value():
|
||||
return True
|
||||
else:
|
||||
errors.append("You must confirm removing the connection.")
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONFIRM_REMOVE_PAGE:
|
||||
self.get_virt_manager_config().remove_connection(self.get_selected_connection())
|
||||
self.set_finished()
|
||||
|
||||
def get_confirm_remove_page(self, screen):
|
||||
self.__confirm = Checkbox("Remove this connection: %s" % self.get_selected_connection(), 0)
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__confirm, 0, 0)
|
||||
return [Label("Remove Host Connection"),
|
||||
grid]
|
||||
|
||||
def RemoveHost():
|
||||
screen = RemoveHostConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# removepool.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
LIST_POOLS_PAGE = 1
|
||||
CONFIRM_PAGE = 2
|
||||
|
||||
class RemoveStoragePoolConfigScreen(StorageListConfigScreen):
|
||||
def __init__(self):
|
||||
StorageListConfigScreen.__init__(self, "Remove A Storage Pool")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_POOLS_PAGE: return self.get_storage_pool_list_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
return page is LIST_POOLS_PAGE and self.has_selectable_pools()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return False
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_POOLS_PAGE:
|
||||
if self.get_selected_pool() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("Please select a storage pool to be removed.")
|
||||
elif page is CONFIRM_PAGE:
|
||||
if self.__confirm.value():
|
||||
return True
|
||||
else:
|
||||
errors.append("You must confirm removing a storage pool.")
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONFIRM_PAGE:
|
||||
self.get_libvirt().destroy_storage_pool(self.get_selected_pool())
|
||||
self.get_libvirt().undefine_storage_pool(self.get_selected_pool())
|
||||
self.set_finished()
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
self.__confirm = Checkbox("Check here to confirm deleting pool: %s" % self.get_selected_pool())
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__confirm, 0, 0)
|
||||
return [Label("Remove Selected Storage Pool"),
|
||||
grid]
|
||||
|
||||
def RemoveStoragePool():
|
||||
screen = RemoveStoragePoolConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,76 @@
|
|||
# removevolume.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
from createmeter import CreateMeter
|
||||
from configscreen import *
|
||||
from volumeconfig import StorageVolumeConfig
|
||||
from utils import *
|
||||
|
||||
SELECT_POOL_PAGE = 1
|
||||
SELECT_VOLUME_PAGE = 2
|
||||
CONFIRM_PAGE = 3
|
||||
|
||||
class RemoveVolumeConfigScreen(StorageListConfigScreen):
|
||||
def __init__(self):
|
||||
StorageListConfigScreen.__init__(self, "Add A New Storage Volume")
|
||||
self.__config = StorageVolumeConfig()
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is SELECT_POOL_PAGE: return self.get_storage_pool_list_page(screen)
|
||||
elif page is SELECT_VOLUME_PAGE: return self.get_storage_volume_list_page(screen)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is SELECT_POOL_PAGE: return self.has_selectable_pools()
|
||||
elif page is SELECT_VOLUME_PAGE: return self.has_selectable_volumes()
|
||||
return False
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is SELECT_POOL_PAGE: return self.get_selected_pool() is not None
|
||||
elif page is SELECT_VOLUME_PAGE: return self.get_selected_volume() is not None
|
||||
elif page is CONFIRM_PAGE:
|
||||
if self.__confirm.value():
|
||||
return True
|
||||
else:
|
||||
errors.append("You must confirm deleting a storage volume.")
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is CONFIRM_PAGE:
|
||||
self.get_libvirt().remove_storage_volume(self.get_selected_pool(), self.get_selected_volume())
|
||||
self.set_finished()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return page > SELECT_POOL_PAGE
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is CONFIRM_PAGE
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
self.__confirm = Checkbox("Check here to confirm deleting volume: %s" % self.get_selected_volume())
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__confirm, 0, 0)
|
||||
return [Label("Remove Selected Storage Volume"),
|
||||
grid]
|
||||
|
||||
def RemoveStorageVolume():
|
||||
screen = RemoveVolumeConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,47 @@
|
|||
# setup.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 setuptools import setup, find_packages
|
||||
|
||||
setup(name = "nodeadmin",
|
||||
version = "1.9.3",
|
||||
package_dir = {'nodeadmin': 'nodeadmin'},
|
||||
packages = find_packages('.'),
|
||||
entry_points = {
|
||||
'console_scripts': [
|
||||
'nodeadmin = nodeadmin.nodeadmin:NodeAdmin',
|
||||
'addvm = nodeadmin.adddomain:AddDomain',
|
||||
'startvm = nodeadmin.startdomain:StartDomain',
|
||||
'stopvm = nodeadmin.stopdomain:StopDomain',
|
||||
'rmvm = nodeadmin.removedomain:RemoveDomain',
|
||||
'migratevm = nodeadmin.migratedomain:MigradeDomain',
|
||||
'createuser = nodeadmin.createuser:CreateUser',
|
||||
'listvms = nodeadmin.listdomains:ListDomains',
|
||||
'definenet = nodeadmin.definenet:DefineNetwork',
|
||||
'createnet = nodeadmin.createnetwork:CreateNetwork',
|
||||
'destroynet = nodeadmin.destroynetwork:DestroyNetwork',
|
||||
'undefinenet = nodeadmin.undefinenetwork:UndefineNetwork',
|
||||
'listnets = nodeadmin.listnetworks:ListNetworks',
|
||||
'addpool = nodeadmin.addpool:AddStoragePool',
|
||||
'rmpool = nodeadmin.removepool:RemoveStoragePool',
|
||||
'startpool = nodeadmin.startpool:StartStoragePool',
|
||||
'stoppool = nodeadmin.stoppool:StopStoragePool',
|
||||
'addvolume = nodeadmin.addvolume:AddStorageVolume',
|
||||
'rmvolume = nodeadmin.removevolume:RemoveStorageVolume',
|
||||
'listpools = nodeadmin.listpools:ListPools']
|
||||
})
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# startdomain.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
class StartDomainConfigScreen(DomainListConfigScreen):
|
||||
LIST_PAGE = 1
|
||||
START_PAGE = 2
|
||||
|
||||
def __init__(self):
|
||||
DomainListConfigScreen.__init__(self, "Start A Domain")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is self.LIST_PAGE:
|
||||
return self.get_domain_list_page(screen, started = False)
|
||||
elif page is self.START_PAGE:
|
||||
return self.get_start_domain_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is self.LIST_PAGE: return self.has_selectable_domains()
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page is self.START_PAGE: return True
|
||||
return False
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is self.LIST_PAGE:
|
||||
if self.get_selected_domain() is not None:
|
||||
domain = self.get_selected_domain()
|
||||
try:
|
||||
self.get_libvirt().create_domain(domain)
|
||||
return True
|
||||
except Exception, error:
|
||||
errors.append("There was an error creating the domain: %s" % domain)
|
||||
errors.append(str(error))
|
||||
else:
|
||||
errors.append("You must first select a domain to start.")
|
||||
|
||||
def get_start_domain_page(self, screen):
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(Label("%s was successfully started." % self.get_selected_domain()), 0, 0)
|
||||
return [grid]
|
||||
|
||||
def StartDomain():
|
||||
screen = StartDomainConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# startpool.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
LIST_POOLS_PAGE = 1
|
||||
FINAL_PAGE = 2
|
||||
|
||||
class StartStoragePoolConfigScreen(StorageListConfigScreen):
|
||||
def __init__(self):
|
||||
StorageListConfigScreen.__init__(self, "Start A Storage Pool")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_POOLS_PAGE: return self.get_storage_pool_list_page(screen, created = False)
|
||||
elif page is FINAL_PAGE: return self.get_final_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
return page is LIST_POOLS_PAGE and self.has_selectable_pools()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return False
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is FINAL_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_POOLS_PAGE:
|
||||
if self.get_selected_pool() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("Please select a storage pool to be started.")
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is LIST_POOLS_PAGE:
|
||||
self.get_libvirt().create_storage_pool(self.get_selected_pool())
|
||||
self.set_finished()
|
||||
|
||||
def get_final_page(self, screen):
|
||||
return [Label("Storage pool started: %s" % self.get_selected_pool())]
|
||||
|
||||
def StartStoragePool():
|
||||
screen = StartStoragePoolConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# stopdomain.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
class StopDomainConfigScreen(DomainListConfigScreen):
|
||||
LIST_PAGE = 1
|
||||
STOP_PAGE = 2
|
||||
|
||||
def __init__(self):
|
||||
DomainListConfigScreen.__init__(self, "Stop A Domain")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is self.LIST_PAGE:
|
||||
return self.get_domain_list_page(screen, defined = False)
|
||||
elif page is self.STOP_PAGE:
|
||||
return self.get_stop_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is self.LIST_PAGE: return self.has_selectable_domains()
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page is self.STOP_PAGE: return True
|
||||
return False
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is self.LIST_PAGE:
|
||||
if self.get_selected_domain() is not None:
|
||||
domain = self.get_selected_domain()
|
||||
try:
|
||||
self.get_libvirt().destroy_domain(domain)
|
||||
return True
|
||||
except Exception, error:
|
||||
errors.append("There was an error stop the domain: %s" % domain)
|
||||
errors.append(str(error))
|
||||
else:
|
||||
errors.append("You must first select a domain to stop.")
|
||||
return False
|
||||
|
||||
def get_stop_page(self, screen):
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(Label("%s was successfully stoped." % self.get_selected_domain()), 0, 0)
|
||||
return [grid]
|
||||
|
||||
def StopDomain():
|
||||
screen = StopDomainConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# stoppool.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
LIST_POOLS_PAGE = 1
|
||||
FINAL_PAGE = 2
|
||||
|
||||
class StopStoragePoolConfigScreen(StorageListConfigScreen):
|
||||
def __init__(self):
|
||||
StorageListConfigScreen.__init__(self, "Stop A Storage Pool")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_POOLS_PAGE: return self.get_storage_pool_list_page(screen, defined = False)
|
||||
elif page is FINAL_PAGE: return self.get_final_page(screen)
|
||||
|
||||
def page_has_next(self, page):
|
||||
return page is LIST_POOLS_PAGE and self.has_selectable_pools()
|
||||
|
||||
def page_has_back(self, page):
|
||||
return False
|
||||
|
||||
def page_has_finish(self, page):
|
||||
return page is FINAL_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_POOLS_PAGE:
|
||||
if self.get_selected_pool() is not None:
|
||||
return True
|
||||
else:
|
||||
errors.append("Please select a storage pool to be stopped.")
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is LIST_POOLS_PAGE:
|
||||
self.get_libvirt().destroy_storage_pool(self.get_selected_pool())
|
||||
self.set_finished()
|
||||
|
||||
def get_final_page(self, screen):
|
||||
return [Label("Storage pool stopped: %s" % self.get_selected_pool())]
|
||||
|
||||
def StopStoragePool():
|
||||
screen = StopStoragePoolConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,63 @@
|
|||
# storagemenu.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 *
|
||||
import traceback
|
||||
|
||||
from menuscreen import MenuScreen
|
||||
from addpool import AddStoragePool
|
||||
from startpool import StartStoragePool
|
||||
from stoppool import StopStoragePool
|
||||
from removepool import RemoveStoragePool
|
||||
from addvolume import AddStorageVolume
|
||||
from removevolume import RemoveStorageVolume
|
||||
from listpools import ListStoragePools
|
||||
|
||||
ADD_POOL = 1
|
||||
START_POOL = 2
|
||||
STOP_POOL = 3
|
||||
REMOVE_POOL = 4
|
||||
ADD_VOLUME = 5
|
||||
REMOVE_VOLUME = 6
|
||||
LIST_POOLS = 7
|
||||
|
||||
class StoragePoolMenuScreen(MenuScreen):
|
||||
def __init__(self):
|
||||
MenuScreen.__init__(self, "Storage Pool Administration")
|
||||
|
||||
def get_menu_items(self):
|
||||
return (("Add A Storage Pool", ADD_POOL),
|
||||
("Start A Storage Pool", START_POOL),
|
||||
("Stop A Storage Pool", STOP_POOL),
|
||||
("Remove A Storage Pool", REMOVE_POOL),
|
||||
("Add A Storage Volume", ADD_VOLUME),
|
||||
("Remove A Storage Volume", REMOVE_VOLUME),
|
||||
("List Storage Pools", LIST_POOLS))
|
||||
|
||||
def handle_selection(self, item):
|
||||
if item is ADD_POOL: AddStoragePool()
|
||||
elif item is START_POOL: StartStoragePool()
|
||||
elif item is STOP_POOL: StopStoragePool()
|
||||
elif item is REMOVE_POOL: RemoveStoragePool()
|
||||
elif item is ADD_VOLUME: AddStorageVolume()
|
||||
elif item is REMOVE_VOLUME: RemoveStorageVolume()
|
||||
elif item is LIST_POOLS: ListStoragePools()
|
||||
|
||||
def StoragePoolMenu():
|
||||
screen = StoragePoolMenuScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,88 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# undefinenetwork.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 configscreen import *
|
||||
|
||||
LIST_PAGE = 1
|
||||
CONFIRM_PAGE = 2
|
||||
UNDEFINE_PAGE = 3
|
||||
|
||||
class UndefineNetworkConfigScreen(NetworkListConfigScreen):
|
||||
def __init__(self):
|
||||
NetworkListConfigScreen.__init__(self, "Undefine A Network")
|
||||
|
||||
def get_elements_for_page(self, screen, page):
|
||||
if page is LIST_PAGE: return self.get_network_list_page(screen, created = False)
|
||||
elif page is CONFIRM_PAGE: return self.get_confirm_page(screen)
|
||||
elif page is UNDEFINE_PAGE: return self.get_undefine_network_page(screen)
|
||||
|
||||
def process_input(self, page, errors):
|
||||
if page is LIST_PAGE:
|
||||
network = self.get_selected_network()
|
||||
self.get_libvirt().undefine_network(network)
|
||||
return True
|
||||
|
||||
def page_has_next(self, page):
|
||||
if page is LIST_PAGE: return self.has_selectable_networks()
|
||||
if page is CONFIRM_PAGE: return True
|
||||
return False
|
||||
|
||||
def page_has_back(self, page):
|
||||
if page is CONFIRM_PAGE: return True
|
||||
if page is UNDEFINE_PAGE: return True
|
||||
return False
|
||||
|
||||
def get_back_page(self, page):
|
||||
if page is CONFIRM_PAGE: return LIST_PAGE
|
||||
elif page is UNDEFINE_PAGE: return LIST_PAGE
|
||||
|
||||
def validate_input(self, page, errors):
|
||||
if page is LIST_PAGE: return True
|
||||
elif page is CONFIRM_PAGE:
|
||||
if self.__confirm_undefine.value():
|
||||
return True
|
||||
else:
|
||||
errors.append("You must confirm undefining %s." % self.get_selected_network())
|
||||
elif page is UNDEFINE_PAGE: return True
|
||||
return False
|
||||
|
||||
def process_input(self, page):
|
||||
if page is LIST_PAGE: return True
|
||||
elif page is CONFIRM_PAGE:
|
||||
network = self.get_selected_network()
|
||||
self.get_libvirt().undefine_network(network)
|
||||
return True
|
||||
elif page is UNDEFINE_PAGE: return True
|
||||
return False
|
||||
|
||||
def get_confirm_page(self, screen):
|
||||
self.__confirm_undefine = Checkbox("Check here to confirm undefining %s." % self.get_selected_network(), 0)
|
||||
grid = Grid(1, 1)
|
||||
grid.setField(self.__confirm_undefine, 0, 0)
|
||||
return [grid]
|
||||
|
||||
def get_undefine_network_page(self, screen):
|
||||
return [Label("Network Is Undefined"),
|
||||
Label("Network has been undefined: %s" % self.get_selected_network())]
|
||||
|
||||
def UndefineNetwork():
|
||||
screen = UndefineNetworkConfigScreen()
|
||||
screen.start()
|
|
@ -0,0 +1,37 @@
|
|||
# userworker.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 libuser
|
||||
|
||||
class UserWorker:
|
||||
'''Provides APIs for creating, modifying and deleting user accounts.'''
|
||||
def __init__(self):
|
||||
self.__admin = libuser.admin()
|
||||
|
||||
def create_user(self, username, password, other_group):
|
||||
'''Creates a new user account with the provides username,
|
||||
password. The user is also added to the optional group
|
||||
if one is specified.'''
|
||||
user = self.__admin.initUser(username)
|
||||
user.set('pw_passwd', password)
|
||||
self.__admin.addUser(user)
|
||||
if other_group is not None:
|
||||
group = self.__admin.lookupGroupByName(other_group)
|
||||
if group is None: raise Exception("Invalid group specified: %s" % other_group)
|
||||
user.add('pw_gid', group.get('pw_gid')[0])
|
||||
self.__admin.modifyUser(user)
|
|
@ -0,0 +1,44 @@
|
|||
# definedomain.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 logging
|
||||
import re
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(asctime)s %(levelname)-8s %(message)s',
|
||||
datefmt='%a, %d %b %Y %H:%M:%S',
|
||||
filename='/var/log/ovirt-nodeadmin.log',
|
||||
filemode='w')
|
||||
|
||||
def string_is_not_blank(value):
|
||||
if len(value) > 0: return True
|
||||
return False
|
||||
|
||||
def string_has_no_spaces(value):
|
||||
if re.match("^[a-zA-Z0-9_]*$", value):
|
||||
return True
|
||||
return False
|
||||
|
||||
def size_as_mb_or_gb(size):
|
||||
'''Takes a size value in bytes and returns it as either a
|
||||
value in megabytes or gigabytes.'''
|
||||
if size / 1024.0**3 < 1.0:
|
||||
result = "%0.2f MB" % (size / 1024.0**2)
|
||||
else:
|
||||
result = "%0.2f GB" % (size / 1024.0**3)
|
||||
return result
|
|
@ -0,0 +1,83 @@
|
|||
# volumeconfig.py - Copyright (C) 2009 Red Hat, Inc.
|
||||
# Written by Darryl L. Pierce <dpierce@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 virtinst
|
||||
from virtinst import Storage
|
||||
|
||||
class StorageVolumeConfig:
|
||||
def __init__(self):
|
||||
self.__pool = None
|
||||
self.__name = ""
|
||||
self.__formats = None
|
||||
self.__format = None
|
||||
self.__max_capacity = 10000
|
||||
self.__allocation = 0
|
||||
|
||||
def set_pool(self, pool):
|
||||
self.__pool = pool
|
||||
self.__formats = None
|
||||
self.__pool_type = virtinst.util.get_xml_path(self.__pool.XMLDesc(0), '/pool/@type')
|
||||
self.__volume_class = Storage.StoragePool.get_volume_for_pool(self.__pool_type)
|
||||
|
||||
def get_pool(self):
|
||||
return self.__pool
|
||||
|
||||
def create_volume(self):
|
||||
volume = self.__volume_class(name = self.__name + ".img",
|
||||
allocation = self.__allocation * 1024**2,
|
||||
capacity = self.__max_capacity * 1024**2,
|
||||
pool = self.__pool)
|
||||
volume.pool = self.__pool
|
||||
if self.needs_format():
|
||||
volume.format = self.__format
|
||||
return volume
|
||||
|
||||
def set_name(self, name):
|
||||
self.__name = name
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def needs_format(self):
|
||||
if self.__pool.__dict__.keys().count("get_formats_for_pool") > 0:
|
||||
return self.__pool.get_formats_for_pool() is not 0
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_formats_for_pool(self):
|
||||
if self.__formats is None:
|
||||
self.__formats = self.__volume_class.formats
|
||||
return self.__formats
|
||||
|
||||
def set_format(self, format):
|
||||
self.__format = format
|
||||
|
||||
def get_format(self):
|
||||
return self.__format
|
||||
|
||||
def set_max_capacity(self, capacity):
|
||||
self.__max_capacity = capacity
|
||||
|
||||
def get_max_capacity(self):
|
||||
return self.__max_capacity
|
||||
|
||||
def set_allocation(self, allocation):
|
||||
self.__allocation = allocation
|
||||
|
||||
def get_allocation(self):
|
||||
return self.__allocation
|
Loading…
Reference in New Issue