[Cluster-devel] conga luci/cluster/cluster_config-macros luci/ ...

rmccabe at sourceware.org rmccabe at sourceware.org
Mon Nov 10 21:02:54 UTC 2008


CVSROOT:	/cvs/cluster
Module name:	conga
Branch: 	RHEL4
Changes by:	rmccabe at sourceware.org	2008-11-10 21:02:48

Modified files:
	luci/cluster   : cluster_config-macros cluster_svc-macros 
	                 fence-macros form-macros index_html 
	                 resource-form-macros resource_form_handlers.js 
	                 validate_config_qdisk.js 
	                 validate_create_gulm.js 
	luci/plone-custom: conga.js update_hostinfo.js 
	luci/site/luci/Extensions: LuciClusterInfo.py LuciDB.py 
	                           LuciValidation.py 
	                           LuciZopeClusterPortal.py 
	                           RicciQueries.py StorageReport.py 
	                           cluster_adapters.py 
	                           ricci_communicator.py 
	luci/site/luci/Extensions/ClusterModel: ModelBuilder.py 
	luci/site/luci/etc: zope.conf.in 
	luci/storage   : form-macros 
	ricci/common   : File.cpp Variable.cpp utils.cpp 
	ricci/include  : shred_allocator.h 
	ricci/modules/cluster/clumon: REDHAT-CLUSTER-MIB REDHAT-MIB 
	ricci/modules/cluster/clumon/src/common: Cluster.cpp 
	ricci/modules/rpm: PackageHandler.cpp 
	ricci/modules/service: ServiceManager.cpp 
	ricci/modules/storage: ContentFS.cpp ExtendedFS.cpp LV.cpp 
	                       LVM.cpp Mapper.cpp MountHandler.cpp 
	                       PTSource.cpp PV.cpp Partition.cpp 
	                       PartitionTable.cpp parted_wrapper.cpp 
	ricci/ricci    : SSLInstance.cpp 

Log message:
	Backport fixes from RHEL5

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/cluster_config-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.4.2.1&r2=1.4.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/cluster_svc-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.1&r2=1.7.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/fence-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2.4.5&r2=1.2.4.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.176.2.24&r2=1.176.2.25
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/index_html.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.30.2.6&r2=1.30.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource-form-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.31.2.12&r2=1.31.2.13
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource_form_handlers.js.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.29.2.7&r2=1.29.2.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_config_qdisk.js.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.2.4&r2=1.5.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_create_gulm.js.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.2&r2=1.1.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/conga.js.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.4.2.3&r2=1.4.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/update_hostinfo.js.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.4.1&r2=1.1.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciClusterInfo.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.10.2.6&r2=1.10.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciDB.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.6.2.3&r2=1.6.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciValidation.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.2&r2=1.9.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopeClusterPortal.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2.2.2&r2=1.2.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/RicciQueries.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.3&r2=1.7.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/StorageReport.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.22.2.5&r2=1.22.2.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.227.2.27&r2=1.227.2.28
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_communicator.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.24.2.3&r2=1.24.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.2.5&r2=1.5.2.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/etc/zope.conf.in.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.4.2&r2=1.1.4.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.20.2.4&r2=1.20.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/File.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.3.2.1&r2=1.3.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/Variable.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.8.4.1&r2=1.8.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/utils.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.8.2.1&r2=1.8.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/include/shred_allocator.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2.4.1&r2=1.2.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/REDHAT-CLUSTER-MIB.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/REDHAT-MIB.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.6.4.2&r2=1.6.4.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/rpm/PackageHandler.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.11.2.6&r2=1.11.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/service/ServiceManager.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.6&r2=1.7.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/ContentFS.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.4.1&r2=1.5.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/ExtendedFS.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.8.2.1&r2=1.8.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/LV.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.3&r2=1.7.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/LVM.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.11.2.2&r2=1.11.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/Mapper.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.3.4.1&r2=1.3.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/MountHandler.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.6.2.1&r2=1.6.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/PTSource.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2.4.1&r2=1.2.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/PV.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.2.2&r2=1.5.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/Partition.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.3.4.1&r2=1.3.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/PartitionTable.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.4.1&r2=1.5.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/parted_wrapper.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.8.4.4&r2=1.8.4.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/SSLInstance.cpp.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.2&r2=1.7.2.3

--- conga/luci/cluster/cluster_config-macros	2008/03/25 01:27:10	1.4.2.1
+++ conga/luci/cluster/cluster_config-macros	2008/11/10 21:02:43	1.4.2.2
@@ -715,21 +715,40 @@
 				</td>
 			</tr>
 
-			<tr class="systemsTable">
-				<td class="systemsTable">Device</td>
-				<td class="systemsTable">
-					<input type="text" name="device"
-						tal:attributes="value clusterinfo/device | nothing" />
-				</td>
-			</tr>
-
-			<tr class="systemsTable">
-				<td class="systemsTable">Label</td>
-				<td class="systemsTable">
-					<input type="text" name="label"
-						tal:attributes="value clusterinfo/label | nothing" />
-				</td>
-			</tr>
+			<tr class="systemsTable"><td colspan="2">
+				<table class="systemsTable">
+					<tr class="systemsTable">
+						<td class="systemsTable">
+							<input type="radio" name="qdisk_dev_label"
+								onclick="disable_text_field(this.form.label, this.form.device)"
+								tal:attributes="
+									checked python:(clusterinfo.get('label') or not clusterinfo.get('device')) and 'checked' or ''">Label
+						</td>
+						<td class="systemsTable">
+							<input type="text" name="label" id="qdisk_label"
+								onfocus="disable_text_field(this.form.label, this.form.device);this.form.qdisk_dev_label[0].checked='checked';"
+								tal:attributes="
+									disabled python:(not clusterinfo.get('label') and clusterinfo.get('device')) and 'disabled' or '';
+									value clusterinfo/label | nothing" />
+						</td>
+					</tr>
+					<tr class="systemsTable">
+						<td class="systemsTable">
+							<input type="radio" name="qdisk_dev_label"
+								onclick="disable_text_field(this.form.device, this.form.label)"
+									tal:attributes="
+										checked python:clusterinfo.get('device') and 'checked' or ''">Device (deprecated)
+						</td>
+						<td class="systemsTable">
+							<input type="text" name="device" id="qdisk_device"
+								onfocus="disable_text_field(this.form.device, this.form.label);this.form.qdisk_dev_label[1].checked='checked';"
+								tal:attributes="
+									disabled python:not clusterinfo.get('device') and 'disabled' or '';
+									value clusterinfo/device | nothing" />
+						</td>
+					</tr>
+				</table>
+			</td></tr>
 		</table>
 		</div>
 
--- conga/luci/cluster/cluster_svc-macros	2008/03/25 01:27:10	1.7.2.1
+++ conga/luci/cluster/cluster_svc-macros	2008/11/10 21:02:43	1.7.2.2
@@ -46,7 +46,7 @@
 						class python: 'cluster service ' + (running and 'running' or 'stopped')"
 						tal:content="svc/name" />
 					<tal:block tal:condition="exists:svc/is_vm">
-						(virtual service)
+						(virtual machine service)
 					</tal:block>
 				</td>
 
@@ -156,46 +156,8 @@
 				<p class="reshdr">Create a Virtual Machine Service</p>
 			</td></tr>
 		<tfoot class="systemsTable">
-			<tr class="systemsTable">
-				<td>Automatically start this service</td>
-				<td>
-					<input type="checkbox" name="autostart" checked="checked">
-				</td>
-			</tr>
-			<tr class="systemsTable">
-				<td>Run exclusive</td>
-				<td>
-					<input type="checkbox" name="exclusive">
-				</td>
-			</tr>
-			<tr class="systemsTable">
-				<td>Failover Domain</td>
-				<td>
-					<select name="domain">
-						<option value="" selected="selected">None</option>
-						<tal:block tal:repeat="f python:here.get_fdom_names(modelb)">
-							<option tal:content="f"
-								tal:attributes="value f" />
-						</tal:block>
-					</select>
-				</td>
-			</tr>
-
-			<tr class="systemsTable">
-				<td>Recovery policy</td>
-				<td>
-					<select name="recovery">
-						<option value="">Select a recovery policy</option>
-						<option name="relocate" value="relocate">Relocate</option>
-						<option name="restart" value="restart">Restart</option>
-						<option name="disable" value="disable">Disable</option>
-					</select>
-				</td>
-			</tr>
-
 			<tr class="systemsTable"
 				tal:condition="exists:clusterinfo/vm_migration_choice">
-
 				<td>Migration type</td>
 				<td>
 					<select name="migration_type">
@@ -205,6 +167,8 @@
 				</td>
 			</tr>
 						
+			<tal:block metal:use-macro="here/cluster_svc-macros/macros/failover-prefs-macro" />
+
 			<tr class="systemsTable"><td colspan="2">
 				<div class="hbSubmit">
 					<input type="submit" value="Create Virtual Machine Service" />
@@ -220,6 +184,10 @@
 				<td><span class="cluster_help" title="e.g., /etc/xen/">Path to VM configuration files</span></td>
 				<td><input type="text" name="vmpath" value="" /></td>
 			</tr>
+			<tr class="systemsTable">
+				<td><span class="cluster_help" title="memberhost:targethost,memberhost:targethost ..">VM Migration Mapping</span></td>
+				<td><input type="text" name="migration_mapping" value="" /></td>
+			</tr>
 		</tbody>
 	</table>
 	</div>
@@ -228,7 +196,7 @@
 
 <div metal:define-macro="vmconfig-form">
 <form method="post" action=""
-	tal:define="vminfo python:here.getVMInfo(modelb, request)">
+	tal:define="sinfo python:here.getVMInfo(modelb, request)">
 
 	<input type="hidden" name="clustername"
 		tal:attributes="value request/clustername | nothing" />
@@ -237,14 +205,14 @@
 		tal:attributes="value request/pagetype | nothing" />
 
 	<input type="hidden" name="oldname"
