Index: umc/modules/univention/management/console/handlers/uvmm/uvmmd.py =================================================================== --- umc/modules/univention/management/console/handlers/uvmm/uvmmd.py (Revision 17805) +++ umc/modules/univention/management/console/handlers/uvmm/uvmmd.py (Arbeitskopie) @@ -171,7 +171,7 @@ req = protocol.Request_GROUP_LIST() if not self.send( req.pack() ): raise ConnectionError() - + groups = self.recv_blocking() tree_data = [] @@ -215,12 +215,12 @@ group.append( node_info.data ) return group - + def get_node_tree( self ): req = protocol.Request_GROUP_LIST() if not self.send( req.pack() ): raise ConnectionError() - + groups = self.recv_blocking() tree_data = [] @@ -291,7 +291,7 @@ if not self.send( req.pack() ): raise ConnectionError() return self.recv_blocking() - + if __name__ == '__main__': notifier.init() Index: umc/modules/univention/management/console/handlers/uvmm/__init__.py =================================================================== --- umc/modules/univention/management/console/handlers/uvmm/__init__.py (Revision 17805) +++ umc/modules/univention/management/console/handlers/uvmm/__init__.py (Arbeitskopie) @@ -195,6 +195,7 @@ umch.simpleHandler.__init__( self, command_description ) self.uvmm = uvmmd.Client( auto_connect = False ) self.device_wizard = DeviceWizard( 'uvmm/device/create' ) + self.domain_wizard = InstanceWizard( 'uvmm/domain/create' ) @staticmethod def _getattr( object, attr, default = '' ): @@ -639,7 +640,7 @@ self.finished( object.id(), res ) def uvmm_domain_state( self, object ): - ud.debug( ud.ADMIN, ud.INFO, 'Domain State' ) + ud.debug( ud.ADMIN, ud.INFO, 'Domain State' ) res = umcp.Response( object ) ud.debug( ud.ADMIN, ud.INFO, 'Domain State: change to %s' % object.options[ 'state' ] ) @@ -653,7 +654,7 @@ self.finished( object.id(), res ) def uvmm_domain_create( self, object ): - ud.debug( ud.ADMIN, ud.INFO, 'Domain create' ) + ud.debug( ud.ADMIN, ud.INFO, 'Device create' ) ( success, res ) = TreeView.safely_get_tree( self.uvmm, object, ( 'group', 'node', 'domain' ) ) if not success: self.finished(object.id(), res) @@ -661,14 +662,28 @@ node_uri = self.uvmm.node_name2uri( object.options[ 'node' ] ) node = self.uvmm.get_node_info( node_uri ) - content = self._dlg_domain_settings( object, node, None ) - res.dialog[ 0 ].set_dialog( umcd.Section( _( 'Add virtual instance' ), content, hideable = False ) ) + self.domain_wizard.action( object, node ) + page = self.domain_wizard.setup( object ) + res.dialog[ 0 ].set_dialog( page ) self.finished(object.id(), res) + # ud.debug( ud.ADMIN, ud.INFO, 'Domain create' ) + # ( success, res ) = TreeView.safely_get_tree( self.uvmm, object, ( 'group', 'node', 'domain' ) ) + # if not success: + # self.finished(object.id(), res) + # return + # node_uri = self.uvmm.node_name2uri( object.options[ 'node' ] ) + # node = self.uvmm.get_node_info( node_uri ) + # content = self._dlg_domain_settings( object, node, None ) + + # res.dialog[ 0 ].set_dialog( umcd.Section( _( 'Add virtual instance' ), content, hideable = False ) ) + + # self.finished(object.id(), res) + def uvmm_domain_remove_images( self, object ): - ud.debug( ud.ADMIN, ud.INFO, 'Domain remove images' ) + ud.debug( ud.ADMIN, ud.INFO, 'Domain remove images' ) ( success, res ) = TreeView.safely_get_tree( self.uvmm, object, ( 'group', 'node', 'domain' ) ) if not success: self.finished(object.id(), res) @@ -694,7 +709,7 @@ lst.add_row( [ umcd.Cell( umcd.Text( '' ), attributes = { 'width' : '10' } ), umcd.Cell( chk_button, attributes = { 'colspan' : '2' } ) ] ) opts = copy.copy( object.options ) - opts[ 'drives' ] = [] + opts[ 'drives' ] = [] back = umcp.SimpleCommand( 'uvmm/domain/overview', options = opts ) req = umcp.SimpleCommand( 'uvmm/domain/remove', options = opts ) fail_overview_cmd = umcp.SimpleCommand( 'uvmm/domain/overview', options = opts ) @@ -703,15 +718,15 @@ button = umcd.Button( _( 'Remove' ), actions = [ umcd.Action( req, boxes ), umcd.Action( success_overview_cmd, status_range = umcd.Action.SUCCESS ), umcd.Action( fail_overview_cmd, status_range = umcd.Action.FAILURE ) ] ) lst.add_row( [ '' ] ) lst.add_row( [ umcd.Cell( cancel, attributes = { 'align' : 'right', 'colspan' : '2' } ), umcd.Cell( button, attributes = { 'align' : 'right' } ) ] ) - + res.dialog[ 0 ].set_dialog( umcd.Section( _( 'Remove the virtual instance %(instance)s?' ) % { 'instance' : domain_info.name }, lst, hideable = False ) ) self.finished(object.id(), res) - + def uvmm_domain_remove( self, object ): - ud.debug( ud.ADMIN, ud.INFO, 'Domain remove' ) + ud.debug( ud.ADMIN, ud.INFO, 'Domain remove' ) res = umcp.Response( object ) - + # remove domain node_uri = self.uvmm.node_name2uri( object.options[ 'node' ] ) domain_info = self.uvmm.get_domain_info( node_uri, object.options[ 'domain' ] ) @@ -725,14 +740,16 @@ self.finished( object.id(), res, report = _( 'The instance %(domain)s was removed successfully' ) % { 'domain' : object.options[ 'domain' ] } ) def uvmm_device_create( self, object ): - ud.debug( ud.ADMIN, ud.INFO, 'Device create' ) + ud.debug( ud.ADMIN, ud.INFO, 'Device create' ) ( success, res ) = TreeView.safely_get_tree( self.uvmm, object, ( 'group', 'node', 'domain' ) ) if not success: self.finished(object.id(), res) return + node_uri = self.uvmm.node_name2uri( object.options[ 'node' ] ) + node = self.uvmm.get_node_info( node_uri ) - self.device_wizard.action( object ) + self.device_wizard.action( object, node ) page = self.device_wizard.setup( object ) res.dialog[ 0 ].set_dialog( page ) - + self.finished(object.id(), res) Index: umc/modules/univention/management/console/handlers/uvmm/wizards.py =================================================================== --- umc/modules/univention/management/console/handlers/uvmm/wizards.py (Revision 17805) +++ umc/modules/univention/management/console/handlers/uvmm/wizards.py (Arbeitskopie) @@ -45,12 +45,13 @@ self.title = title self.description = description self.options = [] + self.actions = [] self.buttons = [] def setup( self, command, options, prev = True, next = True, finish = False ): wizard = umcd.Wizard( self.title ) - wizard._content.add_row( [ umcd.Fill( 2, self.description ), ] ) - wizard._content.add_row( [ umcd.Fill( 2, umcd.Text( '' ) ), ] ) + wizard._content.add_row( [ umcd.Fill( 2, str( self.description ) ), ] ) + wizard._content.add_row( [ umcd.Fill( 2, '' ), ] ) items = [] for option in self.options: if hasattr( option, 'option' ): @@ -58,7 +59,15 @@ if option.option in options: option.default = options[ option.option ] wizard._content.add_row( [ option, ] ) - wizard._content.add_row( [ umcd.Fill( 2, umcd.Text( '' ) ), ] ) + wizard._content.add_row( [ umcd.Fill( 2, '' ), ] ) + if self.actions: + # add already collected options to actions + for button in self.actions: + for action in button.actions: + action.command.options.update( options ) + wizard._content.add_row( [ umcd.List( content = [ self.actions, ], attributes = { 'colspan' : '2' } ), ] ) + wizard._content.add_row( [ umcd.Fill( 2, '' ), ] ) + if not self.buttons: if next: opts = copy.copy( options ) @@ -136,12 +145,15 @@ return self[ self.current ] + def reset( self ): + self.current = None + class DeviceWizard( IWizard ): def __init__( self, command ): IWizard.__init__( self, command ) self.title = _( 'Add a device' ) self.pool_syntax = DynamicSelect( _( 'Storage pool' ) ) - self.pool_syntax.update_choices( [ '/var/lib/libvirt/images', '/var/lib/xen/images' ] ) + # self.pool_syntax.update_choices( [ '/var/lib/libvirt/images', '/var/lib/xen/images' ] ) self.image_syntax = DynamicSelect( _( 'Device image' ) ) # page 0 @@ -171,6 +183,14 @@ page = Page( self.title, _( 'The following device will be create:' ) ) self.append( page ) + def action( self, object, node ): + self.node = node + if self.current == None: + # read pool + self.pool_syntax.update_choices( [ storage.name for storage in self.node.storages ] ) + + return IWizard.action( object ) + def next( self, object ): if self.current == 0: #which device type? if object.options[ 'device-type' ] == 'disk': @@ -216,18 +236,93 @@ self.node = None self.profile_syntax = DynamicSelect( _( 'Profiles' ) ) self.profile_syntax.update_choices( [ item[ 'name' ] for item in self.udm.get_profiles() ] ) + self.arch_syntax = DynamicSelect( _( 'Architecture' ) ) + self.virttech_syntax = DynamicSelect( _( 'Virtualisation Technique' ) ) + self.device_wizard = DeviceWizard( command ) + self.device_wizard_active = False + self.actions[ 'new-device' ] = self.new_device # page 0 - page = Page( self.title, _( 'By selecting a profile for the virtual instance most of the settings will be filled out with default values. In the following steps these values may be modified.' ) ) + page = Page( self.title, _( 'By selecting a profile for the virtual instance most of the settings will be filled out with default values. In the following step these values may be modified.' ) ) page.options.append( umcd.make( ( 'instance-profile', self.profile_syntax ) ) ) self.append( page ) # page 1 - page = Page( self.title, _( '' ) ) - page.options.append( umcd.make( ( 'instance-name', umc.String( _( 'Name' ) ) ) ) ) - page.options.append( umcd.make( ( 'instance-arch', umc.String( _( 'Name' ) ) ) ) ) + page = Page( self.title, _( 'The settings shown below are all read from the selected profile. Please verify that these values fits your environment. At least the name for the virtual instance should be modified.' ) ) + page.options.append( umcd.make( ( 'name', umc.String( _( 'Name' ) ) ) ) ) + page.options.append( umcd.make( ( 'arch', self.arch_syntax ) ) ) + page.options.append( umcd.make( ( 'type', self.virttech_syntax ) ) ) + page.options.append( umcd.make( ( 'memory', umc.String( _( 'Memory' ) ) ) ) ) + page.options.append( umcd.make( ( 'cpus', NumberSelect( _( 'CPUs' ) ) ) ) ) + page.options.append( umcd.make( ( 'vnc', umc.Boolean( _( 'VNC' ) ) ) ) ) + page.options.append( umcd.make( ( 'kblayout', KBLayoutSelect( _( 'Keyboard layout' ) ) ) ) ) self.append( page ) + # page 2 + page = Page( self.title, _( 'The virtual instance will be created with the following settings. ' ) ) + # FIXME: show settings + page.options.append( umcd.HTML( _( 'Attached devices' ) ) ) + # FIXME: show devices + page.options.append( umcd.Text( _( "You may now add additional devices by clicking the button 'Add device'" ) ) ) + add_btn = umcd.Button( _( 'Add device' ), 'uvmm/add', ( umcd.Action( umcp.SimpleCommand( command, options = { 'action' : 'new-device' } ) ), ) ) + page.actions.append( add_btn ) + self.append( page ) + def action( self, object, node ): self.node = node + # at startup + if self.current == None: + # read capabilities + types = [] + archs = [] + for template in node.capabilities: + if not template.virt_tech in types: + types.append( template.virt_tech ) + if not template.arch in archs: + archs.append( template.arch ) + self.virttech_syntax.update_choices( types ) + self.arch_syntax.update_choices( archs ) return IWizard.action( self, object ) + + def next( self, object ): + if self.device_wizard_active: + return self.device_wizard.next( object ) + if self.current == 0: + profile = self.udm.get_profile( object.options[ 'instance-profile' ] ) + object.options[ 'name' ] = profile[ 'name_prefix' ] + object.options[ 'arch' ] = profile[ 'virttech' ] + object.options[ 'memory' ] = profile[ 'ram' ] + object.options[ 'cpus' ] = profile[ 'cpus' ] + object.options[ 'vnc' ] = profile[ 'vnc' ] + object.options[ 'kblayout' ] = profile[ 'kblayout' ] + + return IWizard.next( self, object ) + + def prev( self, object ): + if self.device_wizard_active: + return self.device_wizard.prev( object ) + + return IWizard.prev( self, object ) + + def finish( self, object ): + if self.device_wizard_active: + self.device_wizard_active = False + # FIXME: read result, temporarily store the device in UVMM data structure + self.device_wizard.reset() + return self[ self.current ] + else: + pass # FIXME: create instance + + def new_device( self, object ): + # all next, prev and finished events must be redirected to the device wizard + self.device_wizard_active = True + return self.device_wizard.next( object ) + + def setup( self, object ): + if self.device_wizard_active: + return self.device_wizard.setup( object ) + return IWizard.setup( self, object ) + + def reset( self ): + # FIXME: reset list of devices + IWizard.reset( self ) Index: umc/modules/univention/management/console/handlers/uvmm/udm.py =================================================================== --- umc/modules/univention/management/console/handlers/uvmm/udm.py (Revision 17805) +++ umc/modules/univention/management/console/handlers/uvmm/udm.py (Arbeitskopie) @@ -62,6 +62,15 @@ return res + def get_profile( self, name ): + try: + res = univention.admin.modules.lookup( uvmm_profile, self.co, self.lo, filter = 'cn=%s' % name, scope='one', base = self.base, required = False, unique = True ) + except univention.admin.uexceptions.base, e: + ud.debug( ud.ADMIN, ud.ERROR, 'UVMM/UDM: get_profiles: error while searching for template: %s' % str( e ) ) + return {} + + return res[ 0 ] + if __name__ == '__main__': udm = Client() print udm.get_profiles()