initial import of PLCRT; package separately from monitor-rt
Stephen Soltesz [Fri, 26 Jun 2009 21:30:15 +0000 (21:30 +0000)]
RT_SiteConfig.pm [new file with mode: 0644]
adduserstort.pl [new file with mode: 0755]
conf.d/planetlab.pl [new file with mode: 0644]
cron.d/syncadmins.sh [new file with mode: 0755]
initialdata [new file with mode: 0644]
local/html/Elements/Logo [new file with mode: 0644]
local/html/Ticket/Elements/ShowSummary [new file with mode: 0644]
plcrt.init [new file with mode: 0644]
plcrt.spec [new file with mode: 0644]
rt.cron [new file with mode: 0644]
rtcron.sh [new file with mode: 0755]

diff --git a/RT_SiteConfig.pm b/RT_SiteConfig.pm
new file mode 100644 (file)
index 0000000..5c2f530
--- /dev/null
@@ -0,0 +1,80 @@
+# Any configuration directives you include  here will override
+# RT's default configuration file, RT_Config.pm
+
+#Site Configurations
+
+#Name of the site
+Set($rtname, 'PLC_NAME');
+
+#Site's Organization
+Set($Organization , 'PLC_RT_HOSTNAME');
+
+#Main email address for contacting the Support Team
+Set($CorrespondAddress , 'support@PLC_RT_HOSTNAME');
+
+#Default destination email address for replies
+Set($CommentAddress , 'root@PLC_RT_HOSTNAME');
+
+#System administrator mail address
+Set($OwnerEmail , 'root@PLC_RT_HOSTNAME');
+
+#Maximum attachment size
+Set($MaxAttachmentSize , 10000000);
+
+#Database configurations
+
+#Type of database: Postgresql
+Set($DatabaseType , 'Pg'); # e.g. Pg or mysql
+
+#The name of the database user (inside the database)
+Set($DatabaseUser , 'RT_DB_USER');
+
+#Password the DatabaseUser should use to access the database
+Set($DatabasePassword , 'RT_DB_PASSWORD');
+
+#The name of the RT's database on your database server
+Set($DatabaseName , 'RT_DB_NAME');
+
+#Database host
+Set($DatabaseHost , 'localhost');
+
+#RT's Database host
+Set($DatabaseRTHost , 'localhost');
+
+#Webserver paramters
+
+#Web path, such as https://rt.domain/web_path
+Set($WebPath , "/rt3"); # e.g. Set($WebPath , "");
+
+#URL
+Set($WebBaseURL , "https://PLC_RT_HOSTNAME"); # Set($WebBaseURL , "http://rt.PLC_RT_HOSTNAME");
+
+#Adding plugins
+#Set(@Plugins,qw(RT::FM));
+
+#Tuning Up the RT Config
+
+#Log File
+Set($LogToFile , 'debug');
+Set($LogDir, '/var/log/rt3/');
+#rt_debug.log should be created and set to the correct owner(apache ownerand group)/permissions (-rw-r--r--)Set($LogToFileNamed , "rt_debug.log");
+
+#Notify requestor: True (1)
+Set($NotifyActor, 1);
+
+#Send a copy to RT owner: True
+Set($LoopsToRTOwner , 1);
+
+# Try to figure out CC watchers 
+Set($ParseNewMessageForTicketCcs , 1);
+
+# pattern to self-identify to avoid loops to itself.
+Set($RTAddressRegexp , '^(support|monitor|legal|security)@PLC_RT_HOSTNAME$');
+
+Set($WebImagesURL , $WebPath . "/NoAuth/images/");  # need this for below 
+Set($LogoURL, "/misc/logo.gif"); 
+Set($LogoLinkURL, 'http://PLC_WWW_HOSTNAME'); 
+Set($LogoImageURL, "http://PLC_RT_HOSTNAME/misc/logo.gif"); 
+Set($LogoAltText, "PLC_NAME");
+
+1;
diff --git a/adduserstort.pl b/adduserstort.pl
new file mode 100755 (executable)
index 0000000..a826499
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/perl -w
+#
+# rtadduser: Batch add local users to RT based on a csv file named users_data.csv located # in the same directory
+# Mohamed El Erian <mohamed.elerian@britishcouncil.org.eg,melerian@gmail.com>
+# Partly based on script provided by David Maze <dmaze@cag.lcs.mit.edu>
+# File format is username,realname,email_address,organization,address1,city,country
+# $Id$
+#
+
+use lib "/usr/lib";
+use strict;
+use English;
+use RT::Interface::CLI qw(CleanEnv);
+use RT::User;
+
+CleanEnv();
+RT::LoadConfig();
+RT::Init();
+my @raw_data;
+my $bc_user = '';
+my $username = '';
+my $realname = '';
+my $email_address = '';
+my $organization = '';
+my $address1 = '';
+my $city = '';
+my $country = '';
+my $priv = 0;
+
+if ( $ARGV[0] =~ /priv/ )
+{
+   shift @ARGV;
+   $priv = 1;
+}
+
+open(USERS_DATA, $ARGV[0]) || die("Could not open file!");
+@raw_data=<USERS_DATA>;
+close(USERS_DATA);
+foreach $bc_user (@raw_data)
+{
+ chop($bc_user);
+ ($email_address,$realname,$organization)=split(/\,/,$bc_user);
+
+  my $UserObj = new RT::User(RT::SystemUser);
+       # print "adding user: $email_address\n";
+  $UserObj->Create(Name => $email_address,
+             RealName => $realname,
+             EmailAddress => $email_address,
+             Password => 'tpdemo2009',
+             Organization => $organization,
+             Privileged => $priv);
+             #Address1 => $address1,
+             #City => $city,
+             #Country => country,
+}
+
+
diff --git a/conf.d/planetlab.pl b/conf.d/planetlab.pl
new file mode 100644 (file)
index 0000000..6026845
--- /dev/null
@@ -0,0 +1,130 @@
+
+@ACL = (
+       { GroupDomain => 'SystemInternal',
+         GroupType => 'Everyone',
+         Right => 'CreateTicket', },
+
+       { GroupDomain => 'SystemInternal',
+         GroupType => 'Everyone',
+         Right => 'ReplyToTicket', },
+
+       { GroupDomain => 'RT::System-Role',
+         GroupType => 'AdminCc',
+         Right => 'WatchAsAdminCc', },
+         
+       { GroupDomain => 'RT::System-Role',
+         GroupType => 'Cc',
+         Right => 'ReplyToTicket', },
+
+       { GroupDomain => 'RT::System-Role',
+         GroupType => 'Cc',
+         Right => 'Watch', },
+
+       { GroupDomain => 'RT::System-Role',
+         GroupType => 'Owner',
+         Right => 'ReplyToTicket', },
+
+       { GroupDomain => 'RT::System-Role',
+         GroupType => 'Owner',
+         Right => 'ModifyTicket', },
+);
+
+@Scrips = (
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'AutoReply To Requestors',
+       Template       => 'AutoReply' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Requestors, Ccs and AdminCcs',
+       Template       => 'PlanetLab Correspond with CC in body', },
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'PlanetLab Create with CC in body', },
+);
+
+@Templates = (
+    {  Queue       => '0',
+       Name        => 'Autoreply',                                         # loc
+       Description => 'Default Autoresponse template',                     # loc
+       Content     => 'Subject: AutoReply: {$Ticket->Subject}
+
+Hello,
+
+Thank you very much for reporting this.
+
+This message was automatically generated in response to the
+creation of a trouble ticket regarding:
+
+       "{$Ticket->Subject()}"
+
+There is no need to reply to this message right now.  Your ticket has been
+assigned an ID of [{$rtname} #{$Ticket->id()}].
+
+Please include the string:
+
+    [{$rtname} #{$Ticket->id}]
+
+in the subject line of all future correspondence about this issue. To do so, 
+you may reply to this message.
+
+Thank you,
+{$Ticket->QueueObj->CorrespondAddress()}
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+    {
+      Queue       => '0',
+      Name        => 'PlanetLab Correspond with CC in body',
+      Description => 'Message with the recipients in the header',          # loc
+      Content     => 'RT-Attach-Message: yes
+
+Email Recipients (see http://PLC_RT_HOSTNAME/support )
+    Owner: {$Ticket->OwnerObj->Name}
+    Requestor: {$Ticket->RequestorAddresses}
+{ if ($acc=$Ticket->AdminCcAddresses) { "    Ticket Ccs: " . $acc } }
+
+==================================================
+
+{$Transaction->Content()}
+'
+    },
+    {
+      Queue       => '0',
+      Name        => 'PlanetLab Create with CC in body',
+      Description => 'Create with CC in body',                 # loc
+      Content     => 'RT-Attach-Message: yes
+
+Email Recipients (see http://PLC_RT_HOSTNAME/support )
+    Owner: {$Ticket->OwnerObj->Name}
+    Requestor: {$Ticket->RequestorAddresses}
+{ if ($acc=$Ticket->AdminCcAddresses) { "    Ticket Ccs: " . $acc } }
+
+==================================================
+
+{$Transaction->CreatedAsString}: Request {$Ticket->id} was acted upon.
+Transaction: {$Transaction->Description}
+
+Subject: {$Transaction->Subject || $Ticket->Subject || "(No subject given)"}
+
+{$Transaction->Content()}
+'
+    },
+);
+
+@Queues = (
+          { Name              => 'monitor',
+         Description       => 'Queue for monitor',
+         CorrespondAddress => 'monitor@PLC_RT_HOSTNAME',
+         CommentAddress    => '', },
+
+          { Name              => 'security',
+         Description       => 'Queue for security issues',
+         CorrespondAddress => 'security@PLC_RT_HOSTNAME',
+         CommentAddress    => '', },
+
+          { Name              => 'legal',
+         Description       => 'Queue for legal issues',
+         CorrespondAddress => 'legal@PLC_RT_HOSTNAME',
+         CommentAddress    => '', },
+)
diff --git a/cron.d/syncadmins.sh b/cron.d/syncadmins.sh
new file mode 100755 (executable)
index 0000000..f27243d
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+MDIR=/usr/share/monitor
+source $MDIR/monitorconfig.sh
+${MONITOR_SCRIPT_ROOT}/plcquery.py --type person --withsitename --byrole admin \
+                                       --format="%(email)s,%(first_name)s %(last_name)s,%(name)s" \
+                               | ${MONITOR_SCRIPT_ROOT}/rt3/adduserstort.pl priv -
diff --git a/initialdata b/initialdata
new file mode 100644 (file)
index 0000000..d1a3255
--- /dev/null
@@ -0,0 +1,577 @@
+# Initial data for a fresh RT3 Installation.
+
+@Users = (
+    {  Name     => 'Nobody',
+       RealName => 'Nobody in particular',
+       Comments => 'Do not delete or modify this user. It is integral '
+         . 'to RT\'s internal data structures',
+       Privileged => '0', },
+
+    {  Name         => 'root',
+       Gecos        => 'root',
+       RealName     => 'RT Admin',
+       Password     => 'password',
+       EmailAddress => "root\@localhost",
+       Comments     => 'SuperUser',
+       Privileged   => '1', } );
+
+@Groups = (
+    { Name        => '',
+      Type        => 'Everyone',                        # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Type        => 'Privileged',                      # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Name        => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Unprivileged',                    # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Owner',                               # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Requestor',                           # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Cc',                                  # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'AdminCc',                             # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',        # loc
+    }, );
+
+@Queues = ({ Name              => 'support',
+             Description       => 'Support',
+             CorrespondAddress => 'support@PLC_RT_HOSTNAME',
+             CommentAddress    => '', },
+
+           { Name        => '___Approvals',
+             Description => 'A system-internal queue for the approvals system',
+             Disabled    => 2, } );
+
+@ScripActions = (
+
+    {  Name        => 'Autoreply To Requestors',    # loc
+       Description =>
+'Always sends a message to the requestors independent of message sender' ,                                            # loc
+       ExecModule => 'Autoreply',
+       Argument   => 'Requestor' },
+    { Name        => 'Notify Requestors',                    # loc
+      Description => 'Sends a message to the requestors',    # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Requestor' },
+    { Name        => 'Notify Owner as Comment',              # loc
+      Description => 'Sends mail to the owner',              # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Owner' },
+    { Name        => 'Notify Owner',                         # loc
+      Description => 'Sends mail to the owner',              # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Owner' },
+    { Name        => 'Notify Ccs as Comment',              # loc
+      Description => 'Sends mail to the Ccs as a comment', # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Cc' },
+    { Name        => 'Notify Ccs',                                   # loc
+      Description => 'Sends mail to the Ccs',                        # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Cc' },
+    { Name        => 'Notify AdminCcs as Comment',                        # loc
+      Description => 'Sends mail to the administrative Ccs as a comment', # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'AdminCc' },
+    { Name        => 'Notify AdminCcs',                                   # loc
+      Description => 'Sends mail to the administrative Ccs',              # loc
+      ExecModule  => 'Notify',
+      Argument    => 'AdminCc' },
+
+    { Name        => 'Notify Requestors and Ccs as Comment',              # loc
+      Description => 'Send mail to requestors and Ccs as a comment',      # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Requestor,Cc' },
+
+    { Name        => 'Notify Requestors and Ccs',                         # loc
+      Description => 'Send mail to requestors and Ccs',                   # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Requestor,Cc' },
+
+    { Name        => 'Notify Requestors, Ccs and AdminCcs as Comment',    # loc
+      Description => 'Send mail to all watchers as a "comment"',          # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'All' },
+    { Name        => 'Notify Requestors, Ccs and AdminCcs',               # loc
+      Description => 'Send mail to all watchers',                         # loc
+      ExecModule  => 'Notify',
+      Argument    => 'All' },
+    { Name        => 'Notify Other Recipients as Comment',                # loc
+      Description => 'Sends mail to explicitly listed Ccs and Bccs',      # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'OtherRecipients' },
+    { Name        => 'Notify Other Recipients',                           # loc
+      Description => 'Sends mail to explicitly listed Ccs and Bccs',      # loc
+      ExecModule  => 'Notify',
+      Argument    => 'OtherRecipients' },
+    { Name        => 'User Defined',                                      # loc
+      Description => 'Perform a user-defined action',                     # loc
+      ExecModule  => 'UserDefined', },
+    {  Name        => 'Create Tickets',                                    # loc
+       Description =>
+         'Create new tickets based on this scrip\'s template',             # loc
+       ExecModule => 'CreateTickets', },
+    { Name        => 'Open Tickets',
+      Description => 'Open tickets on correspondence',                    # loc
+      ExecModule  => 'AutoOpen' },
+);
+
+@ScripConditions = (
+    { Name                 => 'On Create',                                # loc
+      Description          => 'When a ticket is created',                 # loc
+      ApplicableTransTypes => 'Create',
+      ExecModule           => 'AnyTransaction', },
+
+    { Name                 => 'On Transaction',                           # loc
+      Description          => 'When anything happens',                    # loc
+      ApplicableTransTypes => 'Any',
+      ExecModule           => 'AnyTransaction', },
+    {
+
+      Name                 => 'On Correspond',                             # loc
+      Description          => 'Whenever correspondence comes in',          # loc
+      ApplicableTransTypes => 'Correspond',
+      ExecModule           => 'AnyTransaction', },
+
+    {
+
+      Name                 => 'On Comment',                                # loc
+      Description          => 'Whenever comments come in',                 # loc
+      ApplicableTransTypes => 'Comment',
+      ExecModule           => 'AnyTransaction' },
+    {
+
+      Name                 => 'On Status Change',                          # loc
+      Description          => 'Whenever a ticket\'s status changes',       # loc
+      ApplicableTransTypes => 'Status',
+      ExecModule           => 'AnyTransaction',
+
+    },
+    {
+
+      Name                 => 'On Priority Change',                       # loc
+      Description          => 'Whenever a ticket\'s priority changes',    # loc
+      ApplicableTransTypes => 'Set',
+      ExecModule           => 'PriorityChange',
+    },
+    {
+
+      Name                 => 'On Owner Change',                           # loc
+      Description          => 'Whenever a ticket\'s owner changes',        # loc
+      ApplicableTransTypes => 'Any',
+      ExecModule           => 'OwnerChange',
+
+    },
+    {
+
+      Name                 => 'On Queue Change',                           # loc
+      Description          => 'Whenever a ticket\'s queue changes',        # loc
+      ApplicableTransTypes => 'Set',
+      ExecModule           => 'QueueChange',
+
+    },
+    {  Name                 => 'On Resolve',                               # loc
+       Description          => 'Whenever a ticket is resolved',            # loc
+       ApplicableTransTypes => 'Status',
+       ExecModule           => 'StatusChange',
+       Argument             => 'resolved'
+
+    },
+
+    {  Name                 => 'User Defined',                             # loc
+       Description          => 'Whenever a user-defined condition occurs', # loc
+       ApplicableTransTypes => 'Any',
+       ExecModule           => 'UserDefined'
+
+    },
+
+);
+
+@Templates = (
+    { Queue       => '0',
+      Name        => 'Blank',                                             # loc
+      Description => 'A blank template',                                  # loc
+      Content     => '', },
+
+    {  Queue       => '0',
+       Name        => 'Transaction',                     # loc
+       Description => 'Default transaction template',    # loc
+       Content     => 'RT-Attach-Message: yes
+
+
+{$Transaction->CreatedAsString}: Request {$Ticket->id} was acted upon.
+Transaction: {$Transaction->Description}
+       Queue: {$Ticket->QueueObj->Name}
+     Subject: {$Transaction->Subject || $Ticket->Subject || "(No subject given)"}
+       Owner: {$Ticket->OwnerObj->Name}
+  Requestors: {$Ticket->RequestorAddresses}
+      Status: {$Ticket->Status}
+ Ticket <URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
+
+
+{$Transaction->Content()}
+'
+    },
+
+    {
+
+      Queue       => '0',
+      Name        => 'Admin Correspondence',                     # loc
+      Description => 'Default admin correspondence template',    # loc
+      Content     => 'RT-Attach-Message: yes
+
+
+<URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Correspondence',                          # loc
+       Description => 'Default correspondence template',         # loc
+       Content     => 'RT-Attach-Message: yes
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Admin Comment',                           # loc
+       Description => 'Default admin comment template',          # loc
+       Content     =>
+'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject); $s =~ s/\\[Comment\\]//g; $comment =~ s/^Re//i; $s;}
+
+
+{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
+This is a comment.  It is not sent to the Requestor(s):
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Status Change',                                     # loc
+       Description => 'Ticket status changed',                             # loc
+       Content     => 'Subject: Status Changed to: {$Transaction->NewValue}
+
+
+{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
+
+{$Transaction->Content()}
+'
+    },
+
+    {
+
+      Queue       => '0',
+      Name        => 'Resolved',                 # loc
+      Description => 'Ticket Resolved',          # loc
+      Content     => 'Subject: Resolved: {$Ticket->Subject}
+
+According to our records, your request has been resolved. If you have any
+further questions or concerns, please respond to this message.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "New Pending Approval",    # loc
+       Description =>
+         "Notify Owners and AdminCcs of new items pending their approval", # loc
+       Content => 'Subject: New Pending Approval: {$Ticket->Subject}
+
+Greetings,
+
+There is a new item pending your approval: "{$Ticket->Subject()}", 
+a summary of which appears below.
+
+Please visit {$RT::WebURL}Approvals/Display.html?id={$Ticket->id}
+to approve or reject this ticket, or {$RT::WebURL}Approvals/ to
+batch-process all your pending approvals.
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "Approval Passed",    # loc
+       Description =>
+         "Notify Owner of their ticket has been approved by some approver", # loc
+       Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been approved by { eval { $Approval->OwnerObj->Name } }.
+Other approvals may be pending.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "All Approvals Passed",    # loc
+       Description =>
+         "Notify Owner of their ticket has been approved by all approvers", # loc
+       Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been approved.  Its Owner may now start to act on it.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "Approval Rejected",    # loc
+       Description =>
+         "Notify Owner of their rejected ticket", # loc
+       Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been rejected by { eval { $Approval->OwnerObj->Name } }.
+'
+    },
+);
+# }}}
+
+@Scrips = (
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Open Tickets',
+       Template       => 'Blank' },
+    {  ScripCondition => 'On Owner Change',
+       ScripAction    => 'Notify Owner',
+       Template       => 'Transaction' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Other Recipients',
+       Template       => 'Correspondence' },
+
+    {  Description => "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval",    # loc
+       Queue          => '___Approvals',
+       ScripCondition => 'User Defined',
+       CustomIsApplicableCode => q[
+           $self->TicketObj->Type eq 'approval'        and
+           $self->TransactionObj->Field eq 'Status'    and
+           $self->TransactionObj->NewValue eq 'open'   and
+           eval { $T::Approving = ($self->TicketObj->AllDependedOnBy( Type => 'ticket' ))[0] }
+       ],
+       ScripAction    => 'Notify Owner',
+       Template       => 'New Pending Approval' },
+    {  Description => "If an approval is rejected, reject the original and delete pending approvals",    # loc
+       Queue            => '___Approvals',
+       ScripCondition   => 'On Status Change',
+       ScripAction      => 'User Defined',
+       CustomPrepareCode => q[
+# ------------------------------------------------------------------- #
+return(0) unless ( lc($self->TransactionObj->NewValue) eq "rejected" or
+                  lc($self->TransactionObj->NewValue) eq "deleted" );
+
+my $rejected = 0;
+my $links = $self->TicketObj->DependedOnBy;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->BaseObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       if ($obj->Type eq 'ticket') {
+           $obj->Comment(
+               Content => $self->loc("Your request was rejected."),
+           );
+           $obj->SetStatus(
+               Status  => 'rejected',
+               Force   => 1,
+           );
+
+           $T::Approval = $self->TicketObj; # so we can access it inside templates
+           $self->{TicketObj} = $obj;  # we want the original id in the token line
+           $rejected = 1;
+       }
+       else {
+           $obj->SetStatus(
+               Status  => 'deleted',
+               Force   => 1,
+           );
+       }
+    }
+}
+
+$links = $self->TicketObj->DependsOn;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->TargetObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       $obj->SetStatus(
+           Status      => 'deleted',
+           Force       => 1,
+       );
+    }
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return $rejected;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template          => 'Approval Rejected', },
+    {  Description => "When a ticket has been approved by any approver, add correspondence to the original ticket", # loc
+       Queue             => '___Approvals',
+       ScripCondition    => 'On Resolve',
+       ScripAction       => 'User Defined',
+       CustomPrepareCode => q[
+# ------------------------------------------------------------------- #
+return(0) unless ($self->TicketObj->Type eq 'approval');
+
+my $note;
+my $t = $self->TicketObj->Transactions;
+while (my $o = $t->Next) {
+    $note .= $o->Content . "\n" if $o->ContentObj
+           and $o->Content !~ /Default Approval/;
+}
+
+foreach my $obj ($self->TicketObj->AllDependedOnBy( Type => 'ticket' )) {
+    $obj->Comment(
+       Content => $self->loc( "Your request has been approved by [_1]. Other approvals may still be pending.", # loc
+           $self->TransactionObj->CreatorObj->Name,
+       ) . "\n" . $self->loc( "Approver's notes: [_1]", # loc
+           $note
+       ),
+    );
+    $T::Approval = $self->TicketObj; # so we can access it inside templates
+    $self->{TicketObj} = $obj;  # we want the original id in the token line
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return 1;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template => 'Approval Passed' },
+    {  Description => "When a ticket has been approved by all approvers, add correspondence to the original ticket", # loc
+       Queue             => '___Approvals',
+       ScripCondition    => 'On Resolve',
+       ScripAction       => 'User Defined',
+       CustomPrepareCode  => q[
+# ------------------------------------------------------------------- #
+# Find all the tickets that depend on this (that this is approving)
+
+my $Ticket = $self->TicketObj;
+my @TOP    = $Ticket->AllDependedOnBy( Type => 'ticket' );
+my $links  = $Ticket->DependedOnBy;
+my $passed = 0;
+
+while (my $link = $links->Next) {
+    my $obj = $link->BaseObj;
+    next if ($obj->HasUnresolvedDependencies( Type => 'approval' ));
+
+    if ($obj->Type eq 'ticket') {
+       $obj->Comment(
+           Content     => $self->loc("Your request has been approved."),
+       );
+       $T::Approval  = $Ticket;    # so we can access it inside templates
+       $self->{TicketObj} = $obj;  # we want the original id in the token line
+       $passed = 1;
+    }
+    elsif ($obj->Type eq 'approval') {
+       $obj->SetStatus( Status => 'open', Force => 1 );
+    }
+    elsif ($RT::UseCodeTickets and $obj->Type eq 'code') {
+       my $code = $obj->Transactions->First->Content;
+       my $rv;
+
+       foreach my $TOP (@TOP) {
+           local $@;
+           $rv++ if eval $code;
+           $RT::Logger->error("Cannot eval code: $@") if $@;
+       }
+
+       if ($rv or !@TOP) {
+           $obj->SetStatus( Status     => 'resolved', Force    => 1,);
+       }
+       else {
+           $obj->SetStatus( Status     => 'rejected', Force    => 1,);
+       }
+    }
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return 0; # ignore $passed;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template => 'All Approvals Passed', },
+
+);
+
+@ACL = (
+    { UserId => 'Nobody',      # - principalId
+      Right  => 'OwnTicket', },
+
+    { UserId => 'root',        # - principalid
+      Right  => 'SuperUser', },
+       
+
+);
+
+# Predefined searches
+
+@Attributes = (
+    { Name => 'Search - My Tickets',
+      Description => '[_1] highest priority tickets I own', # loc
+      Content     =>
+      { Format => "'<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', Priority, QueueName, ExtendedStatus",
+        Query   => " Owner = '__CurrentUser__' AND ( Status = 'new' OR Status = 'open')",
+        OrderBy => 'Priority',
+        Order   => 'DESC' },
+    },
+    { Name => 'Search - Unowned Tickets',
+      Description => '[_1] newest unowned tickets', # loc
+      Content     =>
+# 'Take' #loc
+      { Format => "'<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', QueueName, ExtendedStatus, CreatedRelative, '<A HREF=\"__WebPath__/Ticket/Display.html?Action=Take&id=__id__\">__loc(Take)__</a>/TITLE:&nbsp;' ",
+        Query   => " Owner = 'Nobody' AND ( Status = 'new' OR Status = 'open')",
+        OrderBy => 'Created',
+        Order   => 'DESC' },
+    },
+    { Name => 'HomepageSettings',
+      Description => 'HomepageSettings',
+      Content =>
+      { 'body' => # loc
+       [ { type => 'system', name => 'My Tickets' },
+         { type => 'system', name => 'Unowned Tickets' },
+         { type => 'component',  name => 'QuickCreate'},
+       ],
+        'summary' => # loc
+       [ 
+         { type => 'component', name => 'MyReminders' },
+          { type => 'component', name => 'Quicksearch' },
+         { type => 'component', name => 'RefreshHomepage' },
+       ]
+    },
+}
+);
diff --git a/local/html/Elements/Logo b/local/html/Elements/Logo
new file mode 100644 (file)
index 0000000..5bb6c11
--- /dev/null
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%# 
+%# COPYRIGHT:
+%#  
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
+%#                                          <jesse@bestpractical.com>
+%# 
+%# (Except where explicitly superseded by other copyright notices)
+%# 
+%# 
+%# LICENSE:
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%# 
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%# 
+%# 
+%# CONTRIBUTION SUBMISSION POLICY:
+%# 
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%# 
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%# 
+%# END BPS TAGGED BLOCK }}}
+  <div id="logo">
+    <a href="<%$RT::LogoLinkURL%>"><img src="<%$RT::LogoImageURL%>" alt="<% loc($RT::LogoAltText) %>"  /></a>
+% if ($show_name) {
+    <div class="rtname"><% loc("RT for [_1]", $RT::rtname) %></div>
+% }
+  </div>
+<%args>
+  $show_name => 1
+</%args>
diff --git a/local/html/Ticket/Elements/ShowSummary b/local/html/Ticket/Elements/ShowSummary
new file mode 100644 (file)
index 0000000..9847577
--- /dev/null
@@ -0,0 +1,100 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%# 
+%# COPYRIGHT:
+%#  
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
+%#                                          <jesse@bestpractical.com>
+%# 
+%# (Except where explicitly superseded by other copyright notices)
+%# 
+%# 
+%# LICENSE:
+%# 
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%# 
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%# 
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%# 
+%# 
+%# CONTRIBUTION SUBMISSION POLICY:
+%# 
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%# 
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%# 
+%# END BPS TAGGED BLOCK }}}
+      <table width="100%" class="ticket-summary">
+      <tr>
+       <td valign="top" width="50%" class="boxcontainer">
+         <&| /Widgets/TitleBox, title => loc('The Basics'), 
+               title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id, 
+               class => 'ticket-info-basics' &>
+               <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+         </&>
+
+% if ($Ticket->QueueObj->TicketCustomFields->First) {
+         <&| /Widgets/TitleBox, title => loc('Custom Fields'), 
+               title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id, 
+               class => 'ticket-info-cfs'  &> 
+               <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &>
+         </&>
+% }
+         <&| /Widgets/TitleBox, title => loc('People'), 
+               title_href =>"$RT::WebPath/Ticket/ModifyPeople.html?id=".$Ticket->Id, 
+               class => 'ticket-info-people' &>
+            <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
+         </&>
+
+      <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &>
+        <br />
+         <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &>
+
+      <& /Elements/Callback, %ARGS, _CallbackName => 'LeftColumn' &>
+       </td>
+       <td valign="top" width="50%" class="boxcontainer">
+         <&| /Widgets/TitleBox, title => loc("Dates"),
+               title_href =>"$RT::WebPath/Ticket/ModifyDates.html?id=".$Ticket->Id, 
+               class => 'ticket-info-dates' &>
+         <& /Ticket/Elements/ShowDates, Ticket => $Ticket &>
+         </&>
+
+         <&| /Widgets/TitleBox, title => loc('Links'), 
+               title_href => "$RT::WebPath/Ticket/ModifyLinks.html?id=".$Ticket->Id, 
+               class => 'ticket-info-links' &>
+               <& /Elements/ShowLinks, Ticket => $Ticket &>
+          </&>
+    <& /Elements/Callback, %ARGS, _CallbackName => 'RightColumn' &>
+
+       </td>
+      </tr>
+    </table>
+<%ARGS>
+$Ticket => undef
+$Attachments => undef
+</%ARGS>
+
+
+
+
diff --git a/plcrt.init b/plcrt.init
new file mode 100644 (file)
index 0000000..96aa8f3
--- /dev/null
@@ -0,0 +1,262 @@
+#!/bin/bash
+#
+# priority: 850
+#
+# Manage settings for the RT installtion 
+#
+# Stephen Soltesz <soltesz@cs.princeton.edu>
+# Copyright (C) 2008 The Trustees of Princeton University
+#
+# $Id$
+#
+
+# Source function library and configuration
+. /etc/plc.d/functions
+. /etc/planetlab/plc_config
+local_config=/etc/planetlab/configs/site.xml
+
+PLCRTPATH=/usr/share/plcrt
+
+# Be verbose
+set -x
+
+# Default locations
+PGDATA=/var/lib/pgsql/data
+postgresql_conf=$PGDATA/postgresql.conf
+pghba_conf=$PGDATA/pg_hba.conf
+
+# Export so that we do not have to specify -p to psql invocations
+export PGPORT=$PLC_DB_PORT
+
+
+RT3_DB_USER="rt3user"
+RT3_DB_NAME="rt3"
+
+WROTE_PG_CONFIG=
+
+if [ -z "$PLC_RT_IP" ] ; then
+       PLC_RT_IP=$( gethostbyname $PLC_RT_HOST )
+fi
+
+# NOTE: code duplicated from monitor.functions to allow package to be separate
+#              from it.
+function check_pg_hba ()
+{
+       NAME=$1
+       USER=$2
+       #### SETUP ACCESS to this user and database
+       mkdir -p $PGDATA/pg_hba.conf.d
+       CONF=$PGDATA/pg_hba.conf.d/${NAME}.conf
+       if [ ! -f $CONF ] ; then
+               echo "host $NAME $USER 127.0.0.1/32 password"   > $CONF
+               echo "host $NAME $USER $PLC_MONITOR_IP/32 password" >> $CONF
+
+               WROTE_PG_CONFIG="true"
+       fi
+}
+
+# TODO: make values re-configurable...  this may be an issue with RT's db, though.
+function update_config ()
+{
+       pattern=$1
+       with=$2
+       file=$3
+       sed -i -e "s/$pattern/$with/g" $file
+}
+
+function check_rt_siteconfig ()
+{
+       tmp_siteconfig=$(mktemp)
+       tmp_initialdata=$(mktemp)
+
+       # TODO: need a better approach for this.
+       for f in $PLCRTPATH/conf.d/*.pl ; do 
+               update_config PLC_RT_HOSTNAME $PLC_RT_HOST $f
+       done
+       
+       # if the templates are newer than the actual config, then replace them.
+       if [ $PLCRTPATH/RT_SiteConfig.pm -nt /etc/rt3/RT_SiteConfig.pm ] ;
+       then
+               # copy templates
+               cp -f $PLCRTPATH/RT_SiteConfig.pm $tmp_siteconfig
+               cp -f $PLCRTPATH/initialdata $tmp_initialdata
+
+               # setup RT_SiteConfig.pm
+               update_config PLC_NAME "$PLC_NAME" $tmp_siteconfig
+               update_config PLC_RT_HOSTNAME $PLC_RT_HOST $tmp_siteconfig
+               update_config PLC_WWW_HOSTNAME $PLC_WWW_HOST $tmp_siteconfig
+
+               update_config RT_DB_NAME $RT3_DB_NAME $tmp_siteconfig
+               update_config RT_DB_USER $RT3_DB_USER $tmp_siteconfig
+               update_config RT_DB_PASSWORD $PLC_MONITOR_DBPASSWORD $tmp_siteconfig
+
+               # setup initialdata
+               update_config PLC_RT_HOSTNAME $PLC_RT_HOST $tmp_initialdata
+
+               # copy to live configuration
+               cp -f $tmp_siteconfig /etc/rt3/RT_SiteConfig.pm 
+               cp -f $tmp_initialdata /etc/rt3/initialdata 
+               chmod 644 /etc/rt3/RT_SiteConfig.pm 
+               chmod 644 /etc/rt3/initialdata 
+
+               rm -f $tmp_siteconfig
+               rm -f $tmp_initialdata
+       fi
+}
+
+function check_rt_custom ()
+{
+       rsync -qv -az $PLCRTPATH/local/html /usr/share/rt3
+}
+
+function check_rt_pghba ()
+{
+       NAME=$RT3_DB_NAME
+       USER=$RT3_DB_USER
+       CONF=$PGDATA/pg_hba.conf.d/${NAME}.conf
+       PATTERN="host all postgres 127.0.0.1/32 trust"
+
+       if ! grep -q "$PATTERN" $CONF ; then
+               #### SETUP ACCESS from postgres user to run init for the first time.
+               echo "$PATTERN" >> $CONF
+               WROTE_PG_CONFIG="true"
+       fi
+
+}
+
+function check_rt_aliases ()
+{
+
+       if ! grep -q "rt-mailgate --queue support" /etc/aliases ; 
+       then 
+               sed -i -e "s/^support.*postmaster//g" /etc/aliases
+               sed -i -e "s/^security.*root//g" /etc/aliases
+        cat <<EOF >> /etc/aliases
+# added by RT init scripts for default queues.
+support: "|/usr/sbin/rt-mailgate --queue support --action correspond --url http://localhost/rt3/"
+monitor: "|/usr/sbin/rt-mailgate --queue monitor --action correspond --url http://localhost/rt3/"
+security: "|/usr/sbin/rt-mailgate --queue security --action correspond --url http://localhost/rt3/"
+legal: "|/usr/sbin/rt-mailgate --queue legal --action correspond --url http://localhost/rt3/"
+EOF
+               /usr/bin/newaliases
+       fi
+
+}
+
+function check_rt_init ()
+{
+       if [ ! -f /etc/rt3/setup.finished ] ; then
+               /usr/sbin/rt-setup-database --action init --dba postgres
+               for f in $PLCRTPATH/conf.d/*.pl ; do 
+                       /usr/sbin/rt-setup-database --action insert --dba postgres --datafile $f
+               done
+
+               # run initial setup scripts (run only once, or for the first time)
+               if [ -d $PLCRTPATH/setup.d ] ; then 
+                       for f in $PLCRTPATH/setup.d/*.{pl,py,sh} ; do 
+                               $f
+                       done
+               fi
+
+               touch /etc/rt3/setup.finished
+
+       fi
+}
+
+check_rt_sendmail ()
+{
+       tmp_sendmailmc=$(mktemp)
+       
+       # if the templates is newer than the processed config, then update it
+       if grep -q "Addr=127.0.0.1," /etc/mail/sendmail.mc  ; 
+       then
+               # copy templates
+               cp -f /etc/mail/sendmail.mc $tmp_sendmailmc
+
+               # setup initialdata
+               update_config "Addr=127.0.0.1," "" $tmp_sendmailmc
+
+               # copy to live configuration
+               cp -f $tmp_sendmailmc /etc/mail/sendmail.mc
+               rm -f $tmp_sendmailmc
+
+               # edit /etc/mail/access to add local IP
+               if ! grep "$PLC_RT_IP" /etc/mail/access ; then
+                       echo "$PLC_RT_IP                RELAY" >> /etc/mail/access
+                       makemap hash /etc/mail/access.db < /etc/mail/access
+               fi
+               if [ !  -f /etc/smrsh/rt-mailgate ] ; then
+                       ln -s /usr/sbin/rt-mailgate /etc/smrsh/rt-mailgate
+               fi
+               if ! grep "$PLC_RT_HOST" /etc/mail/local-host-names ; then
+                       # edit /etc/mail/local-host-names
+                       echo "$PLC_RT_HOST" >> /etc/mail/local-host-names
+               fi
+               m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
+               service sendmail restart
+       fi
+
+
+}
+
+if [ "$PLC_RT_ENABLED" != "1" ] ; then
+    exit 0
+fi
+
+case "$1" in
+       start)
+               MESSAGE=$"Bootstrap RT (please wait...)"
+               dialog "$MESSAGE"
+
+               check_pg_hba $RT3_DB_NAME $RT3_DB_USER
+               #check_user_and_db $RT3_DB_NAME $RT3_DB_USER
+               check_rt_siteconfig
+               check_rt_pghba
+               if [ -n "$WROTE_PG_CONFIG" ] ; then
+                       # NOTE: restart db to enable access by users granted above.
+                       service plc restart postgresql
+                       MESSAGE=$"Bootstrap RT 2 (please wait...)"
+                       dialog "$MESSAGE"
+               fi
+               check_rt_aliases
+               check_rt_init
+               check_rt_sendmail
+               check_rt_custom         # todo: restart httpd if needed.
+
+               result "$MESSAGE"
+       ;;
+
+
+       delete)
+               MESSAGE=$"Deleting databases..."
+               dialog "$MESSAGE"
+
+               service plc stop httpd
+
+               dropdb -U postgres $RT3_DB_NAME
+               dropuser -U postgres $RT3_DB_USER
+               rm -f /etc/rt3/RT_SiteConfig.pm
+               rm -f /etc/rt3/initialdata
+               PATTERN="host all postgres 127.0.0.1/32 trust"
+               sed -i -e "s|$PATTERN||g" $PGDATA/pg_hba.conf.d/${RT3_DB_NAME}.conf
+
+               sed -i -e "s/.*mailgate.*//g" /etc/aliases
+               rm -f /etc/rt3/setup.finished
+
+               sed -i -e "s/Port=smtp, Name=MTA/Port=smtp,Addr=127.0.0.1, Name=MTA/g" /etc/mail/sendmail.mc
+               service plc start httpd
+
+               result "$MESSAGE"
+       ;;
+
+       stop)
+               MESSAGE=$"Stopping RT"
+               dialog "$MESSAGE"
+
+               # TODO: is there anything to stop?
+
+               result "$MESSAGE"
+       ;;
+esac
+
+exit $ERRORS
diff --git a/plcrt.spec b/plcrt.spec
new file mode 100644 (file)
index 0000000..65dbbf8
--- /dev/null
@@ -0,0 +1,85 @@
+#
+# $Id$
+# 
+
+%define url $URL: svn+ssh://svn.planet-lab.org/svn/PLCRT/trunk/plcrt.spec $
+
+%define name plcrt
+%define version 1.0
+%define taglevel 1
+
+%define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
+
+Name: %{name}
+Version: %{version}
+Release: %{release}
+License: GPL
+Group: Applications/System
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
+
+Vendor: PlanetLab
+Packager: PlanetLab Central <support@planet-lab.org>
+Distribution: PlanetLab %{plrelease}
+URL: %(echo %{url} | cut -d ' ' -f 2)
+
+Summary: PLCRT account initialization for the root image.
+Group: Applications/System
+
+%description
+PLCRT is a collection of configuration scripts for configuring RT.
+By default RT does not come with all the settings needed for a standard PLC,
+or PlanetLab in particular.  
+
+%package 
+Summary: PLCRT Setup scripts for RT3
+Group: Applications/System
+
+Requires: python
+Requires: perl
+Requires: rt3
+Requires: myplc
+
+
+%prep
+%setup -q
+
+%install
+
+install -d $RPM_BUILD_ROOT/%{_datadir}/%{name}
+install -D -m 755 plcrt.init $RPM_BUILD_ROOT/%{_sysconfdir}/plc.d/plcrt
+
+echo " * Installing core scripts"
+rsync -a ./ $RPM_BUILD_ROOT/%{_datadir}/%{name}/
+
+echo " * Installing cron scripts"
+install -D -m 644 rt.cron $RPM_BUILD_ROOT/%{_sysconfdir}/cron.d/rt.cron
+
+chmod 755 $RPM_BUILD_ROOT/%{_datadir}/%{name}/adduserstort.pl
+chmod 755 $RPM_BUILD_ROOT/%{_datadir}/%{name}/rtcron.d/*.sh
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files 
+%defattr(-,root,root)
+%config /etc/rt3/RT_SiteConfig.pm
+#%config /etc/plcrt.conf
+%{_datadir}/%{name}
+%{_sysconfdir}/plc.d/plcrt
+%{_sysconfdir}/cron.d/rt.cron
+
+%post
+if grep 'pam_loginuid.so' /etc/pam.d/crond ; then
+    sed -i -e 's/^session    required   pam_loginuid.so/#session    required   pam_loginuid.so/g' /etc/pam.d/crond
+fi
+
+if ! grep '<category id="plc_rt">' /etc/planetlab/default_config.xml ; then 
+    sed -i 's|<category id="plc_net">| <category id="plc_rt">\n <name>RT Configuration</name>\n <description>RT</description>\n <variablelist>\n <variable id="enabled" type="boolean">\n <name>Enabled</name>\n <value>false</value>\n <description>Enable on this machine.</description>\n </variable>\n <variable id="host" type="hostname">\n <name>Hostname</name>\n <value>localhost.localdomain</value>\n <description>The fully qualified hostname.</description>\n </variable>\n <variable id="ip" type="ip">\n <name>IP Address</name>\n <value/>\n <description>The IP address of the RT server.</description>\n </variable>\n </variablelist>\n </category>\n <category id="plc_net">|' /etc/planetlab/default_config.xml
+fi
+
+plc-config --save /etc/planetlab/default_config.xml \
+                       --category plc_rt --variable enabled --value true
+
+%changelog
+* Thu Jun 26 2009 Stephen Soltesz <soltesz@cs.princeton.edu> - PLCRT-1.0-1
+- initial addition.
diff --git a/rt.cron b/rt.cron
new file mode 100644 (file)
index 0000000..f194581
--- /dev/null
+++ b/rt.cron
@@ -0,0 +1,6 @@
+SHELL=/bin/bash
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/share/plcrt
+HOME=/usr/share/plcrt
+
+01 * * * * root rtcron.sh
+
diff --git a/rtcron.sh b/rtcron.sh
new file mode 100755 (executable)
index 0000000..6cd578f
--- /dev/null
+++ b/rtcron.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+D=/usr/share/plcrt/
+for f in $D/cron.d/*.sh ; do
+       bash -c "$f"
+done