-		tal:attributes="value vminfo/name | nothing" />
+		tal:attributes="value sinfo/name | nothing" />
 
 	<div class="service_comp_list">
 	<table class="systemsTable">
 		<thead class="systemsTable">
 			<tr class="systemsTable">
 				<td class="systemsTable">
-					<p class="reshdr">Properties for <tal:block tal:replace="vminfo/name | string:virtual machine service"/></p>
+					<p class="reshdr">Properties for <tal:block tal:replace="sinfo/name | string:virtual machine service"/></p>
 				</td>
 			</tr>
 
@@ -313,66 +281,21 @@
 		</thead>
 
 		<tfoot class="systemsTable">
-			<tr class="systemsTable">
-				<td>Automatically start this service</td>
-				<td>
-					<input type="checkbox" name="autostart"
-						tal:attributes="checked python: ('autostart' in vminfo and vminfo['autostart'] != '0') and 'checked' or ''" />
-				</td>
-			</tr>
-			<tr class="systemsTable">
-				<td>Run exclusive</td>
-				<td>
-					<input type="checkbox" name="exclusive"
-						tal:attributes="checked python: ('exclusive' in vminfo and vminfo['exclusive'] != '0') and 'checked' or ''" />
-				</td>
-			</tr>
-			<tr class="systemsTable">
-				<td>Failover Domain</td>
-				<td>
-					<select name="domain">
-						<option value="" tal:content="string:None"
-							tal:attributes="selected python: (not 'domain' in vminfo or not vminfo['domain']) and 'selected' or ''" />
-						<tal:block tal:repeat="f python:here.get_fdom_names(modelb)">
-							<option tal:content="f"
-								tal:attributes="
-									value f;
-									selected python: ('domain' in vminfo and vminfo['domain'] == f) and 'selected' or ''" />
-						</tal:block>
-					</select>
-				</td>
-			</tr>
-			<tr class="systemsTable">
-				<td>Recovery policy</td>
-				<td>
-					<select name="recovery">
-						<option value="">Select a recovery policy</option>
-						<option name="relocate" value="relocate"
-							tal:content="string:Relocate"
-							tal:attributes="selected python: ('recovery' in vminfo and vminfo['recovery'] == 'relocate') and 'selected' or ''" />
-						<option name="restart" value="restart"
-							tal:content="string:Restart"
-							tal:attributes="selected python: ('recovery' in vminfo and vminfo['recovery'] == 'restart') and 'selected' or ''" />
-						<option name="disable" value="disable"
-							tal:content="string:Disable"
-							tal:attributes="selected python: ('recovery' in vminfo and vminfo['recovery'] == 'disable') and 'selected' or ''" />
-					</select>
-				</td>
-			</tr>
-
 			<tr class="systemsTable"
-				tal:condition="exists:vminfo/vm_migration_choice">
+				tal:condition="exists:sinfo/vm_migration_choice">
 
 				<td>Migration type</td>
 				<td>
 					<select name="migration_type">
 						<option value="live" tal:content="string:Live"
-							tal:attributes="selected python:('migrate' not in vminfo or vminfo['migrate'] != 'pause') and 'selected' or ''" />
+							tal:attributes="selected python:(sinfo.get('migrate') != 'pause') and 'selected' or ''" />
 						<option value="pause" tal:content="string:Pause"
-							tal:attributes="selected python:('migrate' in vminfo and vminfo['migrate'] == 'pause') and 'selected' or ''" />
+							tal:attributes="selected python:(sinfo.get('migrate') == 'pause') and 'selected' or ''" />
 					</select>
 				</td>
 			</tr>
+
+			<tal:block metal:use-macro="here/cluster_svc-macros/macros/failover-prefs-macro" />
 						
 			<tr class="systemsTable"><td colspan="2">
 				<div class="hbSubmit">
@@ -386,14 +309,21 @@
 				<td><span class="cluster_help" title="e.g., guest1 if the VM config file is at /etc/xen/guest1">Virtual machine name</span></td>
 				<td>
 					<input type="text" name="vmname"
-						tal:attributes="value vminfo/name | nothing" />
+						tal:attributes="value sinfo/name | nothing" />
 				</td>
 			</tr>
 			<tr class="systemsTable">
 				<td><span class="cluster_help" title="e.g., /etc/xen/">Path to VM configuration files</span></td>
 				<td>
 					<input type="text" name="vmpath"
-						tal:attributes="value vminfo/path | nothing" />
+						tal:attributes="value sinfo/path | nothing" />
+				</td>
+			</tr>
+			<tr class="systemsTable">
+				<td><span class="cluster_help" title="memberhost:targethost,memberhost:targethost ..">VM Migration Mapping</span></td>
+				<td>
+					<input type="text" name="migration_mapping"
+						tal:attributes="value sinfo/migration_mapping | nothing" />
 				</td>
 			</tr>
 		</tbody>
@@ -427,43 +357,7 @@
 						<input type="text" length="20" name="service_name" value="" />
 					</td>
 				</tr>
-				<tr class="systemsTable">
-					<td class="systemsTable">
-						Automatically start this service
-					</td>
-					<td class="systemsTable">
-						<input type="checkbox" name="autostart" checked="checked" />
-					</td>
-				</tr>
-				<tr class="systemsTable">
-					<td class="systemsTable">Run exclusive</td>
-					<td class="systemsTable">
-						<input type="checkbox" name="exclusive">
-					</td>
-				</tr>
-				<tr class="systemsTable">
-					<td class="systemsTable">Failover Domain</td>
-					<td class="systemsTable">
-						<select name="domain">
-							<option value="" selected="selected">None</option>
-							<tal:block tal:repeat="f sinfo/fdoms">
-								<option tal:content="f"
-									tal:attributes="value f" />
-							</tal:block>
-						</select>
-					</td>
-				</tr>
-				<tr class="systemsTable">
-					<td class="systemsTable">Recovery policy</td>
-					<td class="systemsTable">
-						<select name="recovery">
-							<option value="">Select a recovery policy</option>
-							<option name="relocate" value="relocate">Relocate</option>
-							<option name="restart" value="restart">Restart</option>
-							<option name="disable" value="disable">Disable</option>
-						</select>
-					</td>
-				</tr>
+				<tal:block metal:use-macro="here/cluster_svc-macros/macros/failover-prefs-macro" />
 			</table>
 		</form>
 	</div>
@@ -492,6 +386,8 @@
 		<input type="hidden" name="exclusive" value="-1" />
 		<input type="hidden" name="recovery" />
 		<input type="hidden" name="domain" />
+		<input type="hidden" name="max_restarts" />
+		<input type="hidden" name="restart_expire_time" />
 		<input type="hidden" name="form_xml" />
 		<input type="hidden" name="action" value="add" />
 		</form>
@@ -522,7 +418,7 @@
 
 <div metal:define-macro="servicemigrate">
 	<script type="text/javascript">
-		set_page_title('Luci — cluster — services — Migrate a virtual service');
+		set_page_title('Luci — cluster — services — Migrate a virtual machine service');
 	</script>
 
 	<tal:block tal:define="
@@ -625,6 +521,76 @@
 	</tal:block>
 </div>
 
+<div metal:define-macro="failover-prefs-macro" tal:omit-tag="">
+	<tr>
+		<td>Automatically start this service</td>
+		<td>
+			<input type="checkbox" name="autostart"
+				tal:attributes="checked python:(sinfo and sinfo.get('autostart') and sinfo['autostart'].lower() != 'false') and 'checked'" />
+		</td>
+	</tr>
+
+	<tr>
+		<td>Run exclusive</td>
+		<td>
+			<input type="checkbox" name="exclusive"
+				tal:attributes="checked python:(sinfo and sinfo.get('exclusive')and sinfo.get('exclusive').lower() != 'false') and 'checked'" />
+		</td>
+	</tr>
+
+	<tr>
+		<td>Failover Domain</td>
+		<td>
+			<select name="domain">
+				<option value=""
+					tal:attributes="selected python:(not sinfo or not sinfo.get('domain')) and 'selected' or ''">None</option>
+				<tal:block tal:condition="exists:sinfo/fdoms">
+				<tal:block tal:repeat="f sinfo/fdoms">
+					<option tal:content="f" tal:attributes="
+						value f;
+						selected python:(sinfo and sinfo.get('domain') == f) and 'selected' or ''" />
+				</tal:block>
+				</tal:block>
+			</select>
+		</td>
+	</tr>
+
+	<tr class="systemsTable">
+		<td>Recovery policy</td>
+		<td>
+			<select name="recovery">
+				<option value="">Select a recovery policy</option>
+				<option name="relocate" value="relocate"
+					tal:content="string:Relocate"
+					tal:attributes="selected python:(sinfo and sinfo.get('recovery') == 'relocate') and 'selected' or ''" />
+				<option name="restart" value="restart"
+					tal:content="string:Restart"
+					tal:attributes="selected python:(sinfo and sinfo.get('recovery') == 'restart') and 'selected' or ''" />
+				<option name="disable" value="disable"
+					tal:content="string:Disable"
+					tal:attributes="selected python:(sinfo and sinfo.get('recovery') == 'disable') and 'selected' or ''" />
+			</select>
+		</td>
+	</tr>
+
+	<tr class="systemsTable">
+		<td class="systemsTable">
+			Maximum number of restart failures before relocating
+		</td>
+		<td class="systemsTable">
+			<input type="text" size="3" name="max_restarts"
+				tal:attributes="value sinfo/max_restarts|string:0" />
+		</td>
+	</tr>
+	<tr class="systemsTable">
+		<td class="systemsTable">Length of time in seconds after which to forget a restart</td>
+		<td class="systemsTable">
+			<input type="text" size="3" name="restart_expire_time"
+				tal:attributes="value sinfo/restart_expire_time|string:0" />
+		</td>
+	</tr>
+</div>
+
 <div metal:define-macro="service-config-head-macro" tal:omit-tag="">
 	<script type="text/javascript"
 		src="/luci/homebase/homebase_common.js">
@@ -754,7 +720,8 @@
 		<tal:block metal:use-macro="here/resource-form-macros/macros/service-compose-macro" />
 	</div>
 
