/[soft]/rpm/urpmi/branches/1/urpmi.recover
ViewVC logotype

Contents of /rpm/urpmi/branches/1/urpmi.recover

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3132 - (show annotations) (download)
Wed Feb 29 23:59:36 2012 UTC (8 years, 4 months ago) by tv
File size: 5983 byte(s)
branch

1 #!/usr/bin/perl
2
3 # $Id$
4
5 #- Copyright (C) 2006-2010 Mandriva SA
6
7 use strict;
8
9 BEGIN {
10 #- clean environment
11 $ENV{PATH} = "/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin";
12 delete @ENV{qw(ENV BASH_ENV IFS CDPATH)};
13 }
14
15 use urpm::args;
16 use urpm::msg;
17 use URPM;
18 use urpm;
19
20 our $MACROS = '/etc/rpm/macros.d/urpmi.recover.macros';
21 our $listdate;
22 our $do_checkpoint;
23 our $noclean;
24 our $rollback;
25 our $disable;
26
27 sub usage () {
28 print N("urpmi.recover version %s
29 Copyright (C) 2006-2010 Mandriva.
30 This is free software and may be redistributed under the terms of the GNU GPL.
31
32 usage:
33 ", $urpm::VERSION) . N(" --help - print this help message.
34 ") . N(" --checkpoint - set repackaging start now
35 ") . N(" --noclean - don't clean repackage directory on checkpoint
36 ") . N(" --urpmi-root - use another root for urpmi db & rpm installation.
37 ") . N(" --list - list transactions since provided date/duration argument
38 ") . N(" --list-all - list all transactions in rpmdb (long)
39 ") . N(" --list-safe - list transactions since checkpoint
40 ") . N(" --rollback - rollback until specified date,
41 or rollback the specified number of transactions
42 ") . N(" --disable - turn off repackaging
43 ");
44 exit(1);
45 }
46
47 sub fmt_tid {
48 my ($tid) = @_;
49 require POSIX; POSIX->import('strftime');
50 strftime("%F %T", localtime($tid));
51 }
52
53 sub date_to_tid {
54 my ($date) = @_;
55 require Date::Manip; Date::Manip->import;
56 my $d = ParseDate($date)
57 or die N("Invalid date or duration [%s]\n", $date);
58 UnixDate($d, '%s');
59 }
60
61 #- clean up repackage directory
62 sub clean_repackage_dir {
63 my ($repackage_dir) = @_;
64 if (!$repackage_dir || $repackage_dir eq '/') {
65 die N("Repackage directory not defined\n");
66 }
67 -d $repackage_dir
68 or die N("Can't write to repackage directory [%s]\n", $repackage_dir);
69 unless ($noclean) {
70 print N("Cleaning up repackage directory [%s]...\n", $repackage_dir);
71 my $nb = unlink grep { ! -d $_ } glob("$repackage_dir/*");
72 print P("%d file removed\n", "%d files removed\n", $nb, $nb);
73 }
74 }
75
76 #- option parsing
77
78 @ARGV or usage();
79 my $command_line = "@ARGV"; #- for logging
80 urpm::args::parse_cmdline()
81 or exit(1);
82 @ARGV and die N("Spurious command-line arguments [%s]\n", "@ARGV");
83 $do_checkpoint && $rollback
84 and die N("You can't specify --checkpoint and --rollback at the same time\n");
85 $do_checkpoint && $listdate
86 and die N("You can't specify --checkpoint and --list at the same time\n");
87 $rollback && $listdate
88 and die N("You can't specify --rollback and --list at the same time\n");
89 $disable && ($listdate || $rollback || $do_checkpoint)
90 and die N("You can't specify --disable along with another option");
91
92 #- --list <date> and --list-all
93
94 if ($listdate) {
95 my $listtime = -1;
96 if ($listdate eq 'checkpoint') {
97 URPM::read_config_files();
98 $listtime = URPM::expand("%_unsafe_rollbacks");
99 } elsif ($listdate ne -1) {
100 #- convert to timestamp
101 $listtime = date_to_tid($listdate);
102 }
103 my %tids;
104
105 my $db = URPM::DB::open() or die "Can't open RPM DB\n";
106 $db->traverse(sub {
107 my ($p) = @_;
108 my $tid = $p->installtid;
109 return if $tid < $listtime;
110 exists $tids{$tid} or $tids{$tid} = [];
111 push @{ $tids{$tid} }, scalar($p->fullname);
112 });
113
114 unless (scalar keys %tids) {
115 die N("No transaction found since %s\n", $listdate);
116 }
117 print "Date rpms\n";
118 print "------------------- -------------------\n";
119 foreach my $tid (sort { $a <=> $b } keys %tids) {
120 my @p = @{$tids{$tid}};
121 print fmt_tid($tid), " ", shift(@p), "\n";
122 while (@p) {
123 print " " x 20, shift(@p), "\n";
124 }
125 }
126 exit(0);
127 }
128
129 #- check we're running as root
130 $< == 0 or die N("You must be superuser to do this");
131
132 #- --checkpoint
133
134 if ($do_checkpoint) {
135
136 URPM::read_config_files();
137 my $repackage_dir = URPM::expand("%_repackage_dir");
138 my $unsafe_rollbacks = time();
139
140 clean_repackage_dir($repackage_dir);
141
142 #- write rpm config file
143 print N("Writing rpm macros file [%s]...\n", $MACROS);
144 open my $fh, '>', $MACROS
145 or die "Can't open $MACROS for writing: $!\n";
146 print $fh <<MACROS;
147 # Generated by urpmi.recover
148
149 # Turn repackaging on
150 %_repackage_all_erasures 1
151
152 # Put repackaged rpms here (lots of space necessary)
153 %_repackage_dir $repackage_dir
154
155 # Don't erase on rollback before this date (seconds since epoch)
156 %_unsafe_rollbacks $unsafe_rollbacks
157
158 # Automate transaction rollbacks on upgrade failure
159 %_rollback_transaction_on_failure 0
160 MACROS
161 close $fh;
162
163 sys_log("checkpoint defined");
164 exit(0);
165 }
166
167 #- --rollback
168
169 if ($rollback) {
170 sys_log("called with: $command_line");
171
172 my $tid;
173 if ($rollback !~ /\D/) {
174 #- $rollback contains a number of transactions to roll back
175 #- get a date from there
176 my %tids;
177 my $db = URPM::DB::open() or die "Can't open RPM DB\n";
178 $db->traverse(sub { ++$tids{ $_[0]->installtid } });
179 my @tids = sort { $b <=> $a } keys %tids;
180 $tid = $tids[$rollback - 1];
181 } else {
182 #- $rollback contains a date, convert it to tid
183 $tid = date_to_tid($rollback);
184 }
185 $tid or die N("No rollback date found\n");
186
187 my $rollbackdate = fmt_tid($tid);
188 print N("Rollback until %s...\n", $rollbackdate), "\n";
189 exec '/bin/rpm', '-Uvh', '--rollback', $rollbackdate;
190 }
191
192 #- --disable
193
194 if ($disable) {
195 print N("Disabling repackaging\n");
196
197 unless ($noclean) {
198 URPM::read_config_files();
199 my $repackage_dir = URPM::expand("%_repackage_dir");
200 clean_repackage_dir($repackage_dir);
201 }
202
203 open my $fh, '<', $MACROS
204 or die "Can't open $MACROS for reading: $!\n";
205 my $macrosfile = join '', <$fh>;
206 close $fh;
207 #- turn off repackaging macro
208 $macrosfile =~ s/_repackage_all_erasures\s+\w+/_repackage_all_erasures 0/g;
209 print N("Writing rpm macros file [%s]...\n", $MACROS);
210 open $fh, '>', $MACROS
211 or die "Can't open $MACROS for writing: $!\n";
212 print $fh $macrosfile;
213 close $fh;
214
215 sys_log("repackaging disabled");
216 exit(0);
217 }

  ViewVC Help
Powered by ViewVC 1.1.28