VCL-1041 - Customer facing email notifications are ugly

vclmessages.pl: initial add

DataStructure.pm: modified substitute_string_variables subroutine: added a check for $subroutine_mapping_key starting with 'if ' or being 'endif' to skip attempting substitution to ignore HTML comment conditionals from HTML messages

utils.pm: modified mail subroutine: reworked ending code to create a hash of headers for the mail function, add Bcc if $shared_mail_box set, check for html tags in $mailstring and add Content-Type if exist

update-vcl.sql and vcl.sql: added definition and values for messagereset table

siteconfig.php: modified __construct: added check for existance of any html tags in message, subject, or short_message, if contained, set content of that item to empty string and set DBmanagedHTML flag

siteconfig.js: modified messages.prototype.setContents: added section to check for DBmanagedHTML key in returned data, if exists, disable input fields for this item, else enable fields and set messagebody value
diff --git a/managementnode/bin/vclmessages.pl b/managementnode/bin/vclmessages.pl
new file mode 100755
index 0000000..20ae532
--- /dev/null
+++ b/managementnode/bin/vclmessages.pl
@@ -0,0 +1,202 @@
+#!/usr/bin/perl -w
+
+use Getopt::Long;
+use YAML;
+use DBI;
+use Data::Dumper;
+
+my $getnames = 0;
+my $dumpmessage = '';
+my $setmessage = '';
+my $resetmessage = '';
+my $htmlfile = '';
+my $subject = '';
+my $help = 0;
+
+GetOptions ('getmessagenames' => \$getnames,
+            'dumpmessage:s' => \$dumpmessage,
+            'resetmessage:s' => \$resetmessage,
+            'setmessage:s' => \$setmessage,
+            'htmlfile:s' => \$htmlfile,
+            'subject:s' => \$subject,
+            'help|?' => \$help);
+
+if ($help ||
+	($getnames == 1 && ($dumpmessage ne '' || $setmessage ne '' || $resetmessage ne '' || $htmlfile ne '' || $subject ne '')) ||
+	($getnames == 0 && $dumpmessage ne '' && ($setmessage ne '' || $resetmessage ne '' || $htmlfile ne '' || $subject ne '')) ||
+	($getnames == 0 && $resetmessage ne '' && ($setmessage ne '' || $dumpmessage ne '' || $htmlfile ne '' || $subject ne '')) ||
+	($getnames == 0 && $setmessage ne '' && ($dumpmessage ne '' || $resetmessage ne '' || $htmlfile eq '' || $subject eq '')) ||
+	($getnames == 0 && $setmessage eq '' && $dumpmessage eq '' && $resetmessage eq ''))
+{
+	print "Usage:\n\n";
+	print "vclmessages.pl --getmessagenames\n";
+	print "vclmessages.pl --dumpmessage '<name of message>'\n";
+	print "vclmessages.pl --setmessage '<name of message>' --htmlfile <filename> --subject <message subject>\n";
+	print "vclmessages.pl --resetmessage '<name of message>'\n\n";
+	print "vclmessages.pl --help|-?\n\n";
+	print "Where\n\n";
+	print "--getmessagenames displays a list of all available names that can be used\n";
+	print "--dumpmessage displays the current value of a message\n";
+	print "--setmessage sets the value of a message to the contents of the specified file\n";
+	print "--resetmessage sets the value of a message back to the original value as distributed with VCL\n\n";
+	print "<name of message> = the name of the message from the database (enclose in single quotes)\n";
+	print "\tuse --getmessagenames to get a list of message names\n\n";
+	print "<filename> = filename (including path) of file containing html contents for email message\n\n";
+	print "<message subject> = subject for email message (enclose in single quotes)\n\n";
+	exit 0;
+}
+
+my $mode = 'getnames';
+$mode = 'dumpmessage' if($dumpmessage ne '');
+$mode = 'setmessage' if($setmessage ne '');
+$mode = 'resetmessage' if($resetmessage ne '');
+
+my $messagename = $dumpmessage;
+$messagename = $setmessage if($mode eq 'setmessage');
+$messagename = $resetmessage if($mode eq 'resetmessage');
+
+my $database = `grep ^database /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+my $hostname = `grep ^server /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+my $user = `grep ^LockerWrtUser /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+my $password = `grep ^wrtPass /etc/vcl/vcld.conf | awk -F '=' '{print \$2}'`;
+
+chomp $database;
+chomp $hostname;
+chomp $user;
+chomp $password;
+
+my $dsn = "DBI:mysql:database=$database;host=$hostname";
+my $dbh = DBI->connect($dsn, $user, $password);
+
+# ================= get names ================
+if($mode eq 'getnames')
+{
+	my $sth = $dbh->prepare(
+		"SELECT name FROM variable WHERE name LIKE 'usermessage%' OR name LIKE 'adminmessage%' ORDER BY name")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute();
+	while (my $ref = $sth->fetchrow_hashref()) {
+		print "$ref->{'name'}\n";
+	}
+	$sth->finish;
+	$sth->finish;
+	$dbh->disconnect;
+	exit 0;
+}
+# ================ dump message ===============
+elsif($mode eq 'dumpmessage')
+{
+	my $sth = $dbh->prepare(
+		"SELECT value FROM variable WHERE name = ?")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute($messagename);
+	if($sth->rows == 0)
+	{
+		print "Error: Failed to find message with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	if($sth->rows > 1)
+	{
+		print "Error: Found multiple messages with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	my $ref = $sth->fetchrow_hashref();
+	my $data = YAML::Load($ref->{'value'});
+	#print Dumper($data);
+	print "Subject: $data->{'subject'}\n";
+	print "Message:\n";
+	print "$data->{'message'}\n";
+
+	$sth->finish;
+	$dbh->disconnect;
+	exit 0;
+}
+# ================= reset message ===============
+elsif($mode eq 'resetmessage')
+{
+	my $sth = $dbh->prepare(
+		'SELECT value FROM messagereset WHERE name = ?')
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute($messagename) or die "Error: failed to query database: $dbh->errstr()";
+	if($sth->rows == 0)
+	{
+		print "Error: Failed to find message with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	if($sth->rows > 1)
+	{
+		print "Error: Found multiple messages with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+
+	my $ref = $sth->fetchrow_hashref();
+	my $message = $ref->{'value'};
+
+	$sth = $dbh->prepare(
+		"UPDATE variable SET value = ?, setby = 'setemail script', timestamp = NOW() WHERE name = ?")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+
+	$sth->bind_param(1, $message);
+	$sth->bind_param(2, $messagename);
+	$sth->execute() or die "Error: Failed to update value for $messagename\n";
+
+	$sth->finish;
+	$dbh->disconnect;
+	print "Success: Value reset for $messagename\n";
+}
+# ================= set message ===============
+elsif($mode eq 'setmessage')
+{
+	my $htmlemail;
+	open(my $fh, '<', $htmlfile) or die "Error: failed to open $htmlfile for reading";
+	{
+		local $/;
+		$htmlemail = <$fh>;
+	}
+	close($fh);
+
+	my $sth = $dbh->prepare(
+		'SELECT value FROM variable WHERE name = ?')
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+	$sth->execute($messagename) or die "Error: failed to query database: $dbh->errstr()";
+	if($sth->rows == 0)
+	{
+		print "Error: Failed to find message with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+	if($sth->rows > 1)
+	{
+		print "Error: Found multiple messages with name $messagename\n";
+		$sth->finish;
+		$dbh->disconnect;
+		exit 0;
+	}
+
+	my $ref = $sth->fetchrow_hashref();
+	my $data = YAML::Load($ref->{'value'});
+	$data->{'message'} = $htmlemail;
+	$data->{'subject'} = $subject;
+	my $yaml = YAML::Dump($data);
+
+	$sth = $dbh->prepare(
+		"UPDATE variable SET value = ?, setby = 'setemail script', timestamp = NOW() WHERE name = ?")
+		or die "Error: Failed to prepare database query: $dbh->errstr()";
+
+	$sth->bind_param(1, $yaml);
+	$sth->bind_param(2, $messagename);
+	$sth->execute() or die "Error: Failed to update value for $messagename\n";
+
+	$sth->finish;
+	$dbh->disconnect;
+	print "Success: Value for $messagename updated from contents of $htmlfile\n";
+}
diff --git a/managementnode/lib/VCL/DataStructure.pm b/managementnode/lib/VCL/DataStructure.pm
index 3d57fdf..96ac42e 100644
--- a/managementnode/lib/VCL/DataStructure.pm
+++ b/managementnode/lib/VCL/DataStructure.pm
@@ -2641,6 +2641,8 @@
 			next;
 		}
 		#notify($ERRORS{'DEBUG'}, 0, "extracted subroutine mapping key from section of input string: '$input_substitute_section' --> '$subroutine_mapping_key'");
+		# skip keys derived from [if ...] and [endif] to prevent creation of mappings from HTML comment conditionals
+		next if ($subroutine_mapping_key =~ /^if / || $subroutine_mapping_key eq "endif");
 		
 		# Attempt to retrieve the substitution value from the DataStructure data
 		# Check if DataStructure.pm implements a matching 'get_' function
diff --git a/managementnode/lib/VCL/utils.pm b/managementnode/lib/VCL/utils.pm
index 2342e37..75cf782 100644
--- a/managementnode/lib/VCL/utils.pm
+++ b/managementnode/lib/VCL/utils.pm
@@ -1306,28 +1306,22 @@
 		$shared_mail_box = $management_node_info->{SHARED_EMAIL_BOX} if $management_node_info->{SHARED_EMAIL_BOX};
 	}
 
+	my $mail_args = {From => $from, To => $to, Subject => $subject};
 	if ($shared_mail_box) {
-		my $bcc = $shared_mail_box;
-		if ($mailer->open({From => $from, To => $to, Bcc => $bcc, Subject => $subject})) {
-			print $mailer $mailstring;
-			$mailer->close();
-			notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "NOTICE --  Problem sending mail to: $to From");
-		}
-	} ## end if ($shared_mail_box)
+		$mail_args->{Bcc} = $shared_mail_box;
+	}
+	if($mailstring =~ /<html>/ || $mailstring =~ /<html .*>/) {
+		$mail_args->{'Content-Type'} = "text/html";
+		notify($ERRORS{'DEBUG'}, 0, "Encountered message containing <html> tag, adding Content-Type header");
+	}
+	if ($mailer->open($mail_args)) {
+		print $mailer $mailstring;
+		$mailer->close();
+		notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
+	}
 	else {
-		if ($mailer->open({From => $from, To => $to, Subject => $subject,}))
-		{
-			print $mailer $mailstring;
-			$mailer->close();
-			notify($ERRORS{'OK'}, 0, "SUCCESS -- Sending mail To: $to, $subject");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "NOTICE --  Problem sending mail to: $to From");
-		}
-	} ## end else [ if ($shared_mail_box)
+		notify($ERRORS{'WARNING'}, 0, "NOTICE --  Problem sending mail to: $to");
+	}
 } ## end sub mail
 
 #//////////////////////////////////////////////////////////////////////////////
diff --git a/mysql/update-vcl.sql b/mysql/update-vcl.sql
index 1dea030..624f3f1 100644
--- a/mysql/update-vcl.sql
+++ b/mysql/update-vcl.sql
@@ -1128,6 +1128,18 @@
 
 -- --------------------------------------------------------
 
+-- 
+-- Table structure for table `messagereset`
+-- 
+
+CREATE TABLE IF NOT EXISTS `messagereset` (
+  `name` varchar(128) NOT NULL,
+  `value` longtext NOT NULL,
+  PRIMARY KEY (`name`)
+) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure change for table `module`
 --
@@ -1751,6 +1763,30 @@
 -- --------------------------------------------------------
 
 -- 
+-- Inserts for table `messagereset`
+-- 
+
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('adminmessage|image_creation_failed', '---\nmessage: |\n  VCL Image Creation Failed\n  \n  Management node: [management_node_short_name]\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image revision ID: [imagerevision_id]\n  Image name: [image_name]\n  Image display name: [image_prettyname]\n  Image OS package: [image_os_module_perl_package]\n  \n  User ID: [user_id]\n  User login name: [user_login_id]\n  User name: [user_firstname] [user_lastname]\n  User affiliation: [user_affiliation_name]\n  \n  Provisioning module: [computer_provisioning_pretty_name] ([computer_provisioning_name])\n  Provisioning package: [computer_provisioning_module_perl_package]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  VM host ID: [vmhost_id]\n  VM host computer ID: [vmhost_computer_id]\n  VM host computer name: [vmhost_short_name]\n  \n  VM host profile ID: [vmhost_profile_id]\n  VM host profile name: [vmhost_profile_name]\nsubject: ''VCL -- NOTICE FAILED Image [image_capture_type] [image_prettyname]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('adminmessage|image_creation_complete', '---\nmessage: |\n  VCL Image [image_capture_type] Completed\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Image size: [image_size]\n  \n  Revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE [image_capture_type] Completed: [image_name]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('adminmessage|image_creation_started', '---\nmessage: |\n  VCL Image Creation Started\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Base image size: [image_size]\n  Base revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE Creation Started: [image_name]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_reached|Global', '---\nmessage: |\n  Your reservation of [image_prettyname] has ended. Thank you for using [user_affiliation_sitewwwaddress].\n  \n  Regards,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- End of reservation''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|reserved|Global', '---\nmessage: |\n  The resources for your VCL reservation have been successfully reserved.\n  Connection will not be allowed until you click the ''Connect'' button on the ''Current Reservations'' page.\n  You must acknowledge the reservation within the next 15 minutes or the resources will be reclaimed for other VCL users.\n  \n  -Visit [user_affiliation_sitewwwaddress]\n  -Select "Current Reservations"\n  -Click the "Connect" button\n  Upon acknowledgement, all of the remaining connection details will be displayed.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|timeout_no_initial_connection|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_imminent|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname], please save all work and prepare to exit.\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  Visit [user_affiliation_sitewwwaddress] and select Current Reservations to edit this reservation.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the end of your reservation. Please save all work and prepare to log off.''\nsubject: ''VCL -- [notice_interval] until end of reservation''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|production_imagerevision|Global', '---\nmessage: |\n  Revision [imagerevision_revision] of your VCL ''[image_prettyname]'' image has been made production.  Any new reservations for the image will receive this revision by default.\n  \n  If you have any questions, please contact [user_affiliation_helpaddress].\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- Image [image_prettyname] made production''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|timeout_inactivity|Global', '---\nmessage: |\n  Your reservation has timed out due to inactivity for image [image_prettyname].\n  \n  To make another reservation, please revisit:\n  [user_affiliation_sitewwwaddress]\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- reservation timeout''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|image_creation_delayed|Global', '---\nmessage: |\n  We apologize for the inconvenience.\n  Your image creation of [image_prettyname] has been delayed\n  due to a system issue that prevented the automatic completion.\n  \n  The image creation request and the computing resource have\n  been placed in a safe mode. The VCL system administrators\n  have been notified for manual intervention.\n  \n  Once the issues have been resolved, you will be notified\n  by the successful completion email or contacted directly\n  by the VCL system administrators.\n  \n  If you do not receive a response within one business day, please\n  reply to this email.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- NOTICE DELAY Image Creation [image_prettyname]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|reinstalled|Global', '---\nmessage: |\n  Your reservation was successfully reinstalled and you can proceed to reconnect. \n  Please revisit the ''Current Reservations'' page for any additional information.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************''\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation reinstalled''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_reached_imaging|Global', '---\nmessage: |\n  Your imaging reservation of [image_prettyname] has reached it''s scheduled end time.\n  \n  To avoid losing your work we have started an automatic capture of this image. Upon completion of the \n  image capture. You will be notified about the completion of the image capture.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL Image Reservation - Auto capture started''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|image_creation_success|Global', '---\nmessage: |\n  Your VCL image creation request for [image_prettyname] has succeeded.\n  \n  Please visit [user_affiliation_sitewwwaddress] and you should see an image called [image_prettyname].\n  \n  Please test this image to confirm it works correctly.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Creation Succeeded''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|image_checkpoint_success|Global', '---\nmessage: |\n  Your VCL image checkpoint creation request for [image_prettyname] has succeeded.\n  \n  You will need to visit the "Current Reservations" page and click "Connect" in order to be able to reconnect to the computer.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Checkpoint Succeeded''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|timeout_no_acknowledgement|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|future_endtime|Global', '---\nmessage: |\n  You have [notice_interval] until the scheduled end time of your reservation for image [image_prettyname].\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  To edit this reservation:\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select Current Reservations\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: "You have [notice_interval] until the scheduled end time of your reservation. VCL Team\\n"\nsubject: ''VCL -- [notice_interval] until end of reservation for [image_prettyname]''\n');
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES ('usermessage|endtime_imminent_imaging|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname]. \n  \n  At the scheduled end time your imaging reservation will be automatically captured. \n  \n  To prevent this auto capture, visit the VCL site [user_affiliation_sitewwwaddress] manually start the image creation process.\n  \n  Please note this auto capture feature is intended to prevent destorying any work you have done to the image.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the auto capture process is started.''\nsubject: ''VCL Imaging Reservation -- [notice_interval] until starting auto capture''\n');
+
+-- --------------------------------------------------------
+
+-- 
 -- Inserts for table `module`
 -- 
 
diff --git a/mysql/vcl.sql b/mysql/vcl.sql
index a5e41b1..5ac1aa8 100644
--- a/mysql/vcl.sql
+++ b/mysql/vcl.sql
@@ -709,6 +709,18 @@
 
 -- --------------------------------------------------------
 
+-- 
+-- Table structure for table `messagereset`
+-- 
+
+CREATE TABLE IF NOT EXISTS `messagereset` (
+  `name` varchar(128) NOT NULL,
+  `value` longtext NOT NULL,
+  PRIMARY KEY (`name`)
+) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `module`
 --
@@ -1787,6 +1799,29 @@
 (1, 'none');
 
 -- 
+-- Dumping data for table `messagereset`
+-- 
+
+INSERT IGNORE INTO `messagereset` (`name`, `value`) VALUES
+('adminmessage|image_creation_failed', '---\nmessage: |\n  VCL Image Creation Failed\n  \n  Management node: [management_node_short_name]\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image revision ID: [imagerevision_id]\n  Image name: [image_name]\n  Image display name: [image_prettyname]\n  Image OS package: [image_os_module_perl_package]\n  \n  User ID: [user_id]\n  User login name: [user_login_id]\n  User name: [user_firstname] [user_lastname]\n  User affiliation: [user_affiliation_name]\n  \n  Provisioning module: [computer_provisioning_pretty_name] ([computer_provisioning_name])\n  Provisioning package: [computer_provisioning_module_perl_package]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  VM host ID: [vmhost_id]\n  VM host computer ID: [vmhost_computer_id]\n  VM host computer name: [vmhost_short_name]\n  \n  VM host profile ID: [vmhost_profile_id]\n  VM host profile name: [vmhost_profile_name]\nsubject: ''VCL -- NOTICE FAILED Image [image_capture_type] [image_prettyname]''\n'),
+('adminmessage|image_creation_complete', '---\nmessage: |\n  VCL Image [image_capture_type] Completed\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Image size: [image_size]\n  \n  Revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE [image_capture_type] Completed: [image_name]''\n'),
+('adminmessage|image_creation_started', '---\nmessage: |\n  VCL Image Creation Started\n  \n  Request ID: [request_id]\n  Reservation ID: [reservation_id]\n  PID: [process_pid]\n  \n  Image ID: [image_id]\n  Image name: [image_name]\n  Base image size: [image_size]\n  Base revision ID: [imagerevision_id]\n  \n  Management node: [management_node_short_name]\n  \n  Username: [user_login_id]\n  User ID: [user_id]\n  \n  Computer ID: [computer_id]\n  Computer name: [computer_short_name]\n  \n  Use Sysprep: [imagemeta_sysprep]\nsubject: ''VCL IMAGE Creation Started: [image_name]''\n'),
+('usermessage|endtime_reached|Global', '---\nmessage: |\n  Your reservation of [image_prettyname] has ended. Thank you for using [user_affiliation_sitewwwaddress].\n  \n  Regards,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- End of reservation''\n'),
+('usermessage|reserved|Global', '---\nmessage: |\n  The resources for your VCL reservation have been successfully reserved.\n  Connection will not be allowed until you click the ''Connect'' button on the ''Current Reservations'' page.\n  You must acknowledge the reservation within the next 15 minutes or the resources will be reclaimed for other VCL users.\n  \n  -Visit [user_affiliation_sitewwwaddress]\n  -Select "Current Reservations"\n  -Click the "Connect" button\n  Upon acknowledgement, all of the remaining connection details will be displayed.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation''\n'),
+('usermessage|timeout_no_initial_connection|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n'),
+('usermessage|endtime_imminent|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname], please save all work and prepare to exit.\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  Visit [user_affiliation_sitewwwaddress] and select Current Reservations to edit this reservation.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the end of your reservation. Please save all work and prepare to log off.''\nsubject: ''VCL -- [notice_interval] until end of reservation''\n'),
+('usermessage|production_imagerevision|Global', '---\nmessage: |\n  Revision [imagerevision_revision] of your VCL ''[image_prettyname]'' image has been made production.  Any new reservations for the image will receive this revision by default.\n  \n  If you have any questions, please contact [user_affiliation_helpaddress].\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- Image [image_prettyname] made production''\n'),
+('usermessage|timeout_inactivity|Global', '---\nmessage: |\n  Your reservation has timed out due to inactivity for image [image_prettyname].\n  \n  To make another reservation, please revisit:\n  [user_affiliation_sitewwwaddress]\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- reservation timeout''\n'),
+('usermessage|image_creation_delayed|Global', '---\nmessage: |\n  We apologize for the inconvenience.\n  Your image creation of [image_prettyname] has been delayed\n  due to a system issue that prevented the automatic completion.\n  \n  The image creation request and the computing resource have\n  been placed in a safe mode. The VCL system administrators\n  have been notified for manual intervention.\n  \n  Once the issues have been resolved, you will be notified\n  by the successful completion email or contacted directly\n  by the VCL system administrators.\n  \n  If you do not receive a response within one business day, please\n  reply to this email.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- NOTICE DELAY Image Creation [image_prettyname]''\n'),
+('usermessage|reinstalled|Global', '---\nmessage: |\n  Your reservation was successfully reinstalled and you can proceed to reconnect. \n  Please revisit the ''Current Reservations'' page for any additional information.\n  \n  Thank You,\n  VCL Team\n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************''\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] reservation reinstalled''\n'),
+('usermessage|endtime_reached_imaging|Global', '---\nmessage: |\n  Your imaging reservation of [image_prettyname] has reached it''s scheduled end time.\n  \n  To avoid losing your work we have started an automatic capture of this image. Upon completion of the \n  image capture. You will be notified about the completion of the image capture.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ~\nsubject: ''VCL Image Reservation - Auto capture started''\n'),
+('usermessage|image_creation_success|Global', '---\nmessage: |\n  Your VCL image creation request for [image_prettyname] has succeeded.\n  \n  Please visit [user_affiliation_sitewwwaddress] and you should see an image called [image_prettyname].\n  \n  Please test this image to confirm it works correctly.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Creation Succeeded''\n'),
+('usermessage|image_checkpoint_success|Global', '---\nmessage: |\n  Your VCL image checkpoint creation request for [image_prettyname] has succeeded.\n  \n  You will need to visit the "Current Reservations" page and click "Connect" in order to be able to reconnect to the computer.\n  \n  Thank You,\n  VCL Team\nshort_message: ~\nsubject: ''VCL -- [image_prettyname] Image Checkpoint Succeeded''\n'),
+('usermessage|timeout_no_acknowledgement|Global', '---\nmessage: |\n  Your reservation has timed out for image [image_prettyname] because no initial connection was made.\n  \n  To make another reservation, please revisit [user_affiliation_sitewwwaddress].\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance\n  please respond with detailed information on the issue\n  and a help ticket will be generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  ******************************************************************\nshort_message: ~\nsubject: ''VCL -- Reservation Timeout''\n'),
+('usermessage|future_endtime|Global', '---\nmessage: |\n  You have [notice_interval] until the scheduled end time of your reservation for image [image_prettyname].\n  \n  Reservation extensions are available if the machine you are on does not have a reservation immediately following.\n  \n  To edit this reservation:\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select Current Reservations\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: "You have [notice_interval] until the scheduled end time of your reservation. VCL Team\\n"\nsubject: ''VCL -- [notice_interval] until end of reservation for [image_prettyname]''\n'),
+('usermessage|endtime_imminent_imaging|Global', '---\nmessage: |\n  You have [notice_interval] until the end of your reservation for image [image_prettyname]. \n  \n  At the scheduled end time your imaging reservation will be automatically captured. \n  \n  To prevent this auto capture, visit the VCL site [user_affiliation_sitewwwaddress] manually start the image creation process.\n  \n  Please note this auto capture feature is intended to prevent destorying any work you have done to the image.\n  \n  Thank You,\n  VCL Team\n  \n  \n  ******************************************************************\n  This is an automated notice. If you need assistance please respond \n  with detailed information on the issue and a help ticket will be \n  generated.\n  \n  To disable email notices\n  -Visit [user_affiliation_sitewwwaddress]\n  -Select User Preferences\n  -Select General Preferences\n  \n  ******************************************************************\nshort_message: ''You have [notice_interval] until the auto capture process is started.''\nsubject: ''VCL Imaging Reservation -- [notice_interval] until starting auto capture''\n');
+
+-- 
 -- Dumping data for table `module`
 -- 
 
diff --git a/web/.ht-inc/siteconfig.php b/web/.ht-inc/siteconfig.php
index a8f5d39..27d6e0f 100644
--- a/web/.ht-inc/siteconfig.php
+++ b/web/.ht-inc/siteconfig.php
@@ -3134,6 +3134,15 @@
 
 			if($keyparts[0] == 'adminmessage')
 				$keyparts[2] = 'Global';
+			foreach(array('message', 'subject', 'short_message') as $type) {
+				if(! isset($item[$type]))
+					continue;
+				$test = strip_tags($item[$type]);
+				if($test != $item[$type]) {
+					$item['DBmanagedHTML'] = 1;
+					$item[$type] = '';
+				}
+			}
 			$this->units[$k][$keyparts[2]] = $item;
 		}
 		uasort($this->basekeys, "sortKeepIndex");
diff --git a/web/js/siteconfig.js b/web/js/siteconfig.js
index 072c01f..0be32b5 100644
--- a/web/js/siteconfig.js
+++ b/web/js/siteconfig.js
@@ -685,7 +685,22 @@
 	}
 	dojo.byId('messagesaffil').innerHTML = affiltype;
 	dijit.byId('messagessubject').set('value', item['subject']);
-	dijit.byId('messagesbody').set('value', item['message']);
+	if(('DBmanagedHTML' in item) && item['DBmanagedHTML'] == 1) {
+		dijit.byId('messagesbody').set('value', 'This message body contains HTML that is set directly in the database');
+		dijit.byId('messagesbody').set('disabled', true);
+		dijit.byId('messagessubject').set('disabled', true);
+		dijit.byId('messagesshortmsg').set('disabled', true);
+		dijit.byId('messagessavebtn').set('disabled', true);
+		dijit.byId('messagesdelbtn').set('disabled', true);
+	}
+	else {
+		dijit.byId('messagesbody').set('value', item['message']);
+		dijit.byId('messagesbody').set('disabled', false);
+		dijit.byId('messagessubject').set('disabled', false);
+		dijit.byId('messagesshortmsg').set('disabled', false);
+		dijit.byId('messagessavebtn').set('disabled', false);
+		dijit.byId('messagesdelbtn').set('disabled', false);
+	}
 	if('short_message' in item)
 		dijit.byId('messagesshortmsg').set('value', item['short_message']);
 	else