-	<div class="service_comp_list" tal:attributes="id sinfo/root_uuid">
+	<div class="service_comp_list"
+		tal:attributes="id sinfo/root_uuid|string:toplevel">
 	<div tal:repeat="res resource_list"
 		tal:attributes="
 			class python: 'service_comp rc_indent' + str(res['indent_ctr']);
@@ -778,51 +745,9 @@
 	<div class="service_comp_list">
 		<form name="service_name_form">
 			<table class="rescfg">
-				<tr>
-					<td>Automatically start this service</td>
-					<td><input type="checkbox" name="autostart"
-							tal:attributes="checked python: ('autostart' in sinfo and sinfo['autostart'].lower() != 'false') and 'checked'" />
-					</td>
-				</tr>
-				<tr>
-					<td>Run exclusive</td>
-					<td><input type="checkbox" name="exclusive"
-							tal:attributes="checked python: ('exclusive' in sinfo and sinfo['exclusive'].lower() != 'false') and 'checked'" />
-					</td>
-				</tr>
-				<tr>
-					<td>Failover Domain</td>
-					<td>
-						<select name="domain">
-							<option value=""
-								tal:attributes="selected python: (not 'domain' in sinfo or not sinfo['domain']) and 'selected' or ''">None</option>
-							<tal:block tal:repeat="f sinfo/fdoms">
-								<option tal:content="f"
-									tal:attributes="
-										value f;
-										selected python: ('domain' in sinfo and sinfo['domain'] == f) and 'selected' or ''" />
-							</tal:block>
-						</select>
-					</td>
-				</tr>
-				<tr class="systemsTable">
-					<td>Recovery policy</td>
-					<td>
-						<select name="recovery">
-							<option value="">Select a recovery policy</option>
-							<option name="relocate" value="relocate"
-								tal:content="string:Relocate"
-								tal:attributes="selected python: ('recovery' in sinfo and sinfo['recovery'] == 'relocate') and 'selected' or ''" />
-							<option name="restart" value="restart"
-								tal:content="string:Restart"
-								tal:attributes="selected python: ('recovery' in sinfo and sinfo['recovery'] == 'restart') and 'selected' or ''" />
-							<option name="disable" value="disable"
-								tal:content="string:Disable"
-								tal:attributes="selected python: ('recovery' in sinfo and sinfo['recovery'] == 'disable') and 'selected' or ''" />
-						</select>
-					</td>
-				</tr>
+				<tal:block metal:use-macro="here/cluster_svc-macros/macros/failover-prefs-macro" />
 			</table>
+
 			<input type="hidden" name="service_name"
 				tal:attributes="value sinfo/name | string:1" />
 		</form>
@@ -835,7 +760,7 @@
 			tal:attributes="
 				value request/pagetype | request/form/pagetype | nothing" />
 		<input type="hidden" name="clustername"
-			tal:attributes="value clusterinfo/clustername" />
+			tal:attributes="value clusterinfo/clustername | nothing" />
 		<input type="button" value="Add a resource to this service"
 			onclick="add_child_resource(this.form);" />
 		<input type="button" value="Save changes"
@@ -848,6 +773,8 @@
 		<input type="hidden" name="exclusive" value="-1" />
 		<input type="hidden" name="recovery" />
 		<input type="hidden" name="domain" />
+		<input type="hidden" name="max_restarts" />
+		<input type="hidden" name="restart_expire_time" />
 		<input type="hidden" name="form_xml" />
 		<input type="hidden" name="action" value="edit" />
 		</form>
--- conga/luci/cluster/fence-macros	2008/04/21 18:15:17	1.2.4.5
+++ conga/luci/cluster/fence-macros	2008/11/10 21:02:43	1.2.4.6
@@ -684,6 +684,13 @@
 				</td>
 			</tr>
 			<tr>
+				<td>Module Name</td>
+				<td>
+					<input name="modulename" type="text"
+						tal:attributes="value cur_fencedev/modulename | nothing" />
+				</td>
+			</tr>
+			<tr>
 				<td>
 					<span title="Full path to a script to generate fence password">Password Script (optional)</span>
 				</td>
@@ -1850,7 +1857,7 @@
 	</div>
 </div>
 
-<div metal:define-macro="fence-instance-form-gndb"
+<div metal:define-macro="fence-instance-form-gnbd"
 	tal:omit-tag="exists: cur_fence_dev_id">
 	<div id="fence_gnbd_instance" name="fence_gnbd" class="fencedev_instance"
 		tal:omit-tag="exists: cur_fence_dev_id">
@@ -2056,7 +2063,7 @@
 	<tal:block
 		metal:use-macro="here/fence-macros/macros/fence-instance-form-mcdata" />
 	<tal:block
-		metal:use-macro="here/fence-macros/macros/fence-instance-form-gndb" />
+		metal:use-macro="here/fence-macros/macros/fence-instance-form-gnbd" />
 	<tal:block
 		metal:use-macro="here/fence-macros/macros/fence-instance-form-bullpap" />
 	<tal:block
--- conga/luci/cluster/form-macros	2008/04/21 18:15:17	1.176.2.24
+++ conga/luci/cluster/form-macros	2008/11/10 21:02:43	1.176.2.25
@@ -148,6 +148,80 @@
 </div>
 </div>
 
+<div metal:define-macro="lockserver-macro" tal:omit-tag="">
+	<strong class="cluster">Lock Manager</strong>
+	<ul class="vanilla">
+		<li class="vanilla">
+			<input type="radio" name="lockmanager" value="dlm"
+				onchange="toggle_gulm(this.form, this.value)"
+				tal:attributes="checked python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm'">DLM (preferred)
+		</li>
+		<li class="vanilla">
+			<input type="radio" name="lockmanager" value="gulm"
+				onchange="toggle_gulm(this.form, this.value)"
+					tal:attributes="checked python: add_cluster and 'lockmanager' in add_cluster and add_cluster['lockmanager'] == 'gulm'">GULM
+		</li>
+		<div id="gulm_lockservers"
+			tal:attributes="class python: (add_cluster and 'lockmanager' in add_cluster and add_cluster['lockmanager'] != 'gulm') and 'invisible' or ''">
+			<fieldset>
+				<legend class="rescfg">GULM lock server properties</legend>
+				<p>You must enter exactly 1, 3, or 5 GULM lock servers.</p>
+					<table class="systemsTable">
+						<tr>
+							<td class="pad_right">Lock Server 1</td>
+							<td>
+								<input type="text" name="__GULM__:server1"
+									class="hostname"
+									tal:attributes="
+										disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
+										value add_cluster/gulm_lockservers/server1 | nothing" />
+							</td>
+						</tr>
+						<tr>
+							<td class="pad_right">Lock Server 2</td>
+							<td>
+								<input type="text" name="__GULM__:server2"
+									class="hostname"
+									tal:attributes="
+										disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
+										value add_cluster/gulm_lockservers/server2 | nothing" />
+							</td>
+						</tr>
+						<tr>
+							<td class="pad_right">Lock Server 3</td>
+							<td>
+								<input type="text" name="__GULM__:server3"
+									class="hostname"
+									tal:attributes="
+										disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
+										value add_cluster/gulm_lockservers/server3 | nothing" />
+							</td>
+						</tr>
+						<tr>
+							<td class="pad_right">Lock Server 4</td>
+							<td>
+								<input type="text" name="__GULM__:server4"
+									class="hostname" tal:attributes="
+										disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
+										value add_cluster/gulm_lockservers/server4 | nothing" />
+							</td>
+						</tr>
+						<tr>
+							<td class="pad_right">Lock Server 5</td>
+						<td>
+							<input type="text" name="__GULM__:server5"
+								class="hostname"
+								tal:attributes="
+									disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
+									value add_cluster/gulm_lockservers/server5 | nothing" />
+						</td>
+					</tr>
+				</table>
+			</fieldset>
+		</div>
+	</ul>
+</div>
+
 <div metal:define-macro="cluster-form">
 	<h2>Cluster Form</h2>
 </div>
@@ -171,10 +245,17 @@
 		tal:define="
 			global add_cluster request/SESSION/create_cluster | nothing">
 
+		<div class="invisible"
+			tal:condition="not:exists:add_cluster/gulm_support">
+			<div id="lockserver_div">
+				<tal:block metal:use-macro="here/form-macros/macros/lockserver-macro" />
+			</div>
+		</div>
+
 		<input name="pagetype" type="hidden"
 			tal:attributes="value request/form/pagetype | request/pagetype |string:6" />
 
-		<input name="cluster_os" type="hidden"
+		<input name="cluster_os" type="hidden" id="cluster_os"
 			tal:attributes="value add_cluster/cluster_os | nothing" />
 
 		<table id="systemsTable" class="systemsTable" cellspacing="0">
@@ -241,91 +322,11 @@
 					</ul>
 				</td></tr>
 
