[Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...

rmccabe at sourceware.org rmccabe at sourceware.org
Mon Mar 12 04:22:27 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	conga
Branch: 	RHEL5
Changes by:	rmccabe at sourceware.org	2007-03-12 04:22:26

Modified files:
	luci/cluster   : form-chooser form-macros 
	luci/site/luci/Extensions: cluster_adapters.py 
	                           conga_constants.py ricci_bridge.py 

Log message:
	Frontend support for virtual service live migration

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.12.2.4&r2=1.12.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.90.2.20&r2=1.90.2.21
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.120.2.23&r2=1.120.2.24
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.19.2.8&r2=1.19.2.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.30.2.18&r2=1.30.2.19

--- conga/luci/cluster/form-chooser	2007/03/01 00:31:08	1.12.2.4
+++ conga/luci/cluster/form-chooser	2007/03/12 04:22:25	1.12.2.5
@@ -92,6 +92,9 @@
     <span tal:omit-tag="" tal:condition="python: ptype == '28'">
      <div metal:use-macro="here/form-macros/macros/servicerestart"/>
     </span>
+    <span tal:omit-tag="" tal:condition="python: ptype == '59'">
+     <div metal:use-macro="here/form-macros/macros/servicemigrate"/>
+    </span>
     <span tal:omit-tag="" tal:condition="python: ptype == '30'">
      <div metal:use-macro="here/resource-form-macros/macros/resources-form"/>
     </span>
--- conga/luci/cluster/form-macros	2007/03/05 16:50:09	1.90.2.20
+++ conga/luci/cluster/form-macros	2007/03/12 04:22:25	1.90.2.21
@@ -3876,12 +3876,12 @@
 
 			<tr class="cluster service info_top">
 				<td class="cluster service service_name">
-					<strong class="cluster service">Service Name:</strong>
+					<strong class="cluster service">Service Name</strong>
 					<a tal:attributes="
 						href svc/cfgurl;
 						class python: 'cluster service ' + (running and 'running' or 'stopped')"
 						tal:content="svc/name" />
-					<tal:block tal:condition="exists:svc/virt">
+					<tal:block tal:condition="exists:svc/is_vm">
 						(virtual service)
 					</tal:block>
 				</td>
@@ -3898,7 +3898,7 @@
 
 							<option
 								tal:condition="running"
-								tal:attributes="value svc/retstarturl| nothing"
+								tal:attributes="value svc/restarturl | nothing"
 								tal:content="string:Restart this service" />
 
 							<option
@@ -3909,14 +3909,40 @@
 							<option
 								tal:condition="not: running"
 								tal:attributes="value svc/enableurl | nothing"
-								tal:content="string:Start this service" />
+								tal:content="string:Enable this service" />
 
 							<option
 								tal:condition="not: running"
 								tal:attributes="value svc/delurl | nothing"
 								tal:content="string:Delete this service" />
+
 							<option value="">----------</option>
-							<option tal:repeat="starturl svc/links" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+							<tal:block tal:condition="not: running">
+								<tal:block tal:repeat="starturl svc/links">
+									<option
+										tal:condition="not:exists: starturl/migrate"
+										tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" /></option>
+								</tal:block>
+							</tal:block>
+
+							<tal:block tal:condition="running">
+								<tal:block tal:repeat="starturl svc/links">
+									<option
+										tal:condition="not:exists: starturl/migrate"
+										tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" /></option>
+								</tal:block>
+
+								<tal:block tal:condition="svc/is_vm | nothing">
+									<option value="">----------</option>
+									<tal:block tal:repeat="starturl svc/links">
+										<option
+											tal:condition="exists: starturl/migrate"
+											tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+									</tal:block>
+								</tal:block>
+							</tal:block>
+
 						</select>
 						<input type="button" value="Go"
 							onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
@@ -4227,10 +4253,19 @@
 
 	<tal:block tal:define="
 		result python: here.serviceStart(ricci_agent, request)" />
-
-	<!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
 </div>
 
+<div metal:define-macro="servicemigrate">
+	<script type="text/javascript">
+		set_page_title('Luci — cluster — services — Migrate a virtual service');
+	</script>
+
+	<tal:block tal:define="
+		global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
+
+	<tal:block tal:define="
+		result python: here.serviceMigrate(ricci_agent, request)" />
+</div>
 
 <div metal:define-macro="servicerestart">
 	<script type="text/javascript">
@@ -4242,8 +4277,6 @@
 
 	<tal:block tal:define="
 		result python: here.serviceRestart(ricci_agent, request)" />
-
-	<!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
 </div>
 
 <div metal:define-macro="servicestop">
@@ -4256,8 +4289,6 @@
 
 	<span tal:define="
 		result python: here.serviceStop(ricci_agent, request)" />
-
-	<!-- <span metal:use-macro="here/form-macros/macros/serviceconfig-form"/> -->
 </div>
 
 <div metal:define-macro="serviceconfig-type-macro" tal:omit-tag="">
@@ -4367,22 +4398,51 @@
 
 						<option value="">Choose a Task...</option>
 						<tal:block tal:condition="running">
+							<option
+								tal:attributes="value innermap/restarturl">Restart this service</option>
+
+							<option
+								tal:attributes="value innermap/disableurl">Disable this service</option>
+
 							<option value="">----------</option>
-							<option value="" tal:attributes="value innermap/restarturl">Restart this service</option>
-							<option value="" tal:attributes="value innermap/disableurl">Disable this service</option>
-							<option value="">----------</option>
-							<option tal:repeat="starturl innermap/links" value="" tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename"/></option>
+
+							<tal:block tal:repeat="starturl innermap/links">
+								<option
+									tal:condition="not:exists: starturl/migrate"
+									tal:attributes="value starturl/url">Relocate this service to <span tal:replace="starturl/nodename" />
+								</option>
+							</tal:block>
+
+							<tal:block tal:condition="svc/is_vm | nothing">
+								<option value="">----------</option>
+								<tal:block tal:repeat="starturl innermap/links">
+									<option
+										tal:condition="exists: starturl/migrate"
+										tal:attributes="value starturl/url">Migrate this service to <span tal:replace="starturl/nodename" /></option>
+								</tal:block>
+							</tal:block>
 						</tal:block>
 
 						<tal:block tal:condition="not: running">
+							<option
+								tal:attributes="value innermap/enableurl">Enable this service</option>
 							<option value="">----------</option>
-							<option value="" tal:attributes="value innermap/enableurl">Enable this service</option>
+
+							<tal:block tal:repeat="starturl innermap/links">
+								<option
+									tal:condition="not:exists: starturl/migrate"
+									tal:attributes="value starturl/url">Start this service on <span tal:replace="starturl/nodename" />
+								</option>
+							</tal:block>
+
 							<option value="">----------</option>
+
 							<option
 								tal:attributes="value innermap/delurl | nothing"
 								tal:content="string:Delete this service" />
 						</tal:block>
 					</select>
+
 					<input type="button" value="Go"
 						onclick="if (this.form.gourl[this.form.gourl.selectedIndex].value && confirm(this.form.gourl[this.form.gourl.selectedIndex].text + '?')) return dropdown(this.form.gourl)" />
 				</form>
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2007/03/05 16:50:09	1.120.2.23
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2007/03/12 04:22:26	1.120.2.24
@@ -3439,15 +3439,6 @@
 
 			itemmap['autostart'] = item['autostart']
 
-			starturls = list()
-			for node in nodes:
-				starturl = {}
-				if node.getName() != cur_node:
-					starturl['nodename'] = node.getName()
-					starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
-					starturls.append(starturl)
-			itemmap['links'] = starturls
-
 			try:
 				svc = model.retrieveServiceByName(item['name'])
 				itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + SERVICE
@@ -3455,11 +3446,29 @@
 			except:
 				try:
 					svc = model.retrieveVMsByName(item['name'])
-					itemmap['virt'] = True
+					itemmap['is_vm'] = True
 					itemmap['cfgurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG 
 					itemmap['delurl'] = baseurl + "?" + "clustername=" + cluname + "&servicename=" + item['name'] + "&pagetype=" + VM_CONFIG
 				except:
 					continue
+
+			starturls = list()
+			for node in nodes:
+				if node.getName() != cur_node:
+					starturl = {}
+					cur_nodename = node.getName()
+					starturl['nodename'] = cur_nodename
+					starturl['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_START + '&nodename=' + node.getName()
+					starturls.append(starturl)
+
+					if itemmap.has_key('is_vm') and itemmap['is_vm'] is True:
+						migrate_url = { 'nodename': cur_nodename }
+						migrate_url['migrate'] = True
+						migrate_url['url'] = baseurl + '?' + 'clustername=' + cluname +'&servicename=' + item['name'] + '&pagetype=' + SERVICE_MIGRATE + '&nodename=' + node.getName()
+						starturls.append(migrate_url)
+
+			itemmap['links'] = starturls
+
 			dom = svc.getAttribute("domain")
 			if dom is not None:
 				itemmap['faildom'] = dom
@@ -3513,42 +3522,59 @@
 		return hmap
 
 	for item in status:
-		if item['type'] == "service":
+		innermap = {}
+		if item['type'] == 'service':
 			if item['name'] == servicename:
 				hmap['name'] = servicename
-				starturls = list()
 				hmap['autostart'] = item['autostart']
-				if item['running'] == "true":
-					hmap['running'] = "true"
-					#In this case, determine where it can run...
-					innermap = {}
+
+				starturls = list()
+				if item['running'] == 'true':
+					hmap['running'] = 'true'
 					nodename = item['nodename']
-					innermap['current'] = "This service is currently running on %s" % nodename
+					innermap['current'] = 'This service is currently running on %s' % nodename
+
 					innermap['disableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_STOP
 					innermap['restarturl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_RESTART
 					innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
 
+					#In this case, determine where it can run...
 					nodes = model.getNodes()
 					for node in nodes:
-						starturl = {}
 						if node.getName() != nodename:
-							starturl['nodename'] = node.getName()
+							starturl = {}
+							cur_nodename = node.getName()
+							starturl['nodename'] = cur_nodename
 							starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
 							starturls.append(starturl)
+
+							if item.has_key('is_vm') and item['is_vm'] is True:
+								migrate_url = { 'nodename': cur_nodename }
+								migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+								migrate_url['migrate'] = True
+								starturls.append(migrate_url)
 					innermap['links'] = starturls
 				else:
 					#Do not set ['running'] in this case...ZPT will detect it is missing
-					#In this case, determine where it can run...
-					innermap = {}
 					innermap['current'] = "This service is currently stopped"
 					innermap['enableurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START
+					innermap['delurl'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_DELETE
+
 					nodes = model.getNodes()
 					starturls = list()
 					for node in nodes:
 						starturl = {}
-						starturl['nodename'] = node.getName()
+						cur_nodename = node.getName()
+
+						starturl['nodename'] = cur_nodename
 						starturl['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_START + "&nodename=" + node.getName()
 						starturls.append(starturl)
+
+						if item.has_key('is_vm') and item['is_vm'] is True:
+							migrate_url = { 'nodename': cur_nodename }
+							migrate_url['url'] = baseurl + "?" + "clustername=" + cluname +"&servicename=" + servicename + "&pagetype=" + SERVICE_MIGRATE + "&nodename=" + node.getName()
+							migrate_url['migrate'] = True
+							starturls.append(migrate_url)
 					innermap['links'] = starturls
 				hmap['innermap'] = innermap
 
@@ -3659,14 +3685,72 @@
 
 	batch_number, result = startService(rc, svcname, nodename)
 	if batch_number is None or result is None:
-		luci_log.debug_verbose('startService3: SS(%s,%s,%s) call failed' \
+		luci_log.debug_verbose('serviceStart3: SS(%s,%s,%s) call failed' \
+			% (svcname, cluname, nodename))
+		return None
+
+	try:
+		status_msg = "Starting service \'%s\'" % svcname
+		if nodename:
+			status_msg += " on node \'%s\'" % nodename
+		set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, status_msg)
+	except Exception, e:
+		luci_log.debug_verbose('serviceStart4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+
+	response = req.RESPONSE
+	response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
+
+def serviceMigrate(self, rc, req):
+	svcname = None
+	try:
+		svcname = req['servicename']
+	except:
+		try:
+			svcname = req.form['servicename']
+		except:
+			pass
+
+	if svcname is None:
+		luci_log.debug_verbose('serviceMigrate0: no service name')
+		return None
+
+	nodename = None
+	try:
+		nodename = req['nodename']
+	except:
+		try:
+			nodename = req.form['nodename']
+		except:
+			pass
+
+	if nodename is None:
+		luci_log.debug_verbose('serviceMigrate1: no target node name')
+		return None
+		
+	cluname = None
+	try:
+		cluname = req['clustername']
+	except KeyError, e:
+		try:
+			cluname = req.form['clustername']
+		except:
+			pass
+
+	if cluname is None:
+		luci_log.debug_verbose('serviceMigrate2: no cluster name for svc %s' \
+			% svcname)
+		return None
+
+	batch_number, result = migrateService(rc, svcname, nodename)
+	if batch_number is None or result is None:
+		luci_log.debug_verbose('serviceMigrate3: SS(%s,%s,%s) call failed' \
 			% (svcname, cluname, nodename))
 		return None
 
 	try:
-		set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Starting service \'%s\'" % svcname)
+		set_node_flag(self, cluname, rc.hostname(), str(batch_number), SERVICE_START, "Migrating service \'%s\' to node \'%s\'" % (svcname, nodename))
 	except Exception, e:
-		luci_log.debug_verbose('startService4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
+		luci_log.debug_verbose('serviceMigrate4: error setting flags for service %s at node %s for cluster %s' % (svcname, nodename, cluname))
 
 	response = req.RESPONSE
 	response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
--- conga/luci/site/luci/Extensions/conga_constants.py	2007/03/01 00:31:08	1.19.2.8
+++ conga/luci/site/luci/Extensions/conga_constants.py	2007/03/12 04:22:26	1.19.2.9
@@ -44,8 +44,9 @@
 FENCEDEV="54"
 CLUSTER_DAEMON="55"
 SERVICE_DELETE = '56'
-FENCEDEV_DELETE = "57"
+FENCEDEV_DELETE = '57'
 FENCEDEV_NODE_CONFIG = '58'
+SERVICE_MIGRATE = '59'
 
 CONF_EDITOR = '80'
 
--- conga/luci/site/luci/Extensions/ricci_bridge.py	2007/03/01 00:31:08	1.30.2.18
+++ conga/luci/site/luci/Extensions/ricci_bridge.py	2007/03/12 04:22:26	1.30.2.19
@@ -454,6 +454,12 @@
 	ricci_xml = rc.batch_run(batch_str)
 	return batchAttemptResult(ricci_xml)
 
+def migrateService(rc, servicename, preferrednode):
+	batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="migrate_service"><var mutable="false" name="servicename" type="string" value=\"' + servicename + '\"/><var mutable="false" name="nodename" type="string" value=\"' + preferrednode + '\" /></function_call></request></module>'
+
+	ricci_xml = rc.batch_run(batch_str)
+	return batchAttemptResult(ricci_xml)
+
 def updateServices(rc, enable_list, disable_list):
 	batch = ''
 




More information about the Cluster-devel mailing list