Rollback actions can themselves now be rolled back
authorJamie Cameron <jcameron@webmin.com>
Tue, 4 Sep 2007 23:50:28 +0000 (23:50 +0000)
committerJamie Cameron <jcameron@webmin.com>
Tue, 4 Sep 2007 23:50:28 +0000 (23:50 +0000)
webminlog/CHANGELOG
webminlog/lang/en
webminlog/log_parser.pl [new file with mode: 0644]
webminlog/rollback.cgi
webminlog/search.cgi
webminlog/view.cgi
webminlog/webminlog-lib.pl

index 40dac71..4b597f5 100644 (file)
@@ -11,3 +11,5 @@ Updated the action details page to use ui-lib.pl functions for the form.
 When rolling back changed files, you can now select which ones to revert rather than always doing all of them.
 ---- Changes since 1.330 ----
 A description of the search is now shown for searches that didn't match anything.
+---- Changes since 1.350 ----
+Rollback actions can themselves now be rolled back.
index 7519fb4..707c876 100644 (file)
@@ -96,3 +96,5 @@ rollback_modfile=Rolled back contents of file $1.
 rollback_deleted=Deleted file $1.
 rollback_nodeleted=Skipped non-existant file $1.
 rollback_enone=No files selected
+
+log_rollback=Rolled back action $1 in module $2
diff --git a/webminlog/log_parser.pl b/webminlog/log_parser.pl
new file mode 100644 (file)
index 0000000..eee1578
--- /dev/null
@@ -0,0 +1,19 @@
+# log_parser.pl
+# Functions for parsing this module's logs
+
+do 'webminlog-lib.pl';
+
+# parse_webmin_log(user, script, action, type, object, &params)
+# Converts logged information from this module into human-readable form
+sub parse_webmin_log
+{
+local ($user, $script, $action, $type, $object, $p) = @_;
+if ($action eq 'rollback') {
+       return &text('log_rollback', "<i>".$p->{'desc'}."</i>",
+                                    "<i>".$p->{'mdesc'}."</i>");
+       }
+return undef;
+}
+
+1;
+
index 6943adb..1ef2c92 100755 (executable)
@@ -26,8 +26,10 @@ if ($in{'confirm'}) {
                       !-e $f->{'file'} && $f->{'type'} == 2 ||
                       !-l $f->{'file'} && $f->{'type'} == 2) {
                        # Modify or create link
+                       &lock_file($f->{'file'});
                        &unlink_file($f->{'file'});
                        &symlink_file($f->{'data'}, $f->{'file'});
+                       &unlock_file($f->{'file'});
                        print &text('rollback_madelink',
                                    "<tt>$f->{'file'}</tt>",
                                    "<tt>$f->{'data'}</tt>");
@@ -35,17 +37,19 @@ if ($in{'confirm'}) {
                elsif (-e $f->{'file'} && -l $f->{'file'} &&
                       $f->{'type'} == 0) {
                        # Remove link and create file
+                       &lock_file($f->{'file'});
                        &unlink_file($f->{'file'});
                        &open_tempfile(FILE, ">$f->{'file'}");
                        &print_tempfile(FILE, $f->{'data'});
                        &close_tempfile(FILE);
+                       &unlock_file($f->{'file'});
                        print &text('rollback_madefile',
                                    "<tt>$f->{'file'}</tt>");
                        }
                elsif ($f->{'type'} == -1) {
                        if (-e $f->{'file'}) {
                                # Remove file
-                               unlink($f->{'file'});
+                               &unlink_logged($f->{'file'});
                                print &text('rollback_deleted',
                                            "<tt>$f->{'file'}</tt>");
                                }
@@ -56,7 +60,7 @@ if ($in{'confirm'}) {
                        }
                else {
                        # Replace file with old contents
-                       &open_tempfile(FILE, ">$f->{'file'}");
+                       &open_lock_tempfile(FILE, ">$f->{'file'}");
                        &print_tempfile(FILE, $f->{'data'});
                        &close_tempfile(FILE);
                        print &text('rollback_modfile',
@@ -65,6 +69,10 @@ if ($in{'confirm'}) {
                print "<br>\n";
                $done{$f->{'file'}}++;
                }
+       %minfo = &get_module_info($act->{'module'});
+       &webmin_log("rollback", undef, $in{'id'},
+                   { 'desc' => &get_action_description($act),
+                     'mdesc' => $minfo{'desc'} });
        }
 else {
        # Show the user what will be done
index 7c74a67..6f54178 100755 (executable)
@@ -122,31 +122,10 @@ if (@match) {
                        # first time seeing module ..
                        local %minfo = &get_module_info($m);
                        $minfo = $minfo_cache{$m} = \%minfo;
-                       if (-r "../$m/log_parser.pl") {
-                               &foreign_require($m, "log_parser.pl");
-                               $parser{$m}++;
-                               }
                        }
 
                local @cols;
-               $d = &foreign_call($m, "parse_webmin_log",
-                                 $act->{'user'}, $act->{'script'},
-                                 $act->{'action'}, $act->{'type'},
-                                 $act->{'object'}, $act->{'param'})
-                                       if ($parser{$m});
-               local $desc;
-               if ($d) {
-                       $desc = $d;
-                       }
-               elsif ($act->{'action'} eq '_config_') {
-                       $desc = $text{'search_config'};
-                       }
-               else {
-                       $desc = sprintf "%s %s %s\n",
-                               $act->{'action'},
-                               $act->{'type'} ? $act->{'type'} : '',
-                               $act->{'object'} ? $act->{'object'} : '';
-                       }
+               local $desc = &get_action_description($act, 0);
                push(@cols, "<a href='view.cgi?id=$act->{'id'}".
                      "&return=".&urlize($in{'return'}).
                      "&returndesc=".&urlize($in{'returndesc'}).
index def373e..819b714 100755 (executable)
@@ -7,10 +7,6 @@ require './webminlog-lib.pl';
 
 # find the log record to view
 $act = &get_action($in{'id'});
-if (-r "../$act->{'module'}/log_parser.pl") {
-       &foreign_require($act->{'module'}, "log_parser.pl");
-       $parser++;
-       }
 &can_user($act->{'user'}) || &error($text{'view_ecannot'});
 &can_mod($act->{'module'}) || &error($text{'view_ecannot'});
 
@@ -26,15 +22,9 @@ if (@files) {
 print &ui_table_start(&text('view_header', $act->{'id'}),
                      "width=100%", 4);
 
-$d = &foreign_call($act->{'module'}, "parse_webmin_log",
-                  $act->{'user'}, $act->{'script'},
-                  $act->{'action'}, $act->{'type'},
-                  $act->{'object'}, $act->{'param'}, 1) if ($parser);
-print &ui_table_row($text{'view_action'},
-       $d ? $d :
-       $act->{'action'} eq '_config_' ? $text{'search_config'} :
-               join(" ", $act->{'action'}, $act->{'type'}, $act->{'object'}),
-       3);
+# This "" is needed to make the label show properly!
+print &ui_table_row($text{'view_action'}."",
+                   &get_action_description($act, 1), 3);
 
 %minfo = &get_module_info($act->{'module'});
 print &ui_table_row($text{'view_module'},
index a6fb9d3..69f948a 100644 (file)
@@ -1,7 +1,4 @@
 # webminlog-lib.pl
-# XXX file rollback
-#      XXX should we capture all files, or just those changed?
-#      XXX what about commands?
 
 do '../web-lib.pl';
 &init_config();
@@ -204,5 +201,32 @@ if ($st[9] > $index->{'lastchange'}) {
        }
 }
 
+# get_action_description(&action, long)
+# Returns a human-readable description of some action
+sub get_action_description
+{
+local ($act, $long) = @_;
+if (!defined($parser_cache{$act->{'module'}})) {
+       # Bring in module parser library for the first time
+       if (-r "$root_directory/$act->{'module'}/log_parser.pl") {
+               &foreign_require($act->{'module'}, "log_parser.pl");
+               $parser_cache{$act->{'module'}} = 1;
+               }
+       else {
+               $parser_cache{$act->{'module'}} = 0;
+               }
+       }
+local $d;
+if ($parser_cache{$act->{'module'}}) {
+       $d = &foreign_call($act->{'module'}, "parse_webmin_log",
+                          $act->{'user'}, $act->{'script'},
+                          $act->{'action'}, $act->{'type'},
+                          $act->{'object'}, $act->{'param'}, $long);
+       }
+return $d ? $d :
+       $act->{'action'} eq '_config_' ? $text{'search_config'} :
+               join(" ", $act->{'action'}, $act->{'type'}, $act->{'object'});
+}
+
 1;