-				<tr class="systemsTable"
-					tal:condition="exists:add_cluster/gulm_support">
-					<td class="systemsTable" colspan="2">
-						<strong class="cluster">Lock Manager</strong>
-						<ul class="vanilla">
-							<li class="vanilla">
-								<input type="radio"
-									name="lockmanager" value="dlm"
-									onchange="toggle_gulm(this.form, this.value)"
-									tal:attributes="checked python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm'"
-								>DLM (preferred)
-							</li>
-							<li class="vanilla">
-								<input type="radio"
-									name="lockmanager" value="gulm"
-									onchange="toggle_gulm(this.form, this.value)"
-									tal:attributes="checked python: add_cluster and 'lockmanager' in add_cluster and add_cluster['lockmanager'] == 'gulm'"
-								>GULM
-							</li>
-							<div id="gulm_lockservers"
-								tal:attributes="class python: (add_cluster and 'lockmanager' in add_cluster and add_cluster['lockmanager'] != 'gulm') and 'invisible' or ''">
-								<fieldset>
-								<legend class="rescfg">GULM lock server properties</legend>
-								<p>You must enter exactly 1, 3, or 5 GULM lock servers.</p>
-
-								<table class="systemsTable">
-									<tr>
-										<td class="pad_right">Lock Server 1</td>
-										<td>
-											<input type="text"
-												name="__GULM__:server1"
-												class="hostname"
-												tal:attributes="
-													disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
-													value add_cluster/gulm_lockservers/server1 | nothing" />
-										</td>
-									</tr>
-									<tr>
-										<td class="pad_right">Lock Server 2</td>
-										<td>
-											<input type="text"
-												name="__GULM__:server2"
-												class="hostname"
-												tal:attributes="
-													disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
-													value add_cluster/gulm_lockservers/server2 | nothing" />
-										</td>
-									</tr>
-									<tr>
-										<td class="pad_right">Lock Server 3</td>
-										<td>
-											<input type="text"
-												name="__GULM__:server3"
-												class="hostname"
-												tal:attributes="
-													disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
-													value add_cluster/gulm_lockservers/server3 | nothing" />
-										</td>
-									</tr>
-									<tr>
-										<td class="pad_right">Lock Server 4</td>
-										<td>
-											<input type="text"
-												name="__GULM__:server4"
-												class="hostname"
-												tal:attributes="
-													disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
-													value add_cluster/gulm_lockservers/server4 | nothing" />
-										</td>
-									</tr>
-									<tr>
-										<td class="pad_right">Lock Server 5</td>
-										<td>
-											<input type="text"
-												name="__GULM__:server5"
-												class="hostname"
-												tal:attributes="
-													disabled python: not add_cluster or not 'lockmanager' in add_cluster or add_cluster['lockmanager'] != 'gulm';
-													value add_cluster/gulm_lockservers/server5 | nothing" />
-										</td>
-									</tr>
-								</table>
-								</fieldset>
-							</div>
-						<ul>
+				<tr class="systemsTable">
+					<td class="systemsTable" colspan="2" id="lockserver_dialog">
+						<tal:block tal:condition="exists:add_cluster/gulm_support">
+							<tal:block metal:use-macro="here/form-macros/macros/lockserver-macro" />
+						</tal:block>
 					</td>
 				</tr>
 			</tfoot>
@@ -471,6 +472,8 @@
 		</div>
 
 		<div class="hbSubmit" id="hbSubmit">
+			<input id="cluster_version" name="cluster_version" type="hidden"
+				tal:attributes="value os_version | nothing" />
 			<input type="hidden" name="cluster_create" value="1" />
 			<input type="button" name="Submit" value="Submit"
 				onClick="validate_cluster_create(this.form)" />
@@ -939,6 +942,16 @@
 		global status python: here.getClusterStatus(request, ricci_agent);
 		global nds python: here.getNodesInfo(modelb, status, request)" />
 
+	<div tal:condition="python:len(nds) > 0 and nds[0].get('has_errors')" class="errmsgs">
+        <div tal:condition="python:nds[0].get('errmsgs')">
+			The cluster.conf for this cluster appears to have errors: <span tal:replace="python:nds[0].get('errmsgs')" />
+		</div>
+        <div tal:condition="python:not nds[0].get('errmsgs')">
+			The cluster.conf for this cluster appears to have errors
+		</div>
+	</div>
+	<div> </div>
+
 	<div tal:repeat="nd nds">
 		<tal:block
 			tal:define="global node_class python: 'cluster node ' + ((nd['status'] == '0' and 'node_active' or (nd['status'] == '1' and 'node_inactive' or 'node_unknown')))" />
@@ -1094,7 +1107,7 @@
 		<input name="pagetype" type="hidden"
 			tal:attributes="value request/form/pagetype | request/pagetype | string:15" />
 
-		<input name="cluster_os" type="hidden"
+		<input name="cluster_os" type="hidden" id="cluster_os"
 			tal:attributes="value add_cluster/cluster_os | nothing" />
 
 		<table id="systemsTable" class="systemsTable" cellspacing="0">
--- conga/luci/cluster/index_html	2008/06/10 15:29:13	1.30.2.6
+++ conga/luci/cluster/index_html	2008/11/10 21:02:43	1.30.2.7
@@ -27,20 +27,26 @@
 	    <tal:block tal:define="
 			global sinfo nothing;
 			global hascluster request/clustername | nothing;
-			global isBusy python: False;
+			global isBusy python:False;
+			global isVirtualized python:False;
 			global firsttime nothing;
 			global ri_agent nothing;
+			global os_version nothing;
 			global busywaiting python:None" />
 
 		<tal:block tal:condition="hascluster">
 			<tal:block tal:define="
 				global ri_agent python:here.getRicciAgentForCluster(request);
-				resmap python:here.getClusterOS(ri_agent);
-				global isVirtualized resmap/isVirtualized | nothing;
-				global os_version resmap/os | nothing;
-				global isBusy python:here.isClusterBusy(request);
 				global firsttime request/busyfirst | nothing" />
 
+			<tal:block tal:condition="ri_agent"
+				tal:define="resmap python:here.getClusterOS(ri_agent)">
+				<tal:block tal:define="
+					global isVirtualized resmap/isVirtualized | nothing;
+					global os_version resmap/os | nothing;
+					global isBusy python:here.isClusterBusy(request)" />
+			</tal:block>
+
 			<tal:block tal:condition="firsttime">
 				<tal:block tal:define="global busywaiting python:True" />
 				<meta http-equiv="refresh"
--- conga/luci/cluster/resource-form-macros	2008/05/12 18:04:12	1.31.2.12
+++ conga/luci/cluster/resource-form-macros	2008/11/10 21:02:43	1.31.2.13
@@ -1397,7 +1397,7 @@
 				<input type="text" size="20" name="user"
 					tal:attributes="
 						disabled python: editDisabled;
-						value res/user | nothing" />
+						value res/attrs/user | nothing" />
 			</td>
 		</tr>
 		<tr class="systemsTable">
@@ -1406,7 +1406,7 @@
 				<input type="text" size="20" name="home"
 					tal:attributes="
 						disabled python: editDisabled;
-						value res/home | nothing" />
+						value res/attrs/home | nothing" />
 			</td>
 		</tr>
 		<tr class="systemsTable">
@@ -1415,7 +1415,7 @@
 				<input type="text" size="20" name="vhost"
 					tal:attributes="
 						disabled python: editDisabled;
-						value res/vhost | nothing" />
+						value res/attrs/vhost | nothing" />
 			</td>
 		</tr>
 	</table>
--- conga/luci/cluster/resource_form_handlers.js	2008/03/25 01:27:10	1.29.2.7
+++ conga/luci/cluster/resource_form_handlers.js	2008/11/10 21:02:43	1.29.2.8
@@ -479,6 +479,8 @@
 	var domain = null;
 	var exclusive = 0;
 	var recovery = null;
+	var max_restarts = null;
+	var restart_expire_time = null;
 
 	submit_btn = submit_button;
 	submit_button.disabled = true;
@@ -509,6 +511,18 @@
 					recovery = null;
 			}
 
+			if (form[i].max_restarts) {
+				max_restarts = form[i].max_restarts.value;
+				if (str_is_blank(max_restarts))
+					max_restarts = null;
+			}
+
+			if (form[i].restart_expire_time) {
+				restart_expire_time = form[i].restart_expire_time.value;
+				if (str_is_blank(restart_expire_time))
+					restart_expire_time = null;
+			}
+
 			if (form[i].domain) {
 				domain = form[i].domain.options[form[i].domain.options.selectedIndex].value;
 				if (str_is_blank(domain))
@@ -581,6 +595,10 @@
 		master_form.domain.value = domain;
 	if (recovery)
 		master_form.recovery.value = recovery;
+	if (max_restarts)
+		master_form.max_restarts.value = max_restarts;
+	if (restart_expire_time)
+		master_form.restart_expire_time.value = restart_expire_time;
 	master_form.autostart.value = autostart;
 	master_form.exclusive.value = exclusive;
 
--- conga/luci/cluster/validate_config_qdisk.js	2008/03/25 01:27:10	1.5.2.4
+++ conga/luci/cluster/validate_config_qdisk.js	2008/11/10 21:02:43	1.5.2.5
@@ -206,6 +206,9 @@
 		var no_label = !form.label || str_is_blank(form.label.value);
 		if (no_dev && no_label)
 			errors.push('You must give either a label or a device.');
+		if (!no_dev && !no_label) {
+			errors.push('You may not specify both a device and a label.');
+		}
 
 		var hnum = document.getElementById('num_heuristics');
 		if (hnum) {
--- conga/luci/cluster/validate_create_gulm.js	2008/03/25 01:27:10	1.1.2.2
+++ conga/luci/cluster/validate_create_gulm.js	2008/11/10 21:02:43	1.1.2.3
@@ -65,10 +65,19 @@
 }
 
 function validate_cluster_create(form) {
-	if (form.lockmanager && !form.lockmanager[0].checked) {
-		var errors = check_gulm_lkserv();
-		if (error_dialog(errors))
-			return (-1);
+	try {
+		if (!form.cluster_os.value) {
+			get_system_info(null, null, 1);
+		}
+	} catch (e) {
+	}
+
+	if (form.cluster_os.value) {
+		if (form.lockmanager && !form.lockmanager[0].checked) {
+			var errors = check_gulm_lkserv();
+			if (error_dialog(errors))
+				return (-1);
+		}
+		return validateForm(form);
 	}
-	return validateForm(form);
 }
--- conga/luci/plone-custom/conga.js	2008/06/10 14:48:30	1.4.2.3
+++ conga/luci/plone-custom/conga.js	2008/11/10 21:02:43	1.4.2.4
@@ -248,6 +248,12 @@
 	elem.parentNode.removeChild(elem);
 }
 
+function disable_text_field(enable_obj, disable_obj) {
+	disable_obj.value = "";
+	disable_obj.disabled = "disabled";
+	enable_obj.disabled = "";
+}
+
 function swap_tabs(new_label, cur_tab, new_tab) {
 	if (cur_tab == new_tab) {
 		return (cur_tab);
--- conga/luci/plone-custom/update_hostinfo.js	2008/03/25 01:27:11	1.1.4.1
+++ conga/luci/plone-custom/update_hostinfo.js	2008/11/10 21:02:43	1.1.4.2
@@ -97,6 +97,7 @@
 	var errors = [];
 	var msgs = [];
 	var systems_list = get_systems_list_offsets(errors);
+	var cluster_os = null;
 
 	for (var i = 0 ; i < systems_list.length ; i++) {
 		var cur_node_props = node_props[systems_list[i][0]];
@@ -106,6 +107,10 @@
 			var addr_elem = document.getElementById('__SYSTEM' + offset + ':Addr');
 			var pwd_elem = document.getElementById('__SYSTEM' + offset + ':Passwd');
 			var fp_elem = document.getElementById('__SYSTEM' + offset + 'Fingerprint');
+			try {
+				cluster_os = cur_node_props['OS'];
+			} catch (e) {
+			}
 
 			if (cur_node_props['available'] != 'True') {
 				errors.push(cur_node_props['err_msg']);
@@ -130,7 +135,32 @@
 				}
 			}
 		} catch (e) {
-			alert(e);
+			//alert(e);
+		}
+	}
+
+	if (cluster_os !== null) {
+		var os_str = null;
+
+		if (cluster_os.match(/Nahant/)) {
+			var lsdiv = document.getElementById('lockserver_div');
+			if (lsdiv !== null) {
+				var ls_cell = document.getElementById('lockserver_dialog');
+				if (ls_cell !== null) {
+					lsdiv.id = null;
+					ls_cell.appendChild(lsdiv);
+				}
+			}
+			os_str = 'rhel4';
+		} else {
+			os_str = 'rhel5';
+		}
+
+		if (os_str !== null) {
+			var os_in = document.getElementById('cluster_os');
+			if (os_in !== null) {
+				os_in.value = os_str;
+			}
 		}
 	}
 
--- conga/luci/site/luci/Extensions/LuciClusterInfo.py	2008/06/10 14:48:31	1.10.2.6
+++ conga/luci/site/luci/Extensions/LuciClusterInfo.py	2008/11/10 21:02:43	1.10.2.7
@@ -82,6 +82,9 @@
 		vals['votes'] = '[unknown]'
 		vals['quorate'] = '[unknown]'
 		vals['minQuorum'] = '[unknown]'
+		if model.has_erors():
+			vals['errors'] = True
+			vals['errmsgs'] = model.get_errmsgs()
 		results.append(vals)
 	except Exception, e:
 		if LUCI_DEBUG_MODE is True:
@@ -420,6 +423,20 @@
 		hmap['recovery'] = None
 
 	try:
+		hmap['max_restarts'] = svc.getAttribute('max_restarts')
+		if not hmap['max_restarts']:
+			hmap['max_restarts'] = 0
+	except:
+		hmap['max_restarts'] = 0
+
+	try:
+		hmap['restart_expire_time'] = svc.getAttribute('restart_expire_time')
+		if not hmap['restart_expire_time']:
+			hmap['restart_expire_time'] = 0
+	except:
+		hmap['restart_expire_time'] = 0
+
+	try:
 		if int(svc.getAttribute('exclusive')):
 			hmap['exclusive'] = 'true'
 		else:
@@ -738,6 +755,9 @@
 			hlist.append(hmap)
 	clumap['hlist'] = hlist
 
+	if model.has_errors():
+		clumap['has_errors'] = True
+		clumap['errmsgs'] = model.get_errmsgs()
 	return clumap
 
 def getClustersInfo(self, status, req):
@@ -1081,6 +1101,10 @@
 			fdom_dict_list.append(fdom_dict)
 
 		nl_map['fdoms'] = fdom_dict_list
+
+		if model and model.has_errors():
+			nl_map['has_errors'] = True
+			nl_map['errmsgs'] = model.get_errmsgs()
 		resultlist.append(nl_map)
 
 	return resultlist
--- conga/luci/site/luci/Extensions/LuciDB.py	2008/03/25 01:27:12	1.6.2.3
+++ conga/luci/site/luci/Extensions/LuciDB.py	2008/11/10 21:02:43	1.6.2.4
@@ -836,6 +836,9 @@
 	for node in nodes:
 		hostname = node[0]
 
+		if hostname[-6:] == '__flag':
+			continue
+
 		if exclude_names is not None and hostname in exclude_names:
 			if LUCI_DEBUG_MODE is True:
 				luci_log.debug_verbose('GRA5: %s is in the excluded names list, excluding it' % hostname)
--- conga/luci/site/luci/Extensions/LuciValidation.py	2008/05/12 17:09:53	1.9.2.2
+++ conga/luci/site/luci/Extensions/LuciValidation.py	2008/11/10 21:02:44	1.9.2.3
@@ -268,7 +268,7 @@
 
 def validate_clusvc_add(model, request):
 	errors = list()
-	fvar = GetReqVars(request, [ 'form_xml', 'domain', 'recovery', 'svc_name', 'action' ])
+	fvar = GetReqVars(request, [ 'form_xml', 'domain', 'recovery', 'svc_name', 'action', 'max_restarts', 'restart_expire_time' ])
 
 	form_xml = fvar['form_xml']
 	if form_xml is None:
@@ -370,6 +370,28 @@
 	if recovery is not None and recovery != 'restart' and recovery != 'relocate' and recovery != 'disable':
 		errors.append('You entered an invalid recovery option: "%s" Valid options are "restart" "relocate" and "disable."')
 
+	max_restarts = None
+	restart_expire_time = None
+
+	if recovery == 'restart':
+		if fvar['max_restarts'] is not None:
+			try:
+				max_restarts = int(fvar['max_restarts'])
+				if max_restarts < 0:
+					raise ValueError, 'must be greater than or equal to 0'
+			except Exception, e:
+				errors.append('Maximum restarts must be a number greater than or equal to 0')
+				max_restarts = None
+		if fvar['restart_expire_time'] is not None:
+			try:
+				restart_expire_time = int(fvar['restart_expire_time'])
+				if restart_expire_time < 0:
+					raise ValueError, 'must be greater than or equal to 0'
+			except Exception, e:
+				errors.append('Restart expire time must be a number greater than or equal to 0')
+				restart_expire_time = None
+
+
 	service_name = fvar['svc_name']
 	if service_name is None:
 		if LUCI_DEBUG_MODE is True:
@@ -440,6 +462,11 @@
 		new_service.addAttribute('domain', fdom)
 	if recovery:
 		new_service.addAttribute('recovery', recovery)
+	if max_restarts is not None:
+		new_service.addAttribute('max_restarts', str(max_restarts))
+	if restart_expire_time is not None:
+		new_service.addAttribute('restart_expire_time', str(restart_expire_time))
+
 	new_service.addAttribute('exclusive', str(exclusive))
 	if autostart is not None:
 		new_service.attr_hash['autostart'] = autostart
@@ -725,6 +752,8 @@
 
 	if not device and not label:
 		errors.append('No Device or Label value was given')
+	if device and label:
+		errors.append('You may not specify both device and label')
 
 	num_heuristics = 0
 	try:
@@ -1058,7 +1087,7 @@
 def validate_vmsvc_form(model, request):
 	errors = list()
 
-	fvar = GetReqVars(request, [ 'vmname', 'oldname', 'vmpath', 'recovery', 'domain', 'migration_type'])
+	fvar = GetReqVars(request, [ 'vmname', 'oldname', 'vmpath', 'recovery', 'domain', 'migration_type', 'max_restarts', 'restart_expire_time', 'migration_mapping'])
 
 	vm_name = fvar['vmname']
 	if vm_name is None:
@@ -1088,10 +1117,32 @@
 	if recovery is not None and recovery != 'restart' and recovery != 'relocate' and recovery != 'disable':
 		errors.append('You entered an invalid recovery option "%s" for VM service "%s". Valid options are "restart" "relocate" and "disable"' % (recovery, vm_name))
 
+	max_restarts = None
+	restart_expire_time = None
+	if recovery == 'restart':
+		if fvar['max_restarts'] is not None:
+			try:
+				max_restarts = int(fvar['max_restarts'])
+				if max_restarts < 0:
+					raise ValueError, 'must be greater than or equal to 0'
+			except Exception, e:
+				errors.append('Maximum restarts must be a number greater than or equal to 0')
+				max_restarts = None
+		if fvar['restart_expire_time'] is not None:
+			try:
+				restart_expire_time = int(fvar['restart_expire_time'])
+				if restart_expire_time < 0:
+					raise ValueError, 'must be greater than or equal to 0'
+			except Exception, e:
+				errors.append('Restart expire time must be a number greater than or equal to 0')
+				restart_expire_time = None
+
 	migration_type = fvar['migration_type']
 	if migration_type is not None and migration_type != 'live' and migration_type != 'pause':
 		errors.append('Migration type must be either "live" or "pause"')
 
+	migration_mapping = fvar['migration_mapping']
+
 	if len(errors) > 0:
 		return (False, {'errors': errors })
 
@@ -1133,6 +1184,14 @@
 	if migration_type:
 		xvm.addAttribute('migrate', str(migration_type))
 
+	if migration_mapping:
+		xvm.addAttribute('migration_mapping', str(migration_mapping))
+	else:
+		try:
+			xvm.removeAttribute('migration_mapping')
+		except:
+			pass
+
 	fdom = fvar['domain']
 	if fdom:
 		xvm.addAttribute('domain', fdom)
@@ -1141,7 +1200,6 @@
 			xvm.removeAttribute('domain')
 		except:
 			pass
-
 	if recovery:
 		xvm.addAttribute('recovery', recovery)
 	else:
@@ -1149,6 +1207,10 @@
 			xvm.removeAttribute('recovery')
 		except:
 			pass
+	if max_restarts is not None:
+		xvm.addAttribute('max_restarts', str(max_restarts))
+	if restart_expire_time is not None:
+		xvm.addAttribute('restart_expire_time', str(restart_expire_time))
 
 	if delete_vm is True:
 		action = VM_CONFIG
--- conga/luci/site/luci/Extensions/LuciZopeClusterPortal.py	2008/03/25 01:27:12	1.2.2.2
+++ conga/luci/site/luci/Extensions/LuciZopeClusterPortal.py	2008/11/10 21:02:44	1.2.2.3
@@ -251,10 +251,10 @@
 
 	if model.getIsVirtualized() is True:
 		vmadd = {}
-		vmadd['Title'] = 'Add a Virtual Service'
+		vmadd['Title'] = 'Add a Virtual Machine Service'
 		vmadd['cfg_type'] = 'vmadd'
 		vmadd['absolute_url'] = '%s?pagetype=%s&clustername=%s' % (url, VM_ADD, cluname)
-		vmadd['Description'] = 'Add a Virtual Service to this cluster'
+		vmadd['Description'] = 'Add a Virtual Machine Service to this cluster'
 		if pagetype == VM_ADD:
 			vmadd['currentItem'] = True
 		else:
@@ -305,7 +305,7 @@
 		svc['Title'] = name
 		svc['cfg_type'] = 'vm'
 		svc['absolute_url'] = '%s?pagetype=%s&servicename=%s&clustername=%s' % (url, VM_CONFIG, name, cluname)
-		svc['Description'] = 'Configure this Virtual Service'
+		svc['Description'] = 'Configure this Virtual Machine Service'
 		if pagetype == VM_CONFIG:
 			try:
 				xname = request['servicename']
--- conga/luci/site/luci/Extensions/RicciQueries.py	2008/03/25 01:27:12	1.7.2.3
+++ conga/luci/site/luci/Extensions/RicciQueries.py	2008/11/10 21:02:44	1.7.2.4
@@ -6,12 +6,10 @@
 # Free Software Foundation.
 
 from xml.dom import minidom
-from ricci_communicator import RicciCommunicator
+from ricci_communicator import RicciCommunicator, batch_status
 from LuciSyslog import get_logger
 from conga_constants import LUCI_DEBUG_MODE
 
-
-
 luci_log = get_logger()
 
 def addClusterNodeBatch(cluster_name,
@@ -115,7 +113,7 @@
 	batch.append('<module name="cluster">')
 	batch.append('<request API_version="1.0">')
 	batch.append('<function_call name="start_node">')
-	batch.append('<var mutable="false" name="enable_services" type="boolean" value="true"/>"')
+	batch.append('<var mutable="false" name="enable_services" type="boolean" value="true"/>')
 	batch.append('</function_call>')
 	batch.append('</request>')
 	batch.append('</module>')
@@ -342,6 +340,30 @@
 	ricci_xml = rc.batch_run(batch_str)
 	return batchAttemptResult(ricci_xml)
 
+def setClusterConfSync(rc, clusterconf, propagate=True):
+	if propagate is True:
+		propg = 'true'
+	else:
+		propg = 'false'
+
+	conf = str(clusterconf).replace('<?xml version="1.0"?>', '')
+	conf = conf.replace('<?xml version="1.0" ?>', '')
+	conf = conf.replace('<? xml version="1.0"?>', '')
+	conf = conf.replace('<? xml version="1.0" ?>', '')
+
+	batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="set_cluster.conf"><var type="boolean" name="propagate" mutable="false" value="%s"/><var type="xml" mutable="false" name="cluster.conf">%s</var></function_call></request></module>' % (propg, conf)
+
+	ricci_xml = rc.batch_run(batch_str, async=False)
+	if not ricci_xml:
+		return False
+	batch_xml = ricci_xml.getElementsByTagName('batch')
+	if not batch_xml:
+		return None
+	(num, total) = batch_status(batch_xml[0])
+	if num == total:
+		return True
+	return False
+
 def getNodeLogs(rc):
 	from time import time, ctime
 
--- conga/luci/site/luci/Extensions/StorageReport.py	2008/04/11 06:48:11	1.22.2.5
+++ conga/luci/site/luci/Extensions/StorageReport.py	2008/11/10 21:02:44	1.22.2.6
@@ -1621,9 +1621,10 @@
 		mutable = var.getAttribute('mutable') == 'true'
 		var_type = var.getAttribute('type')
 		value = var.getAttribute('value')
+		def_value = value
 
 		d_units = ''
-		if name in ('size', 'extent_size', 'block_size', 'size_free', 'partition_begin' ):
+		if name in ('size', 'extent_size', 'block_size', 'journal_size', 'size_free', 'partition_begin' ):
 			d_units = 'bytes'
 		if 'percent' in name:
 			d_units = '%'
@@ -1685,7 +1686,7 @@
 			d_value = str(value)
 
 		hidden = False
-		if var_type == 'hidden' or name in ( 'partition_begin', 'snapshot' ):
+		if var_type == 'hidden' or name in ( 'partition_begin', 'snapshot' ) or name[0:11] == '__snap_size':
 			hidden = True
 
 		if name == 'removable':
@@ -1697,6 +1698,7 @@
 				'name': name,
 				'pretty_name': get_pretty_prop_name(name),
 				'type': d_type,
+				'default_val': def_value,
 				'value': d_value,
 				'units': d_units,
 				'validation': validation_data,
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2008/04/18 20:37:45	1.227.2.27
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2008/11/10 21:02:44	1.227.2.28
@@ -378,8 +378,8 @@
 
 	if cluster_os is None:
 		if LUCI_DEBUG_MODE is True:
-			luci_log.debug_verbose('Unable to determine cluster OS for %s' % clustername)
-		return (False, { 'errors': [ 'Unable to determine the version of the cluster suite this cluster is running' ] })
+			luci_log.debug_verbose('Unable to determine the operating system version for %s' % clustername)
+		return (False, { 'errors': [ 'Unable to determine the version of the cluster software this cluster is running' ] })
 
 	shared_storage = False
 	try:
@@ -545,41 +545,24 @@
 	next_node_id = 1
 
 	try:
-		for x in system_list:
-			i = system_list[x]
-
-			try:
-				batch_node = rq.addClusterNodeBatch(clustername,
-								True,
-								True,
-								shared_storage,
-								False,
-								download_pkgs,
-								model.GULM_ptr is not None,
-								reboot_nodes)
-				if not batch_node:
-					raise Exception, 'batch is blank'
-				system_list[x]['batch'] = batch_node
-			except Exception, e:
-				cur_system['errors'] = True
-				incomplete = True
-
-				try:
-					if not cur_system['prev_auth']:
-						rc.unauth()
-						del cur_system['trusted']
-				except Exception, e:
-					if LUCI_DEBUG_MODE is True:
-						luci_log.debug_verbose('VACN12: %s: %r %s' \
-							% (cur_host, e, str(e)))
-
-				errors.append('Unable to initiate cluster join for node "%s"' \
-					% cur_host)
-				if LUCI_DEBUG_MODE is True:
-					luci_log.debug_verbose('VACN13: %s: %r %s' \
-						% (cur_host, e, str(e)))
-				continue
+		skeys = system_list.keys()
+		skeys.sort()
+		batch_node = rq.addClusterNodeBatch(clustername,
+						True,
+						True,
+						shared_storage,
+						False,
+						download_pkgs,
+						model.GULM_ptr is not None,
+						reboot_nodes)
+		batch_node_xml = minidom.parseString('<batch>%s</batch>' % batch_node)
+		batch_node_xml = batch_node_xml.getElementsByTagName('batch')[0]
+		if not batch_node_xml:
+			raise Exception, 'batch is blank'
 
+		for x in skeys:
+			i = system_list[x]
+			system_list[x]['batch'] = batch_node_xml
 			next_node_id += 1
 			new_node = ClusterNode()
 			new_node.attr_hash['name'] = str(i['host'])
@@ -598,36 +581,20 @@
 		if not conf_str:
 			raise Exception, 'Unable to save the new cluster model'
 
-		batch_number, result = rq.setClusterConf(cluster_ricci, conf_str)
-		if not batch_number or not result:
-			raise Exception, 'batch or result is None'
+		# Propagate the new cluster.conf to the existing nodes
+		# before having any of the new nodes join. If this fails,
+		# abort the whole process.
+		result = rq.setClusterConfSync(cluster_ricci, conf_str)
+		if result != True:
+			errors.append('Unable to update the cluster configuration on existing cluster nodes')
+			request.SESSION.set('add_node', add_cluster)
+			return (False, { 'errors': errors, 'messages': messages })
 	except Exception, e:
 		incomplete = True
 		errors.append('Unable to generate the new cluster configuration')
 		if LUCI_DEBUG_MODE is True:
 			luci_log.debug_verbose('VACN14: %s' % e)
 
-	# Propagate the new cluster.conf to the existing nodes
-	# before having any of the new nodes join. If this fails,
-	# abort the whole process.
-	try:
-		while True:
-			batch_ret = cluster_ricci.batch_status(batch_number)
-			code = batch_ret[0]
-			if code is True:
-				break
-			if code == -1:
-				errors.append(batch_ret[1])
-				raise Exception, str(batch_ret[1])
-			if code is False:
-				time.sleep(0.5)
-	except Exception, e:
-		incomplete = True
-		errors.append('Unable to update the cluster node list for %s' \
-			% clustername)
-		if LUCI_DEBUG_MODE is True:
-			luci_log.debug_verbose('VACN15: %r %s' % (e, str(e)))
-
 	if incomplete or len(errors) > 0:
 		request.SESSION.set('add_node', add_cluster)
 		return (False, { 'errors': errors, 'messages': messages })
@@ -1167,7 +1134,6 @@
 				msg_list.append('Fix the error and try again:\n')
 			else:
 				msg_list.append('PASSED\n')
-				model.setModified(True)
 				msg_list.append('DONE\n')
 				msg_list.append('Propagating the new cluster.conf')
 
--- conga/luci/site/luci/Extensions/ricci_communicator.py	2008/03/25 01:27:12	1.24.2.3
+++ conga/luci/site/luci/Extensions/ricci_communicator.py	2008/11/10 21:02:44	1.24.2.4
@@ -169,7 +169,7 @@
 				luci_log.debug_net('RC:UNAUTH0: unauthenticate %s for %s:%d' \
 					% (ret, self.__hostname, self.__port))
 			if ret != '0':
-				raise Exception, 'Invalid response'
+				raise Exception, 'Invalid response: %s' % ret
 
 			try:
 				self.ss.untrust()
@@ -494,7 +494,7 @@
 					% batch_xml.toxml())
 			except:
 				pass
-		raise RicciError, 'Not an XML batch node'
+		raise RicciError, 'Not an XML batch node: %s' % batch_xml.nodeName
 
 	total = 0
 	last = 0
@@ -544,7 +544,7 @@
 		if LUCI_DEBUG_NET is True:
 			luci_log.debug_net_priv('RC:EMS0: Expecting "batch" got "%s"' \
 				% batch_xml.toxml())
-		raise RicciError, 'Invalid XML node; expecting a batch node'
+		raise RicciError, 'Invalid XML node; expecting a batch node: %s' % batch_xml.nodeName
 
 	c = 0
 	for node in batch_xml.childNodes:
--- conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py	2008/03/25 01:27:13	1.5.2.5
+++ conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py	2008/11/10 21:02:44	1.5.2.6
@@ -127,6 +127,8 @@
     if domm is None:
       raise Exception, 'No cluster configuration'
 
+    self.errors = False
+    self.errmsg = None
     self.lock_type = DLM_TYPE
     self.mcast_address = mcast_addr
     self.mcast_interface = None
@@ -164,6 +166,12 @@
     self.check_for_multicast()
     self.check_for_nodeids()
 
+  def has_errors(self):
+    return self.errors
+
+  def get_errmsgs(self):
+    return self.errmsg
+
   def getClusterOS(self):
     return self.cluster_os
 
@@ -339,12 +347,24 @@
     for fd in self.getFenceDevices():
       agent = fd.getAgentType()
       if agent is not None:
-        agent_hash[fd.getName()] = agent
+        try:
+          agent_hash[fd.getName()] = agent
+        except KeyError, e:
+          self.errors = True
+          self.errmsg = 'Unknown fence device: %s' % fd.getName()
+        except Exception, e1:
+          self.errors = True
 
     for node in self.getNodes():
       for level in node.getFenceLevels():
         for child in level.getChildren():
-          child.setAgentType(agent_hash[child.getName()])
+          try:
+            child.setAgentType(agent_hash[child.getName()])
+          except KeyError, e:
+            self.errors = True
+            self.errmsg = 'Unknown fence device: %s' % child.getName()
+          except Exception, e1:
+            self.errors = True
     
   ##This method builds RefObject containers for appropriate
   ##entities after the object tree is built.
--- conga/luci/site/luci/etc/zope.conf.in	2008/03/25 01:27:13	1.1.4.2
+++ conga/luci/site/luci/etc/zope.conf.in	2008/11/10 21:02:45	1.1.4.3
@@ -872,6 +872,8 @@
 #
 #    default_zpublisher_encoding utf-8
 
+default-zpublisher-encoding utf-8
+
 # Directives: servers
 #
 # Description:
--- conga/luci/storage/form-macros	2008/03/25 01:27:13	1.20.2.4
+++ conga/luci/storage/form-macros	2008/11/10 21:02:45	1.20.2.5
@@ -87,6 +87,7 @@
 						</select>
 					</td>
 				</tr>
+				<tal:comment tal:replace="nothing">
 				<tr>
 					<td>
 						Display Devices by
@@ -99,6 +100,7 @@
 						</select>
 					</td>
 				</tr>
+				</tal:comment>
 			</table>
 		</form>
 	</fieldset>
@@ -865,21 +867,28 @@
 
 							<tal:block tal:condition="python:prop_type == 'select'">
 								<select tal:define="prop_options prop/value" tal:attributes="name p">
-									<tal:block
-										tal:condition="python: prop_units != 'bytes'"
-										tal:repeat="prop_opt prop_options">
-										<option tal:attributes="value prop_opt" />
-										<span tal:replace="prop_opt" />
+									<tal:block tal:condition="python: prop_units != 'bytes'">
+										<tal:block tal:repeat="prop_opt prop_options">
+											<option tal:attributes="value prop_opt" />
+											<span tal:replace="prop_opt" />
+										</tal:block>
 									</tal:block>
-									<tal:block
-										tal:condition="python: prop_units == 'bytes'"
-										tal:repeat="prop_opt prop_options">
-										<option tal:attributes="value prop_opt" />
-										<span
+
+									<tal:block tal:condition="python: prop_units == 'bytes'">
+										<tal:block
 											tal:define="
-												dummy python: here.bytes_to_value_units(prop_opt);
-												value python: str(dummy[0]) + ' ' + str(dummy[1])"
-											tal:replace="value" />
+													dummy2 python:map(lambda x: int(x), prop_options);
+													dummy3 python:dummy2.sort()"
+											tal:repeat="prop_opt dummy2">
+												<option tal:attributes="
+															value prop_opt;
+															selected python:prop.get('default_val') == str(prop_opt) and 'selected' or ''" />
+												<span
+													tal:define="
+														dummy python: here.bytes_to_value_units(prop_opt);
+														value python: str(dummy[0]) + ' ' + str(dummy[1])"
+													tal:replace="value" />
+										</tal:block>
 									</tal:block>
 								</select>
 							</tal:block>
--- conga/ricci/common/File.cpp	2008/03/25 01:27:14	1.3.2.1
+++ conga/ricci/common/File.cpp	2008/11/10 21:02:45	1.3.2.2
@@ -139,17 +139,17 @@
 	MutexLocker l(*_mutex);
 
 	long len = size();
-	const auto_ptr<char> buff(new char[len]);
+	char buff[len];
 	try {
 		((fstream *) _pimpl->fs)->seekg(0, ios::beg);
 		check_failed();
-		((fstream *) _pimpl->fs)->read(buff.get(), len);
+		((fstream *) _pimpl->fs)->read(buff, len);
 		check_failed();
-		String ret(buff.get(), len);
-		::shred(buff.get(), len);
+		String ret(buff, len);
+		::shred(buff, len);
 		return ret;
 	} catch ( ... ) {
-		::shred(buff.get(), len);
+		::shred(buff, len);
 		throw;
 	}
 }
--- conga/ricci/common/Variable.cpp	2008/03/25 01:27:14	1.8.4.1
+++ conga/ricci/common/Variable.cpp	2008/11/10 21:02:45	1.8.4.2
@@ -26,6 +26,8 @@
 
 #include <stdio.h>
 
+#include <vector>
+#include <algorithm>
 using namespace std;
 
 // ##### class Variable #####
--- conga/ricci/common/utils.cpp	2008/03/25 01:27:14	1.8.2.1
+++ conga/ricci/common/utils.cpp	2008/11/10 21:02:45	1.8.2.2
@@ -23,8 +23,13 @@
 #include "utils.h"
 #include "executils.h"
 
-#include <openssl/md5.h>
+#include <unistd.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <math.h>
+#include <errno.h>
+#include <limits.h>
+#include <openssl/md5.h>
 
 //#include <iostream>
 
@@ -201,24 +206,44 @@
 long long
 utils::to_long(const String& str)
 {
-	return atoll(str.c_str());
+	char *p = NULL;
+	long long ret;
+	ret = strtoll(strip(str).c_str(), &p, 10);
+	if (p != NULL && *p != '\0')
+		throw String("Not a number: ") + str;
+	if (ret == LLONG_MIN && errno == ERANGE)
+		throw String("Numeric underflow: ") + str;
+	if (ret == LLONG_MAX && errno == ERANGE)
+		throw String("Numeric overflow: ") + str;
+	return ret;
 }
 
 float
 utils::to_float(const String& str)
 {
-	float num = 0;
+	char *p = NULL;
+	float ret;
 
-	sscanf(strip(str).c_str(), "%f", &num);
-	return num;
+	ret = strtof(strip(str).c_str(), &p);
+	if (p != NULL && *p == '\0')
+		throw String("Invalid floating point number: ") + str;
+	if (ret == 0 && errno == ERANGE)
+		throw String("Floating point underflow: ") + str;
+	if ((ret == HUGE_VALF || ret == HUGE_VALL) && errno == ERANGE)
+		throw String("Floating point overflow: ") + str;
+
+	return ret;
 }
 
 String
 utils::to_string(int value)
 {
 	char tmp[64];
+	int ret;
 
-	sprintf(tmp, "%d", value);
+	ret = snprintf(tmp, sizeof(tmp), "%d", value);
+	if (ret < 0 || (size_t) ret >= sizeof(tmp))
+		throw String("Invalid integer");
 	return tmp;
 }
 
@@ -226,8 +251,11 @@
 utils::to_string(long value)
 {
 	char tmp[64];
+	int ret;
 
-	sprintf(tmp, "%ld", value);
+	ret = snprintf(tmp, sizeof(tmp), "%ld", value);
+	if (ret < 0 || (size_t) ret >= sizeof(tmp))
+		throw String("Invalid long integer");
 	return tmp;
 }
 
@@ -235,8 +263,11 @@
 utils::to_string(long long value)
 {
 	char tmp[64];
+	int ret;
 
-	sprintf(tmp, "%lld", value);
+	ret = snprintf(tmp, sizeof(tmp), "%lld", value);
+	if (ret < 0 || (size_t) ret >= sizeof(tmp))
+		throw String("Invalid long long integer");
 	return tmp;
 }
 
--- conga/ricci/include/shred_allocator.h	2008/03/25 01:27:15	1.2.4.1
+++ conga/ricci/include/shred_allocator.h	2008/11/10 21:02:45	1.2.4.2
@@ -33,6 +33,12 @@
 #ifndef __CONGA_SHRED_ALLOCATOR_H
 #define __CONGA_SHRED_ALLOCATOR_H
 
+extern "C" {
+	#include <unistd.h>
+	#include <stdlib.h>
+	#include <string.h>
+}
+
 #include <new>
 
 template<typename _Tp>
--- conga/ricci/modules/cluster/clumon/REDHAT-CLUSTER-MIB	2006/06/14 21:44:36	1.1
+++ conga/ricci/modules/cluster/clumon/REDHAT-CLUSTER-MIB	2008/11/10 21:02:45	1.1.4.1
@@ -234,7 +234,7 @@
 	::= { rhcTables 1 }
 
 rhcNodeEntry OBJECT-TYPE
-	SYNTAX      RchNodeEntry
+	SYNTAX      RhcNodeEntry
 	MAX-ACCESS  not-accessible
 	STATUS      current
 	DESCRIPTION
@@ -311,7 +311,7 @@
 	::= { rhcTables 2 }
 
 rhcServiceEntry OBJECT-TYPE
-	SYNTAX      RchServiceEntry
+	SYNTAX      RhcServiceEntry
 	MAX-ACCESS  not-accessible
 	STATUS      current
 	DESCRIPTION
--- conga/ricci/modules/cluster/clumon/REDHAT-MIB	2006/06/14 21:44:36	1.1
+++ conga/ricci/modules/cluster/clumon/REDHAT-MIB	2008/11/10 21:02:46	1.1.4.1
@@ -2,8 +2,7 @@
 
 
 IMPORTS
-	enterprises				FROM RFC1155-SMI
-	MODULE-IDENTITY				FROM SNMPv2-SMI;
+	enterprises, MODULE-IDENTITY				FROM RFC1155-SMI;
 
 
 RedHat MODULE-IDENTITY
--- conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp	2007/10/10 18:19:30	1.6.4.2
+++ conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp	2008/11/10 21:02:47	1.6.4.3
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) Red Hat, Inc. 2005-2007
+** Copyright (C) Red Hat, Inc. 2005-2008
 **
 ** This program is free software; you can redistribute it and/or modify it
 ** under the terms of the GNU General Public License version 2 as
@@ -25,7 +25,8 @@
 #include <stdio.h>
 
 extern "C" {
-#	include <libcman.h>
+	#include <limits.h>
+	#include <libcman.h>
 }
 
 using namespace std;
--- conga/ricci/modules/rpm/PackageHandler.cpp	2008/06/10 14:48:32	1.11.2.6
+++ conga/ricci/modules/rpm/PackageHandler.cpp	2008/11/10 21:02:47	1.11.2.7
@@ -511,9 +511,12 @@
 			if (kernel.find("xen") == kernel.npos) {
 				set.packages.push_back("kmod-gfs");
 				set.packages.push_back("kmod-gfs2");
+				set.packages.push_back("cmirror");
+				set.packages.push_back("kmod-cmirror");
 			} else {
 				set.packages.push_back("kmod-gfs-xen");
 				set.packages.push_back("kmod-gfs2-xen");
+				set.packages.push_back("kmod-cmirror-xen");
 			}
 		}
 	}
--- conga/ricci/modules/service/ServiceManager.cpp	2008/06/10 14:48:33	1.7.2.6
+++ conga/ricci/modules/service/ServiceManager.cpp	2008/11/10 21:02:47	1.7.2.7
@@ -521,11 +521,12 @@
 		servs.push_back("gfs");
 		servs.push_back("scsi_reserve");
 	} else if (RHEL5 || FC6) {
-		descr = "Shared Storage: clvmd, gfs, gfs2";
+		descr = "Shared Storage: clvmd, cmirror, gfs, gfs2";
 		servs.push_back("clvmd");
 		servs.push_back("gfs");
 		servs.push_back("gfs2");
 		servs.push_back("scsi_reserve");
+		servs.push_back("cmirror");
 	}
 	s = ServiceSet(name, descr);
 	if (populate_set(s, servs))
--- conga/ricci/modules/storage/ContentFS.cpp	2008/03/25 01:27:19	1.5.4.1
+++ conga/ricci/modules/storage/ContentFS.cpp	2008/11/10 21:02:47	1.5.4.2
@@ -28,6 +28,7 @@
 #include "BDFactory.h"
 #include "defines.h"
 #include "utils.h"
+#include <algorithm>
 
 
 using namespace std;
--- conga/ricci/modules/storage/ExtendedFS.cpp	2008/03/25 01:27:19	1.8.2.1
+++ conga/ricci/modules/storage/ExtendedFS.cpp	2008/11/10 21:02:47	1.8.2.2
@@ -27,8 +27,9 @@
 #include "UMountError.h"
 #include "FileMagic.h"
 
-
+#include <algorithm>
 #include <iostream>
+
 using namespace std;
 
 
--- conga/ricci/modules/storage/LV.cpp	2008/03/25 01:27:19	1.7.2.3
+++ conga/ricci/modules/storage/LV.cpp	2008/11/10 21:02:47	1.7.2.4
@@ -124,7 +124,7 @@
     long long min  = utils::to_long(xml.get_attr("min"));
     long long max  = utils::to_long(xml.get_attr("max"));
     long long step = utils::to_long(xml.get_attr("step"));
-    long long min_size = (long long ) (size * (usage / 100.0));
+    long long min_size = (long long) (size * usage) / 100;
     if (min_size > min)
       min = min_size;
     else if (min_size > max)
--- conga/ricci/modules/storage/LVM.cpp	2008/03/25 01:27:19	1.11.2.2
+++ conga/ricci/modules/storage/LVM.cpp	2008/11/10 21:02:47	1.11.2.3
@@ -252,7 +252,7 @@
   String attrs = words[LVS_ATTR_IDX];
   props.set(Variable("attrs", attrs));
 
-  props.set(Variable("mirrored", attrs[0] == 'm'));
+  props.set(Variable("mirrored", attrs[0] == 'm' || attrs[0] == 'M'));
 
   // clustered
   String vg_attrs = words[LVS_VG_ATTR_IDX];
@@ -602,17 +602,37 @@
 void
 LVM::lvremove(const String& path)
 {
-  vector<String> args;
-  args.push_back("lvchange");
-  args.push_back("-an");
-  args.push_back(path);
-
-  String out, err;
-  int status;
-  if (utils::execute(LVM_BIN_PATH, args, out, err, status, false))
-    throw command_not_found_error_msg(LVM_BIN_PATH);
-  if (status != 0)
-    throw String("Unable to deactivate LV (might be in use by other cluster nodes)");
+	vector<String> args;
+	args.push_back("lvchange");
+	args.push_back("-an");
+	args.push_back(path);
+
+	String out, err;
+	int status;
+
+	if (utils::execute(LVM_BIN_PATH, args, out, err, status, false))
+		throw command_not_found_error_msg(LVM_BIN_PATH);
+
+	if (status != 0) {
+		bool ignore_err = false;
+
+		try {
+			Props props;
+			std::list<counting_auto_ptr<BD> > sources;
+			std::list<counting_auto_ptr<BD> > targets;
+			probe_vg(path, props, sources, targets);
+			if (props.get("snapshot").get_bool() ||
+				props.get("mirror").get_bool())
+			{
+				ignore_err = true;
+			}
+		} catch (...) {
+			ignore_err = false;
+		}
+
+		if (!ignore_err)
+			throw String("Unable to deactivate LV (might be in use by other cluster nodes)");
+	}
 
   try {
     args.clear();
--- conga/ricci/modules/storage/Mapper.cpp	2008/03/25 01:27:19	1.3.4.1
+++ conga/ricci/modules/storage/Mapper.cpp	2008/11/10 21:02:47	1.3.4.2
@@ -26,6 +26,7 @@
 #include "BDFactory.h"
 #include "MapperFactory.h"
 #include "MidAir.h"
+#include <algorithm>
 
 
 using namespace std;
--- conga/ricci/modules/storage/MountHandler.cpp	2008/03/25 01:27:19	1.6.2.1
+++ conga/ricci/modules/storage/MountHandler.cpp	2008/11/10 21:02:47	1.6.2.2
@@ -37,8 +37,9 @@
 #include <sys/file.h>
 #include <errno.h>
 
-
+#include <algorithm>
 #include <iostream>
+
 using namespace std;
 
 
--- conga/ricci/modules/storage/PTSource.cpp	2008/03/25 01:27:19	1.2.4.1
+++ conga/ricci/modules/storage/PTSource.cpp	2008/11/10 21:02:47	1.2.4.2
@@ -25,6 +25,7 @@
 #include "PartitionTable.h"
 #include "parted_wrapper.h"
 
+#include <algorithm>
 
 using namespace std;
 
--- conga/ricci/modules/storage/PV.cpp	2008/03/25 01:27:19	1.5.2.2
+++ conga/ricci/modules/storage/PV.cpp	2008/11/10 21:02:47	1.5.2.3
@@ -26,6 +26,7 @@
 #include "MapperFactory.h"
 #include "utils.h"
 #include "LVMClusterLockingError.h"
+#include <algorithm>
 
 
 using namespace std;
--- conga/ricci/modules/storage/Partition.cpp	2008/03/25 01:27:19	1.3.4.1
+++ conga/ricci/modules/storage/Partition.cpp	2008/11/10 21:02:47	1.3.4.2
@@ -30,6 +30,7 @@
 #include "ContentExtendedPartition.h"
 #include "PV.h"
 
+#include <algorithm>
 
 using namespace std;
 
--- conga/ricci/modules/storage/PartitionTable.cpp	2008/03/25 01:27:19	1.5.4.1
+++ conga/ricci/modules/storage/PartitionTable.cpp	2008/11/10 21:02:47	1.5.4.2
@@ -28,7 +28,7 @@
 #include "MapperFactory.h"
 #include "utils.h"
 
-
+#include <algorithm>
 #include <iostream>
 
 
--- conga/ricci/modules/storage/parted_wrapper.cpp	2008/03/25 01:27:19	1.8.4.4
+++ conga/ricci/modules/storage/parted_wrapper.cpp	2008/11/10 21:02:47	1.8.4.5
@@ -24,8 +24,9 @@
 #include "parted_wrapper.h"
 #include "utils.h"
 
-
+#include <algorithm>
 #include <iostream>
+
 using namespace std;
 
 
--- conga/ricci/ricci/SSLInstance.cpp	2008/03/25 01:27:19	1.7.2.2
+++ conga/ricci/ricci/SSLInstance.cpp	2008/11/10 21:02:48	1.7.2.3
@@ -498,6 +498,8 @@
 			e = "SSL_ERROR_WANT_X509_LOOKUP";
 			break;
 		case SSL_ERROR_SYSCALL:
+			if (err == EAGAIN || err == EINTR)
+				return;
 			e = "SSL_ERROR_SYSCALL";
 			break;
 		case SSL_ERROR_SSL:




More information about the Cluster-devel mailing list